Author: des
Date: Mon Apr 29 20:13:09 2013
New Revision: 250056
URL: http://svnweb.freebsd.org/changeset/base/250056

Log:
  Add a -Z option which zeroes unused blocks.  It can be combined with -E,
  in which case unused blocks are first zeroed and then erased.
  
  Reviewed by:  mckusick
  MFC after:    3 weeks

Modified:
  head/sbin/fsck_ffs/fsck.h
  head/sbin/fsck_ffs/fsck_ffs.8
  head/sbin/fsck_ffs/fsutil.c
  head/sbin/fsck_ffs/main.c
  head/sbin/fsck_ffs/pass5.c

Modified: head/sbin/fsck_ffs/fsck.h
==============================================================================
--- head/sbin/fsck_ffs/fsck.h   Mon Apr 29 20:09:44 2013        (r250055)
+++ head/sbin/fsck_ffs/fsck.h   Mon Apr 29 20:13:09 2013        (r250056)
@@ -74,6 +74,7 @@
 #define        MINBUFS         10      /* minimum number of buffers required */
 #define        MAXBUFS         40      /* maximum space to allocate to buffers 
*/
 #define        INOBUFSIZE      64*1024 /* size of buffer to read inodes in 
pass1 */
+#define        ZEROBUFSIZE     (dev_bsize * 128) /* size of zero buffer used 
by -Z */
 
 union dinode {
        struct ufs1_dinode dp1;
@@ -306,7 +307,8 @@ char        yflag;                  /* assume a yes 
response *
 int    bkgrdflag;              /* use a snapshot to run on an active system */
 int    bflag;                  /* location of alternate super block */
 int    debug;                  /* output debugging info */
-int    Eflag;                  /* zero out empty data blocks */
+int    Eflag;                  /* delete empty data blocks */
+int    Zflag;                  /* zero empty data blocks */
 int    inoopt;                 /* trim out unused inodes */
 char   ckclean;                /* only do work if not cleanly unmounted */
 int    cvtlevel;               /* convert to newer file system format */
@@ -402,6 +404,7 @@ int         blread(int fd, char *buf, ufs2_dadd
 void           bufinit(void);
 void           blwrite(int fd, char *buf, ufs2_daddr_t blk, ssize_t size);
 void           blerase(int fd, ufs2_daddr_t blk, long size);
+void           blzero(int fd, ufs2_daddr_t blk, long size);
 void           cacheino(union dinode *dp, ino_t inumber);
 void           catch(int);
 void           catchquit(int);

Modified: head/sbin/fsck_ffs/fsck_ffs.8
==============================================================================
--- head/sbin/fsck_ffs/fsck_ffs.8       Mon Apr 29 20:09:44 2013        
(r250055)
+++ head/sbin/fsck_ffs/fsck_ffs.8       Mon Apr 29 20:13:09 2013        
(r250056)
@@ -38,7 +38,7 @@
 .Nd file system consistency check and interactive repair
 .Sh SYNOPSIS
 .Nm
-.Op Fl BEFfnpry
+.Op Fl BEFfnpryZ
 .Op Fl b Ar block
 .Op Fl c Ar level
 .Op Fl m Ar mode
@@ -280,6 +280,15 @@ Assume a yes response to all questions a
 .Nm ;
 this should be used with great caution as this is a free license
 to continue after essentially unlimited trouble has been encountered.
+.It Fl Z
+Similar to
+.Fl E ,
+but overwrites unused blocks with zeroes.
+If both
+.Fl E
+and
+.Fl Z
+are specified, blocks are first zeroed and then erased.
 .El
 .Pp
 Inconsistencies checked are as follows:

Modified: head/sbin/fsck_ffs/fsutil.c
==============================================================================
--- head/sbin/fsck_ffs/fsutil.c Mon Apr 29 20:09:44 2013        (r250055)
+++ head/sbin/fsck_ffs/fsutil.c Mon Apr 29 20:13:09 2013        (r250056)
@@ -618,6 +618,35 @@ blerase(int fd, ufs2_daddr_t blk, long s
        return;
 }
 
+void
+blzero(int fd, ufs2_daddr_t blk, long size)
+{
+       static char *zero;
+       off_t offset, len;
+
+       if (fd < 0)
+               return;
+       len = ZEROBUFSIZE;
+       if (zero == NULL) {
+               zero = calloc(len, 1);
+               if (zero == NULL)
+                       errx(EEXIT, "cannot allocate buffer pool");
+       }
+       offset = blk * dev_bsize;
+       if (lseek(fd, offset, 0) < 0)
+               rwerror("SEEK BLK", blk);
+       while (size > 0) {
+               if (size > len)
+                       size = len;
+               else
+                       len = size;
+               if (write(fd, zero, len) != len)
+                       rwerror("WRITE BLK", blk);
+               blk += len / dev_bsize;
+               size -= len;
+       }
+}
+
 /*
  * Verify cylinder group's magic number and other parameters.  If the
  * test fails, offer an option to rebuild the whole cylinder group.

Modified: head/sbin/fsck_ffs/main.c
==============================================================================
--- head/sbin/fsck_ffs/main.c   Mon Apr 29 20:09:44 2013        (r250055)
+++ head/sbin/fsck_ffs/main.c   Mon Apr 29 20:13:09 2013        (r250056)
@@ -82,7 +82,7 @@ main(int argc, char *argv[])
        sync();
        skipclean = 1;
        inoopt = 0;
-       while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npry")) != -1) {
+       while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npryZ")) != -1) {
                switch (ch) {
                case 'b':
                        skipclean = 0;
@@ -147,6 +147,10 @@ main(int argc, char *argv[])
                        nflag = 0;
                        break;
 
+               case 'Z':
+                       Zflag++;
+                       break;
+
                default:
                        usage();
                }

Modified: head/sbin/fsck_ffs/pass5.c
==============================================================================
--- head/sbin/fsck_ffs/pass5.c  Mon Apr 29 20:09:44 2013        (r250055)
+++ head/sbin/fsck_ffs/pass5.c  Mon Apr 29 20:13:09 2013        (r250056)
@@ -252,7 +252,7 @@ pass5(void)
                        frags = 0;
                        for (j = 0; j < fs->fs_frag; j++) {
                                if (testbmap(d + j)) {
-                                       if (Eflag && start != -1) {
+                                       if ((Eflag || Zflag) && start != -1) {
                                                clear_blocks(start, d + j - 1);
                                                start = -1;
                                        }
@@ -274,7 +274,7 @@ pass5(void)
                                ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
                        }
                }
-               if (Eflag && start != -1)
+               if ((Eflag || Zflag) && start != -1)
                        clear_blocks(start, d - 1);
                if (fs->fs_contigsumsize > 0) {
                        int32_t *sump = cg_clustersum(newcg);
@@ -586,6 +586,10 @@ static void clear_blocks(ufs2_daddr_t st
 
        if (debug)
                printf("Zero frags %jd to %jd\n", start, end);
-       blerase(fswritefd, fsbtodb(&sblock, start),
-           lfragtosize(&sblock, end - start + 1));
+       if (Zflag)
+               blzero(fswritefd, fsbtodb(&sblock, start),
+                   lfragtosize(&sblock, end - start + 1));
+       if (Eflag)
+               blerase(fswritefd, fsbtodb(&sblock, start),
+                   lfragtosize(&sblock, end - start + 1));
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to