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=-1.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, NICE_REPLY_A,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 2526 invoked from network); 8 Jun 2022 14:50:52 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 8 Jun 2022 14:50:52 -0000 Received: from mail.posixcafe.org ([45.76.19.58]) by 9front; Wed Jun 8 10:49:23 -0400 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posixcafe.org; s=20200506; t=1654699759; 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: in-reply-to:in-reply-to:references:references; bh=tcLOys8yhV3F/xsImrshGCS34rlXRb9v2sEUEfcAyFQ=; b=a0HDpeG+4x6cp/9gkXi7ICbByA5bM8adoDnqHTLdYYywsabIzkKDAz1PH2zY1I7FutSI2V eAxJJl+1xRkmkKqpfjC3PjFrv/sVy7wJQsIyFkDhp1Fa78cJ/0yfa03PpLh0/lL6+OHm06 DRUMlKa4odjvHfPLdMif3HIvjYG74c4= Received: from [192.168.168.200] (161-97-228-135.lpcnextlight.net [161.97.228.135]) by mail.posixcafe.org (OpenSMTPD) with ESMTPSA id 89433289 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for <9front@9front.org>; Wed, 8 Jun 2022 09:49:18 -0500 (CDT) Message-ID: <27178dc6-eefd-7b5a-c243-467331d31e10@posixcafe.org> Date: Wed, 8 Jun 2022 08:48:42 -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 References: <847F45EC7225C1D0B69E796B69D6E3ED@eigenstate.org> <475b654b-641e-6f08-c5bc-bcf6aab4f51a@posixcafe.org> From: Jacob Moody In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: converged asynchronous GPU-scale core module descriptor-based frontend Subject: Re: [9front] [PATCH] private /srv attach option Reply-To: 9front@9front.org Precedence: bulk Another iteration on this: Scrapped the attach option. This uses a /new child directory for getting a fresh instance. The new instance is alloted on walks to this dir, but due to our fid clone conventions you can safely interact with the file without worrying about it nuking your /srv. Only other change from the previous patch is that we ensure that each private session has unique qid paths. This makes the convention for getting a private /srv: bind /srv/new /srv This patch might need a bit more tidying, but in general I am pretty happy with this interface. Thanks, moody ---- diff 1b5ea51ee1203952900fafc0def48985d900f7a7 uncommitted --- a//sys/src/9/port/devsrv.c +++ b//sys/src/9/port/devsrv.c @@ -5,6 +5,7 @@ #include "fns.h" #include "../port/error.h" +#include "netif.h" typedef struct Srv Srv; struct Srv @@ -17,16 +18,29 @@ ulong path; }; -static QLock srvlk; -static Srv *srv; -static int qidpath; +typedef struct Fid Fid; +struct Fid +{ + int ref; + QLock lk; + Srv *tail; + ulong nextpath; +}; +struct { + QLock; + ulong path; +} sessions; + +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) { + qidpath = NETTYPE(qidpath); + for(sp = f->tail; sp != nil; sp = sp->link) { if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0)) return sp; } @@ -38,28 +52,57 @@ { Srv *sp; Qid q; + Fid *f; + ulong id; if(s == DEVDOTDOT){ - devdir(c, c->qid, "#s", 0, eve, 0555, dp); + devdir(c, c->qid, "#s", 0, eve, 0555|DMDIR, dp); return 1; } - qlock(&srvlk); - if(name != nil) - sp = srvlookup(name, -1); - else { - for(sp = srv; sp != nil && s > 0; sp = sp->link) + f = c->aux; + qlock(&f->lk); + id = NETID(c->qid.path); + + if(name != nil){ + if(strcmp(name, "new") == 0){ + if(f != &global && --f->ref == 0){ + qunlock(&f->lk); + free(f); + } else + qunlock(&f->lk); + f = smalloc(sizeof *f); + qlock(&sessions); + id = ++sessions.path; + qunlock(&sessions); + f->ref = 1; + f->nextpath = 2; + mkqid(&q, NETQID(id, 1), 0, QTDIR); + devdir(c, q, "new", 0, eve, 0555|DMDIR, dp); + c->aux = f; + return 1; + } + sp = srvlookup(f, name, -1); + } else { + if(s == 0){ + mkqid(&q, NETQID(id, 1), 0, QTDIR); + devdir(c, q, "new", 0, eve, 0555|DMDIR, dp); + qunlock(&f->lk); + return 1; + } + s -= 1; + 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); + mkqid(&q, NETQID(id, sp->path), 0, QTFILE); /* 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 +109,38 @@ static void srvinit(void) { - qidpath = 1; + global.nextpath = 2; } static Chan* srvattach(char *spec) { - return devattach('s', spec); + Chan *c; + + c = devattach('s', spec); + c->aux = &global; + 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 +153,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 +167,7 @@ break; } } - qunlock(&srvlk); + qunlock(&f->lk); return s; } @@ -111,6 +175,7 @@ srvopen(Chan *c, int omode) { Srv *sp; + Fid *f; Chan *nc; if(c->qid.type == QTDIR){ @@ -123,13 +188,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 +210,7 @@ nc = sp->chan; incref(nc); - qunlock(&srvlk); + qunlock(&f->lk); poperror(); cclose(c); @@ -155,6 +221,7 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) { Srv *sp; + Fid *f; if(openmode(omode) != OWRITE) error(Eperm); @@ -162,31 +229,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->nextpath++; - c->qid.path = sp->path; + c->qid.path = NETQID(NETID(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,18 +267,21 @@ 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) + if(sp->path == NETTYPE(c->qid.path)) break; l = &sp->link; } @@ -232,7 +303,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 +326,7 @@ { char *strs; Srv *sp; + Fid *f; Dir d; if(c->qid.type & QTDIR) @@ -261,13 +341,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 +368,7 @@ if(d.mode != ~0UL) sp->perm = d.mode & 0777; - qunlock(&srvlk); + qunlock(&f->lk); poperror(); free(strs); @@ -298,16 +380,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 +420,7 @@ srvwrite(Chan *c, void *va, long n, vlong) { Srv *sp; + Fid *f; Chan *c1; int fd; char buf[32]; @@ -334,15 +433,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 +452,7 @@ sp->chan = c1; - qunlock(&srvlk); + qunlock(&f->lk); poperror(); return n; } @@ -381,11 +482,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); }