From: Jacob Moody <moody@mail.posixcafe.org>
To: 9front@9front.org
Subject: Re: [9front] [PATCH] private /srv attach option
Date: Wed, 8 Jun 2022 08:48:42 -0600 [thread overview]
Message-ID: <27178dc6-eefd-7b5a-c243-467331d31e10@posixcafe.org> (raw)
In-Reply-To: <fa5b5eb1-bf4e-ba56-6922-1f3bca25824e@posixcafe.org>
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);
}
next prev parent reply other threads:[~2022-06-08 14:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-30 11:50 Jacob Moody
2022-05-30 14:44 ` ori
2022-05-30 17:26 ` Jacob Moody
2022-05-30 20:04 ` ori
2022-05-31 7:03 ` hiro
2022-05-31 15:09 ` Jacob Moody
2022-05-31 16:04 ` Jacob Moody
2022-06-08 14:48 ` Jacob Moody [this message]
2022-06-22 15:22 ` cinap_lenrek
2022-05-30 14:56 ` ori
2022-07-10 21:47 ` ori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=27178dc6-eefd-7b5a-c243-467331d31e10@posixcafe.org \
--to=moody@mail.posixcafe.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).