From 7410b84b64308b82cf6109129259a065a157f3f4 Mon Sep 17 00:00:00 2001 From: des Date: Wed, 31 Aug 2011 16:25:34 +0000 Subject: [PATCH] MFH r221107, r221108: alphabetize command-line options MFH r221233: add -E option (BIO_DELETE unused blocks) git-svn-id: svn://svn.freebsd.org/base/stable/8@225296 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sbin/fsck_ffs/fsck.h | 2 ++ sbin/fsck_ffs/fsck_ffs.8 | 42 ++++++++++++++++++++++++++++------------ sbin/fsck_ffs/fsutil.c | 17 +++++++++++++++- sbin/fsck_ffs/main.c | 16 +++++++++------ sbin/fsck_ffs/pass5.c | 25 ++++++++++++++++++++++-- 5 files changed, 81 insertions(+), 21 deletions(-) diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index ad7fe138e..d67bcc5fe 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -270,6 +270,7 @@ 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 inoopt; /* trim out unused inodes */ char ckclean; /* only do work if not cleanly unmounted */ int cvtlevel; /* convert to newer file system format */ @@ -333,6 +334,7 @@ char *blockcheck(char *name); 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, long size); +void blerase(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 f60e5e268..523cb6543 100644 --- a/sbin/fsck_ffs/fsck_ffs.8 +++ b/sbin/fsck_ffs/fsck_ffs.8 @@ -29,7 +29,7 @@ .\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 .\" $FreeBSD$ .\" -.Dd January 25, 2009 +.Dd April 27, 2011 .Dt FSCK_FFS 8 .Os .Sh NAME @@ -38,7 +38,7 @@ .Nd file system consistency check and interactive repair .Sh SYNOPSIS .Nm -.Op Fl BFprfny +.Op Fl BEFfnpry .Op Fl b Ar block .Op Fl c Ar level .Op Fl m Ar mode @@ -139,6 +139,34 @@ action. The following flags are interpreted by .Nm : .Bl -tag -width indent +.It Fl B +A check is done on the specified and possibly active file system. +The set of corrections that can be done is limited to those done +when running in preen mode (see the +.Fl p +flag). +If unexpected errors are found, +the file system is marked as needing a foreground check and +.Nm +exits without attempting any further cleaning. +.It Fl E +Clear unallocated blocks, notifying the underlying device that they +are not used and that their contents may be discarded. +This is useful for filesystems which have been mounted on systems +without TRIM support, or with TRIM support disabled, as well as +filesystems which have been copied from one device to another. +.Pp +See the +.Fl E +and +.Fl t +flags of +.Xr newfs 8 , +and +the +.Fl t +flag of +.Xr tunefs 8 . .It Fl F Determine whether the file system needs to be cleaned immediately in foreground, or if its cleaning can be deferred to background. @@ -160,16 +188,6 @@ The only thing that .Nm does is to determine whether a foreground or background check is needed and exit with an appropriate status code. -.It Fl B -A check is done on the specified and possibly active file system. -The set of corrections that can be done is limited to those done -when running in preen mode (see the -.Fl p -flag). -If unexpected errors are found, -the file system is marked as needing a foreground check and -.Nm -exits without attempting any further cleaning. .It Fl b Use the block specified immediately after the flag as the super block for the file system. diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index 68d113a3f..85ea03352 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -39,9 +39,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include -#include #include #include @@ -421,6 +422,20 @@ blwrite(int fd, char *buf, ufs2_daddr_t blk, long size) return; } +void +blerase(int fd, ufs2_daddr_t blk, long size) +{ + off_t ioarg[2]; + + if (fd < 0) + return; + ioarg[0] = blk * dev_bsize; + ioarg[1] = size; + ioctl(fd, DIOCGDELETE, ioarg); + /* we don't really care if we succeed or not */ + return; +} + /* * 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 0366e456b..7d7447326 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:CdfFm:npry")) != -1) { + while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npry")) != -1) { switch (ch) { case 'b': skipclean = 0; @@ -106,6 +106,10 @@ main(int argc, char *argv[]) debug++; break; + case 'E': + Eflag++; + break; + case 'f': skipclean = 0; break; @@ -605,9 +609,9 @@ getmntpt(const char *name) static void usage(void) { - (void) fprintf(stderr, - "usage: %s [-BFprfny] [-b block] [-c level] [-m mode] " - "filesystem ...\n", - getprogname()); - exit(1); + (void) fprintf(stderr, + "usage: %s [-BEFprfny] [-b block] [-c level] [-m mode] " + "filesystem ...\n", + getprogname()); + exit(1); } diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 173156efa..012623fa9 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *, int *, int, int); +static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end); + void pass5(void) { @@ -57,7 +59,7 @@ pass5(void) int inomapsize, blkmapsize; struct fs *fs = &sblock; struct cg *cg = &cgrp; - ufs2_daddr_t d, dbase, dmax; + ufs2_daddr_t d, dbase, dmax, start; int excessdirs, rewritecg = 0; struct csum *cs; struct csum_total cstotal; @@ -241,13 +243,21 @@ pass5(void) setbit(cg_inosused(newcg), i); newcg->cg_cs.cs_nifree--; } + start = -1; for (i = 0, d = dbase; d < dmax; d += fs->fs_frag, i += fs->fs_frag) { frags = 0; for (j = 0; j < fs->fs_frag; j++) { - if (testbmap(d + j)) + if (testbmap(d + j)) { + if (Eflag && start != -1) { + clear_blocks(start, d + j - 1); + start = -1; + } continue; + } + if (start == -1) + start = d + j; setbit(cg_blksfree(newcg), i + j); frags++; } @@ -262,6 +272,8 @@ pass5(void) ffs_fragacct(fs, blk, newcg->cg_frsum, 1); } } + if (Eflag && start != -1) + clear_blocks(start, d - 1); if (fs->fs_contigsumsize > 0) { int32_t *sump = cg_clustersum(newcg); u_char *mapp = cg_clustersfree(newcg); @@ -550,3 +562,12 @@ check_maps( } } } + +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)); +} -- 2.45.0