svn commit: r188278 - stable/7/sbin/dumpfs

Robert Watson rwatson at FreeBSD.org
Sat Feb 7 03:15:54 PST 2009


Author: rwatson
Date: Sat Feb  7 11:15:53 2009
New Revision: 188278
URL: http://svn.freebsd.org/changeset/base/188278

Log:
  Merge r187814, r187820 from head to stable/7:
  
    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.
  
    Discussed with:       jeff, Richard Clayton <richard dot clayton at cl.cam.ac.uk>
    Sponsored by: Google, Inc.
  
    Print disk offets as %jd rather than %lld; I fixed one before committing
    but missed the other, which breaks 64-bit builds.
  
    Reported by:  bf <bf2006a at yahoo dot com>
  
  Reviewed by:	mckusick

Modified:
  stable/7/sbin/dumpfs/   (props changed)
  stable/7/sbin/dumpfs/dumpfs.8
  stable/7/sbin/dumpfs/dumpfs.c

Modified: stable/7/sbin/dumpfs/dumpfs.8
==============================================================================
--- stable/7/sbin/dumpfs/dumpfs.8	Sat Feb  7 11:12:30 2009	(r188277)
+++ stable/7/sbin/dumpfs/dumpfs.8	Sat Feb  7 11:15:53 2009	(r188278)
@@ -36,15 +36,18 @@
 .Nd dump file system information
 .Sh SYNOPSIS
 .Nm
+.Op Fl f
 .Op Fl m
 .Ar filesys | device
 .Sh DESCRIPTION
 The
 .Nm
 utility prints out the super block and cylinder group information
-for the file system or special device specified, unless
+for the file system or special device specified, unless the
+.Fl f
+or
 .Fl m
-is specified.
+flag is specified.
 The listing is very long and detailed.
 This
 command is useful mostly for finding out certain file system
@@ -52,6 +55,15 @@ information such as the file system bloc
 free space percentage.
 .Pp
 If
+.Fl f
+is specified, a sorted list of all free fragments and free fragment ranges,
+as represented in cylinder group block free lists, is printed.
+If the flag is specified twice, contiguous free fragments are not collapsed
+into ranges and instead printed in a simple list.
+Fragment numbers may be converted to raw byte offsets by multiplying by the
+fragment size, which may be useful when recovering deleted data.
+.Pp
+If
 .Fl m
 is specified, a
 .Xr newfs 8

Modified: stable/7/sbin/dumpfs/dumpfs.c
==============================================================================
--- stable/7/sbin/dumpfs/dumpfs.c	Sat Feb  7 11:12:30 2009	(r188277)
+++ stable/7/sbin/dumpfs/dumpfs.c	Sat Feb  7 11:15:53 2009	(r188278)
@@ -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("-%jd", (intmax_t)(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);
 }


More information about the svn-src-all mailing list