# HG changeset patch # User Francisco J Ballesteros # Date 1328895739 0 # Node ID 9100bac012ae7ac201bacbaaf801f713ddedc017 # Parent f63d21e2da68c9a6869fc7b8e8e547ed15157aa8 Cfs: fixes, rewrites, and more testing R=nixiedev CC=nix-dev http://codereview.appspot.com/5653059 Committer: John Floren diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/attr.c --- a/sys/src/cmd/Cfs/attr.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/attr.c Fri Feb 10 17:42:19 2012 +0000 @@ -19,12 +19,12 @@ struct Adef { char* name; - long (*wattr)(Fsys*, Memblk*, void*, long); - long (*rattr)(Fsys*, Memblk*, void*, long); + long (*wattr)(Memblk*, void*, long); + long (*rattr)(Memblk*, void*, long); }; -static long wname(Fsys*, Memblk*, void*, long); -static long rname(Fsys*, Memblk*, void*, long); +static long wname(Memblk*, void*, long); +static long rname(Memblk*, void*, long); static Adef adef[] = { @@ -149,7 +149,7 @@ } static long -wname(Fsys *, Memblk *f, void *buf, long len) +wname(Memblk *f, void *buf, long len) { char *p, *old; ulong maxsz; @@ -172,7 +172,7 @@ } static long -rname(Fsys *, Memblk *f, void *buf, long len) +rname(Memblk *f, void *buf, long len) { long l; @@ -184,7 +184,7 @@ } long -dfwattr(Fsys *fs, Memblk *f, char *name, void *val, long nval) +dfwattr(Memblk *f, char *name, void *val, long nval) { int i; @@ -192,13 +192,13 @@ iswlocked(f); for(i = 0; i < nelem(adef); i++) if(strcmp(adef[i].name, name) == 0) - return adef[i].wattr(fs, f, val, nval); + return adef[i].wattr(f, val, nval); error("user defined attributes not yet implemented"); return -1; } long -dfrattr(Fsys *fs, Memblk *f, char *name, void *val, long count) +dfrattr(Memblk *f, char *name, void *val, long count) { int i; @@ -206,7 +206,7 @@ isrlocked(f); for(i = 0; i < nelem(adef); i++) if(strcmp(adef[i].name, name) == 0) - return adef[i].rattr(fs, f, val, count); + return adef[i].rattr(f, val, count); error("user defined attributes not yet implemented"); return -1; } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/conf.h --- a/sys/src/cmd/Cfs/conf.h Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/conf.h Fri Feb 10 17:42:19 2012 +0000 @@ -15,11 +15,10 @@ Dminfree = 100000, /* min nb. of free blocks in disk */ /* disk parameters; don't change */ - Dblksz = 1*KiB, /* disk block size */ + Dblksz = 512UL, /* disk block size */ Dblkhdrsz = 2*BIT64SZ, Ndptr = 2, /* # of direct data pointers */ Niptr = 2, /* # of indirect data pointers */ - #else Incr = 16, Fmemsz = 64 * MiB, /* max size of in-memory file data */ @@ -31,7 +30,6 @@ Dblkhdrsz = 2*BIT64SZ, Ndptr = 8, /* # of direct data pointers */ Niptr = 4, /* # of indirect data pointers */ - #endif Dminattrsz = Dblksz/2, /* min size for attributes */ @@ -57,3 +55,4 @@ Fhashsz = 7919, /* size of file hash (plan9 has 35454 files). */ }; + diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/dblk.c --- a/sys/src/cmd/Cfs/dblk.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/dblk.c Fri Feb 10 17:42:19 2012 +0000 @@ -16,12 +16,12 @@ */ void -dbclear(Fsys *fs, u64int addr, int type) +dbclear(u64int addr, int type) { static Diskblk d; static QLock lk; - dDprint("dbclear d%#ullx\n", addr); + dDprint("dbclear d%#ullx type DB%s\n", addr, tname[type]); qlock(&lk); d.tag = TAG(addr, type); d.epoch = now(); @@ -33,12 +33,12 @@ } void -meltedref(Fsys *fs, Memblk *rb) +meltedref(Memblk *rb) { if(rb->frozen && rb->dirty){ if(catcherror()) sysfatal("writing ref: %r"); - dbwrite(fs, rb); + dbwrite(rb); noerror(); } rb->frozen = rb->dirty = 0; @@ -55,7 +55,7 @@ */ u64int -newblkaddr(Fsys *fs) +newblkaddr(void) { u64int addr, naddr; @@ -73,11 +73,28 @@ addr = fs->super->d.eaddr; fs->super->d.eaddr += Dblksz; changed(fs->super); + /* + * ref blocks are allocated and initialized on demand, + * and they must be zeroed before used. + * do this holding the lock so others find everything + * initialized. + */ + if(((addr-Dblk0addr)/Dblksz)%Nblkgrpsz == 0){ + dDprint("new ref blk addr = d%#ullx\n", addr); + if(catcherror()){ + qunlock(fs); + error(nil); + } + dbclear(addr, DBref); /* fs initialization */ + noerror(); + addr += Dblksz; + fs->super->d.eaddr += Dblksz; + } }else if(fs->super->d.free != 0){ addr = fs->super->d.free; qunlock(fs); - naddr = dbgetref(fs, addr); /* acquires locks */ + naddr = dbgetref(addr); /* acquires locks */ qlock(fs); if(addr != fs->super->d.free){ /* had a race */ @@ -86,30 +103,12 @@ fs->super->d.free = naddr; fs->super->d.nfree -= 1; changed(fs->super); - goto found; }else{ /* backward compatible with fossil */ error("disk is full"); } - /* - * ref blocks are allocated and initialized on demand, - * and they must be zeroed before used. - * do this holding the lock so others find everything - * initialized. - */ - if(((addr-Dblk0addr)/Dblksz)%Nblkgrpsz == 0){ - if(catcherror()){ - qunlock(fs); - error(nil); - } - dbclear(fs, addr-Dblksz, DBref); /* fs initialization */ - noerror(); - addr += Dblksz; - fs->super->d.eaddr += Dblksz; - } -found: qunlock(fs); - okaddr(fs, addr); + okaddr(addr); dDprint("newblkaddr = d%#ullx\n", addr); return addr; @@ -147,7 +146,7 @@ */ u64int -dbgetref(Fsys *fs, u64int addr) +dbgetref(u64int addr) { Memblk *rb; u64int raddr, ref; @@ -160,17 +159,17 @@ return 1; raddr = refaddr(addr, &i); - rb = dbget(fs, DBref, raddr); + rb = dbget(DBref, raddr); qlock(fs); - meltedref(fs, rb); + meltedref(rb); ref = rb->d.ref[i]; qunlock(fs); - mbput(fs, rb); + mbput(rb); return ref; } void -dbsetref(Fsys *fs, u64int addr, u64int ref) +dbsetref(u64int addr, u64int ref) { Memblk *rb; u64int raddr; @@ -180,17 +179,17 @@ if(addr < Dblk0addr) sysfatal("dbsetref"); raddr = refaddr(addr, &i); - rb = dbget(fs, DBref, raddr); + rb = dbget(DBref, raddr); qlock(fs); - meltedref(fs, rb); + meltedref(rb); rb->d.ref[i] = ref; changed(rb); qunlock(fs); - mbput(fs, rb); + mbput(rb); } void -dbincref(Fsys *fs, u64int addr) +dbincref(u64int addr) { Memblk *rb; u64int raddr; @@ -198,17 +197,17 @@ dDprint("dbincref %#ullx\n", addr); raddr = refaddr(addr, &i); - rb = dbget(fs, DBref, raddr); + rb = dbget(DBref, raddr); qlock(fs); - meltedref(fs, rb); + meltedref(rb); rb->d.ref[i]++; changed(rb); qunlock(fs); - mbput(fs, rb); + mbput(rb); } u64int -dbdecref(Fsys *fs, u64int addr) +dbdecref(u64int addr) { Memblk *rb; u64int raddr, ref; @@ -218,8 +217,8 @@ sysfatal("dbdecref"); dDprint("dbdecref %#ullx\n", addr); raddr = refaddr(addr, &i); - rb = dbget(fs, DBref, raddr); - meltedref(fs, rb); + rb = dbget(DBref, raddr); + meltedref(rb); qlock(fs); rb->d.ref[i]--; ref = rb->d.ref[i]; @@ -232,12 +231,12 @@ changed(rb); } qunlock(fs); - mbput(fs, rb); + mbput(rb); return ref; } static Mfile* -mfalloc(Fsys *fs) +mfalloc(void) { Mfile *mf; @@ -254,7 +253,7 @@ } Memblk* -dballoc(Fsys *fs, uint type) +dballoc(uint type) { Memblk *b; u64int addr; @@ -265,20 +264,20 @@ if(root) type = DBfile; else - addr = newblkaddr(fs); + addr = newblkaddr(); dDprint("dballoc DB%s\n", tname[type]); - b = mballoc(fs, addr); + b = mballoc(addr); b->d.tag = TAG(b->addr,type); changed(b); if(catcherror()){ - mbput(fs, b); + mbput(b); error(nil); } if(addr != Noaddr && addr >= Dblk0addr) - dbsetref(fs, addr, 1); + dbsetref(addr, 1); if(type == DBfile) - b->mf = mfalloc(fs); - mbhash(fs, b); + b->mf = mfalloc(); + mbhash(b); dDprint("dballoc DB%s -> %H\n", tname[type], b); noerror(); return b; @@ -311,12 +310,14 @@ if(u.m[0] != 0x88) sysfatal("fix hosttodisk/disktohost for big endian"); - if(!TAGADDROK(b->d.tag, b->addr)) + if(!TAGADDROK(b->d.tag, b->addr)){ +print("disktohost: %H", b); error("disktohost: bad tag"); } +} long -dbwrite(Fsys *fs, Memblk *b) +dbwrite(Memblk *b) { Memblk *nb; @@ -325,15 +326,15 @@ nb = hosttodisk(b); nb->d.epoch = now(); if(pwrite(fs->fd, &nb->d, sizeof nb->d, nb->addr) != Dblksz){ - mbput(fs, nb); + mbput(nb); error("dbwrite: %r"); } - mbput(fs, nb); + mbput(nb); return Dblksz; } long -dbread(Fsys *fs, Memblk *b) +dbread(Memblk *b) { long tot, nr; uchar *p; @@ -355,7 +356,7 @@ disktohost(b); if(TAGTYPE(b->d.tag) != DBref) b->frozen = 1; - dDprint("dbread %H", b); + if(0)dDprint("dbread %H", b); return tot; } @@ -366,38 +367,46 @@ * entire directory is removed from memory. */ Memblk* -dbget(Fsys *fs, uint type, u64int addr) +dbget(uint type, u64int addr) { Memblk *b; u64int tag; - dDprint("dbget d%#ullx\n",addr); - okaddr(fs, addr); - b = mbget(fs, addr); - if(b != nil) + dDprint("dbget DB%s d%#ullx\n", tname[type], addr); + okaddr(addr); + tag = TAG(addr,type); + b = mbget(addr); + if(b != nil){ + if(b->d.tag != tag) + sysfatal("dbget: got bad tag"); return b; + } /* * others might request the same block while we read it. * the first one hashing it wins; no locks. */ - tag = TAG(addr,type); - b = mballoc(fs, addr); + b = mballoc(addr); if(catcherror()){ - mbput(fs, b); + mbput(b); error(nil); } - dbread(fs, b); - if(b->d.tag != tag) - sysfatal("dbget: wrong tag"); + dbread(b); + if(b->d.tag != tag){ + dDprint("dbget: wanted DB%s; got DB%s\n", + tname[type], tname[TAGTYPE(b->d.tag)]); +abort(); + sysfatal("dbget: read bad tag %#ullx %#ullx", b->d.tag, tag); + } if(type == DBfile){ assert(b->mf == nil); - b->mf = mfalloc(fs); + b->mf = mfalloc(); gmeta(b->mf, b->d.embed, Embedsz); b->written = 1; } + noerror(); - b = mbhash(fs, b); + b = mbhash(b); return b; } @@ -405,7 +414,7 @@ * caller responsible for locking. */ Memblk* -dbdup(Fsys *fs, Memblk *b) +dbdup(Memblk *b) { Memblk *nb; uint type; @@ -413,7 +422,7 @@ Mfile *nm, *m; type = TAGTYPE(b->d.tag); - nb = dballoc(fs, type); + nb = dballoc(type); switch(type){ case DBfree: case DBref: @@ -423,29 +432,22 @@ case DBdata: memmove(nb->d.data, b->d.data, Dblkdatasz); break; - case DBptr: - for(i = 0; i < Dptrperblk; i++){ - nb->d.ptr[i] = b->d.ptr[i]; - if(nb->d.ptr[i] != 0) - dbincref(fs, b->d.ptr[i]); - } - break; case DBfile: isrlocked(b); isloaded(b); nb->d.asize = b->d.asize; nb->d.aptr = b->d.aptr; if(nb->d.aptr != 0) - dbincref(fs, b->d.aptr); + dbincref(b->d.aptr); for(i = 0; i < nelem(b->d.dptr); i++){ nb->d.dptr[i] = b->d.dptr[i]; if(nb->d.dptr[i] != 0) - dbincref(fs, b->d.dptr[i]); + dbincref(b->d.dptr[i]); } for(i = 0; i < nelem(b->d.iptr); i++){ nb->d.iptr[i] = b->d.iptr[i]; if(nb->d.iptr[i] != 0) - dbincref(fs, b->d.iptr[i]); + dbincref(b->d.iptr[i]); } memmove(nb->d.embed, b->d.embed, Embedsz); nm = nb->mf; @@ -466,7 +468,13 @@ } break; default: - sysfatal("dbdup: type"); + if(type < DBptr0 || type >= DBptr0 + Niptr) + sysfatal("dbdup: type %d", type); + for(i = 0; i < Dptrperblk; i++){ + nb->d.ptr[i] = b->d.ptr[i]; + if(nb->d.ptr[i] != 0) + dbincref(b->d.ptr[i]); + } } changed(nb); return nb; diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/disk Binary file sys/src/cmd/Cfs/disk has changed diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/dk.h --- a/sys/src/cmd/Cfs/dk.h Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/dk.h Fri Feb 10 17:42:19 2012 +0000 @@ -1,4 +1,3 @@ -typedef struct Fattr Fattr; typedef struct Fmeta Fmeta; typedef struct Child Child; typedef struct Ddatablk Ddatablk; @@ -29,13 +28,12 @@ * - Disk refs count only references within the tree on disk. * (perhaps loaded in memory waiting for a further sync) * - Children do not imply new refs to the parents. - * Locking: * - * Assumptions: + * Locking & Assumptions: * - /active is *never* found on disk, it's memory-only. * - b->addr is worm. * - b->next is locked by the hash bucked lock - * - blocks added to the end of the hash chain. + * - blocks are added to the end of the hash chain. * - blocks are locked by the file responsible for them, when not frozen. * - super, disk refs, block allocation, free list, ... protected by fs lock * - We try not to hold more than one lock, using the @@ -47,21 +45,27 @@ * in which case db*ref functions write the block in place and melt it. * - the block epoch number for a on-disk block is the time when it * was written (thus it's archived "/" has a newer epoch). - * Order: - * fs & super: while locked can't acquire fs or blocks. - * blocks: parent -> child; block -> ref block + * + * Lock order: + * - fs & super: while locked can't acquire fs or blocks. + * - parent block -> child + * (but a DBfile protects all ptr and data blocks under it). + * - block -> ref block */ enum { /* block types */ DBfree = 0, - DBdata, - DBptr, DBref, DBattr, DBfile, DBsuper, + DBdata, /* direct block */ + DBptr0 = DBdata+1, /* simple-indirect block */ + /* double */ + /* triple */ + /*...*/ }; /* @@ -71,9 +75,9 @@ * * blk 0: unused * blk 1: super - * ref blk + Nblkgrpsz blocks + * ref blk + Nblkgrpsz-1 blocks * ... - * ref blk + Nblkgrpsz blocks + * ref blk + Nblkgrpsz-1 blocks * * The code assumes these structures are packed. * Be careful if they are changed to make things easy for the @@ -92,7 +96,7 @@ struct Drefblk { - u64int ref[1]; /* RC or next in free list */ + u64int ref[1]; /* disk RC or next block in free list */ }; struct Dattrblk @@ -107,7 +111,7 @@ */ struct Dentry { - u64int file; /* file address or 0 when archived */ + u64int file; /* file address or 0 when unused */ }; /* @@ -135,14 +139,14 @@ enum { - FMuid = 0, + FMuid = 0, /* strings in mandatory attributes */ FMgid, FMmuid, FMname, FMnstr, }; -struct Dmeta +struct Dmeta /* mandatory metadata */ { u64int id; /* ctime, actually */ u64int mode; @@ -155,14 +159,11 @@ /* * Superblock. * The stored tree is: - * / - * active/ root of the current or active tree * archive/ root of the archived tree * * ... - * / old root of active as of epoch#1 - * ... - * / old root of active as of epoch#n + * (/ and /active are only memory and never on disk, parts + * under /active that are on disk are shared with entries in /archive) */ struct Dsuperblk { @@ -179,7 +180,7 @@ enum { - Noaddr = ~0UL + Noaddr = ~0UL /* null address, for / */ }; #define TAG(addr,type) ((addr)<<8|((type)&0x7F)) @@ -187,13 +188,17 @@ #define TAGADDROK(t,addr) (((t)&~0xFF) == ((addr)<<8)) /* - * disk block + * disk blocks + */ + +/* + * header for all disk blocks. + * Those using on-disk references keep them at a DBref block */ struct Diskblkhdr { u64int tag; /* block tag */ u64int epoch; /* block epoch */ - /* ref is kept on Dref blocks */ }; union Diskblk @@ -212,27 +217,31 @@ uchar ddata[Dblksz]; }; +/* + * These are derived. + * Artificially lowered for testing to exercise indirect blocks and lists. + */ enum { Dblkdatasz = sizeof(Diskblk) - sizeof(Diskblkhdr), - Embedsz = Dblkdatasz - sizeof(Dfileblk), + Embedsz = Dblkdatasz - sizeof(Dfileblk), + +#ifdef TESTING + Dentryperblk = 4, + Dptrperblk = 4, + Drefperblk = 4, +#else Dentryperblk = Dblkdatasz / sizeof(Dentry), Dptrperblk = Dblkdatasz / sizeof(u64int), Drefperblk = Dblkdatasz / sizeof(u64int), +#endif }; + /* * File attributes are name/value pairs. - * A few ones have the name implied by their position. - * All integer values are always kept LE. - * addr u64int - * mode u32int - * mtime u64int - * length u64int - * uid [n] + UTF8 + '\0' - * gid [n] + UTF8 + '\0' - * muid [n] + UTF8 + '\0' - * name [n] + UTF8 + '\0' + * By now, only mandatory attributes are implemented, and + * have names implied by their position in the Dmeta structure. */ /* @@ -240,16 +249,9 @@ */ /* - * unpacked file attributes point into the Bfile embedded data. + * The first time a directory data is used, it is fully loaded and + * a Child list refers to the data blocks, to simplify navigation. */ -struct Fattr -{ - Fattr *next; - char *name; - uchar *val; - long nval; -}; - struct Child { Memblk *f; /* actual child */ @@ -257,6 +259,9 @@ Dentry *d; /* loaded dentry */ }; +/* + * File metadata + */ struct Fmeta { Dmeta; @@ -266,6 +271,9 @@ char *name; }; +/* + * On memory file information. + */ struct Mfile { RWLock; @@ -275,7 +283,7 @@ Mfile *next; /* in free Mfile list */ }; - Memblk* lastb; /* last returned data block */ + Memblk* lastb; /* memo: last returned data block */ ulong lastbno; /* for the last asked block # */ Child *child; /* direct references to loaded children */ @@ -289,23 +297,23 @@ struct Memblk { Ref; - u64int addr; /* block address */ - Memblk *next; /* in hash or free list */ + u64int addr; /* block address */ + Memblk *next; /* in hash or free list */ - /* for DBref only */ union{ - Memblk *rnext; /* in list of ref blocks */ - Mfile *mf; /* per file mem info */ + Memblk *rnext; /* in list of DBref blocks */ + Mfile *mf; /* DBfile on memory info. */ }; - int dirty; /* must be written */ - int frozen; /* is frozen */ - int written; /* no need to scan this for dirties */ + int dirty; /* must be written */ + int frozen; /* is frozen */ + int written; /* no need to scan this for dirties */ + Diskblk d; }; /* - * Slice into a block + * Slice into a block, used to read/write file blocks. */ struct Blksl { @@ -320,33 +328,33 @@ struct{ RWLock; Memblk *b; - } fhash[Fhashsz]; + } fhash[Fhashsz]; /* hash of blocks by address */ - Memblk *blk; - usize nblk; - usize nablk; - usize nused; - usize nfree; - Memblk *free; - Mfile *mfree; + Memblk *blk; /* static global array of memory blocks */ + usize nblk; /* # of entries used */ + usize nablk; /* # of entries allocated */ + usize nused; /* blocks in use */ + usize nfree; /* free blocks */ - Memblk *refs; + Memblk *free; /* free list of unused blocks in blk */ + Mfile *mfree; /* unused list */ - usize limit; + Memblk *refs; /* list of DBref blocks (also hashed) */ + Memblk *super; /* locked by blklk */ Memblk *root; /* only in memory */ Memblk *active; /* /active */ Memblk *archive; /* /archive */ Memblk *fzsuper; /* frozen super */ - Memblk *fzactive; /* frozen active */ - Memblk *fzarchive; /* frozen archive */ - char *dev; - int fd; + char *dev; /* name for disk */ + int fd; /* of disk */ + usize limit; /* address for end of disk */ }; #pragma varargck type "H" Memblk* extern char*tname[]; +extern Fsys*fs; diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/fblk.c --- a/sys/src/cmd/Cfs/fblk.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/fblk.c Fri Feb 10 17:42:19 2012 +0000 @@ -73,24 +73,26 @@ static Memblk* -getmelted(Fsys *fs, uint type, u64int *addrp) +getmelted(uint type, u64int *addrp) { Memblk *b, *nb; if(*addrp == 0){ - b = dballoc(fs, type); + b = dballoc(type); *addrp = b->addr; + incref(b); return b; } - b = dbget(fs, type, *addrp); + b = dbget(type, *addrp); if(b->frozen == 0) return b; - nb = dbdup(fs, b); - dbdecref(fs, b->addr); - mbput(fs, b); + nb = dbdup(b); + dbdecref(b->addr); + mbput(b); *addrp = nb->addr; + incref(nb); return nb; } @@ -99,7 +101,7 @@ * if mkit. The file must be r/wlocked and melted if mkit. */ static Memblk* -dfblk(Fsys *fs, Memblk *f, ulong bno, int mkit) +dfblk(Memblk *f, ulong bno, int mkit) { ulong prev, nblks; int i, idx, nindir, type; @@ -107,6 +109,7 @@ u64int *addrp; Mfile *m; + if(0)dDprint("DF0 %H", f); m = f->mf; if(mkit){ iswlocked(f); @@ -124,7 +127,7 @@ /* BUG: read ahead */ } if(m->lastb != nil) - mbput(fs, m->lastb); + mbput(m->lastb); m->lastb = nil; } m->lastbno = bno; @@ -140,9 +143,9 @@ */ if(bno < nelem(f->d.dptr)){ if(mkit) - b = getmelted(fs, DBdata, &f->d.dptr[bno]); + b = getmelted(DBdata, &f->d.dptr[bno]); else - b = dbget(fs, DBdata, f->d.dptr[bno]); + b = dbget(DBdata, f->d.dptr[bno]); goto Found; } @@ -163,56 +166,68 @@ } if(i == nelem(f->d.iptr)) sysfatal("fblkaddr"); + + type = DBptr0+i; + dDprint("dfblk indirect DB%s nblks %uld (ppb %ud) bno %uld\n", + tname[type], nblks, Dptrperblk, bno); pb = f; incref(pb); - addrp = &f->d.iptr[bno]; + addrp = &f->d.iptr[i]; if(mkit) - b = getmelted(fs, DBptr, addrp); + b = getmelted(type, addrp); else - b = dbget(fs, DBptr, *addrp); + b = dbget(type, *addrp); /* invariant at the loop header: - * b: ptr block we are looking at. + * b: DBptr block we are looking at. * nblks: # of data blocks addressed by b * pb: parent of b * addrp: ptr to b within fb. */ if(catcherror()){ - mbput(fs, pb); - mbput(fs, b); + mbput(pb); + mbput(b); error(nil); } - for(nindir = i; nindir >= 0; nindir--){ - nblks /= Dptrperblk; - idx = bno/nblks; + for(nindir = i+1; nindir >= 0; nindir--){ + dDprint("indir DB%s d%#ullx nblks %uld ptrperblk %d bno %uld\n", + tname[DBdata+nindir], *addrp, nblks, Dptrperblk, bno); + dDprint(" in %H", b); + idx = 0; + if(nindir > 0){ + nblks /= Dptrperblk; + idx = bno/nblks; + } if(*addrp == 0 && !mkit){ /* hole */ b = nil; }else{ - type = DBptr; - if(nindir == 0) - type = DBdata; + assert(type >= DBdata); if(mkit) - b = getmelted(fs, type, addrp); + b = getmelted(type, addrp); else - b = dbget(fs, type, *addrp); + b = dbget(type, *addrp); addrp = &b->d.ptr[idx]; - mbput(fs, pb); + mbput(pb); pb = b; } USED(&b); /* force to memory in case of error */ USED(&pb); /* force to memory in case of error */ bno -= idx * nblks; prev += idx * nblks; + type--; } - mbput(fs, pb); noerror(); Found: -// if(b != nil) -// incref(b); -// m->lastb = b; /* memo the last search; beware of holes vs. memos */ + if(0){ + if(b != nil) + incref(b); + m->lastb = b; /* memo the last search */ + }else + m->lastb = nil; + if(0)dDprint("DF1 %H%H", f,b); return b; } @@ -241,15 +256,14 @@ * The block is returned unlocked, but still protected by the file lock. */ Blksl -dfslice(Fsys *fs, Memblk *f, ulong len, uvlong off, int iswr) +dfslice(Memblk *f, ulong len, uvlong off, int iswr) { Blksl sl; - ulong doff, dlen, bno, nsize; + ulong boff, doff, dlen, bno; - dDprint("slice off %#ullx len %#ulx wr=%d at m%#p\n", off, len, iswr, f); + dDprint("slice off %#ullx len %#ulx wr=%d at m%#p\n%H", off, len, iswr, f,f); memset(&sl, 0, sizeof sl); - nsize = off + 0; if(iswr){ iswlocked(f); ismelted(f); @@ -266,36 +280,36 @@ sl.data = f->d.embed + doff + off; sl.len = dlen - off; }else{ - off -= dlen; - bno = off / Dblkdatasz; - off %= Dblkdatasz; + bno = (off-dlen) / Dblkdatasz; + boff = (off-dlen) % Dblkdatasz; - sl.b = dfblk(fs, f, bno, iswr); - - dDprint("dfblk %H%uld -> %H", f, bno, sl.b); + sl.b = dfblk(f, bno, iswr); if(iswr) ismelted(sl.b); if(sl.b != nil) - sl.data = sl.b->d.data + off; - - sl.len = Dblkdatasz - off; - if(doff + bno*Dblkdatasz + off + sl.len > f->mf->length) - sl.len = f->mf->length - (doff + bno*Dblkdatasz + off); + sl.data = sl.b->d.data + boff; + sl.len = Dblkdatasz - boff; } + if(sl.len > len) sl.len = len; - nsize += sl.len; + if(off + sl.len > f->mf->length) + if(iswr) + fresize(f, off + sl.len); + else + sl.len = f->mf->length - off; Done: - if(iswr && nsize > f->mf->length) - fresize(f, nsize); - if(sl.b == nil) + if(sl.b == nil){ dDprint("slice-> null with len %#ulx\n", sl.len); - else if(TAGTYPE(sl.b->d.tag) == DBfile) - dDprint("slice-> off %#ulx len %#ulx at m%#p\n", - (uchar*)sl.data - sl.b->d.embed, sl.len, sl.b); + return sl; + } + assert(sl.b->ref > 1); + if(TAGTYPE(sl.b->d.tag) == DBfile) + dDprint("slice -> off %#ulx len %#ulx at m%#p fsz %#ullx\n", + (uchar*)sl.data - sl.b->d.embed, sl.len, sl.b, f->mf->length); else - dDprint("slice-> off %#ulx len %#ulx at m%#p\n", - (uchar*)sl.data - sl.b->d.data, sl.len, sl.b); + dDprint("slice-> off %#ulx len %#ulx at m%#p fsz %#ullx\n", + (uchar*)sl.data - sl.b->d.data, sl.len, sl.b, f->mf->length); return sl; } @@ -366,7 +380,7 @@ * as its child entry is alive. */ void -dflink(Fsys *fs, Memblk *d, Memblk *f) +dflink(Memblk *d, Memblk *f) { Blksl sl; Dentry *de; @@ -378,7 +392,7 @@ ismelted(d); isdir(d); if(d->mf->length > 0 && d->mf->child == nil) - dfloaddir(fs, d, 1); + dfloaddir(d, 1); c = addchild(d, f); if(catcherror()){ @@ -387,13 +401,13 @@ } off = 0; for(;;){ - sl = dfslice(fs, d, sizeof(Dentry), off, 1); + sl = dfslice(d, sizeof(Dentry), off, 1); if(sl.len == 0) break; ismelted(sl.b); off += sl.len; if(sl.len < sizeof(Dentry)){ /* trailing part in block */ - mbput(fs, sl.b); + mbput(sl.b); continue; } de = sl.data; @@ -402,10 +416,10 @@ c->b = sl.b; de->file = f->addr; changed(sl.b); - mbput(fs, sl.b); + mbput(sl.b); break; } - mbput(fs, sl.b); + mbput(sl.b); } changed(d); noerror(); @@ -416,7 +430,7 @@ * caller locks both d and f */ void -dfunlink(Fsys *fs, Memblk *d, Memblk *f) +dfunlink(Memblk *d, Memblk *f) { Dentry *de; Child *c; @@ -426,20 +440,20 @@ ismelted(d); isdir(d); if(d->mf->length > 0 && d->mf->child == nil) - dfloaddir(fs, d, 1); + dfloaddir(d, 1); c = getchild(d, f); ismelted(c->b); de = c->d; de->file = 0; changed(c->b); - mbput(fs, c->b); + mbput(c->b); delchild(d, c); changed(d); } void -dfloaddir(Fsys *fs, Memblk *d, int locked) +dfloaddir(Memblk *d, int locked) { Blksl sl; Dentry *de; @@ -460,26 +474,26 @@ } off = 0; for(;;){ - sl = dfslice(fs, d, sizeof(Dentry), off, 0); + sl = dfslice(d, sizeof(Dentry), off, 0); if(sl.len == 0) break; off += sl.len; if(sl.len < sizeof(Dentry)){ /* trailing part in block */ - mbput(fs, sl.b); + mbput(sl.b); continue; } if(catcherror()){ - mbput(fs, sl.b); + mbput(sl.b); error(nil); } de = sl.data; if(de->file == 0) continue; - f = dbget(fs, DBfile, de->file); + f = dbget(DBfile, de->file); c = addchild(d, f); c->d = de; c->b = sl.b; - mbput(fs, f); + mbput(f); noerror(); } if(!locked) @@ -494,7 +508,7 @@ * dir must be already loaded. */ Memblk* -dfwalk(Fsys *fs, Memblk *d, char *name, int iswr) +dfwalk(Memblk *d, char *name, int iswr) { Memblk *f, *nf; int i; @@ -524,11 +538,11 @@ return(f); } /* hard: it's frozen and iswr; must melt it */ - nf = dbdup(fs, f); + nf = dbdup(f); wunlock(f->mf); wlock(nf->mf); - dbdecref(fs, f->addr); - mbput(fs, f); + dbdecref(f->addr); + mbput(f); c->f = nf; incref(nf); c->d->file = nf->addr; @@ -548,7 +562,7 @@ * Return it wlocked, so nobody can freeze it again before we use it. */ Memblk* -dfmelt(Fsys *fs, Memblk *f) +dfmelt(Memblk *f) { char **names; int nnames; @@ -591,18 +605,18 @@ free(names[nnames]); free(names); wunlock(b->mf); - mbput(fs, b); + mbput(b); error("can't melt: %r"); } while(nnames-- > 0){ if(b->mf->length > 0 && b->mf->child == nil) - dfloaddir(fs, b, 1); - nb = dfwalk(fs, b, names[--nnames], 1); + dfloaddir(b, 1); + nb = dfwalk(b, names[--nnames], 1); free(names[nnames]); names[nnames] = nil; wunlock(b->mf); - mbput(fs, b); + mbput(b); b = nb; USED(&b); /* flush b to memory for error()s */ } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/file.c --- a/sys/src/cmd/Cfs/file.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/file.c Fri Feb 10 17:42:19 2012 +0000 @@ -19,7 +19,7 @@ * Ok if nelems is 0. */ Memblk* -walkpath(Fsys *fs, Memblk *f, char *elems[], int nelems) +walkpath(Memblk *f, char *elems[], int nelems) { int i; Memblk *nf; @@ -28,7 +28,7 @@ rlock(f->mf); if(f->mf->length > 0 && f->mf->child == nil){ runlock(f->mf); - dfloaddir(fs, f, 0); + dfloaddir(f, 0); rlock(f->mf); } if(catcherror()){ @@ -38,7 +38,7 @@ for(i = 0; i < nelems; i++){ if((f->mf->mode&DMDIR) == 0) error("not a directory"); - nf = dfwalk(fs, f, elems[i], 0); + nf = dfwalk(f, elems[i], 0); runlock(f->mf); f = nf; USED(&f); /* in case of error() */ @@ -50,7 +50,7 @@ } Memblk* -dfcreate(Fsys *fs, Memblk *parent, char *name, char *uid, ulong mode) +dfcreate(Memblk *parent, char *name, char *uid, ulong mode) { Memblk *b; Mfile *m; @@ -61,19 +61,19 @@ wlock(parent->mf); if(parent->frozen){ wunlock(parent->mf); - parent = dfmelt(fs, parent); + parent = dfmelt(parent); }else incref(parent); - b = dballoc(fs, DBfile); + b = dballoc(DBfile); }else - b = dballoc(fs, Noaddr); /* root */ + b = dballoc(Noaddr); /* root */ if(catcherror()){ wunlock(b->mf); - mbput(fs, b); + mbput(b); if(parent != nil){ wunlock(parent->mf); - mbput(fs, parent); + mbput(parent); } error("create: %r"); } @@ -90,9 +90,9 @@ if(parent != nil){ m->gid = parent->mf->uid; - dflink(fs, parent, b); + dflink(parent, b); wunlock(parent->mf); - mbput(fs, parent); + mbput(parent); } noerror(); changed(b); @@ -104,17 +104,18 @@ * returns a slice into a block for reading. */ Blksl -dfreadblk(Fsys *fs, Memblk *f, ulong len, uvlong off) +dfreadblk(Memblk *f, ulong len, uvlong off) { Blksl sl; + dDprint("dfreadblk m%#p len %#ulx off %#ullx\n", f, len, off); isfile(f); rlock(f->mf); if(catcherror()){ runlock(f->mf); error("read: %r"); } - sl = dfslice(fs, f, len, off, 0); + sl = dfslice(f, len, off, 0); noerror(); runlock(f->mf); return sl; @@ -125,30 +126,31 @@ * the block is returned unlocked. */ Blksl -dfwriteblk(Fsys *fs, Memblk *f, uvlong off) +dfwriteblk(Memblk *f, ulong count, uvlong off) { Blksl sl; + dDprint("dfwriteblk m%#p off %#ullx\n", f, off); isnotdir(f); wlock(f->mf); if(f->frozen){ wunlock(f->mf); - f = dfmelt(fs, f); + f = dfmelt(f); }else incref(f); if(catcherror()){ wunlock(f->mf); error(nil); } - sl = dfslice(fs, f, 0, off, 1); + sl = dfslice(f, count, off, 1); noerror(); wunlock(f->mf); - mbput(fs, f); + mbput(f); return sl; } ulong -dfpread(Fsys *fs, Memblk *f, void *a, ulong count, uvlong off) +dfpread(Memblk *f, void *a, ulong count, uvlong off) { Blksl sl; ulong tot; @@ -156,7 +158,7 @@ p = a; for(tot = 0; tot < count; tot += sl.len){ - sl = dfreadblk(fs, f, count, off); + sl = dfreadblk(f, count-tot, off+tot); if(sl.len == 0) break; if(sl.data == nil){ @@ -164,13 +166,13 @@ continue; } memmove(p+tot, sl.data, sl.len); - mbput(fs, sl.b); + mbput(sl.b); } return tot; } ulong -dfpwrite(Fsys *fs, Memblk *f, void *a, ulong count, uvlong off) +dfpwrite(Memblk *f, void *a, ulong count, uvlong off) { Blksl sl; ulong tot; @@ -178,12 +180,12 @@ p = a; for(tot = 0; tot < count; tot += sl.len){ - sl = dfwriteblk(fs, f, off); + sl = dfwriteblk(f, count-tot, off+tot); if(sl.len == 0 || sl.data == nil) sysfatal("dfpwrite: bug"); memmove(sl.data, p+tot, sl.len); changed(sl.b); - mbput(fs, sl.b); + mbput(sl.b); } return tot; } @@ -200,23 +202,23 @@ * freeze a direct or indirect pointer and everything below it. */ static void -ptrfreeze(Fsys *fs, u64int addr, int nind) +ptrfreeze(u64int addr, int nind) { int i; Memblk *b; if(addr == 0) return; - b = mbget(fs, addr); + b = mbget(addr); if(b == nil) return; /* on disk: frozen */ if(!b->frozen){ b->frozen = 1; if(nind > 0) for(i = 0; i < Dptrperblk; i++) - ptrfreeze(fs, b->d.ptr[i], nind-1); + ptrfreeze(b->d.ptr[i], nind-1); } - mbput(fs, b); + mbput(b); } /* @@ -224,7 +226,7 @@ * Do not recur if children is found frozen. */ void -dffreeze(Fsys *fs, Memblk *f) +dffreeze(Memblk *f) { int i; Memblk *b; @@ -234,16 +236,16 @@ dDprint("dffrezee m%#p\n", f); f->frozen = 1; for(i = 0; i < nelem(f->d.dptr); i++) - ptrfreeze(fs, f->d.dptr[i], 0); + ptrfreeze(f->d.dptr[i], 0); for(i = 0; i < nelem(f->d.iptr); i++) - ptrfreeze(fs, f->d.dptr[i], i+1); + ptrfreeze(f->d.dptr[i], i+1); if((f->mf->mode&DMDIR) == 0) return; for(i = 0; i < f->mf->nchild; i++){ b = f->mf->child[i].f; if(!b->frozen){ wlock(b->mf); - dffreeze(fs, b); + dffreeze(b); wunlock(b->mf); } } @@ -253,32 +255,32 @@ * freeze a direct or indirect pointer and everything below it. */ static void -ptrsync(Fsys *fs, u64int addr, int nind) +ptrsync(u64int addr, int nind) { int i; Memblk *b; if(addr == 0) return; - b = mbget(fs, addr); + b = mbget(addr); if(b == nil) return; /* on disk */ if(!b->frozen) sysfatal("ptrsync: not frozen\n\t%H", b); if(b->dirty) - dbwrite(fs, b); + dbwrite(b); b->dirty = 0; - mbput(fs, b); + mbput(b); if(nind > 0) for(i = 0; i < Dptrperblk; i++) - ptrsync(fs, b->d.ptr[i], nind-1); + ptrsync(b->d.ptr[i], nind-1); } /* * Ensure all frozen but dirty blocks are in disk. */ void -dfsync(Fsys *fs, Memblk *f) +dfsync(Memblk *f) { int i; @@ -289,15 +291,15 @@ sysfatal("dfsync: not frozen\n\t%H", f); for(i = 0; i < nelem(f->d.dptr); i++) - ptrsync(fs, f->d.dptr[i], 0); + ptrsync(f->d.dptr[i], 0); for(i = 0; i < nelem(f->d.iptr); i++) - ptrsync(fs, f->d.dptr[i], i+1); + ptrsync(f->d.dptr[i], i+1); for(i = 0; i < f->mf->nchild; i++) - dfsync(fs, f->mf->child[i].f); + dfsync(f->mf->child[i].f); rlock(f->mf); if(f->dirty) - dbwrite(fs, f); + dbwrite(f); f->dirty = 0; f->written = 1; runlock(f->mf); @@ -307,25 +309,25 @@ * release a direct or indirect pointer and everything below it. */ static int -ptrreclaim(Fsys *fs, u64int addr, int nind) +ptrreclaim(u64int addr, int nind) { int i; Memblk *b; if(addr == 0) return 0; - if(dbdecref(fs, addr) != 0) + if(dbdecref(addr) != 0) return 0; - b = dbget(fs, nind == 0? DBdata: DBptr, addr); + b = dbget(DBdata+nind, addr); if(!b->frozen) sysfatal("ptrreclaim: not frozen\n\t%H", b); - mbunhash(fs, b); + mbunhash(b); if(b->ref != 1) sysfatal("dfreclaim: bug?"); if(nind > 0) for(i = 0; i < Dptrperblk; i++) - ptrreclaim(fs, b->d.ptr[i], nind-1); - mbput(fs, b); + ptrreclaim(b->d.ptr[i], nind-1); + mbput(b); return 1; } @@ -340,31 +342,31 @@ * TODO: do this using an external cleaner program? */ int -dfreclaim(Fsys *fs, Memblk *f) +dfreclaim(Memblk *f) { int i, tot; tot = 0; dDprint("dfreclaim %H", f); - if(dbdecref(fs, f->addr) != 0) + if(dbdecref(f->addr) != 0) return 0; tot++; if(!f->frozen) sysfatal("dfsync: not frozen\n\t%H", f); incref(f); - mbunhash(fs, f); + mbunhash(f); if(f->ref != 1) sysfatal("dfreclaim: ref is %d", f->ref); for(i = 0; i < nelem(f->d.dptr); i++) - tot += ptrreclaim(fs, f->d.dptr[i], 0); + tot += ptrreclaim(f->d.dptr[i], 0); for(i = 0; i < nelem(f->d.iptr); i++) - tot += ptrreclaim(fs, f->d.dptr[i], i+1); + tot += ptrreclaim(f->d.dptr[i], i+1); if(f->mf->mode&DMDIR){ isloaded(f); for(i = 0; i < f->mf->nchild; i++) - tot += dfreclaim(fs, f->mf->child[i].f); + tot += dfreclaim(f->mf->child[i].f); } - mbput(fs, f); + mbput(f); return tot; } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/fns.h --- a/sys/src/cmd/Cfs/fns.h Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/fns.h Fri Feb 10 17:42:19 2012 +0000 @@ -1,45 +1,41 @@ -/* - |c/f2p *.c - */ - extern u64int addrofref(u64int refaddr, int idx); extern void changed(Memblk *b); extern void clean(Memblk *b); -extern Memblk* dballoc(Fsys *fs, uint type); -extern void dbclear(Fsys *fs, u64int addr, int type); -extern u64int dbdecref(Fsys *fs, u64int addr); -extern Memblk* dbdup(Fsys *fs, Memblk *b); -extern Memblk* dbget(Fsys *fs, uint type, u64int addr); -extern u64int dbgetref(Fsys *fs, u64int addr); -extern void dbincref(Fsys *fs, u64int addr); -extern long dbread(Fsys *fs, Memblk *b); -extern void dbsetref(Fsys *fs, u64int addr, u64int ref); -extern long dbwrite(Fsys *fs, Memblk *b); +extern Memblk* dballoc(uint type); +extern void dbclear(u64int addr, int type); +extern u64int dbdecref(u64int addr); +extern Memblk* dbdup(Memblk *b); +extern Memblk* dbget(uint type, u64int addr); +extern u64int dbgetref(u64int addr); +extern void dbincref(u64int addr); +extern long dbread(Memblk *b); +extern void dbsetref(u64int addr, u64int ref); +extern long dbwrite(Memblk *b); extern void delchild(Memblk *d, Child *c); -extern Memblk* dfcreate(Fsys *fs, Memblk *parent, char *name, char *uid, ulong mode); -extern void dffreeze(Fsys *fs, Memblk *f); -extern void dflink(Fsys *fs, Memblk *d, Memblk *f); -extern void dfloaddir(Fsys *fs, Memblk *d, int locked); -extern Memblk* dfmelt(Fsys *fs, Memblk *f); -extern ulong dfpread(Fsys *fs, Memblk *f, void *a, ulong count, uvlong off); -extern ulong dfpwrite(Fsys *fs, Memblk *f, void *a, ulong count, uvlong off); -extern long dfrattr(Fsys *fs, Memblk *f, char *name, void *val, long count); -extern Blksl dfreadblk(Fsys *fs, Memblk *f, ulong len, uvlong off); -extern int dfreclaim(Fsys *fs, Memblk *f); -extern Blksl dfslice(Fsys *fs, Memblk *f, ulong len, uvlong off, int iswr); -extern void dfsync(Fsys *fs, Memblk *f); -extern void dfunlink(Fsys *fs, Memblk *d, Memblk *f); -extern Memblk* dfwalk(Fsys *fs, Memblk *d, char *name, int iswr); -extern long dfwattr(Fsys *fs, Memblk *f, char *name, void *val, long nval); -extern Blksl dfwriteblk(Fsys *fs, Memblk *f, uvlong off); +extern Memblk* dfcreate(Memblk *parent, char *name, char *uid, ulong mode); +extern void dffreeze(Memblk *f); +extern void dflink(Memblk *d, Memblk *f); +extern void dfloaddir(Memblk *d, int locked); +extern Memblk* dfmelt(Memblk *f); +extern ulong dfpread(Memblk *f, void *a, ulong count, uvlong off); +extern ulong dfpwrite(Memblk *f, void *a, ulong count, uvlong off); +extern long dfrattr(Memblk *f, char *name, void *val, long count); +extern Blksl dfreadblk(Memblk *f, ulong len, uvlong off); +extern int dfreclaim(Memblk *f); +extern Blksl dfslice(Memblk *f, ulong len, uvlong off, int iswr); +extern void dfsync(Memblk *f); +extern void dfunlink(Memblk *d, Memblk *f); +extern Memblk* dfwalk(Memblk *d, char *name, int iswr); +extern long dfwattr(Memblk *f, char *name, void *val, long nval); +extern Blksl dfwriteblk(Memblk *f, ulong count, uvlong off); extern void disktohost(Memblk *b); extern ulong embedattrsz(Memblk *f); -extern void fsdump(Fsys *fs); -extern Fsys* fsfmt(char *dev); -extern Memblk* fsfreeze(Fsys *fs); -extern Fsys* fsopen(char *dev); -extern void fsreclaim(Fsys *fs); -extern void fssync(Fsys *fs); +extern void fsdump(void); +extern void fsfmt(char *dev); +extern Memblk* fsfreeze(void); +extern void fsopen(char *dev); +extern void fsreclaim(void); +extern void fssync(void); extern void gmeta(Fmeta *meta, void *buf, ulong nbuf); extern Memblk* hosttodisk(Memblk *b); extern void isdir(Memblk *d); @@ -53,17 +49,17 @@ extern void main(int argc, char *argv[]); extern void main(int argc, char *argv[]); extern void main(int, char *argv[]); -extern Memblk* mballoc(Fsys *fs, u64int addr); -extern Memblk* mbdup(Fsys *fs, Memblk *b); +extern Memblk* mballoc(u64int addr); +extern Memblk* mbdup(Memblk *b); extern int mbfmt(Fmt *fmt); -extern Memblk* mbget(Fsys *fs, u64int addr); -extern Memblk* mbhash(Fsys *fs, Memblk *b); -extern void mbput(Fsys *fs, Memblk *b); -extern void mbunhash(Fsys *fs, Memblk *b); -extern void meltedref(Fsys *fs, Memblk *rb); -extern u64int newblkaddr(Fsys *fs); +extern Memblk* mbget(u64int addr); +extern Memblk* mbhash(Memblk *b); +extern void mbput(Memblk *b); +extern void mbunhash(Memblk *b); +extern void meltedref(Memblk *rb); +extern u64int newblkaddr(void); extern uvlong now(void); -extern void okaddr(Fsys *fs, u64int addr); +extern void okaddr(u64int addr); extern ulong pmeta(void *buf, ulong nbuf, Fmeta *meta); extern u64int refaddr(u64int addr, int *idx); -extern Memblk* walkpath(Fsys *fs, Memblk *f, char *elems[], int nelems); +extern Memblk* walkpath(Memblk *f, char *elems[], int nelems); diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/fscmd.c --- a/sys/src/cmd/Cfs/fscmd.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/fscmd.c Fri Feb 10 17:42:19 2012 +0000 @@ -29,7 +29,7 @@ } static Memblk* -walkto(Fsys *fs, char *a, char **lastp) +walkto(char *a, char **lastp) { char *els[Nels], *path; int nels; @@ -46,10 +46,10 @@ error("walkpath: %r"); } if(lastp != nil){ - f = walkpath(fs, fs->root, els, nels-1); + f = walkpath(fs->root, els, nels-1); *lastp = a + strlen(a) - strlen(els[nels-1]); }else - f = walkpath(fs, fs->root, els, nels); + f = walkpath(fs->root, els, nels); free(path); noerror(); if(verb) @@ -58,14 +58,14 @@ } static void -fscd(Fsys*, int, char *argv[]) +fscd(int, char *argv[]) { free(fsdir); fsdir = strdup(argv[1]); } static void -fsput(Fsys *fs, int, char *argv[]) +fsput(int, char *argv[]) { int fd; char *fn; @@ -89,23 +89,23 @@ fprint(2, "%s: error: %r\n", argv[0]); goto done; } - m = walkto(fs, argv[2], &fn); - f = dfcreate(fs, m, fn, d->uid, d->mode&(DMDIR|0777)); + m = walkto(argv[2], &fn); + f = dfcreate(m, fn, d->uid, d->mode&(DMDIR|0777)); if((d->mode&DMDIR) == 0){ off = 0; for(;;){ nr = read(fd, buf, sizeof buf); if(nr <= 0) break; - nw = dfpwrite(fs, f, buf, nr, off); + nw = dfpwrite(f, buf, nr, off); dDprint("wrote %ld of %ld bytes\n", nw, nr); off += nr; } } - mbput(fs, m); + mbput(m); if(verb) print("created %H", f); - mbput(fs, f); + mbput(f); noerror(); done: close(fd); @@ -113,7 +113,7 @@ } static void -fscat(Fsys *fs, int, char *argv[]) +fscat(int, char *argv[]) { Memblk *f; Mfile *m; @@ -125,19 +125,19 @@ fprint(2, "%s: error: %r\n", argv[0]); return; } - f = walkto(fs, argv[2], nil); + f = walkto(argv[2], nil); if(catcherror()){ fprint(2, "%s: error: %r\n", argv[0]); - mbput(fs, f); + mbput(f); return; } m = f->mf; - print("%-30s\t%M\t%5ulld\t%s %ulld refs\n", - m->name, (ulong)m->mode, m->length, m->uid, dbgetref(fs, f->addr)); + print("cat %-30s\t%M\t%5ulld\t%s %ulld refs\n", + m->name, (ulong)m->mode, m->length, m->uid, dbgetref(f->addr)); if((m->mode&DMDIR) == 0){ off = 0; for(;;){ - nr = dfpread(fs, f, buf, sizeof buf, off); + nr = dfpread(f, buf, sizeof buf, off); if(nr <= 0) break; write(1, buf, nr); @@ -146,11 +146,59 @@ } noerror(); noerror(); - mbput(fs, f); + mbput(f); } static void -flist(Fsys *fs, Memblk *f, char *ppath) +fsget(int, char *argv[]) +{ + Memblk *f; + Mfile *m; + char buf[4096]; + uvlong off; + long nr; + int fd; + + fd = create(argv[1], OWRITE, 0664); + if(fd < 0){ + fprint(2, "%s: error: %r\n", argv[0]); + return; + } + if(catcherror()){ + close(fd); + fprint(2, "%s: error: %r\n", argv[0]); + return; + } + f = walkto(argv[2], nil); + if(catcherror()){ + mbput(f); + error(nil); + } + m = f->mf; + print("get %-30s\t%M\t%5ulld\t%s %ulld refs\n", + m->name, (ulong)m->mode, m->length, m->uid, dbgetref(f->addr)); +print("%H", f); + if((m->mode&DMDIR) == 0){ + off = 0; + for(;;){ + nr = dfpread(f, buf, sizeof buf, off); + if(nr <= 0) + break; + if(write(fd, buf, nr) != nr){ + fprint(2, "%s: error: %r\n", argv[0]); + break; + } + off += nr; + } + } + close(fd); + noerror(); + noerror(); + mbput(f); +} + +static void +flist(Memblk *f, char *ppath) { char *path; Mfile *m; @@ -158,7 +206,7 @@ m = f->mf; if(m->mode&DMDIR) - dfloaddir(fs, f, 0); + dfloaddir(f, 0); rlock(m); if(ppath == nil){ print("/"); @@ -166,35 +214,45 @@ }else path = smprint("%s/%s", ppath, m->name); print("%-30s\t%M\t%5ulld\t%s %ulld refs\n", - path, (ulong)m->mode, m->length, m->uid, dbgetref(fs, f->addr)); + path, (ulong)m->mode, m->length, m->uid, dbgetref(f->addr)); if(m->mode&DMDIR) for(i = 0; i < m->nchild; i++) - flist(fs, m->child[i].f, path); + flist(m->child[i].f, path); runlock(m); free(path); } static void -fslist(Fsys *fs, int, char**) +fslist(int, char**) { - print("fsys '%s' blksz %ulld:\n", fs->dev, fs->super->d.dblksz); + u64int msz, fact; + int i; + + msz = Embedsz - Dminattrsz + Ndptr*Dblkdatasz; + fact = Dblkdatasz; + for(i = 0; i < Niptr; i++){ + msz += Dptrperblk * fact; + fact *= Dptrperblk; + } + print("fsys '%s' blksz %ulld maxdfsz %ulld:\n", + fs->dev, fs->super->d.dblksz, msz); if(verb) - fsdump(fs); + fsdump(); else - flist(fs, fs->root, nil); + flist(fs->root, nil); print("\n"); } static void -fssnap(Fsys *fs, int, char**) +fssnap(int, char**) { - fssync(fs); + fssync(); } static void -fsrcl(Fsys *fs, int, char**) +fsrcl(int, char**) { - fsreclaim(fs); + fsreclaim(); } static void @@ -207,23 +265,26 @@ static struct { char *name; - void (*f)(Fsys*, int, char**); + void (*f)(int, char**); int nargs; char *usage; } cmds[] = { {"cd", fscd, 2, "cd!where"}, {"put", fsput, 3, "put!src!dst"}, + {"get", fsget, 3, "get!dst!src"}, {"cat", fscat, 3, "cat!what"}, {"ls", fslist, 1, "ls"}, {"snap", fssnap, 1, "snap"}, {"rcl", fsrcl, 1, "rcl"}, }; +static char xdbg[256]; +static char zdbg[256]; + void main(int argc, char *argv[]) { - Fsys *fs; char *dev; char *args[Nels]; int i, j, nargs; @@ -238,8 +299,8 @@ break; default: if(ARGC() >= 'A' && ARGC() <= 'Z'){ - dbg['d'] = 1; - dbg[ARGC()] = 1; + xdbg['d'] = 1; + xdbg[ARGC()] = 1; }else usage(); }ARGEND; @@ -250,14 +311,14 @@ errinit(Errstack); if(catcherror()) sysfatal("error: %r"); - fs = fsopen(dev); + fsopen(dev); for(i = 0; i < argc; i++){ if(catcherror()) sysfatal("cmd %s: %r", argv[i]); if(verb>1) - fsdump(fs); + fsdump(); else if(verb) - flist(fs, fs->root, nil); + flist(fs->root, nil); print("%% %s\n", argv[i]); nargs = gettokens(argv[i], args, Nels, "!"); for(j = 0; j < nelem(cmds); j++){ @@ -265,8 +326,11 @@ continue; if(cmds[j].nargs != 0 && cmds[j].nargs != nargs) print("usage: %s\n", cmds[j].usage); - else - cmds[j].f(fs, nargs, args); + else{ + memmove(dbg, xdbg, sizeof xdbg); + cmds[j].f(nargs, args); + memmove(dbg, zdbg, sizeof zdbg); + } break; } noerror(); @@ -278,9 +342,9 @@ } } if(verb>1) - fsdump(fs); + fsdump(); else if(verb) - flist(fs, fs->root, nil); + flist(fs->root, nil); noerror(); exits(nil); } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/fsfmt.c --- a/sys/src/cmd/Cfs/fsfmt.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/fsfmt.c Fri Feb 10 17:42:19 2012 +0000 @@ -20,7 +20,6 @@ void main(int argc, char *argv[]) { - Fsys *fs; int verb; char *dev; @@ -46,9 +45,9 @@ errinit(Errstack); if(catcherror()) sysfatal("error: %r"); - fs = fsfmt(dev); + fsfmt(dev); if(verb) - fsdump(fs); + fsdump(); noerror(); exits(nil); } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/fsys.c --- a/sys/src/cmd/Cfs/fsys.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/fsys.c Fri Feb 10 17:42:19 2012 +0000 @@ -10,6 +10,8 @@ #include "dk.h" #include "fns.h" +Fsys *fs; + /* * All the code assumes outofmemoryexits = 1. */ @@ -30,7 +32,7 @@ } void -okaddr(Fsys *fs, u64int addr) +okaddr(u64int addr) { if(addr < Dblksz || addr >= fs->limit) error("okaddr %#ullx", addr); @@ -40,7 +42,7 @@ * NO LOCKS. debug only */ void -fsdump(Fsys *fs) +fsdump(void) { int i, flg; Memblk *b; @@ -60,7 +62,7 @@ print("free:"); flg = dbg['D']; dbg['D'] = 0; - for(a = b->d.free; a != 0; a = dbgetref(fs, a)) + for(a = b->d.free; a != 0; a = dbgetref(a)) print(" d%#ullx", a); dbg['D'] = flg; print("\n"); @@ -91,7 +93,7 @@ } static void -freezerefs(Fsys *fs) +freezerefs(void) { Memblk *rb; @@ -102,22 +104,22 @@ } static void -writerefs(Fsys *fs) +writerefs(void) { Memblk *rb; qlock(fs); for(rb = fs->refs; rb != nil; rb = rb->next) - meltedref(fs, rb); + meltedref(rb); qunlock(fs); } static void -freezesuper(Fsys *fs) +freezesuper(void) { Memblk *b; - b = mbdup(fs, fs->super); + b = mbdup(fs->super); qlock(fs); b->d = fs->super->d; assert(fs->fzsuper == nil); @@ -127,14 +129,14 @@ } static void -writesuper(Fsys *fs) +writesuper(void) { qlock(fs); assert(fs->fzsuper != nil); qunlock(fs); - dbwrite(fs, fs->fzsuper); + dbwrite(fs->fzsuper); dDprint("fswrite: %H", fs->fzsuper); - mbput(fs, fs->fzsuper); + mbput(fs->fzsuper); fs->fzsuper = nil; } @@ -144,13 +146,13 @@ * blocks may write to the disk. */ static void -fswrite(Fsys *fs) +fswrite(void) { if(fs->fzsuper == nil) sysfatal("can't fswrite if we didn't fsfreeze"); - writerefs(fs); - dfsync(fs, fs->archive); - writesuper(fs); + writerefs(); + dfsync(fs->archive); + writesuper(); } /* @@ -159,7 +161,7 @@ * returns the just frozen tree. */ Memblk* -fsfreeze(Fsys *fs) +fsfreeze(void) { Memblk *na, *oa, *arch, *super; Child *ac; @@ -173,8 +175,8 @@ wunlock(fs->active->mf); error("freeze already in progress"); } - dfloaddir(fs, fs->active, 1); - dfloaddir(fs, fs->archive, 1); + dfloaddir(fs->active, 1); + dfloaddir(fs->archive, 1); super = fs->super; if(catcherror()){ /* @@ -193,42 +195,42 @@ * active. */ oa = fs->active; - na = dbdup(fs, oa); + na = dbdup(oa); wlock(na->mf); seprint(name, name+sizeof(name), "%ulld", oa->d.epoch); - dfwattr(fs, oa, "name", name, strlen(name)+1); + dfwattr(oa, "name", name, strlen(name)+1); ac = fs->root->mf->child; assert(ac->f == oa); ac->f = na; /* keeps the ref we have */ ac->d->file = na->addr; if(fs->archive->frozen){ - arch = dbdup(fs, fs->archive); + arch = dbdup(fs->archive); wlock(arch->mf); wunlock(fs->archive->mf); - mbput(fs, fs->archive); + mbput(fs->archive); fs->archive = arch; for(i = nelem(super->d.root)-1; i > 0; i--) super->d.root[i] = super->d.root[i-1]; super->d.root[0] = fs->archive->addr; } - dflink(fs, fs->archive, oa); + dflink(fs->archive, oa); fs->active = na; fs->archive->frozen = 1; /* for fsfmt */ /* 1. Free the entire previously active */ - dffreeze(fs, oa); + dffreeze(oa); wunlock(oa->mf); /* 2. Freeze whatever new blocks are found in archive */ - dffreeze(fs, fs->archive); + dffreeze(fs->archive); /* 3. Freeze the on-disk reference counters * and the state of the super-block. */ - freezerefs(fs); - freezesuper(fs); + freezerefs(); + freezesuper(); /* /* 4. release locks, all done. @@ -239,11 +241,9 @@ return na; } -static Fsys* +static void fsinit(char *dev, int nblk) { - Fsys *fs; - fs = mallocz(sizeof *fs, 1); fs->dev = strdup(dev); fs->fd = open(dev, ORDWR); @@ -260,8 +260,7 @@ if(fs->limit < 10*Dblksz) sysfatal("disk is ridiculous"); fs->blk = malloc(fs->nablk * sizeof fs->blk[0]); - dDprint("fsys '%s' open\n", fs->dev); - return fs; + dDprint("fsys '%s' init\n", fs->dev); } /* @@ -271,53 +270,51 @@ * /active is allocated on disk, but not on disk. It will be linked into * /archive as a child in the future. */ -Fsys* +void fsfmt(char *dev) { - Fsys *fs; Memblk *super; if(catcherror()) sysfatal("fsfmt: error: %r"); - fs = fsinit(dev, 16); /* enough # of blocks for fmt */ + fsinit(dev, 16); /* enough # of blocks for fmt */ - fs->super = dballoc(fs, DBsuper); + fs->super = dballoc(DBsuper); super = fs->super; super->d.eaddr = fs->super->addr + Dblksz; super->d.dblksz = Dblksz; super->d.nblkgrpsz = Nblkgrpsz; super->d.dminattrsz = Dminattrsz; - fs->root = dfcreate(fs, nil, "", getuser(), DMDIR|0555); - fs->active = dfcreate(fs, fs->root, "active", getuser(), DMDIR|0775); - fs->archive = dfcreate(fs, fs->root, "archive", getuser(), DMDIR|0555); + fs->root = dfcreate(nil, "", getuser(), DMDIR|0555); + fs->active = dfcreate(fs->root, "active", getuser(), DMDIR|0775); + fs->archive = dfcreate(fs->root, "archive", getuser(), DMDIR|0555); super->d.root[0] = fs->archive->addr; - fsfreeze(fs); - fswrite(fs); + fsfreeze(); + fswrite(); noerror(); - return fs; } void -fssync(Fsys *fs) +fssync(void) { /* * TODO: If active has not changed and we are just going * to dump a new archive for no change, do nothing. */ - fsfreeze(fs); - fswrite(fs); + fsfreeze(); + fswrite(); } static Memblk* -readsuper(Fsys *fs) +readsuper(void) { Memblk *super; - fs->super = dbget(fs, DBsuper, Dblksz); + fs->super = dbget(DBsuper, Dblksz); super = fs->super; if(super->d.dblksz != Dblksz) error("bad Dblksz"); @@ -334,28 +331,25 @@ * To open more file systems, use more processes! */ -Fsys* +void fsopen(char *dev) { - Fsys *fs; - if(catcherror()) sysfatal("fsopen: error: %r"); - fs = fsinit(dev, 0); + fsinit(dev, 0); - readsuper(fs); + readsuper(); - fs->root = dfcreate(fs, nil, "", getuser(), DMDIR|0555); - fs->active = dfcreate(fs, fs->root, "active", getuser(), DMDIR|0775); - fs->archive = dbget(fs, DBfile, fs->super->d.root[0]); + fs->root = dfcreate(nil, "", getuser(), DMDIR|0555); + fs->active = dfcreate(fs->root, "active", getuser(), DMDIR|0775); + fs->archive = dbget(DBfile, fs->super->d.root[0]); wlock(fs->root->mf); wlock(fs->archive->mf); - dflink(fs, fs->root, fs->archive); + dflink(fs->root, fs->archive); wunlock(fs->archive->mf); wunlock(fs->root->mf); noerror(); - return fs; } /* @@ -381,7 +375,7 @@ * This should be called if fs->super->d.nfree < some number. */ void -fsreclaim(Fsys *fs) +fsreclaim(void) { uvlong nfree; Child *c, *victim; @@ -401,7 +395,7 @@ dDprint("fsreclaim: reclaiming: %ulld free\n", nfree); arch = fs->archive; wlock(arch->mf); - dfloaddir(fs, arch, 1); + dfloaddir(arch, 1); if(arch->mf->nchild < 2){ wunlock(arch->mf); dDprint("nothing to reclaim\n"); @@ -425,14 +419,14 @@ * value they should have (the reference is gone from disk). */ victim->d->file = 0; - dbwrite(fs, victim->b); + dbwrite(victim->b); delchild(arch, victim); wunlock(arch->mf); - n = dbgetref(fs, gone->addr); + n = dbgetref(gone->addr); if(n != 1) sysfatal("reclaim: gone ref is %d != 1", n); - n = dfreclaim(fs, gone); + n = dfreclaim(gone); dDprint("%d block%s reclaimed\n", n, n?"s":""); tot += n; @@ -445,11 +439,11 @@ * We don't snap here because that is likely to allocate more * blocks. */ - freezerefs(fs); - writerefs(fs); - freezesuper(fs); + freezerefs(); + writerefs(); + freezesuper(); dDprint("fsreclaim: %H", fs->fzsuper); - writesuper(fs); + writesuper(); } if(tot > 0) fprint(2, "%s: %d block%s reclaimed\n", argv0, tot, tot?"s":""); diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/main.c --- a/sys/src/cmd/Cfs/main.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/main.c Fri Feb 10 17:42:19 2012 +0000 @@ -13,19 +13,17 @@ void main(int, char *argv[]) { - Fsys *fs; - argv0 = argv[0]; fmtinstall('H', mbfmt); fmtinstall('M', dirmodefmt); errinit(Errstack); if(catcherror()) sysfatal("error: %r"); - fs = fsopen("disk"); - fsdump(fs); + fsopen("disk"); + fsdump(); dbg['D'] = 1; - fsreclaim(fs); - fsdump(fs); + fsreclaim(); + fsdump(); noerror(); exits(nil); } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/mblk.c --- a/sys/src/cmd/Cfs/mblk.c Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/mblk.c Fri Feb 10 17:42:19 2012 +0000 @@ -22,28 +22,64 @@ char*tname[] = { [DBfree] "free", +[DBsuper] "super", +[DBref] "ref", [DBdata] "data", -[DBptr] "ptr", -[DBref] "ref", [DBattr] "attr", [DBfile] "file", -[DBsuper] "super" +[DBptr0] "ptr0", +[DBptr0+1] "ptr1", +[DBptr0+2] "ptr2", +[DBptr0+3] "ptr3", +[DBptr0+4] "ptr4", +[DBptr0+5] "ptr5", +[DBptr0+6] "ptr6", }; #define EP(e) ((e)&0xFFFFFFFFUL) /* * NO LOCKS. debug only */ +static void +fmttab(Fmt *fmt, int t) +{ + if(t-- > 0) + fmtprint(fmt, "\t"); + while(t-- > 0) + fmtprint(fmt, " "); +} +static int mbtab; +static void +fmtptr(Fmt *fmt, u64int addr, char *tag, int n) +{ + Memblk *b; + + if(addr == 0) + return; + b = mbget(addr); + if(b == nil){ + fmttab(fmt, mbtab); + fmtprint(fmt, "%s[%d] = d%#ullx \n", tag, n, addr); + }else{ + decref(b); + fmtprint(fmt, "%H", b); + } +} + int mbfmt(Fmt *fmt) { Memblk *b; - int type, i, n, once; + int type, i, n, once, xdbg; b = va_arg(fmt->args, Memblk*); if(b == nil) return fmtprint(fmt, "\n"); type = TAGTYPE(b->d.tag); + fmttab(fmt, mbtab); + mbtab++; + xdbg = dbg['D']; + dbg['D'] = 0; fmtprint(fmt, "m%#p d%#ullx", b, b->addr); if(b->frozen) fmtprint(fmt, " FZ"); @@ -59,58 +95,53 @@ case DBattr: fmtprint(fmt, "\n"); break; - case DBptr: - fmtprint(fmt, "\n"); - for(i = n = 0; i < Dptrperblk; i++) - if(b->d.ptr[i]){ - fmtprint(fmt, "\t[%d]=d%#ullx", i, b->d.ptr[i]); - if(++n%4 == 0) - fmtprint(fmt, "\n"); - } - if(n%4 != 0) - fmtprint(fmt, "\n"); - break; case DBref: fmtprint(fmt, " rnext m%#p\n", b->rnext); for(i = n = 0; i < Drefperblk; i++) if(b->d.ref[i]){ fmtprint(fmt, "\t[%d]d%#ullx=%#ullx", i, addrofref(b->addr, i), b->d.ref[i]); - if(++n%5 == 0) + if(++n%5 == 0){ fmtprint(fmt, "\n"); + if(i < Dptrperblk-1) + fmttab(fmt, mbtab); + } } if(n%5 != 0) fmtprint(fmt, "\n"); break; case DBfile: - fmtprint(fmt, "\n\tasz %#ullx aptr %#ullx\n", b->d.asize, b->d.aptr); + fmtprint(fmt, "\n"); + fmttab(fmt, mbtab); + fmtprint(fmt, "asz %#ullx aptr %#ullx\n", b->d.asize,b->d.aptr); if(b->mf == nil){ - fmtprint(fmt, "\tno mfile\n"); + fmtprint(fmt, "no mfile\n"); break; } - fmtprint(fmt, "\tid %#ullx mode %M mt %#ullx sz %#ullx '%s' '%s'\n", + fmttab(fmt, mbtab); + fmtprint(fmt, "id %#ullx mode %M mt %#ullx sz %#ullx '%s' '%s'\n", EP(b->mf->id), (ulong)b->mf->mode, EP(b->mf->mtime), b->mf->length, b->mf->uid, b->mf->name); - fmtprint(fmt, "\tparent m%#p nr%d nw%d lastb m%#p lastbno %uld\n", + fmttab(fmt, mbtab); + fmtprint(fmt, "parent m%#p nr%d nw%d lastb m%#p lastbno %uld\n", b->mf->parent, b->mf->readers, b->mf->writer, b->mf->lastb, b->mf->lastbno); if(b->mf->nchild > 0){ - fmtprint(fmt, "\tchild:"); + fmttab(fmt, mbtab); + fmtprint(fmt, "child:"); for(i = 0; i < b->mf->nchild; i++) fmtprint(fmt, " m%#p", b->mf->child[i].f); fmtprint(fmt, "\n"); } - fmtprint(fmt, "\tdptr:"); for(i = 0; i < nelem(b->d.dptr); i++) - fmtprint(fmt, " d%#ullx", b->d.dptr[i]); - fmtprint(fmt, "\n"); - fmtprint(fmt, "\tiptr:"); + fmtptr(fmt, b->d.dptr[i], "d", i); for(i = 0; i < nelem(b->d.iptr); i++) - fmtprint(fmt, " d%#ullx", b->d.iptr[i]); - fmtprint(fmt, "\n"); + fmtptr(fmt, b->d.iptr[i], "i", i); break; case DBsuper: - fmtprint(fmt, "\n\tfree d%#ullx eaddr %#ullx root [", b->d.free, b->d.eaddr); + fmttab(fmt, mbtab); + fmtprint(fmt, "free d%#ullx eaddr %#ullx root [", + b->d.free, b->d.eaddr); once = 0; for(i = 0; i < nelem(b->d.root); i++) if(b->d.root[i] != 0){ @@ -120,7 +151,18 @@ } fmtprint(fmt, "]\n"); break; + default: + if(type < DBptr0 || type >= DBptr0+Niptr){ + fmtprint(fmt, "", type); + break; + } + fmtprint(fmt, "\n"); + for(i = 0; i < Dptrperblk; i++) + fmtptr(fmt, b->d.ptr[i], "p", i); + break; } + dbg['D'] = xdbg; + mbtab--; return 0; } @@ -147,7 +189,7 @@ } Memblk* -mbhash(Fsys *fs, Memblk *b) +mbhash(Memblk *b) { Memblk **h; uint hv; @@ -158,7 +200,7 @@ for(h = &fs->fhash[hv].b; *h != nil; h = &(*h)->next) if((*h)->addr == b->addr){ /* concurrent reads, use the first one */ - mbput(fs, b); + mbput(b); b = *h; goto Found; } @@ -178,7 +220,7 @@ } static void -mbfree(Fsys *fs, Memblk *b) +mbfree(Memblk *b) { Mfile *mf; @@ -197,7 +239,7 @@ b->mf = nil; mf->nchild = 0; if(mf->lastb != nil) - mbput(fs, mf->lastb); + mbput(mf->lastb); mf->lastb = nil; mf->lastbno = 0; mf->parent = nil; @@ -220,7 +262,7 @@ } void -mbunhash(Fsys *fs, Memblk *b) +mbunhash(Memblk *b) { Memblk **h; uint hv; @@ -238,14 +280,14 @@ b->next = nil; fs->nused--; wunlock(&fs->fhash[hv]); - mbput(fs, b); + mbput(b); return; } sysfatal("mbunhash: not found"); } Memblk* -mballoc(Fsys *fs, u64int addr) +mballoc(u64int addr) { Memblk *b; @@ -270,7 +312,7 @@ } Memblk* -mbget(Fsys *fs, u64int addr) +mbget(u64int addr) { Memblk *b; uint hv; @@ -278,29 +320,29 @@ hv = addr%nelem(fs->fhash); rlock(&fs->fhash[hv]); for(b = fs->fhash[hv].b; b != nil; b = b->next) - if(b->addr == b->addr){ + if(b->addr == addr){ incref(b); break; } runlock(&fs->fhash[hv]); - dDprint("mbget %#ullx -> %H", addr, b); + dDprint("mbget %#ullx -> m%#p\n", addr, b); return b; } void -mbput(Fsys *fs, Memblk *b) +mbput(Memblk *b) { - dDprint("mbput m%#p pc=%#p\n", b, getcallerpc(&fs)); + dDprint("mbput m%#p pc=%#p\n", b, getcallerpc(&b)); if(decref(b) == 0) - mbfree(fs, b); + mbfree(b); } Memblk* -mbdup(Fsys *fs, Memblk *b) +mbdup(Memblk *b) { Memblk *nb; - nb = mballoc(fs, b->addr); + nb = mballoc(b->addr); memmove(&nb->d, &b->d, sizeof b->d); return nb; } diff -r f63d21e2da68 -r 9100bac012ae sys/src/cmd/Cfs/mkfile --- a/sys/src/cmd/Cfs/mkfile Fri Feb 10 17:38:04 2012 +0000 +++ b/sys/src/cmd/Cfs/mkfile Fri Feb 10 17:42:19 2012 +0000 @@ -27,3 +27,5 @@ fns.h