ref: 9699d5434fadf3d775757f3d037a0f1cf86bbf75
parent: 264f5a53b0c6e8ad5ed23a8ad89f0379fcc9f0fd
author: 9ferno <[email protected]>
date: Wed Nov 30 09:15:25 EST 2022
fixed bugs in the Tdata trailing path
--- a/all.h
+++ b/all.h
@@ -82,6 +82,7 @@
Iobuf *back; /* for lru */
union{
u8 *xiobuf; /* "real" buffer pointer */
+ u64 *xiobuf64;
Data *io;
Metadata *m;
};
--- a/blk.c
+++ b/blk.c
@@ -105,7 +105,8 @@
showdentry(fd, buf);
return;
}else if(tag == Tdata){
- fprint(fd, "%s %llud %llud %d\n", tagnames[tag], t->path, t->dblkno, t->len);
+ fprint(fd, "%s %llud %llud %d\n",
+ tagnames[tag], ((u64*)buf)[t->len*Nu64perblock -1], t->dblkno, t->len);
showdata(fd, buf);
return;
}else if(tag < Maxtind)
--- a/block.c
+++ b/block.c
@@ -18,8 +18,10 @@
void
main(int argc, char *argv[])
{
+ u8 tag;
u64 size, blkno;
- u8 buf[Blocksize+1];
+ u8 buf[Maxdatablocksize];
+ Data *da;
ARGBEGIN{
default: usage();
@@ -50,7 +52,13 @@
// nunits = size/Blocksize;
memset(buf, 0, Blocksize);
devread(blkno, buf, 1);
- showblock(1, buf);
+ tag = buf[0];
+ if(tag == Tdata){
+ da = (Data*)buf;
+ devread(blkno, buf, da->len);
+ showblock(1, buf);
+ }else
+ showblock(1, buf);
close(devfd);
exits(0);
}
--- a/dat.h
+++ b/dat.h
@@ -59,6 +59,8 @@
Maxdatablockunits = 2048,
Nindperblock= (Blocksize-3*sizeof(u64))/sizeof(u64),/* number of pointers per block */
+ Nu64perblock= (Blocksize/sizeof(u64)), /* number of u64's in a block */
+ Dpathidx = (Blocksize/sizeof(u64) -1), /* index of path in the last data block, last u64 */
Namelen = 127, /* maximum length of a file name, calculated manually */
Ndblock = 32, /* number of direct blocks in a Dentry */
@@ -142,13 +144,13 @@
u8 unused; /* for alignment and future use */
u16 len;
u64 dblkno; /* block number of the directory entry */
- u64 path; /* same as qid.path */
+ // u64 path; /* same as qid.path */
};
#pragma pack off
enum {
/* max possible size of data that can be stuffed into a Dentry */
- Ddatasize = Blocksize -sizeof(u64 /* path */) -sizeof(Dentryhdr),
+ Ddatasize = Blocksize -sizeof(Dentryhdr) -sizeof(u64 /* trailing path */),
Maxdatablocksize = Maxdatablockunits*Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */),
};
@@ -208,7 +210,7 @@
{
Datahdr;
u8 buf[1]; /* upto Maxdatablocksize, followed by u64 qid.path */
- /* u64 path; same as qid.path at the end of the data content */
+ /* u64 path; same as qid.path at the end of the data content - check consistency */
};
#pragma pack off
--- a/find.c
+++ b/find.c
@@ -197,12 +197,12 @@
/* returns 0 for invalid, 1 for valid blocks */
u8
-checkvalid(u64 blkno, u8 dtag, u64 dpath, u64 dqpath, u8 tag, u64 qpath, u16 len)
+checkvalid(u64 blkno, u8 dtag, u64 dpath, u8 tag, u64 qpath, u16 len)
{
- if(dtag != tag || dpath != qpath || dqpath != qpath){
+ if(dtag != tag || dpath != qpath){
/* if(debug) */
- fprint(2, "checkvalid invalid %llud tag/path expected %s/%llud actual %s/%llud %llud\n",
- blkno, tagnames[tag], qpath, tagnames[dtag], dpath, dqpath);
+ fprint(2, "checkvalid invalid %llud tag/path expected %s/%llud actual %s/%llud\n",
+ blkno, tagnames[tag], qpath, tagnames[dtag], dpath);
fprint(2, "invalid used: %llud\n", blkno);
return 0;
}else if(debug)
@@ -214,9 +214,10 @@
walkindir(s8 depth, u64 blkno, u8 tag, u8 bottomtag, u64 qpath)
{
u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+ u64 ebuf[Nu64perblock];
Indirect *t;
Data *ct;
- u64 cblkno;
+ u64 cblkno, path;
int i;
devread(blkno, buf, Metadataunits);
@@ -236,7 +237,9 @@
else{
devread(cblkno, cbuf, 1);
ct = (Data*)cbuf;
- if(checkvalid(cblkno, ct->tag, ct->path, bottomtag, qpath, ct->len) &&
+ devread(cblkno+ct->len-1, ebuf, 1);
+ path = ebuf[Dpathidx];
+ if(checkvalid(cblkno, ct->tag, path, bottomtag, qpath, ct->len) &&
issearchblock(cblkno, ct->len))
return Found;
}
@@ -259,10 +262,11 @@
walkfile(s8 depth, u64 blkno)
{
u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+ u64 ebuf[Nu64perblock];
Dentry *d;
Data *ct;
Indirect *it;
- u64 cblkno;
+ u64 cblkno, path;
int i;
devread(blkno, buf, Metadataunits);
@@ -290,7 +294,10 @@
return Notfound;
devread(cblkno, cbuf, 1);
ct = (Data*)cbuf;
- if(checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len) &&
+ devread(cblkno+ct->len-1, ebuf, 1);
+ path = ebuf[Dpathidx];
+ if(checkvalid(cblkno, ct->tag, path,
+ Tdata, d->qpath, ct->len) &&
issearchblock(cblkno, ct->len))
return Found;
}
--- a/free.c
+++ b/free.c
@@ -89,9 +89,10 @@
{
s8 *buf;
- buf = emalloc(Metadatablocksize);
- devread(blkno, buf, Metadataunits);
- loadextents(&frees, buf, Maxdatablocksize);
+ buf = emalloc(Maxdatablocksize);
+ devread(blkno, buf, 1);
+ devread(blkno, buf, ((Data*)buf)->len);
+ loadextents(&frees, buf, ((Data*)buf)->len*Blocksize);
free(buf);
}
--- a/iobuf.c
+++ b/iobuf.c
@@ -561,20 +561,19 @@
{
uintptr pc;
u16 ptag;
- u64 pqpath, ppath;
+ u64 pqpath;
if(tag == Tdata){
ptag = p->io->tag;
- pqpath = p->io->path;
- ppath = p->xiobuf[len*Blocksize -sizeof(u64)];
+ pqpath = p->xiobuf64[p->len*Nu64perblock -1];
}else{
ptag = ((Dentry*)p->cur)->tag;
- pqpath = ppath = ((Dentry*)p->cur)->path;
+ pqpath = ((Dentry*)p->cur)->path;
}
if(len != p->len ||
tag != ptag ||
- (qpath != Qpnone && (pqpath != qpath || ppath != qpath))){
+ (qpath != Qpnone && pqpath != qpath)){
pc = getcallerpc(&p);
dprint(" tag = %G; expected %G; blkno = %llud\n",
@@ -587,12 +586,12 @@
tagnames[tag],
len, p->len);
} else {
- dprint(" tag/path = %G/%llux %llux; expected %G/%llux\n",
- (uint)ptag, pqpath, ppath, tag, qpath);
- dprint("checktag pc=%p disk %s(block %llud) tag/path=%s/%llud %llud;"
+ dprint(" tag/path = %G/%llux; expected %G/%llux\n",
+ (uint)ptag, pqpath, tag, qpath);
+ dprint("checktag pc=%p disk %s(block %llud) tag/path=%s/%llud;"
" expected %s/%llud\n",
pc, devfile, p->blkno,
- tagnames[ptag], pqpath, ppath,
+ tagnames[ptag], pqpath,
tagnames[tag], qpath);
panic("checktag failed\n");
}
@@ -612,7 +611,7 @@
devfile, (u64)p->blkno, tagnames[tag], qpath);
if(tag == Tdata){
p->io->tag = Tdata;
- p->io->path = qpath;
+ p->xiobuf64[p->len*Nu64perblock -1] = qpath;
}else{
((Dentry*)p->new)->tag = tag;
((Dentry*)p->new)->path = qpath;
--- a/sub.c
+++ b/sub.c
@@ -90,7 +90,7 @@
memset(buf->xiobuf, 0, len*Blocksize);
if(tag == Tdata){
buf->io->len = len;
- buf->xiobuf[len*Blocksize -sizeof(u64)] = qpath;
+ buf->xiobuf64[len*Nu64perblock -1] = qpath;
}else
recentmetadata(buf->m, &buf->cur, &buf->new);
settag(buf, tag, qpath);
--- a/tests/test.2/blocks/24
+++ b/tests/test.2/blocks/24
@@ -43,4 +43,5 @@
0123456789
0123456789
0123456789
-01234567
\ No newline at end of file
+0123456789
+0123456789
--- a/tests/test.2/notes
+++ b/tests/test.2/notes
@@ -2,6 +2,9 @@
Write to a /file1 and update the file using different offsets. Check that the contents match after each addition.
+# to see the raw contents of block 24
+dd -if test.2/disk -bs 512 -skip 24 -count 1 | xd -c
+
block - description
0 - magic dir entry and data
2 - /adm/config dir entry
--- a/tests/testextents.c
+++ b/tests/testextents.c
@@ -37,7 +37,7 @@
bp = Bfdopen(0, OREAD);
Blethal(bp, nil);
- initextents(&es, "testextents");
+ initextents(&es, "testextents", nil);
while((line = Brdstr(bp, '\n', 1)) != nil) {
bno = strtoull(line, &p, 10);
p++; /* for the space */
--- a/updatefrees.c
+++ b/updatefrees.c
@@ -9,6 +9,9 @@
disk/unused <{disk/used tests/test.0/disk} 32 | tr -d ' ' > /mnt/term/tmp/unused.blocks
cat /mnt/term/tmp/unused.blocks
disk/updatefrees tests/test.0/disk /mnt/term/tmp/unused.blocks
+
+ TODO
+ does not work when the size of free extents > Blocksize-(3*8)
*/
int debug = 0;
@@ -27,8 +30,9 @@
u64 size, freeblkno;
s32 nfreesize;
s8 buf[Metadatablocksize], frees[Maxdatablocksize];
+ u64 freesdata[Nu64perblock];
int fd;
- Data *c;
+ Data *f;
Dentry *d;
ARGBEGIN{
@@ -47,7 +51,7 @@
if(freesfile == nil)
sysfatal("no frees file");
- memset(buf,0,Metadatablocksize);
+ memset(buf, 0, Metadatablocksize);
memset(frees, 0, Maxdatablocksize);
fd = open(freesfile, OREAD);
@@ -54,14 +58,18 @@
if(fd < 0)
sysfatal("updatefrees: cannot open freesfile %s\n", freesfile);
- nfreesize = read(fd, frees, Maxdatablocksize);
+ nfreesize = readn(fd, frees, Maxdatablocksize);
if(nfreesize <= 0)
sysfatal("updatefrees: nfreesize %d <= 0\n", nfreesize);
+ if(nfreesize > (Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)))
+ sysfatal("updatefrees: unsupported nfreesize %d needs more than a block Datablocksize %llud\n",
+ nfreesize, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
if(nfreesize > Maxdatablocksize)
sysfatal("updatefrees: unsupported nfreesize %d > Datablocksize %llud\n",
nfreesize, Maxdatablocksize);
close(fd);
+ /* use the first block to write */
freeblkno = atoll((s8*)frees);
if (access(devfile, AREAD|AWRITE) == -1)
@@ -91,12 +99,15 @@
print("changed dblocks[0]: %llud to %llud\n", d->dblocks[0], freeblkno);
d->dblocks[0] = freeblkno;
- c = (Data*)frees;
- c->tag = Tdata;
- c->path = Qpfrees;
+ f = (Data*)freesdata;
+ f->tag = Tdata;
+ f->len = 1;
+ memcpy(f->buf, frees, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
+ freesdata[Dpathidx] = Qpfrees;
devwrite(Bdfrees, buf, Metadataunits);
- devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
+ // devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
+ devwrite(freeblkno, (s8*)freesdata, 1);
}
close(devfd);
exits(0);
--- a/used.c
+++ b/used.c
@@ -92,9 +92,10 @@
walkindir(u64 blkno, u16 tag, u16 bottomtag, u64 qpath)
{
u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+ u64 ebuf[Nu64perblock];
Indirect *t;
Data *da;
- u64 cblkno;
+ u64 cblkno, path;
int i;
Dentry *cd;
@@ -116,7 +117,9 @@
}else{
devread(cblkno, cbuf, 1);
da = (Data*)cbuf;
- checkvalid(cblkno, da->tag, da->path, Tdata, da->path, da->len);
+ devread(cblkno+da->len-1, ebuf, 1);
+ path = ebuf[Dpathidx];
+ checkvalid(cblkno, da->tag, path, Tdata, qpath, da->len);
}
}
}else{
@@ -190,10 +193,11 @@
walkfile(u64 blkno)
{
u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+ u64 ebuf[Nu64perblock];
Dentry *d;
Data *ct;
Indirect *it;
- u64 cblkno;
+ u64 cblkno, path;
int i;
devread(blkno, buf, Metadataunits);
@@ -223,7 +227,9 @@
return;
devread(cblkno, cbuf, 1);
ct = (Data*)cbuf;
- checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len);
+ devread(cblkno+ct->len-1, ebuf, 1);
+ path = ebuf[Dpathidx];
+ checkvalid(cblkno, ct->tag, path, Tdata, d->qpath, ct->len);
}
for(i = 0; i<Niblock; i++){
cblkno = d->iblocks[i];
@@ -237,115 +243,6 @@
fprint(2, "invalid indir tag of block %llud %d %s\n",
cblkno, it->tagi, tagnames[it->tagi]);
fprint(2, "%llud\n", cblkno);
- }
- }
- return;
-}
-
-/* checks the ending path and takes too long */
-void
-walkfileproper(u64 blkno)
-{
- u8 buf[Metadatablocksize], *cbuf;
- Dentry *d;
- Data *ct;
- Indirect *it;
- u64 cblkno;
- int i;
-
- devread(blkno, buf, Metadataunits);
- recentmetadata(buf, &d, nil);
- if(chatty9p)
- print("walkfile %llud tag %s name %s d->qid.path %llud\n",
- blkno, tagnames[d->tag], d->name, d->qpath);
- if(d->tag != Tdentry || d->path != d->qpath){
- if(chatty9p)
- print("walkfile invalid %llud tag/path expected %s/%llud actual %s/%llud\n",
- blkno, tagnames[Tdentry], d->qpath, tagnames[d->tag], d->path);
- fprint(2, "%llud\n", blkno);
- }else{
- // print("%llud\n", blkno);
- add(&useds, blkno, Metadataunits);
- }
- /* do not list the data blocks used by /adm/frees
- as they are considered to be free blocks */
- if(blkno == Bdfrees)
- return;
- if(d->size <= Ddatasize)
- return;
-
- cbuf = malloc(Maxdatablockunits*Blocksize);
- for(i = 0; i<Ndblock; i++){
- cblkno = d->dblocks[i];
- if(cblkno == 0){
- free(cbuf);
- return;
- }
- devread(cblkno, cbuf, 1);
- ct = (Data*)cbuf;
- checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len);
- }
- for(i = 0; i<Niblock; i++){
- cblkno = d->iblocks[i];
- if(cblkno == 0){
- free(cbuf);
- return;
- }
- devread(cblkno, cbuf, Metadataunits);
- recentmetadata(cbuf, &it, nil);
- if(it->tagi == Tind0+i){
- walkindir(cblkno, Tind0+i, Tdata, d->qpath);
- }else{
- fprint(2, "invalid indir tag of block %llud\n", cblkno);
- fprint(2, "%llud\n", cblkno);
- }
- }
- free(cbuf);
- return;
-}
-
-void
-walkindirproper(u64 blkno, u16 tag, u16 bottomtag, u64 qpath)
-{
- u8 buf[Metadatablocksize], *cbuf;
- Indirect *t;
- Data *da;
- u64 cblkno;
- int i;
- Dentry *cd;
-
- devread(blkno, buf, Metadataunits);
- recentmetadata(buf, &t, nil);
- if(checkvalid(blkno, t->tagi, t->path, tag, qpath, Metadataunits)){
- if(tag == Tind0){
- for(i = 0; i<Nindperblock; i++){
- cblkno = t->bufa[i];
- if(cblkno == 0)
- return;
- if(bottomtag == Tdentry){
- cbuf = malloc(Metadatablocksize);
- devread(cblkno, cbuf, Metadataunits);
- recentmetadata(cbuf, &cd, nil);
- if((cd->mode & DMDIR) > 0)
- walkdirectory(cblkno);
- else
- walkfile(cblkno);
- free(cbuf);
- }else{
- cbuf = malloc(Maxdatablockunits*Blocksize);
- devread(cblkno, cbuf, 1);
- da = (Data*)cbuf;
- checkvalid(cblkno, da->tag, da->path, Tdata, da->path, da->len);
- free(cbuf);
- }
- }
- }else{
- for(i = 0; i<Nindperblock; i++){
- cblkno = t->bufa[i];
- if(cblkno == 0)
- return;
- walkindir(cblkno, tag-1, bottomtag, qpath);
- }
}
}
return;