2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 static const char copyright[] =
33 "@(#) Copyright (c) 1983, 1993\n\
34 The Regents of the University of California. All rights reserved.\n";
38 static char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) 4/19/94";
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
45 * tunefs: change layout parameters to an existing file system.
47 #include <sys/param.h>
48 #include <sys/mount.h>
49 #include <sys/disklabel.h>
52 #include <ufs/ufs/ufsmount.h>
53 #include <ufs/ufs/dinode.h>
54 #include <ufs/ffs/fs.h>
67 /* the optimization warning string template */
68 #define OPTWARN "should optimize for %s with minfree %s %d%%"
71 #define sblock disk.d_fs
77 main(int argc, char *argv[])
79 char *avalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
81 const char *special, *on;
84 int Aflag, aflag, eflag, evalue, fflag, fvalue, Jflag, Lflag, lflag;
85 int mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag, svalue;
94 Aflag = aflag = eflag = fflag = Jflag = Lflag = lflag = mflag = 0;
95 Nflag = nflag = oflag = pflag = sflag = tflag = 0;
96 avalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
97 evalue = fvalue = mvalue = ovalue = svalue = 0;
99 found_arg = 0; /* At least one arg is required. */
100 while ((ch = getopt(argc, argv, "Aa:e:f:J:L:l:m:N:n:o:ps:t:")) != -1)
110 name = "POSIX.1e ACLs";
112 if (strcmp(avalue, "enable") &&
113 strcmp(avalue, "disable")) {
114 errx(10, "bad %s (options are %s)",
115 name, "`enable' or `disable'");
122 name = "maximum blocks per file in a cylinder group";
123 evalue = atoi(optarg);
125 errx(10, "%s must be >= 1 (was %s)",
132 name = "average file size";
133 fvalue = atoi(optarg);
135 errx(10, "%s must be >= 1 (was %s)",
142 name = "gjournaled file system";
144 if (strcmp(Jvalue, "enable") &&
145 strcmp(Jvalue, "disable")) {
146 errx(10, "bad %s (options are %s)",
147 name, "`enable' or `disable'");
155 name = "volume label";
158 while (isalnum(Lvalue[++i]));
159 if (Lvalue[i] != '\0') {
161 "bad %s. Valid characters are alphanumerics.",
164 if (strlen(Lvalue) >= MAXVOLLEN) {
165 errx(10, "bad %s. Length is longer than %d.",
166 name, MAXVOLLEN - 1);
173 name = "multilabel MAC file system";
175 if (strcmp(lvalue, "enable") &&
176 strcmp(lvalue, "disable")) {
177 errx(10, "bad %s (options are %s)",
178 name, "`enable' or `disable'");
185 name = "minimum percentage of free space";
186 mvalue = atoi(optarg);
187 if (mvalue < 0 || mvalue > 99)
188 errx(10, "bad %s (%s)", name, optarg);
196 if (strcmp(Nvalue, "enable") &&
197 strcmp(Nvalue, "disable")) {
198 errx(10, "bad %s (options are %s)",
199 name, "`enable' or `disable'");
206 name = "soft updates";
208 if (strcmp(nvalue, "enable") != 0 &&
209 strcmp(nvalue, "disable") != 0) {
210 errx(10, "bad %s (options are %s)",
211 name, "`enable' or `disable'");
218 name = "optimization preference";
219 if (strcmp(optarg, "space") == 0)
220 ovalue = FS_OPTSPACE;
221 else if (strcmp(optarg, "time") == 0)
225 "bad %s (options are `space' or `time')",
237 name = "expected number of files per directory";
238 svalue = atoi(optarg);
240 errx(10, "%s must be >= 1 (was %s)",
249 if (strcmp(tvalue, "enable") != 0 &&
250 strcmp(tvalue, "disable") != 0) {
251 errx(10, "bad %s (options are %s)",
252 name, "`enable' or `disable'");
262 if (found_arg == 0 || argc != 1)
265 on = special = argv[0];
266 if (ufs_disk_fillout(&disk, special) == -1)
268 if (disk.d_name != special) {
269 special = disk.d_name;
270 if (statfs(special, &stfs) == 0 &&
271 strcmp(special, stfs.f_mntonname) == 0)
280 name = "volume label";
281 strlcpy(sblock.fs_volname, Lvalue, MAXVOLLEN);
284 name = "POSIX.1e ACLs";
285 if (strcmp(avalue, "enable") == 0) {
286 if (sblock.fs_flags & FS_ACLS) {
287 warnx("%s remains unchanged as enabled", name);
288 } else if (sblock.fs_flags & FS_NFS4ACLS) {
289 warnx("%s and NFSv4 ACLs are mutually "
292 sblock.fs_flags |= FS_ACLS;
293 warnx("%s set", name);
295 } else if (strcmp(avalue, "disable") == 0) {
296 if ((~sblock.fs_flags & FS_ACLS) ==
298 warnx("%s remains unchanged as disabled",
301 sblock.fs_flags &= ~FS_ACLS;
302 warnx("%s cleared", name);
307 name = "maximum blocks per file in a cylinder group";
308 if (sblock.fs_maxbpg == evalue)
309 warnx("%s remains unchanged as %d", name, evalue);
311 warnx("%s changes from %d to %d",
312 name, sblock.fs_maxbpg, evalue);
313 sblock.fs_maxbpg = evalue;
317 name = "average file size";
318 if (sblock.fs_avgfilesize == (unsigned)fvalue) {
319 warnx("%s remains unchanged as %d", name, fvalue);
322 warnx("%s changes from %d to %d",
323 name, sblock.fs_avgfilesize, fvalue);
324 sblock.fs_avgfilesize = fvalue;
329 if (strcmp(Jvalue, "enable") == 0) {
330 if (sblock.fs_flags & FS_GJOURNAL) {
331 warnx("%s remains unchanged as enabled", name);
333 sblock.fs_flags |= FS_GJOURNAL;
334 warnx("%s set", name);
336 } else if (strcmp(Jvalue, "disable") == 0) {
337 if ((~sblock.fs_flags & FS_GJOURNAL) ==
339 warnx("%s remains unchanged as disabled",
342 sblock.fs_flags &= ~FS_GJOURNAL;
343 warnx("%s cleared", name);
349 if (strcmp(lvalue, "enable") == 0) {
350 if (sblock.fs_flags & FS_MULTILABEL) {
351 warnx("%s remains unchanged as enabled", name);
353 sblock.fs_flags |= FS_MULTILABEL;
354 warnx("%s set", name);
356 } else if (strcmp(lvalue, "disable") == 0) {
357 if ((~sblock.fs_flags & FS_MULTILABEL) ==
359 warnx("%s remains unchanged as disabled",
362 sblock.fs_flags &= ~FS_MULTILABEL;
363 warnx("%s cleared", name);
368 name = "minimum percentage of free space";
369 if (sblock.fs_minfree == mvalue)
370 warnx("%s remains unchanged as %d%%", name, mvalue);
372 warnx("%s changes from %d%% to %d%%",
373 name, sblock.fs_minfree, mvalue);
374 sblock.fs_minfree = mvalue;
375 if (mvalue >= MINFREE && sblock.fs_optim == FS_OPTSPACE)
376 warnx(OPTWARN, "time", ">=", MINFREE);
377 if (mvalue < MINFREE && sblock.fs_optim == FS_OPTTIME)
378 warnx(OPTWARN, "space", "<", MINFREE);
383 if (strcmp(Nvalue, "enable") == 0) {
384 if (sblock.fs_flags & FS_NFS4ACLS) {
385 warnx("%s remains unchanged as enabled", name);
386 } else if (sblock.fs_flags & FS_ACLS) {
387 warnx("%s and POSIX.1e ACLs are mutually "
390 sblock.fs_flags |= FS_NFS4ACLS;
391 warnx("%s set", name);
393 } else if (strcmp(Nvalue, "disable") == 0) {
394 if ((~sblock.fs_flags & FS_NFS4ACLS) ==
396 warnx("%s remains unchanged as disabled",
399 sblock.fs_flags &= ~FS_NFS4ACLS;
400 warnx("%s cleared", name);
405 name = "soft updates";
406 if (strcmp(nvalue, "enable") == 0) {
407 if (sblock.fs_flags & FS_DOSOFTDEP)
408 warnx("%s remains unchanged as enabled", name);
409 else if (sblock.fs_clean == 0) {
410 warnx("%s cannot be enabled until fsck is run",
413 sblock.fs_flags |= FS_DOSOFTDEP;
414 warnx("%s set", name);
416 } else if (strcmp(nvalue, "disable") == 0) {
417 if ((~sblock.fs_flags & FS_DOSOFTDEP) == FS_DOSOFTDEP)
418 warnx("%s remains unchanged as disabled", name);
420 sblock.fs_flags &= ~FS_DOSOFTDEP;
421 warnx("%s cleared", name);
426 name = "optimization preference";
427 chg[FS_OPTSPACE] = "space";
428 chg[FS_OPTTIME] = "time";
429 if (sblock.fs_optim == ovalue)
430 warnx("%s remains unchanged as %s", name, chg[ovalue]);
432 warnx("%s changes from %s to %s",
433 name, chg[sblock.fs_optim], chg[ovalue]);
434 sblock.fs_optim = ovalue;
435 if (sblock.fs_minfree >= MINFREE &&
436 ovalue == FS_OPTSPACE)
437 warnx(OPTWARN, "time", ">=", MINFREE);
438 if (sblock.fs_minfree < MINFREE && ovalue == FS_OPTTIME)
439 warnx(OPTWARN, "space", "<", MINFREE);
443 name = "expected number of files per directory";
444 if (sblock.fs_avgfpdir == (unsigned)svalue) {
445 warnx("%s remains unchanged as %d", name, svalue);
448 warnx("%s changes from %d to %d",
449 name, sblock.fs_avgfpdir, svalue);
450 sblock.fs_avgfpdir = svalue;
454 name = "issue TRIM to the disk";
455 if (strcmp(tvalue, "enable") == 0) {
456 if (sblock.fs_flags & FS_TRIM)
457 warnx("%s remains unchanged as enabled", name);
459 sblock.fs_flags |= FS_TRIM;
460 warnx("%s set", name);
462 } else if (strcmp(tvalue, "disable") == 0) {
463 if ((~sblock.fs_flags & FS_TRIM) == FS_TRIM)
464 warnx("%s remains unchanged as disabled", name);
466 sblock.fs_flags &= ~FS_TRIM;
467 warnx("%s cleared", name);
472 if (sbwrite(&disk, Aflag) == -1)
474 ufs_disk_close(&disk);
476 bzero(&args, sizeof(args));
478 stfs.f_flags | MNT_UPDATE | MNT_RELOAD, &args) < 0)
479 err(9, "%s: reload", special);
480 warnx("file system reloaded");
484 if (disk.d_error != NULL)
485 errx(11, "%s: %s", special, disk.d_error);
487 err(12, "%s", special);
493 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
494 "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
495 " [-J enable | disable ] [-L volname] [-l enable | disable]",
496 " [-m minfree] [-N enable | disable] [-n enable | disable]",
497 " [-o space | time] [-p] [-s avgfpdir] [-t enable | disable]",
498 " special | filesystem");
505 warnx("POSIX.1e ACLs: (-a) %s",
506 (sblock.fs_flags & FS_ACLS)? "enabled" : "disabled");
507 warnx("NFSv4 ACLs: (-N) %s",
508 (sblock.fs_flags & FS_NFS4ACLS)? "enabled" : "disabled");
509 warnx("MAC multilabel: (-l) %s",
510 (sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled");
511 warnx("soft updates: (-n) %s",
512 (sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled");
513 warnx("gjournal: (-J) %s",
514 (sblock.fs_flags & FS_GJOURNAL)? "enabled" : "disabled");
515 warnx("trim: (-t) %s",
516 (sblock.fs_flags & FS_TRIM)? "enabled" : "disabled");
517 warnx("maximum blocks per file in a cylinder group: (-e) %d",
519 warnx("average file size: (-f) %d",
520 sblock.fs_avgfilesize);
521 warnx("average number of files in a directory: (-s) %d",
523 warnx("minimum percentage of free space: (-m) %d%%",
525 warnx("optimization preference: (-o) %s",
526 sblock.fs_optim == FS_OPTSPACE ? "space" : "time");
527 if (sblock.fs_minfree >= MINFREE &&
528 sblock.fs_optim == FS_OPTSPACE)
529 warnx(OPTWARN, "time", ">=", MINFREE);
530 if (sblock.fs_minfree < MINFREE &&
531 sblock.fs_optim == FS_OPTTIME)
532 warnx(OPTWARN, "space", "<", MINFREE);
533 warnx("volume label: (-L) %s",