commit a9df616ed71ee9e4d8b559526a9396e6a3273153
parent fd6cb5e974b08a14e7ab48718decc7742d635e6b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 23 Aug 2020 18:44:21 +0200
dev: Change Qid representation
We were using a hort to represent Qid numbers, which demostrated
to be too short for some devices. This patch converts Qid to a
structure with the 3 fields used in 9p, even when version is not
used in any place.
Change-Id: Id2c5b88b5098303aef003a84763ad77e1c929c89
Diffstat:
13 files changed, 100 insertions(+), 75 deletions(-)
diff --git a/include/9os/io.h b/include/9os/io.h
@@ -12,8 +12,25 @@
#define KSEEK_CUR 1
#define KSEEK_END 2
+#define QID(t, v, p) ((Qid) {.type = (t), .vers = (v), .path = (p)})
+
typedef struct dir Dir;
-typedef unsigned short Qid;
+typedef struct qid Qid;
+
+enum devflags {
+ O_READ = 1 << 0,
+ O_WRITE = 1 << 1,
+ O_RDWR = 1 << 2,
+ O_BIND = 1 << 3,
+ O_DIR = 1 << 4,
+ O_STAT = 1 << 5,
+};
+
+struct qid {
+ unsigned long long path;
+ unsigned long vers;
+ unsigned char type;
+};
struct dir {
char name[NAMELEN];
@@ -41,15 +58,6 @@ extern int readdir(DIR *dir, struct dirent *ent);
extern int closedir(DIR *dir);
extern int dirstat(char *name, Dir *dir);
-enum devflags {
- O_READ = 1 << 0,
- O_WRITE = 1 << 1,
- O_RDWR = 1 << 2,
- O_BIND = 1 << 3,
- O_DIR = 1 << 4,
- O_STAT = 1 << 5,
-};
-
/* driver functions */
extern int mount(char *srv, char *mnt, char *spec);
extern int create(const char *name, int flags);
diff --git a/src/kernel/dev/dev.c b/src/kernel/dev/dev.c
@@ -31,6 +31,12 @@ static Chan fdset[NR_CHANS];
static Chan slash;
static struct mpoint mpoints[NR_MPOINTS];
+int
+sameqid(Qid q1, Qid q2)
+{
+ return q1.type == q2.type && q1.vers == q2.vers && q1.path == q2.path;
+}
+
Chan *
newchan(unsigned char type)
{
@@ -56,7 +62,7 @@ newchan(unsigned char type)
void
delchan(Chan *c)
{
- c->qid = 0;
+ c->qid = QID(0, 0, 0);
c->dev = 0;
c->offset = 0;
c->type = NODEV;
@@ -174,7 +180,7 @@ mntpoint(int type, Qid qid)
unlock(&mp->mutex);
continue;
}
- if (cn->type == type && cn->qid == qid) {
+ if (cn->type == type && sameqid(cn->qid, qid)) {
unlock(&mp->mutex);
return mp->old;
}
@@ -206,7 +212,7 @@ devattach(int id, int dev)
if ((c = newchan(type)) == NULL)
return NULL;
c->dev = dev;
- c->qid = CHDIR;
+ c->qid = QID(CHDIR, 0, 0);
return c;
}
@@ -245,7 +251,7 @@ namec(const char *name, int mode)
return NULL;
for (s = next(s, elem); *elem; s = next(s, elem)) {
- if ((c->qid & CHDIR) == 0)
+ if (c->qid.type != CHDIR)
goto notfound;
if (devtab[c->type]->walk(c, elem) < 0) {
delchan(c);
@@ -347,7 +353,7 @@ mkentry(Chan *c, Dir *dir,
dir->length = length;
dir->qid = qid;
dir->mode = mode;
- if (qid & CHDIR)
+ if (qid.type == CHDIR)
dir->mode |= O_DIR;
dir->type = c->type;
dir->dev = c->dev;
@@ -420,7 +426,7 @@ devstat(Chan *dirc, char *file,
dir.qid = mnt->qid;
dir.type = mnt->type;
}
- if (dir.qid != c->qid || dir.type != c->type)
+ if (sameqid(dir.qid, c->qid) || dir.type != c->type)
continue;
r = dirtop9(&dir, buf, n);
goto leave;
@@ -481,7 +487,7 @@ read(int fd, void *buf, int n)
if ((c = fd2chan(fd)) == NULL)
return -1;
- if ((c->qid & CHDIR) && (n < DIRLEN))
+ if (c->qid.type == CHDIR && n < DIRLEN)
errno = EINVAL;
else
r = devtab[c->type]->read(c, buf, n);
@@ -499,7 +505,7 @@ write(int fd, void *buf, int n)
if ((c = fd2chan(fd)) == NULL)
return -1;
- if (c->qid & CHDIR)
+ if (c->qid.type == CHDIR)
errno = EISDIR;
else
r = devtab[c->type]->write(c, buf, n);
@@ -517,7 +523,7 @@ seek(int fd, long off, int whence)
if ((c = fd2chan(fd)) == NULL)
return -1;
- if (c->qid & CHDIR)
+ if (c->qid.type == CHDIR)
errno = EISDIR;
else
r = devtab[c->type]->seek(c, off, whence);
@@ -535,7 +541,7 @@ fsync(int fd)
if ((c = fd2chan(fd)) == NULL)
return -1;
- if (c->qid & CHDIR)
+ if (c->qid.type == CHDIR)
errno = EISDIR;
else
r = devtab[c->type]->sync(c, SYNCDEV);
@@ -611,7 +617,7 @@ addmntpoint(Chan *c, char *new)
if ((cn = namec(new, O_READ)) == NULL)
goto err0;
- if ((cn->qid & CHDIR) == 0) {
+ if (cn->qid.type != CHDIR) {
errno = ENOTDIR;
goto err1;
}
diff --git a/src/kernel/dev/dev.h b/src/kernel/dev/dev.h
@@ -5,7 +5,8 @@
#define NR_BINDS 4
#define NR_FILES 20
#define NODEV 255
-#define CHDIR (1 << 15)
+#define CHDIR 0x80
+#define CHFILE 0x00
#define SYNCDEV 0
#define SYNCALL 1
@@ -51,7 +52,7 @@ struct attr {
char *value;
};
-
+extern int sameqid(Qid q1, Qid qid2);
extern Chan *namec(const char *name, int mode);
extern Chan *clone(Chan *c, Chan *nc);
extern Chan *attach(int id, int dev);
diff --git a/src/kernel/dev/devar.c b/src/kernel/dev/devar.c
@@ -89,7 +89,10 @@ argen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir)
return -1;
}
- mkentry(c, dir, hdr.ar_name, atol(hdr.ar_size), n, O_READ);
+ mkentry(c, dir,
+ hdr.ar_name, atol(hdr.ar_size),
+ QID(CHFILE, 0, n),
+ O_READ);
return 1;
}
@@ -113,19 +116,21 @@ arread(Chan *c, void *buf, int n)
Chan cs;
struct arfile *ar;
long size;
+ long long path;
- if (c->qid == CHDIR)
+ if (c->qid.type == CHDIR)
return dirread(c, buf, n, NULL, 0, argen);
- if (c->dev >= nars || (c->qid & CHDIR))
+ if (c->dev >= nars)
panic("arread1");
ar = &archives[c->dev];
- if (c->qid >= NR_FILES || ar->offset[c->qid] == -1)
+ path = c->qid.path;
+ if (path >= NR_FILES || ar->offset[path] == -1)
panic("arread2");
clone(ar->c, &cs);
- size = ar->size[c->qid];
+ size = ar->size[path];
if (c->offset >= size)
return 0;
@@ -136,7 +141,7 @@ arread(Chan *c, void *buf, int n)
if (n > size - c->offset)
n = size - c->offset;
- off = ar->offset[c->qid] + c->offset + sizeof(struct ar_hdr);
+ off = ar->offset[path] + c->offset + sizeof(struct ar_hdr);
if (devtab[cs.type]->seek(&cs, off, KSEEK_SET) < 0)
return -1;
diff --git a/src/kernel/dev/devblk.c b/src/kernel/dev/devblk.c
@@ -39,8 +39,8 @@ static char buffers[NR_BUFFERS][BLKSIZ];
static Buffer bcache[NR_BUFFERS];
static const Dirtab dirtab[] = {
- {"raw", Qraw, 0, O_READ | O_WRITE},
- {"ctl", Qctl, 0, O_READ | O_WRITE}
+ {"raw", QID(CHFILE, 0, Qraw), 0, O_READ | O_WRITE},
+ {"ctl", QID(CHFILE, 0, Qctl), 0, O_READ | O_WRITE}
};
static Blk *blks[NR_BLKS];
@@ -169,7 +169,7 @@ rawread(Chan *c, void *buf, int nbytes)
static int
blkread(Chan *c, void *buf, int n)
{
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qblockfs:
return dirread(c, buf, n, dirtab, NELEM(dirtab), devgen);
case Qraw:
@@ -219,7 +219,7 @@ rawwrite(Chan *c, void *buf, int nbytes)
static int
blkwrite(Chan *c, void *buf, int n)
{
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qraw:
return rawwrite(c, buf, n);
case Qctl:
diff --git a/src/kernel/dev/devcons.c b/src/kernel/dev/devcons.c
@@ -23,8 +23,8 @@ enum Orootqid {
};
static const Dirtab dirtab[] = {
- {"raw", Qraw, 0, O_READ | O_WRITE},
- {"ctl", Qctl, 0, O_READ | O_WRITE}
+ {"raw", QID(CHFILE, 0, Qraw), 0, O_READ | O_WRITE},
+ {"ctl", QID(CHFILE, 0, Qctl), 0, O_READ | O_WRITE}
};
static Chan *in;
@@ -206,7 +206,7 @@ conswrite(Chan *c, void *buf, int n)
{"delout", consdelout}
};
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qraw:
return conswriteraw(buf, n);
case Qctl:
@@ -349,7 +349,7 @@ readqueue(void *buf, int n)
static int
consread(Chan *c, void *buf, int n)
{
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qconsfs:
return dirread(c, buf, n, dirtab, NELEM(dirtab), devgen);
case Qraw:
diff --git a/src/kernel/dev/devfip.c b/src/kernel/dev/devfip.c
@@ -171,10 +171,14 @@ fipgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir)
}
if (i < NELEM(uuidnames)) {
- mkentry(c, dir, uuidnames[i].name, ntry.size, n, O_READ);
+ mkentry(c, dir,
+ uuidnames[i].name, ntry.size,
+ UID(CHFILE, 0, n), O_READ);
} else {
// TODO: set name depending on uuid node value
- mkentry(c, dir, unk, ntry.size, n, O_READ);
+ mkentry(c, dir,
+ unk, ntry.size,
+ UID(CHFILE, 0, n), O_READ);
}
return 1;
@@ -199,19 +203,21 @@ fipread(Chan *c, void *buf, int n)
Chan cs;
struct fipfile *fip;
long size;
+ long long path;
- if (c->qid == CHDIR)
+ if (c->qid.type == CHDIR)
return dirread(c, buf, n, NULL, 0, fipgen);
- if (c->dev >= nfips || (c->qid & CHDIR))
+ if (c->dev >= nfips)
panic("fipread1");
fip = &archives[c->dev];
- if (c->qid >= NR_FILES || fip->offset[c->qid] < 0)
+ path = c->qid.path;
+ if (path >= NR_FILES || fip->offset[path] < 0)
panic("fipread2");
clone(fip->c, &cs);
- size = fip->size[c->qid];
+ size = fip->size[path];
if (c->offset >= size)
return 0;
@@ -222,7 +228,7 @@ fipread(Chan *c, void *buf, int n)
if (n > size - c->offset)
n = size - c->offset;
- off = fip->offset[c->qid] + c->offset;
+ off = fip->offset[path] + c->offset;
if (devtab[cs.type]->seek(&cs, off, KSEEK_SET) < 0)
return -1;
diff --git a/src/kernel/dev/devroot.c b/src/kernel/dev/devroot.c
@@ -25,26 +25,25 @@ enum Orootqid {
static const Dirtab dirtab[] = {
- {"dev", CHDIR | Qdev, 0, O_READ},
- {"realm", CHDIR | Qrealm, 0, O_READ},
- {"blobs", CHDIR | Qblobs, 0, O_READ},
- {"arfs", CHDIR | Qarfs, 0, O_READ},
- {"fip", CHDIR | Qfip, 0, O_READ},
+ {"dev", QID(CHDIR, 0, Qdev), 0, O_READ},
+ {"blobs", QID(CHDIR, 0, Qblobs), 0, O_READ},
+ {"arfs", QID(CHDIR, 0, Qarfs), 0, O_READ},
+ {"fip", QID(CHDIR, 0, Qfip), 0, O_READ},
};
static const Dirtab devfstab[] = {
- {"uart0", CHDIR | Qdevuart0, 0, O_READ},
- {"uart1", CHDIR | Qdevuart1, 0, O_READ},
- {"uart2", CHDIR | Qdevuart2, 0, O_READ},
- {"uart3", CHDIR | Qdevuart3, 0, O_READ},
- {"cons", CHDIR | Qdevcons, 0, O_READ},
- {"blk", CHDIR | Qdevblk, 0, O_READ},
+ {"uart0", QID(CHDIR, 0, Qdevuart0), 0, O_READ},
+ {"uart1", QID(CHDIR, 0, Qdevuart1), 0, O_READ},
+ {"uart2", QID(CHDIR, 0, Qdevuart2), 0, O_READ},
+ {"uart3", QID(CHDIR, 0, Qdevuart3), 0, O_READ},
+ {"cons", QID(CHDIR, 0, Qdevcons), 0, O_READ},
+ {"blk", QID(CHDIR, 0, Qdevblk), 0, O_READ},
};
static int
rootgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir)
{
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qroot:
tab = dirtab;
ntab = NELEM(dirtab);
@@ -98,13 +97,13 @@ rootread(Chan *c, void *buf, int n)
{
const Dirtab *dp;
- if ((c->qid & CHDIR) != 0)
+ if (c->qid.type == CHDIR)
return dirread(c, buf, n, NULL, 0, rootgen);
- if (c->qid == Qblobctl)
+ if (c->qid.path == Qblobctl)
return blobstatus(c, buf, n);
- dp = &blobtab[c->qid - Qblobctl];
+ dp = &blobtab[c->qid.path - Qblobctl];
return buf2chan(c, buf, dp->data, n, dp->length);
}
diff --git a/src/kernel/dev/devuart.c b/src/kernel/dev/devuart.c
@@ -19,8 +19,8 @@ enum Ouartqid {
};
static const Dirtab dirtab[] = {
- {"raw", Qraw, 0, O_READ | O_WRITE},
- {"ctl", Qctl, 0, O_READ | O_WRITE}
+ {"raw", QID(CHFILE, 0, Qraw), 0, O_READ | O_WRITE},
+ {"ctl", QID(CHFILE, 0, Qctl), 0, O_READ | O_WRITE}
};
static Uart *uarts[NR_UARTS];
@@ -180,7 +180,7 @@ uartread(Chan *c, void *buf, int n)
{
Uart *up;
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Quartfs:
return dirread(c, buf, n, dirtab, NELEM(dirtab), devgen);
case Qraw:
@@ -199,7 +199,7 @@ uartwrite(Chan *c, void *buf, int n)
{
Uart *up;
- switch (c->qid & ~CHDIR) {
+ switch (c->qid.path) {
case Qraw:
up = getuart(c);
return (*up->phy->write)(up, buf, n);
diff --git a/src/kernel/dev/mkblobh b/src/kernel/dev/mkblobh
@@ -15,7 +15,7 @@ function mkblob()
{
printf "static const Dirtab blobtab[] = {\n"
- printf "\t{\"ctl\", Qblobctl, 0, O_READ},\n"
+ printf "\t{\"ctl\", QID(CHFILE, 0, Qblobctl), 0, O_READ},\n"
for (file in blob) {
if (blobaddr[file]) {
split(blobaddr[file], v, ",")
@@ -27,7 +27,7 @@ function mkblob()
gsub(/\..*/, "", addr)
siz = "sizeof(" addr ")"
}
- printf "\t{\"%s\", Qblobctl+%d, %s, O_READ, %s},\n",
+ printf "\t{\"%s\", QID(CHFILE, 0, Qblobctl+%d), %s, O_READ, %s},\n",
file, ++n, siz, addr
}
printf "};\n"
diff --git a/src/kernel/dlang.c b/src/kernel/dlang.c
@@ -259,13 +259,13 @@ do_stat(const struct cmd *cmd, struct args *args)
"mode: %x\n"
"type: %d\n"
"dev: %d\n"
- "qid: %x\n",
+ "qid: %x,%lx,%llx\n",
dir.name,
dir.length,
dir.mode,
dir.type,
dir.dev,
- dir.qid
+ dir.qid.type, dir.qid.vers, dir.qid.path
);
return 0;
diff --git a/src/lib9p/dirtop9.c b/src/lib9p/dirtop9.c
@@ -15,9 +15,9 @@ dirtop9(Dir *dp, unsigned char *buf, int n)
p = buf + 2;
SHORT(dp->type, p); /* type */
LONG(dp->dev, p); /* dev */
- CHAR(dp->qid >> 8, p); /* qid.type */
- LONG(0, p); /* qid.vers */
- LLONG(dp->qid, p); /* qid.path */
+ CHAR(dp->qid.type, p); /* qid.type */
+ LONG(dp->qid.vers, p); /* qid.vers */
+ LLONG(dp->qid.path, p);/* qid.path */
LONG(0, p); /* mode */
LONG(0, p); /* atime */
LONG(0, p); /* mtime */
diff --git a/src/lib9p/p9todir.c b/src/lib9p/p9todir.c
@@ -11,16 +11,16 @@
int
p9todir(Dir *dp, unsigned char *buf, int size)
{
- int n, len;
- long l;
- unsigned long long type, path;
+ int n, len, type;
+ long l, vers;
+ unsigned long long path;
n = 0;
SHORT(len, buf, n, size); /* len */
SHORT(dp->type, buf, n, size); /* type */
LONG(dp->dev, buf, n, size); /* dev */
CHAR(type, buf, n, size); /* qid.type */
- LONG(l, buf, n, size); /* qid.vers */
+ LONG(vers, buf, n, size); /* qid.vers */
LLONG(path, buf, n, size); /* qid.path */
LONG(l, buf, n, size); /* mode */
LONG(l, buf, n, size); /* atime */
@@ -36,7 +36,7 @@ p9todir(Dir *dp, unsigned char *buf, int size)
errno = EINVAL;
return -1;
}
- dp->qid = type << 8 | path;
+ dp->qid = QID(type, vers, path);
return n;
}