diff options
-rw-r--r-- | sbin/fsck_ffs/fsck.h | 5 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsck_ffs.8 | 11 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsutil.c | 29 | ||||
-rw-r--r-- | sbin/fsck_ffs/main.c | 6 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 12 |
5 files changed, 56 insertions, 7 deletions
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 7b45d48..45b242c 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -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_daddr_t blk, long size); 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); diff --git a/sbin/fsck_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8 index 0513017..0b3f992 100644 --- a/sbin/fsck_ffs/fsck_ffs.8 +++ b/sbin/fsck_ffs/fsck_ffs.8 @@ -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 asked by .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: diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index 9ebc342..f177408 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -618,6 +618,35 @@ blerase(int fd, ufs2_daddr_t blk, long size) 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. diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 27f17db..d074447 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -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(); } diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 146acec..38068eb 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -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 start, ufs2_daddr_t end) 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)); } |