ref: 9b76881a8e11c44aae5dfd447e1cd1bc074ec9f3
dir: /updatefrees.c/
#include <u.h> #include <libc.h> #include "dat.h" #include "fns.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 > Blocksize-(3*8) */ int debug = 0; char *devfile = nil, *freesfile = nil; static void usage(void) { fprint(2, "usage: updatefrees [-D] fsfile freecontentfile\n"); exits("usage"); } void main(int argc, char *argv[]) { u64 size, freeblkno; s32 nfreesize; s8 buf[Metadatablocksize], frees[Maxdatablocksize]; u64 freesdata[Nu64perblock]; int fd; Data *f; Dentry *d; 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(frees, 0, Maxdatablocksize); fd = open(freesfile, OREAD); if(fd < 0) sysfatal("updatefrees: cannot open freesfile %s\n", freesfile); 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) 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); d->size = nfreesize; if(nfreesize < Ddatasize){ strncpy(d->buf, frees, nfreesize); devwrite(Bdfrees, buf, Metadataunits); }else{ if(d->dblocks[0] != freeblkno) print("changed dblocks[0]: %llud to %llud\n", d->dblocks[0], freeblkno); d->dblocks[0] = freeblkno; f = (Data*)freesdata; f->tag = Tdata; f->len = 1; memcpy(f->buf, frees, Blocksize -Ddataidssize); freesdata[Dpathidx] = Qpfrees; devwrite(Bdfrees, buf, Metadataunits); // devwrite(freeblkno, frees, nlastdatablocks(nfreesize)); devwrite(freeblkno, (s8*)freesdata, 1); } close(devfd); exits(0); }