ref: 5258bb0610a7af3630b212f652db71d5f55952ae
parent: e17ea9d6bc50ccf3291647bf2af303dc254b327f
author: kvik <[email protected]>
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){