shithub: gefs

Download patch

ref: 5a8080ba42efa1fe75d286fec5e94b7aa004959d
parent: 6bbc20102b8c32cb055b22d19736820e1f987f7f
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Apr 17 11:24:09 EDT 2023

ream: add special "adm" snapshot for users file

Until now, we loaded users from /adm/users in the
main snapshot; this made main more special than
necessary, and made it ambiguous which snapshot
users would get permissions from when traveling
through time.

Now, the adm label makes it unambiguous.

--- a/load.c
+++ b/load.c
@@ -105,8 +105,9 @@
 	fprint(2, "\tnextgen:\t%lld\n", fs->nextgen);
 	fprint(2, "\tblocksize:\t%lld\n", Blksz);
 	fprint(2, "\tcachesz:\t%lld MiB\n", fs->cmax*Blksz/MiB);
-	if((t = opensnap("main")) == nil)
+	if((t = opensnap("adm")) == nil)
 		sysfatal("load users: no main label");
 	if((e = loadusers(2, t)) != nil)
 		sysfatal("load users: %s\n", e);
+	closesnap(t);
 }
--- a/ream.c
+++ b/ream.c
@@ -6,8 +6,80 @@
 #include "dat.h"
 #include "fns.h"
 
+enum {
+	Qmainroot,
+	Qadmroot,
+	Qadmuser,
+	Nreamqid,
+};
 
+char *defaultusers =
+	"-1:adm::glenda\n"
+	"0:none::\n"
+	"1:tor:tor:\n"
+	"2:glenda:glenda:\n"
+	"10000:sys::\n"
+	"10001:map:map:\n"
+	"10002:doc::\n"
+	"10003:upas:upas:\n"
+	"10004:font::\n"
+	"10005:bootes:bootes:\n";
+
 static void
+fillxdir(Xdir *d, vlong qid, char *name, int type, int mode)
+{
+	memset(d, 0, sizeof(Xdir));
+	d->qid = (Qid){qid, 0, type};
+	d->mode = mode;
+	d->atime = 0;
+	d->mtime = 0;
+	d->length = 0;
+	d->name = name;
+	d->uid = -1;
+	d->gid = -1;
+	d->muid = 0;
+}
+
+static void
+initadm(Blk *r, Blk *u)
+{
+	char *p, kbuf[Keymax], vbuf[Inlmax];
+	Kvp kv;
+	Xdir d;
+
+	/* nb: values must be inserted in key order */
+	kv.k = kbuf;
+	kv.nk = Offksz;
+	kv.v = vbuf;
+	kv.nv = Ptrsz;
+	kbuf[0] = Kdat;
+	PACK64(kbuf+1, (uvlong)Qadmuser);
+	PACK64(kbuf+9, 0ULL);
+	packbp(kv.v, kv.nv, &u->bp);
+	setval(r, &kv);
+
+	fillxdir(&d, Qadmuser, "users", QTFILE, 0664);
+	d.length = strlen(defaultusers);
+	if(dir2kv(Qadmroot, &d, &kv, vbuf, sizeof(vbuf)) == -1)
+		sysfatal("ream: pack users: %r");
+	setval(r, &kv);
+	fillxdir(&d, Qadmroot, "", QTDIR, DMDIR|0775);
+	if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
+		sysfatal("ream: pack root: %r");
+	setval(r, &kv);
+
+	if((p = packsuper(kbuf, sizeof(kbuf), 0)) == nil)
+		sysfatal("ream: pack super");
+	kv.k = kbuf;
+	kv.nk = p - kbuf;
+	if((p = packdkey(vbuf, sizeof(vbuf), -1, "")) == nil)
+		sysfatal("ream: pack super");
+	kv.v = vbuf;
+	kv.nv = p - vbuf;
+	setval(r, &kv);
+}
+
+static void
 initroot(Blk *r)
 {
 	char *p, kbuf[Keymax], vbuf[Inlmax];
@@ -15,16 +87,7 @@
 	Xdir d;
 
 	/* nb: values must be inserted in key order */
-	memset(&d, 0, sizeof(Xdir));
-	d.qid = (Qid){fs->nextqid++, 0, QTDIR};
-	d.mode = DMDIR|0775;
-	d.atime = 0;
-	d.mtime = 0;
-	d.length = 0;
-	d.name = "";
-	d.uid = -1;
-	d.gid = -1;
-	d.muid = 0;
+	fillxdir(&d, Qmainroot, "", QTDIR, DMDIR|0775);
 	if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
 		sysfatal("ream: pack root: %r");
 	setval(r, &kv);
@@ -41,12 +104,20 @@
 }
 
 static void
-initsnap(Blk *s, Blk *r)
+initsnap(Blk *s, Blk *r, Blk *a)
 {
 	char *p, kbuf[Keymax], vbuf[Treesz];
 	Tree t;
 	Kvp kv;
 
+	p = packlabel(kbuf, sizeof(kbuf), "adm");
+	kv.k = kbuf;
+	kv.nk = p - kbuf;
+	p = packsnap(vbuf, sizeof(vbuf), 1);
+	kv.v = vbuf;
+	kv.nv = p - vbuf;
+	setval(s, &kv);
+
 	p = packlabel(kbuf, sizeof(kbuf), "empty");
 	kv.k = kbuf;
 	kv.nk = p - kbuf;
@@ -54,6 +125,7 @@
 	kv.v = vbuf;
 	kv.nv = p - vbuf;
 	setval(s, &kv);
+
 	p = packlabel(kbuf, sizeof(kbuf), "main");
 	kv.k = kbuf;
 	kv.nk = p - kbuf;
@@ -67,7 +139,7 @@
 	kv.nk = p - kbuf;
 
 	memset(&t, 0, sizeof(Tree));
-	t.nsucc = 0;
+	t.nsucc = 1;
 	t.nlbl = 2;
 	t.ht = 1;
 	t.gen = fs->nextgen++;
@@ -77,6 +149,22 @@
 	kv.v = vbuf;
 	kv.nv = p - vbuf;
 	setval(s, &kv);
+
+	p = packsnap(kbuf, sizeof(kbuf), 1);
+	kv.k = kbuf;
+	kv.nk = p - kbuf;
+
+	memset(&t, 0, sizeof(Tree));
+	t.nsucc = 0;
+	t.nlbl = 1;
+	t.ht = 1;
+	t.gen = fs->nextgen++;
+	t.prev = -1ULL;
+	t.bp = a->bp;
+	p = packtree(vbuf, sizeof(vbuf), &t);
+	kv.v = vbuf;
+	kv.nv = p - vbuf;
+	setval(s, &kv);
 }
 
 static void
@@ -135,9 +223,9 @@
 void
 reamfs(char *dev)
 {
+	Blk *sb, *mb, *ab, *ub;
 	vlong sz, asz, off;
-	Blk *rb, *tb;
-	Mount *mnt;
+	Mount *mnt, *adm;
 	Arena *a;
 	Dir *d;
 	int i;
@@ -155,6 +243,11 @@
 	if((mnt->root = mallocz(sizeof(Tree), 1)) == nil)
 		sysfatal("ream: alloc tree: %r");
 
+	if((adm = mallocz(sizeof(Mount), 1)) == nil)
+		sysfatal("ream: alloc mount: %r");
+	if((adm->root = mallocz(sizeof(Tree), 1)) == nil)
+		sysfatal("ream: alloc tree: %r");
+
 	fs->narena = (sz + 64ULL*GiB - 1) / (64ULL*GiB);
 	if(fs->narena < 8)
 		fs->narena = 8;
@@ -182,33 +275,53 @@
 		if(compresslog(a) == -1)
 			sysfatal("compress log: %r");
 	}
-	if((tb = newblk(mnt->root, Tleaf)) == nil)
+	if((mb = newblk(mnt->root, Tleaf)) == nil)
 		sysfatal("ream: allocate root: %r");
-	holdblk(tb);
-	initroot(tb);
-	finalize(tb);
-	syncblk(tb);
+	holdblk(mb);
+	initroot(mb);
+	finalize(mb);
+	syncblk(mb);
 
 	mnt->root->ht = 1;
-	mnt->root->bp = tb->bp;
+	mnt->root->bp = mb->bp;
 
+	if((ab = newblk(adm->root, Tleaf)) == nil)
+		sysfatal("ream: allocate root: %r");
+	if((ub = newblk(adm->root, Tdat)) == nil)
+		sysfatal("ream: allocate root: %r");
+	holdblk(ab);
+	holdblk(ub);
+	memcpy(ub->data, defaultusers, strlen(defaultusers));
+	finalize(ub);
+	syncblk(ub);
+	initadm(ab, ub);
+	finalize(ab);
+	syncblk(ab);
+
+	adm->root->ht = 1;
+	adm->root->bp = ab->bp;
+
 	/*
 	 * Now that we have a completely empty fs, give it
 	 * a single snap block that the tree will insert
 	 * into, and take a snapshot as the initial state.
 	 */
-	if((rb = newblk(mnt->root, Tleaf)) == nil)
+	if((sb = newblk(mnt->root, Tleaf)) == nil)
 		sysfatal("ream: allocate snaps: %r");
-	holdblk(rb);
-	initsnap(rb, tb);
-	finalize(rb);
-	syncblk(rb);
+	holdblk(sb);
+	initsnap(sb, mb, ab);
+	finalize(sb);
+	syncblk(sb);
 
-	fs->snap.bp = rb->bp;
+	fs->snap.bp = sb->bp;
 	fs->snap.ht = 1;
 
-	dropblk(tb);
-	dropblk(rb);
+	dropblk(mb);
+	dropblk(ab);
+	dropblk(ub);
+	dropblk(sb);
+	fs->nextqid = Nreamqid;
+
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
 		finalize(a->tail);
--- a/snap.c
+++ b/snap.c
@@ -315,7 +315,7 @@
 	Msg m[2];
 	int nm;
 
-	if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0)
+	if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0 || strcmp(name, "adm") == 0)
 		return Ename;
 
 	nm = 0;
@@ -363,7 +363,7 @@
 	char buf[2][Kvmax];
 	Msg m[2];
 
-	if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0)
+	if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0 || strcmp(name, "adm") == 0)
 		return Ename;
 	t->nlbl++;
 	m[0].op = Oinsert;
--- a/user.c
+++ b/user.c
@@ -6,18 +6,6 @@
 #include "dat.h"
 #include "fns.h"
 
-char *defaultusers =
-	"-1:adm::glenda\n"
-	"0:none::\n"
-	"1:tor:tor:\n"
-	"2:glenda:glenda:\n"
-	"10000:sys::\n"
-	"10001:map:map:\n"
-	"10002:doc::\n"
-	"10003:upas:upas:\n"
-	"10004:font::\n"
-	"10005:bootes:bootes:\n";
-
 static int
 walk1(Tree *t, vlong up, char *name, Qid *qid, vlong *len)
 {
@@ -260,13 +248,10 @@
 	vlong len;
 	Qid q;
 
-	s = defaultusers;
 	if(walk1(t, -1, "", &q, &len) == -1)
 		return Efs;
-	if(walk1(t, q.path, "adm", &q, &len) == -1)
-		goto Defaulted;
 	if(walk1(t, q.path, "users", &q, &len) == -1)
-		goto Defaulted;
+		return Eio;
 	if(q.type != QTFILE)
 		return Etype;
 	if(len >= 1*MiB)
@@ -273,9 +258,7 @@
 		return Efsize;
 	if((s = slurp(t, q.path, len)) == nil)
 		return Eio;
-Defaulted:
 	e = parseusers(fd, s);
-	if(s != defaultusers)
-		free(s);
+	free(s);
 	return e;
 }