ref: 1a4e1fc2e52ab80b55ef0d7fdccca973267fb4cc
dir: /updatefrees.c/
#include <u.h> #include <libc.h> #include "dat.h" #include "fns.h" #include "extents.h" /* update /adm/frees 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 > Maxdatablocksize */ int chatty9p; int debug = 0; char *devfile = nil, *freesfile = nil; Extents frees = {0}; static void usage(void) { fprint(2, "usage: updatefrees [-D] fsfile freecontentfile\n"); exits("usage"); } void main(int argc, char *argv[]) { u64 size, freeblkno, nblocks; s32 nfreesize; s8 buf[Metadatablocksize], freesdata[Maxdatablockunits*Blocksize]; int fd; Data *f; Dentry *d; u64 *f64; ARGBEGIN{ default: usage(); case 'D': debug++; break; }ARGEND if(argc != 2) usage(); devfile = argv[0]; if(devfile == nil) sysfatal("no disk file"); freesfile = strdup(argv[1]); if(freesfile == nil) sysfatal("no frees file"); memset(buf, 0, Metadatablocksize); memset(freesdata, 0, Maxdatablockunits*Blocksize); f = (Data*)freesdata; f64 = (u64*)freesdata; fd = open(freesfile, OREAD); if(fd < 0) sysfatal("updatefrees: cannot open freesfile %s\n", freesfile); nfreesize = readn(fd, f->buf, Maxdatablocksize); if(nfreesize <= 0) sysfatal("updatefrees: nfreesize %d <= 0\n", nfreesize); if(nfreesize > (Maxdatablocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */))) sysfatal("updatefrees: unsupported nfreesize %d needs more than a block Datablocksize %llud\n", nfreesize, Maxdatablocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)); if(nfreesize >= Maxdatablocksize) sysfatal("updatefrees: unsupported nfreesize %d > Datablocksize %llud\n", nfreesize, Maxdatablocksize); close(fd); if (access(devfile, AREAD|AWRITE) == -1) sysfatal("%s cannot access device", devfile); size = devinit(devfile); if(size == 0) panic("null size %s", devfile); if(debug){ print("Namelen %d\n", Namelen); print("Dentry size %d\n", sizeof(Dentry)); } devread(Bdfrees, buf, Metadataunits); // showblock(1, buf); recentmetadata(buf, &d, nil); if(d->size != nfreesize) print("changed size: %llud to %d\n", d->size, nfreesize); memset(d->buf, 0, Ddatasize); d->size = nfreesize; if(nfreesize <= Ddatasize){ strncpy(d->buf, (s8*)f->buf, nfreesize); devwrite(Bdfrees, buf, Metadataunits); }else{ initextents(&frees, "frees", nil); loadextents(&frees, (s8*)f->buf, nfreesize); nblocks = nlastdatablocks(nfreesize); freeblkno = balloc(&frees, nblocks); d->dblocks[0] = freeblkno; f->tag = Tdata; f->len = nblocks; f64[nblocks*Nu64perblock -1] = Qpfrees; devwrite(Bdfrees, buf, Metadataunits); devwrite(freeblkno, (s8*)freesdata, nblocks); } close(devfd); exits(0); }