From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 5706 invoked from network); 30 May 2022 11:53:52 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 30 May 2022 11:53:52 -0000 Received: from mail.posixcafe.org ([45.76.19.58]) by 9front; Mon May 30 07:50:39 -0400 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posixcafe.org; s=20200506; t=1653911435; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Fic/j/CaH1EUJcUW43i9Lwcp1yFVdOowyaQKhL9DN3Y=; b=rfkU1btYyMTq8Ukdt/mF48Irb2+5zURq/2t4rmurmfJvXrM/7L+h7yfLG28aVmdBtklKwg cj5Y7v2+dmcNs7RFFaIXEvag0H3yslq4XRVND/I8ltawQrL0UBIcDBoQHOQgvcU6efmtxE ChQ3yZ8IxnCJD3UXC0A4LBJ6lgdH3Nk= Received: from [192.168.168.200] (161-97-228-135.lpcnextlight.net [161.97.228.135]) by mail.posixcafe.org (OpenSMTPD) with ESMTPSA id a4a00355 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for <9front@9front.org>; Mon, 30 May 2022 06:50:35 -0500 (CDT) Message-ID: <6bb0ee7b-0916-a6df-913e-3f41256ce1eb@posixcafe.org> Date: Mon, 30 May 2022 05:50:13 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1 Content-Language: en-US To: 9front@9front.org From: Jacob Moody Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: immutable immutable SQL cache general-purpose framework Subject: [9front] [PATCH] private /srv attach option Reply-To: 9front@9front.org Precedence: bulk This patch add a 'p' attach option to srv to get a private session. The sessions work similarly to #| sessions. Attaching a private /srv does not effect future attaches to '#s' without the private option. I figure the global /srv can be explicitly given up through chdev if desired. --- diff b75e549126641108880a24a4ff0b38171eb1a856 uncommitted --- a//sys/src/9/port/devsrv.c +++ b//sys/src/9/port/devsrv.c @@ -17,16 +17,23 @@ ulong path; }; -static QLock srvlk; -static Srv *srv; -static int qidpath; +typedef struct Fid Fid; +struct Fid +{ + int ref; + QLock lk; + Srv *tail; + int qidpath; +}; +static Fid global; + static Srv* -srvlookup(char *name, ulong qidpath) +srvlookup(Fid *f, char *name, ulong qidpath) { Srv *sp; - for(sp = srv; sp != nil; sp = sp->link) { + for(sp = f->tail; sp != nil; sp = sp->link) { if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0)) return sp; } @@ -38,6 +45,7 @@ { Srv *sp; Qid q; + Fid *f; if(s == DEVDOTDOT){ devdir(c, c->qid, "#s", 0, eve, 0555, dp); @@ -44,15 +52,17 @@ return 1; } - qlock(&srvlk); + f = c->aux; + + qlock(&f->lk); if(name != nil) - sp = srvlookup(name, -1); + sp = srvlookup(f, name, -1); else { - for(sp = srv; sp != nil && s > 0; sp = sp->link) + for(sp = f->tail; sp != nil && s > 0; sp = sp->link) s--; } if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) { - qunlock(&srvlk); + qunlock(&f->lk); return -1; } mkqid(&q, sp->path, 0, QTFILE); @@ -59,7 +69,7 @@ /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); - qunlock(&srvlk); + qunlock(&f->lk); return 1; } @@ -66,19 +76,45 @@ static void srvinit(void) { - qidpath = 1; + global.qidpath = 1; } static Chan* srvattach(char *spec) { - return devattach('s', spec); + Chan *c; + Fid *f; + + c = devattach('s', spec); + f = &global; + if(spec != nil && spec[0] == 'p'){ + f = smalloc(sizeof *f); + f->qidpath = 1; + f->ref = 1; + } + c->aux = f; + return c; } static Walkqid* srvwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, nc, name, nname, 0, 0, srvgen); + Walkqid *wq; + Fid *f; + + wq = devwalk(c, nc, name, nname, 0, 0, srvgen); + if(wq == nil || wq->clone == nil || wq->clone == c) + return wq; + + f = c->aux; + /* global doesn't ref count */ + if(f == &global) + return wq; + + qlock(&f->lk); + f->ref++; + qunlock(&f->lk); + return wq; } static int @@ -91,11 +127,13 @@ srvname(Chan *c) { Srv *sp; + Fid *f; char *s; s = nil; - qlock(&srvlk); - for(sp = srv; sp != nil; sp = sp->link) { + f = &global; + qlock(&f->lk); + for(sp = f->tail; sp != nil; sp = sp->link) { if(sp->chan == c){ s = malloc(3+strlen(sp->name)+1); if(s != nil) @@ -103,7 +141,7 @@ break; } } - qunlock(&srvlk); + qunlock(&f->lk); return s; } @@ -111,6 +149,7 @@ srvopen(Chan *c, int omode) { Srv *sp; + Fid *f; Chan *nc; if(c->qid.type == QTDIR){ @@ -123,13 +162,14 @@ c->offset = 0; return c; } - qlock(&srvlk); + f = c->aux; + qlock(&f->lk); if(waserror()){ - qunlock(&srvlk); + qunlock(&f->lk); nexterror(); } - sp = srvlookup(nil, c->qid.path); + sp = srvlookup(f, nil, c->qid.path); if(sp == nil || sp->chan == nil) error(Eshutdown); @@ -144,7 +184,7 @@ nc = sp->chan; incref(nc); - qunlock(&srvlk); + qunlock(&f->lk); poperror(); cclose(c); @@ -155,6 +195,7 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) { Srv *sp; + Fid *f; if(openmode(omode) != OWRITE) error(Eperm); @@ -162,31 +203,32 @@ if(strlen(name) >= sizeof(up->genbuf)) error(Etoolong); + f = c->aux; sp = smalloc(sizeof *sp); kstrdup(&sp->name, name); kstrdup(&sp->owner, up->user); - qlock(&srvlk); + qlock(&f->lk); if(waserror()){ - qunlock(&srvlk); + qunlock(&f->lk); free(sp->owner); free(sp->name); free(sp); nexterror(); } - if(srvlookup(name, -1) != nil) + if(srvlookup(f, name, -1) != nil) error(Eexist); sp->perm = perm&0777; - sp->path = qidpath++; + sp->path = f->qidpath++; c->qid.path = sp->path; c->qid.type = QTFILE; - sp->link = srv; - srv = sp; + sp->link = f->tail; + f->tail = sp; - qunlock(&srvlk); + qunlock(&f->lk); poperror(); c->flag |= COPEN; @@ -199,16 +241,19 @@ srvremove(Chan *c) { Srv *sp, **l; + Fid *f; if(c->qid.type == QTDIR) error(Eperm); - qlock(&srvlk); + f = c->aux; + + qlock(&f->lk); if(waserror()){ - qunlock(&srvlk); + qunlock(&f->lk); nexterror(); } - l = &srv; + l = &f->tail; for(sp = *l; sp != nil; sp = *l) { if(sp->path == c->qid.path) break; @@ -232,7 +277,15 @@ *l = sp->link; sp->link = nil; - qunlock(&srvlk); + if(f != &global){ + f->ref--; + if(f->ref <= 0) + free(f); + else + qunlock(&f->lk); + } else + qunlock(&f->lk); + poperror(); if(sp->chan != nil) @@ -247,6 +300,7 @@ { char *strs; Srv *sp; + Fid *f; Dir d; if(c->qid.type & QTDIR) @@ -261,13 +315,15 @@ if(n == 0) error(Eshortstat); - qlock(&srvlk); + f = c->aux; + + qlock(&f->lk); if(waserror()){ - qunlock(&srvlk); + qunlock(&f->lk); nexterror(); } - sp = srvlookup(nil, c->qid.path); + sp = srvlookup(f, nil, c->qid.path); if(sp == nil) error(Enonexist); @@ -286,7 +342,7 @@ if(d.mode != ~0UL) sp->perm = d.mode & 0777; - qunlock(&srvlk); + qunlock(&f->lk); poperror(); free(strs); @@ -298,16 +354,32 @@ static void srvclose(Chan *c) { + Fid *f; + /* * in theory we need to override any changes in removability * since open, but since all that's checked is the owner, * which is immutable, all is well. */ - if(c->flag & CRCLOSE){ + if((c->flag & COPEN) && (c->flag & CRCLOSE)){ if(waserror()) - return; + goto ref; + srvremove(c); poperror(); + } else { + +ref: + f = c->aux; + + if(f != &global){ + qlock(&f->lk); + f->ref--; + if(f->ref <= 0) + free(f); + else + qunlock(&f->lk); + } } } @@ -322,6 +394,7 @@ srvwrite(Chan *c, void *va, long n, vlong) { Srv *sp; + Fid *f; Chan *c1; int fd; char buf[32]; @@ -334,15 +407,17 @@ c1 = fdtochan(fd, -1, 0, 1); /* error check and inc ref */ - qlock(&srvlk); + f = c->aux; + + qlock(&f->lk); if(waserror()) { - qunlock(&srvlk); + qunlock(&f->lk); cclose(c1); nexterror(); } if(c1->qid.type & QTAUTH) error("cannot post auth file in srv"); - sp = srvlookup(nil, c->qid.path); + sp = srvlookup(f, nil, c->qid.path); if(sp == nil) error(Enonexist); @@ -351,7 +426,7 @@ sp->chan = c1; - qunlock(&srvlk); + qunlock(&f->lk); poperror(); return n; } @@ -381,11 +456,13 @@ srvrenameuser(char *old, char *new) { Srv *sp; + Fid *f; - qlock(&srvlk); - for(sp = srv; sp != nil; sp = sp->link) { + f = &global; + qlock(&f->lk); + for(sp = f->tail; sp != nil; sp = sp->link) { if(sp->owner != nil && strcmp(old, sp->owner) == 0) kstrdup(&sp->owner, new); } - qunlock(&srvlk); + qunlock(&f->lk); }