diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-01-28 09:33:00 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-01-28 09:33:00 +0000 |
commit | 72666b75fd4ca3c1dba2215cc9681322d3a3ba0f (patch) | |
tree | eefd0840a57323969ee345db6b769d3f4b0df088 /sbin/dumpfs/dumpfs.c | |
parent | 390e30c82cf0bca964e300d873e8e5b83bb86bd5 (diff) | |
download | FreeBSD-src-72666b75fd4ca3c1dba2215cc9681322d3a3ba0f.zip FreeBSD-src-72666b75fd4ca3c1dba2215cc9681322d3a3ba0f.tar.gz |
Add a new flag to dumpfs(8), -f, which causes dumpfs to list all free
fragments in the file system by fragment (block) number. This new
mode does the necessary arithmetic to generate absolute fragment
numbers rather than than the cg-relative numbers printed in the default
mode.
If -f is passed once, contiguous fragment ranges are collapsed into
an X-Y format as free block lists are currently printed in regular
dumpfs output, but if specified twice, all block numbers are printed
individually, allowing both compact and more script-friendly
representation.
This proves quite handy when attempting to recover deleted data, as it
allows exclusion of non-deleted data from blocks searched.
MFC after: 1 week
Discussed with: jeff, Richard Clayton <richard dot clayton at cl.cam.ac.uk>
Sponsored by: Google, Inc.
Diffstat (limited to 'sbin/dumpfs/dumpfs.c')
-rw-r--r-- | sbin/dumpfs/dumpfs.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c index e0b809e..14f6ea2 100644 --- a/sbin/dumpfs/dumpfs.c +++ b/sbin/dumpfs/dumpfs.c @@ -1,4 +1,10 @@ /* + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * @@ -74,8 +80,11 @@ struct uufsd disk; int dumpfs(const char *); int dumpcg(void); +int dumpfreespace(const char *, int); +void dumpfreespacecg(int); int marshal(const char *); void pbits(void *, int); +void pblklist(void *, int, off_t, int); void ufserr(const char *); void usage(void) __dead2; @@ -83,12 +92,15 @@ int main(int argc, char *argv[]) { const char *name; - int ch, domarshal, eval; + int ch, dofreespace, domarshal, eval; - domarshal = eval = 0; + dofreespace = domarshal = eval = 0; - while ((ch = getopt(argc, argv, "m")) != -1) { + while ((ch = getopt(argc, argv, "fm")) != -1) { switch (ch) { + case 'f': + dofreespace++; + break; case 'm': domarshal = 1; break; @@ -102,6 +114,10 @@ main(int argc, char *argv[]) if (argc < 1) usage(); + if (dofreespace && domarshal) + usage(); + if (dofreespace > 2) + usage(); while ((name = *argv++) != NULL) { if (ufs_disk_fillout(&disk, name) == -1) { @@ -109,7 +125,9 @@ main(int argc, char *argv[]) eval |= 1; continue; } - if (domarshal) + if (dofreespace) + eval |= dumpfreespace(name, dofreespace); + else if (domarshal) eval |= marshal(name); else eval |= dumpfs(name); @@ -333,6 +351,30 @@ dumpcg(void) } int +dumpfreespace(const char *name, int fflag) +{ + int i; + + while ((i = cgread(&disk)) != 0) { + if (i == -1) + goto err; + dumpfreespacecg(fflag); + } + return (0); +err: + ufserr(name); + return (1); +} + +void +dumpfreespacecg(int fflag) +{ + + pblklist(cg_blksfree(&acg), afs.fs_fpg, disk.d_lcg * afs.fs_fpg, + fflag); +} + +int marshal(const char *name) { struct fs *fs; @@ -401,6 +443,27 @@ pbits(void *vp, int max) } void +pblklist(void *vp, int max, off_t offset, int fflag) +{ + int i, j; + char *p; + + for (i = 0, p = vp; i < max; i++) { + if (isset(p, i)) { + printf("%jd", (intmax_t)(i + offset)); + if (fflag < 2) { + j = i; + while ((i+1)<max && isset(p, i+1)) + i++; + if (i != j) + printf("-%lld", i + offset); + } + printf("\n"); + } + } +} + +void ufserr(const char *name) { if (disk.d_error != NULL) @@ -412,6 +475,6 @@ ufserr(const char *name) void usage(void) { - (void)fprintf(stderr, "usage: dumpfs [-m] filesys | device\n"); + (void)fprintf(stderr, "usage: dumpfs [-fm] filesys | device\n"); exit(1); } |