shithub: mq

Download patch

ref: 5258bb0610a7af3630b212f652db71d5f55952ae
parent: e17ea9d6bc50ccf3291647bf2af303dc254b327f
author: kvik <kvik@a-b.xyz>
date: Sun Dec 13 13:55:48 EST 2020

mq: create an automatic root stream group

mq is quite often used in situations where only a single stream group
is needed.  In these cases it is preferable to just create the streams
immediately under the mq mount, avoiding the need for redundant naming
and an extra level in hierarchy.

We allow this by allocating an automatic root stream group at startup.

--- a/man/4/mq
+++ b/man/4/mq
@@ -148,6 +148,7 @@
 being created automatically.
 Similarly, streams are allocated by creating files inside the group
 directory.
+On startup an empty stream group is allocated at the root level.
 .PP
 The file
 .I order
--- a/src/mq.c
+++ b/src/mq.c
@@ -52,12 +52,13 @@
 };
 
 enum {
-	/* Dirty trick to help clients tell us from most others. */
+	/* Dirty trick to help clients tell our
+	 * root from most others, see pin(1). */
 	Qroot = 0xA,
-		Qmq = 0x1,
-			Qstream,
-			Qorder,
-			Qctl,
+	Qmq = 0x1,
+		Qstream,
+		Qorder,
+		Qctl,
 };
 void
 filesettype(File *f, ushort type)
@@ -66,7 +67,8 @@
 	 * Use four most-significant bits to store the type.
 	 * This depends on the 9pfile(2) library generating
 	 * simple incremental qid paths.
-	*/
+	 */
+	f->qid.path &= ~(uvlong)0xF<<60;
 	f->qid.path |= (uvlong)(type&0xF)<<60;
 }
 
@@ -91,7 +93,13 @@
 	mq->replay = Replayoff;
 
 	ctl = order = nil;
-	if((d = createfile(parent, name, uid, perm, mq)) == nil)
+	if(strcmp(name, "/") == 0){
+		d = parent;
+		d->aux = mq;
+	}
+	else
+		d = createfile(parent, name, uid, perm, mq);
+	if(d == nil)
 		goto err;
 	filesettype(d, Qmq);
 
@@ -428,11 +436,6 @@
 
 	switch(filetype(parent)){
 	case Qroot:
-		if(!(perm&DMDIR)){
-			respond(r, "forbidden");
-			return;
-		}
-		/* fallthrough */
 	case Qmq:
 		if(perm&DMDIR)
 			f = mqcreate(parent, name, uid, perm);
@@ -441,7 +444,7 @@
 		break;
 	}
 	if(f == nil)
-		responderror(r);
+		respond(r, "internal failure");
 	else
 		respond(r, nil);
 }
@@ -652,6 +655,7 @@
 	}ARGEND;
 
 	fs.tree = alloctree(nil, nil, DMDIR|0777, xdestroyfile);
+	mqcreate(fs.tree->root, "/", nil, 0);
 	filesettype(fs.tree->root, Qroot);
 
 	if(name || mtpt){