Add support for FS_TRIM to user-mode UFS utilities.

Reviewed by:	mckusick, pjd, pho
Tested by:	pho
MFC after:	1 month
This commit is contained in:
Konstantin Belousov 2010-12-29 12:31:18 +00:00
parent 8c2a54de80
commit a738d4cf20
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216798
7 changed files with 72 additions and 9 deletions

View File

@ -253,9 +253,11 @@ dumpfs(const char *name)
printf("fs_flags expanded "); printf("fs_flags expanded ");
if (fsflags & FS_NFS4ACLS) if (fsflags & FS_NFS4ACLS)
printf("nfsv4acls "); printf("nfsv4acls ");
if (fsflags & FS_TRIM)
printf("trim ");
fsflags &= ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS | fsflags &= ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS |
FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED | FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED |
FS_NFS4ACLS | FS_SUJ); FS_NFS4ACLS | FS_SUJ | FS_TRIM);
if (fsflags != 0) if (fsflags != 0)
printf("unknown flags (%#x)", fsflags); printf("unknown flags (%#x)", fsflags);
putchar('\n'); putchar('\n');

View File

@ -151,6 +151,8 @@ mkfs(struct partition *pp, char *fsys)
sblock.fs_flags |= FS_GJOURNAL; sblock.fs_flags |= FS_GJOURNAL;
if (lflag) if (lflag)
sblock.fs_flags |= FS_MULTILABEL; sblock.fs_flags |= FS_MULTILABEL;
if (tflag)
sblock.fs_flags |= FS_TRIM;
/* /*
* Validate the given file system size. * Validate the given file system size.
* Verify that its last block can actually be accessed. * Verify that its last block can actually be accessed.

View File

@ -28,7 +28,7 @@
.\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 .\" @(#)newfs.8 8.6 (Berkeley) 5/3/95
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 14, 2010 .Dd December 9, 2010
.Dt NEWFS 8 .Dt NEWFS 8
.Os .Os
.Sh NAME .Sh NAME
@ -36,7 +36,7 @@
.Nd construct a new UFS1/UFS2 file system .Nd construct a new UFS1/UFS2 file system
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl EJNUln .Op Fl EJNUlnt
.Op Fl L Ar volname .Op Fl L Ar volname
.Op Fl O Ar filesystem-type .Op Fl O Ar filesystem-type
.Op Fl S Ar sector-size .Op Fl S Ar sector-size
@ -241,6 +241,14 @@ A valid
.Ar size .Ar size
value cannot be larger than the default one, value cannot be larger than the default one,
which means that the file system cannot extend into the reserved space. 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 .El
.Pp .Pp
The following options override the standard sizes for the disk geometry. The following options override the standard sizes for the disk geometry.

View File

@ -91,6 +91,7 @@ int Xflag = 0; /* exit in middle of newfs for testing */
int Jflag; /* enable gjournal for file system */ int Jflag; /* enable gjournal for file system */
int lflag; /* enable multilabel for file system */ int lflag; /* enable multilabel for file system */
int nflag; /* do not create .snap directory */ int nflag; /* do not create .snap directory */
int tflag; /* enable TRIM */
intmax_t fssize; /* file system size */ intmax_t fssize; /* file system size */
int sectorsize; /* bytes/sector */ int sectorsize; /* bytes/sector */
int realsectorsize; /* bytes/sector in hardware */ int realsectorsize; /* bytes/sector in hardware */
@ -139,7 +140,7 @@ main(int argc, char *argv[])
part_name = 'c'; part_name = 'c';
reserved = 0; reserved = 0;
while ((ch = getopt(argc, argv, 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) { switch (ch) {
case 'E': case 'E':
Eflag = 1; Eflag = 1;
@ -279,6 +280,9 @@ main(int argc, char *argv[])
*cp != '\0' || fssize < 0) *cp != '\0' || fssize < 0)
errx(1, "%s: bad file system size", optarg); errx(1, "%s: bad file system size", optarg);
break; break;
case 't':
tflag = 1;
break;
case '?': case '?':
default: default:
usage(); usage();
@ -495,6 +499,7 @@ usage()
fprintf(stderr, "\t-p partition name (a..h)\n"); fprintf(stderr, "\t-p partition name (a..h)\n");
fprintf(stderr, "\t-r reserved sectors at the end of device\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-s file system size (sectors)\n");
fprintf(stderr, "\t-t enable TRIM\n");
exit(1); exit(1);
} }

View File

@ -85,6 +85,7 @@ extern int Xflag; /* exit in middle of newfs for testing */
extern int Jflag; /* enable gjournal for file system */ extern int Jflag; /* enable gjournal for file system */
extern int lflag; /* enable multilabel MAC for file system */ extern int lflag; /* enable multilabel MAC for file system */
extern int nflag; /* do not create .snap directory */ extern int nflag; /* do not create .snap directory */
extern int tflag; /* enable TRIM */
extern intmax_t fssize; /* file system size */ extern intmax_t fssize; /* file system size */
extern int sectorsize; /* bytes/sector */ extern int sectorsize; /* bytes/sector */
extern int realsectorsize; /* bytes/sector in hardware*/ extern int realsectorsize; /* bytes/sector in hardware*/

View File

@ -28,7 +28,7 @@
.\" @(#)tunefs.8 8.2 (Berkeley) 12/11/93 .\" @(#)tunefs.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 6, 2010 .Dd December 9, 2010
.Dt TUNEFS 8 .Dt TUNEFS 8
.Os .Os
.Sh NAME .Sh NAME
@ -51,6 +51,7 @@
.Op Fl p .Op Fl p
.Op Fl s Ar avgfpdir .Op Fl s Ar avgfpdir
.Op Fl S Ar size .Op Fl S Ar size
.Op Fl t Cm enable | disable
.Ar special | filesystem .Ar special | filesystem
.Sh DESCRIPTION .Sh DESCRIPTION
The The
@ -143,6 +144,14 @@ Specify the expected number of files per directory.
.It Fl S Ar size .It Fl S Ar size
Specify the softdep journal size in bytes. Specify the softdep journal size in bytes.
The minimum is 4M. 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 .El
.Pp .Pp
At least one of the above flags is required. At least one of the above flags is required.

View File

@ -82,11 +82,13 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue; char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
char *tvalue;
const char *special, *on; const char *special, *on;
const char *name; const char *name;
int active; int active;
int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, Lflag; int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, Lflag;
int lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag; int lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag;
int tflag;
int svalue, Sflag, Svalue; int svalue, Sflag, Svalue;
int ch, found_arg, i; int ch, found_arg, i;
const char *chg[2]; const char *chg[2];
@ -96,12 +98,13 @@ main(int argc, char *argv[])
if (argc < 3) if (argc < 3)
usage(); usage();
Aflag = aflag = eflag = fflag = jflag = Jflag = Lflag = lflag = 0; 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; avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0; evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
active = 0; active = 0;
found_arg = 0; /* At least one arg is required. */ 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) { switch (ch) {
case 'A': case 'A':
@ -268,6 +271,18 @@ main(int argc, char *argv[])
Sflag = 1; Sflag = 1;
break; 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: default:
usage(); usage();
} }
@ -493,6 +508,24 @@ main(int argc, char *argv[])
sblock.fs_avgfpdir = svalue; 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) if (sbwrite(&disk, Aflag) == -1)
goto err; goto err;
@ -1011,12 +1044,13 @@ journal_alloc(int64_t size)
void void
usage(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]", "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
" [-J enable | disable] [-j enable | disable]", " [-J enable | disable] [-j enable | disable]",
" [-L volname] [-l enable | disable] [-m minfree]", " [-L volname] [-l enable | disable] [-m minfree]",
" [-N enable | disable] [-n enable | disable]", " [-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); exit(2);
} }
@ -1035,6 +1069,8 @@ printfs(void)
(sblock.fs_flags & FS_SUJ)? "enabled" : "disabled"); (sblock.fs_flags & FS_SUJ)? "enabled" : "disabled");
warnx("gjournal: (-J) %s", warnx("gjournal: (-J) %s",
(sblock.fs_flags & FS_GJOURNAL)? "enabled" : "disabled"); (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", warnx("maximum blocks per file in a cylinder group: (-e) %d",
sblock.fs_maxbpg); sblock.fs_maxbpg);
warnx("average file size: (-f) %d", warnx("average file size: (-f) %d",