Author: kib
Date: Wed Dec 29 12:31:18 2010
New Revision: 216798
URL: http://svn.freebsd.org/changeset/base/216798

Log:
  Add support for FS_TRIM to user-mode UFS utilities.
  
  Reviewed by:  mckusick, pjd, pho
  Tested by:    pho
  MFC after:    1 month

Modified:
  head/sbin/dumpfs/dumpfs.c
  head/sbin/newfs/mkfs.c
  head/sbin/newfs/newfs.8
  head/sbin/newfs/newfs.c
  head/sbin/newfs/newfs.h
  head/sbin/tunefs/tunefs.8
  head/sbin/tunefs/tunefs.c

Modified: head/sbin/dumpfs/dumpfs.c
==============================================================================
--- head/sbin/dumpfs/dumpfs.c   Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/dumpfs/dumpfs.c   Wed Dec 29 12:31:18 2010        (r216798)
@@ -253,9 +253,11 @@ dumpfs(const char *name)
                printf("fs_flags expanded ");
        if (fsflags & FS_NFS4ACLS)
                printf("nfsv4acls ");
+       if (fsflags & FS_TRIM)
+               printf("trim ");
        fsflags &= ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS |
                     FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED |
-                    FS_NFS4ACLS | FS_SUJ);
+                    FS_NFS4ACLS | FS_SUJ | FS_TRIM);
        if (fsflags != 0)
                printf("unknown flags (%#x)", fsflags);
        putchar('\n');

Modified: head/sbin/newfs/mkfs.c
==============================================================================
--- head/sbin/newfs/mkfs.c      Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/newfs/mkfs.c      Wed Dec 29 12:31:18 2010        (r216798)
@@ -151,6 +151,8 @@ mkfs(struct partition *pp, char *fsys)
                sblock.fs_flags |= FS_GJOURNAL;
        if (lflag)
                sblock.fs_flags |= FS_MULTILABEL;
+       if (tflag)
+               sblock.fs_flags |= FS_TRIM;
        /*
         * Validate the given file system size.
         * Verify that its last block can actually be accessed.

Modified: head/sbin/newfs/newfs.8
==============================================================================
--- head/sbin/newfs/newfs.8     Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/newfs/newfs.8     Wed Dec 29 12:31:18 2010        (r216798)
@@ -28,7 +28,7 @@
 .\"     @(#)newfs.8    8.6 (Berkeley) 5/3/95
 .\" $FreeBSD$
 .\"
-.Dd September 14, 2010
+.Dd December 9, 2010
 .Dt NEWFS 8
 .Os
 .Sh NAME
@@ -36,7 +36,7 @@
 .Nd construct a new UFS1/UFS2 file system
 .Sh SYNOPSIS
 .Nm
-.Op Fl EJNUln
+.Op Fl EJNUlnt
 .Op Fl L Ar volname
 .Op Fl O Ar filesystem-type
 .Op Fl S Ar sector-size
@@ -241,6 +241,14 @@ A valid
 .Ar size
 value cannot be larger than the default one,
 which means that the file system cannot extend into the reserved space.
+.It Fl t
+Turn on the TRIM enable flag.
+If enabled, and if the underlying device supports the BIO_DELETE
+command, the file system will send a delete request to the underlying
+device for each freed block.
+The trim enable flag is typically set when the underlying device
+uses flash-memory as the device can use the delete command to
+pre-zero or at least avoid copying blocks that have been deleted.
 .El
 .Pp
 The following options override the standard sizes for the disk geometry.

Modified: head/sbin/newfs/newfs.c
==============================================================================
--- head/sbin/newfs/newfs.c     Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/newfs/newfs.c     Wed Dec 29 12:31:18 2010        (r216798)
@@ -91,6 +91,7 @@ int   Xflag = 0;              /* exit in middle of new
 int    Jflag;                  /* enable gjournal for file system */
 int    lflag;                  /* enable multilabel for file system */
 int    nflag;                  /* do not create .snap directory */
+int    tflag;                  /* enable TRIM */
 intmax_t fssize;               /* file system size */
 int    sectorsize;             /* bytes/sector */
 int    realsectorsize;         /* bytes/sector in hardware */
@@ -139,7 +140,7 @@ main(int argc, char *argv[])
        part_name = 'c';
        reserved = 0;
        while ((ch = getopt(argc, argv,
-           "EJL:NO:RS:T:UXa:b:c:d:e:f:g:h:i:lm:no:p:r:s:")) != -1)
+           "EJL:NO:RS:T:UXa:b:c:d:e:f:g:h:i:lm:no:p:r:s:t")) != -1)
                switch (ch) {
                case 'E':
                        Eflag = 1;
@@ -279,6 +280,9 @@ main(int argc, char *argv[])
                            *cp != '\0' || fssize < 0)
                                errx(1, "%s: bad file system size", optarg);
                        break;
+               case 't':
+                       tflag = 1;
+                       break;
                case '?':
                default:
                        usage();
@@ -495,6 +499,7 @@ usage()
        fprintf(stderr, "\t-p partition name (a..h)\n");
        fprintf(stderr, "\t-r reserved sectors at the end of device\n");
        fprintf(stderr, "\t-s file system size (sectors)\n");
+       fprintf(stderr, "\t-t enable TRIM\n");
        exit(1);
 }
 

Modified: head/sbin/newfs/newfs.h
==============================================================================
--- head/sbin/newfs/newfs.h     Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/newfs/newfs.h     Wed Dec 29 12:31:18 2010        (r216798)
@@ -85,6 +85,7 @@ extern int    Xflag;          /* exit in middle of 
 extern int     Jflag;          /* enable gjournal for file system */
 extern int     lflag;          /* enable multilabel MAC for file system */
 extern int     nflag;          /* do not create .snap directory */
+extern int     tflag;          /* enable TRIM */
 extern intmax_t        fssize;         /* file system size */
 extern int     sectorsize;     /* bytes/sector */
 extern int     realsectorsize; /* bytes/sector in hardware*/

Modified: head/sbin/tunefs/tunefs.8
==============================================================================
--- head/sbin/tunefs/tunefs.8   Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/tunefs/tunefs.8   Wed Dec 29 12:31:18 2010        (r216798)
@@ -28,7 +28,7 @@
 .\"     @(#)tunefs.8   8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd March 6, 2010
+.Dd December 9, 2010
 .Dt TUNEFS 8
 .Os
 .Sh NAME
@@ -51,6 +51,7 @@
 .Op Fl p
 .Op Fl s Ar avgfpdir
 .Op Fl S Ar size
+.Op Fl t Cm enable | disable
 .Ar special | filesystem
 .Sh DESCRIPTION
 The
@@ -143,6 +144,14 @@ Specify the expected number of files per
 .It Fl S Ar size
 Specify the softdep journal size in bytes.
 The minimum is 4M.
+.It Fl t Cm enable | disable
+Turn on/off the TRIM enable flag.
+If enabled, and if the underlying device supports the BIO_DELETE
+command, the file system will send a delete request to the underlying
+device for each freed block.
+The trim enable flag is typically set when the underlying device
+uses flash-memory as the device can use the delete command to
+pre-zero or at least avoid copying blocks that have been deleted.
 .El
 .Pp
 At least one of the above flags is required.

Modified: head/sbin/tunefs/tunefs.c
==============================================================================
--- head/sbin/tunefs/tunefs.c   Wed Dec 29 12:25:45 2010        (r216797)
+++ head/sbin/tunefs/tunefs.c   Wed Dec 29 12:31:18 2010        (r216798)
@@ -82,11 +82,13 @@ int
 main(int argc, char *argv[])
 {
        char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
+       char *tvalue;
        const char *special, *on;
        const char *name;
        int active;
        int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, Lflag;
        int lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag;
+       int tflag;
        int svalue, Sflag, Svalue;
        int ch, found_arg, i;
        const char *chg[2];
@@ -96,12 +98,13 @@ main(int argc, char *argv[])
        if (argc < 3)
                usage();
        Aflag = aflag = eflag = fflag = jflag = Jflag = Lflag = lflag = 0;
-       mflag = Nflag = nflag = oflag = pflag = sflag = 0;
+       mflag = Nflag = nflag = oflag = pflag = sflag = tflag = 0;
        avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
        evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
        active = 0;
        found_arg = 0;          /* At least one arg is required. */
-       while ((ch = getopt(argc, argv, "Aa:e:f:j:J:L:l:m:N:n:o:ps:S:")) != -1)
+       while ((ch = getopt(argc, argv, "Aa:e:f:j:J:L:l:m:N:n:o:ps:S:t:"))
+           != -1)
                switch (ch) {
 
                case 'A':
@@ -268,6 +271,18 @@ main(int argc, char *argv[])
                        Sflag = 1;
                        break;
 
+               case 't':
+                       found_arg = 1;
+                       name = "trim";
+                       tvalue = optarg;
+                       if (strcmp(tvalue, "enable") != 0 &&
+                           strcmp(tvalue, "disable") != 0) {
+                               errx(10, "bad %s (options are %s)",
+                                   name, "`enable' or `disable'");
+                       }
+                       tflag = 1;
+                       break;
+
                default:
                        usage();
                }
@@ -493,6 +508,24 @@ main(int argc, char *argv[])
                        sblock.fs_avgfpdir = svalue;
                }
        }
+       if (tflag) {
+               name = "issue TRIM to the disk";
+               if (strcmp(tvalue, "enable") == 0) {
+                       if (sblock.fs_flags & FS_TRIM)
+                               warnx("%s remains unchanged as enabled", name);
+                       else {
+                               sblock.fs_flags |= FS_TRIM;
+                               warnx("%s set", name);
+                       }
+               } else if (strcmp(tvalue, "disable") == 0) {
+                       if ((~sblock.fs_flags & FS_TRIM) == FS_TRIM)
+                               warnx("%s remains unchanged as disabled", name);
+                       else {
+                               sblock.fs_flags &= ~FS_TRIM;
+                               warnx("%s cleared", name);
+                       }
+               }
+       }
 
        if (sbwrite(&disk, Aflag) == -1)
                goto err;
@@ -1011,12 +1044,13 @@ out:
 void
 usage(void)
 {
-       fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
+       fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
 "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
 "              [-J enable | disable] [-j enable | disable]", 
 "              [-L volname] [-l enable | disable] [-m minfree]",
 "              [-N enable | disable] [-n enable | disable]",
-"              [-o space | time] [-p] [-s avgfpdir] special | filesystem");
+"              [-o space | time] [-p] [-s avgfpdir] [-t enable | disable]",
+"              special | filesystem");
        exit(2);
 }
 
@@ -1035,6 +1069,8 @@ printfs(void)
                (sblock.fs_flags & FS_SUJ)? "enabled" : "disabled");
        warnx("gjournal: (-J)                                     %s",
                (sblock.fs_flags & FS_GJOURNAL)? "enabled" : "disabled");
+       warnx("trim: (-t)                                         %s", 
+               (sblock.fs_flags & FS_TRIM)? "enabled" : "disabled");
        warnx("maximum blocks per file in a cylinder group: (-e)  %d",
              sblock.fs_maxbpg);
        warnx("average file size: (-f)                            %d",
_______________________________________________
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