diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-06-19 22:58:16 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-06-19 22:58:16 +0200 |
commit | 159f96c534563f26edeeb227cd00f1bdd3bd2596 (patch) | |
tree | 20a396455cad2d59fd677d19a1539d5e531e69ae /sys/src/cmd/cwfs | |
parent | 8561a843070582d48ef7f99e1138941c3509975f (diff) |
cwfs: properly handle 64 bit qid path
for historical reasons, kenfs stores directory entries in pre 9p2000
format with directories having the QPDIR bit 31 set in the qid path.
however, the 64 bit fileserver allows 64 bit qid paths.
given that we do not support pre 9p2000 clients and do not rely on
the QPDIR, but want to keep the block check tags consistent, we will
*INVERT* the QPDIR bit in directory entry qid paths for directories.
this preserves the on-disk semantics (for < 31 bit qmax) but does
not complicate qid generation and recovery. also makes it easy to
convert between directory entry qid and 9p format.
Diffstat (limited to 'sys/src/cmd/cwfs')
-rw-r--r-- | sys/src/cmd/cwfs/9p2.c | 25 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/chk.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/con.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cw.c | 10 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/dentry.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/iobuf.c | 15 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/portfns.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/sub.c | 5 |
8 files changed, 37 insertions, 30 deletions
diff --git a/sys/src/cmd/cwfs/9p2.c b/sys/src/cmd/cwfs/9p2.c index 990933b99..70dd85c7b 100644 --- a/sys/src/cmd/cwfs/9p2.c +++ b/sys/src/cmd/cwfs/9p2.c @@ -27,11 +27,9 @@ mkmode9p1(ulong mode9p2) void mkqid9p1(Qid9p1* qid9p1, Qid* qid) { - if(qid->path & 0xFFFFFFFF00000000LL) - panic("mkqid9p1: path %lluX", (Wideoff)qid->path); - qid9p1->path = qid->path & 0xFFFFFFFF; + qid9p1->path = qid->path; if(qid->type & QTDIR) - qid9p1->path |= QPDIR; + qid9p1->path ^= QPDIR; qid9p1->version = qid->vers; } @@ -74,7 +72,9 @@ mkmode9p2(int mode9p1) void mkqid9p2(Qid* qid, Qid9p1* qid9p1, int mode9p1) { - qid->path = (ulong)(qid9p1->path & ~QPDIR); + qid->path = qid9p1->path; + if(mode9p1 & DDIR) + qid->path ^= QPDIR; qid->vers = qid9p1->version; qid->type = mktype9p2(mode9p1); } @@ -399,7 +399,7 @@ walkname(File* file, char* wname, Qid* wqid) Iobuf *p, *p1; Dentry *d, *d1; int error, slot, mask; - Off addr, qpath; + Off addr; p = p1 = nil; @@ -482,10 +482,9 @@ setdot: goto out; } } - qpath = d->qid.path; p1 = dnodebuf1(p, d, addr, 0, file->uid); p = nil; - if(p1 == nil || checktag(p1, Tdir, qpath)){ + if(p1 == nil || checktag(p1, Tdir, d->qid.path ^ QPDIR)){ error = Eentry; goto out; } @@ -854,7 +853,7 @@ fs_create(Chan* chan, Fcall* f, Fcall* r) error = Efull; goto out; } - if(checktag(p1, Tdir, d->qid.path)){ + if(checktag(p1, Tdir, d->qid.path ^ QPDIR)){ putbuf(p1); goto phase; } @@ -904,7 +903,7 @@ fs_create(Chan* chan, Fcall* f, Fcall* r) if((p1 = getbuf(file->fs->dev, addr1, Brd|Bimm|Bmod)) == nil) goto phase; d1 = getdir(p1, slot1); - if(d1 == nil || checktag(p1, Tdir, d->qid.path)) { + if(d1 == nil || checktag(p1, Tdir, d->qid.path ^ QPDIR)) { putbuf(p1); goto phase; } @@ -929,7 +928,7 @@ fs_create(Chan* chan, Fcall* f, Fcall* r) d1->mode = DALLOC | (f->perm & 0777); if(f->perm & DMDIR) { d1->mode |= DDIR; - d1->qid.path |= QPDIR; + d1->qid.path ^= QPDIR; } if(f->perm & DMAPPEND) d1->mode |= DAPND; @@ -1359,7 +1358,7 @@ doremove(File *f) p1 = dnodebuf(p, d, addr, 0, f->uid); if(!p1) break; - if(checktag(p1, Tdir, d->qid.path)) { + if(checktag(p1, Tdir, d->qid.path ^ QPDIR)) { err = Ephase; goto out; } @@ -1688,7 +1687,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) for(addr = 0; ; addr++){ if((p = dnodebuf(p1, d1, addr, 0, file->uid)) == nil) break; - if(checktag(p, Tdir, d1->qid.path)){ + if(checktag(p, Tdir, d1->qid.path ^ QPDIR)){ putbuf(p); continue; } diff --git a/sys/src/cmd/cwfs/chk.c b/sys/src/cmd/cwfs/chk.c index 1b793c69c..c2a4644ee 100644 --- a/sys/src/cmd/cwfs/chk.c +++ b/sys/src/cmd/cwfs/chk.c @@ -430,7 +430,9 @@ fsck(Dentry *d) } /* check qid */ - edent.qpath = d->qid.path & ~QPDIR; + edent.qpath = d->qid.path; + if(d->mode & DDIR) + edent.qpath ^= QPDIR; qmark(edent.qpath); if(edent.qpath > maxq) maxq = edent.qpath; diff --git a/sys/src/cmd/cwfs/con.c b/sys/src/cmd/cwfs/con.c index fa4d42a90..2b418d8c6 100644 --- a/sys/src/cmd/cwfs/con.c +++ b/sys/src/cmd/cwfs/con.c @@ -513,8 +513,10 @@ doclean(Iobuf *p, Dentry *d, int n, Off a) mod = 0; qpath = d->qid.path; typ = Tfile; - if(d->mode & DDIR) + if(d->mode & DDIR){ + qpath ^= QPDIR; typ = Tdir; + } for(i=0; i<NDBLOCK; i++) { print("dblock[%d] = %lld\n", i, (Wideoff)d->dblock[i]); ckblock(p->dev, d->dblock[i], typ, qpath); diff --git a/sys/src/cmd/cwfs/cw.c b/sys/src/cmd/cwfs/cw.c index 054ae5e3b..6ab93302e 100644 --- a/sys/src/cmd/cwfs/cw.c +++ b/sys/src/cmd/cwfs/cw.c @@ -1311,11 +1311,11 @@ isdirty(Cw *cw, Iobuf *p, Off addr, int tag) } Off -cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) +cwrecur(Cw *cw, Off addr, int tag, int tag1, Off qp) { Iobuf *p; Dentry *d; - long qp1; + Off qp1; int i, j, shouldstop; Off na; char *np; @@ -1373,14 +1373,16 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) d = getdir(p, i); if((d->mode & (DALLOC|DTMP)) != DALLOC) continue; - qp1 = d->qid.path & ~QPDIR; if(np) strncpy(np, d->name, NAMELEN); else if(i > 0) fprint(2, "cwrecur: root with >1 directory\n"); + qp1 = d->qid.path; tag1 = Tfile; - if(d->mode & DDIR) + if(d->mode & DDIR){ + qp1 ^= QPDIR; tag1 = Tdir; + } for(j=0; j<NDBLOCK; j++) { na = d->dblock[j]; if(na) { diff --git a/sys/src/cmd/cwfs/dentry.c b/sys/src/cmd/cwfs/dentry.c index ad0d55d0e..cd258b1f8 100644 --- a/sys/src/cmd/cwfs/dentry.c +++ b/sys/src/cmd/cwfs/dentry.c @@ -65,6 +65,8 @@ rel2abs(Iobuf *p, Dentry *d, Off a, int tag, int putb, int uid) } dev = p->dev; qpath = d->qid.path; + if(d->mode & DDIR) + qpath ^= QPDIR; /* is `a' a direct block? */ if(a < NDBLOCK) { diff --git a/sys/src/cmd/cwfs/iobuf.c b/sys/src/cmd/cwfs/iobuf.c index 0caebf38b..a123ec502 100644 --- a/sys/src/cmd/cwfs/iobuf.c +++ b/sys/src/cmd/cwfs/iobuf.c @@ -201,19 +201,18 @@ int checktag(Iobuf *p, int tag, Off qpath) { Tag *t; - ulong pc; + uintptr pc; - qpath &= ~QPDIR; t = (Tag*)(p->iobuf+BUFSIZE); - if((tag != t->tag) || ((qpath != QPNONE) && (qpath != t->path))){ + if(tag != t->tag || qpath != QPNONE && qpath != t->path){ pc = getcallerpc(&p); if(qpath == QPNONE){ - fprint(2, "checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G\n", + fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G\n", pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag); } else { - fprint(2, "checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n", - pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, qpath); + fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n", + pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath); } return 1; } @@ -221,14 +220,14 @@ checktag(Iobuf *p, int tag, Off qpath) } void -settag(Iobuf *p, int tag, long qpath) +settag(Iobuf *p, int tag, Off qpath) { Tag *t; t = (Tag*)(p->iobuf+BUFSIZE); t->tag = tag; if(qpath != QPNONE) - t->path = qpath & ~QPDIR; + t->path = qpath; p->flags |= Bmod; } diff --git a/sys/src/cmd/cwfs/portfns.h b/sys/src/cmd/cwfs/portfns.h index 5df207770..4a5d7ca9e 100644 --- a/sys/src/cmd/cwfs/portfns.h +++ b/sys/src/cmd/cwfs/portfns.h @@ -160,7 +160,7 @@ void sec2rtc(Timet, Rtc *); void fs_send(Queue*, void*); void serve(void *); int serve9p2(Msgbuf*); -void settag(Iobuf*, int, long); +void settag(Iobuf*, int, Off); int strtouid(char*); Off superaddr(Device*); void superream(Device*, Off); diff --git a/sys/src/cmd/cwfs/sub.c b/sys/src/cmd/cwfs/sub.c index ddb95d7d2..a6093aea5 100644 --- a/sys/src/cmd/cwfs/sub.c +++ b/sys/src/cmd/cwfs/sub.c @@ -380,8 +380,9 @@ qidpathgen(Device *dev) if(!p || checktag(p, Tsuper, QPSUPER)) panic("newqid: super block"); sb = (Superb*)p->iobuf; - sb->qidgen++; - path = sb->qidgen; + do { + path = ++sb->qidgen; + } while(path == QPDIR); putbuf(p); return path; } |