ref: ce708f49bf5ec6c6b3fe1bb29d401c42b841b649
dir: /updatefrees.c/
#include <u.h> #include <libc.h> #include "dat.h" #include "fns.h" #include "extents.h" /* update /a/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}; void *emalloc(u32); void panic(char *fmt, ...); 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[Blocksize], freesdata[Maxdatablockunits*Blocksize]; int fd; Data *f; Dentry *d; u64 *f64; Errenv env = {0}; envpp = privalloc(); *envpp = &env; if(waserror()){ panic(0, "err stack %d: %lux %lux %lux %lux %lux %lux", env.nlabel, env.label[0][JMPBUFPC], env.label[1][JMPBUFPC], env.label[2][JMPBUFPC], env.label[3][JMPBUFPC], env.label[4][JMPBUFPC], env.label[5][JMPBUFPC]); } 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, Blocksize); 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("Servicelen %d\n", Servicelen); print("Dentry size %d\n", sizeof(Dentry)); } devread(Bdfrees, buf, 1); // showblock(1, buf); d = (Dentry*)buf; 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, 1); }else{ initextents(&frees, "frees", 0, 0, 2, nil, fprint, panic, emalloc); loadextents(&frees, (s8*)f->buf, nfreesize); nblocks = nlastdatablocks(nfreesize); ualloc(&frees, nblocks, &freeblkno); d->dblocks[0] = freeblkno; f->tag = Tdata; f->len = nblocks; f64[nblocks*Nu64perblock -1] = Qpfrees; devwrite(Bdfrees, buf, 1); devwrite(freeblkno, (s8*)freesdata, nblocks); } close(devfd); exits(0); }