18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1983, 1993 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * 58fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 68fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 78fae3551SRodney W. Grimes * are met: 88fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 98fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 108fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 118fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 128fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 138fae3551SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 148fae3551SRodney W. Grimes * must display the following acknowledgement: 158fae3551SRodney W. Grimes * This product includes software developed by the University of 168fae3551SRodney W. Grimes * California, Berkeley and its contributors. 178fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 188fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 198fae3551SRodney W. Grimes * without specific prior written permission. 208fae3551SRodney W. Grimes * 218fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 228fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 238fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 248fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 258fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 268fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 278fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 288fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 298fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 308fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318fae3551SRodney W. Grimes * SUCH DAMAGE. 328fae3551SRodney W. Grimes */ 338fae3551SRodney W. Grimes 348fae3551SRodney W. Grimes #ifndef lint 358679b1b4SPhilippe Charnier static const char copyright[] = 368fae3551SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 378fae3551SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 388fae3551SRodney W. Grimes #endif /* not lint */ 398fae3551SRodney W. Grimes 408fae3551SRodney W. Grimes #ifndef lint 418679b1b4SPhilippe Charnier #if 0 428fae3551SRodney W. Grimes static char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) 4/19/94"; 438679b1b4SPhilippe Charnier #endif 448679b1b4SPhilippe Charnier static const char rcsid[] = 457f3dea24SPeter Wemm "$FreeBSD$"; 468fae3551SRodney W. Grimes #endif /* not lint */ 478fae3551SRodney W. Grimes 488fae3551SRodney W. Grimes /* 498fae3551SRodney W. Grimes * tunefs: change layout parameters to an existing file system. 508fae3551SRodney W. Grimes */ 518fae3551SRodney W. Grimes #include <sys/param.h> 527382c45aSLuoqi Chen #include <sys/mount.h> 5375766e17SPoul-Henning Kamp #include <sys/disklabel.h> 548fae3551SRodney W. Grimes #include <sys/stat.h> 558fae3551SRodney W. Grimes 567382c45aSLuoqi Chen #include <ufs/ufs/ufsmount.h> 571c85e6a3SKirk McKusick #include <ufs/ufs/dinode.h> 581c85e6a3SKirk McKusick #include <ufs/ffs/fs.h> 598fae3551SRodney W. Grimes 608fae3551SRodney W. Grimes #include <err.h> 618fae3551SRodney W. Grimes #include <fcntl.h> 628fae3551SRodney W. Grimes #include <fstab.h> 638fae3551SRodney W. Grimes #include <paths.h> 648679b1b4SPhilippe Charnier #include <stdio.h> 658fae3551SRodney W. Grimes #include <stdlib.h> 66060ac658SSheldon Hearn #include <string.h> 678fae3551SRodney W. Grimes #include <unistd.h> 688fae3551SRodney W. Grimes 698fae3551SRodney W. Grimes /* the optimization warning string template */ 708fae3551SRodney W. Grimes #define OPTWARN "should optimize for %s with minfree %s %d%%" 718fae3551SRodney W. Grimes 728fae3551SRodney W. Grimes union { 738fae3551SRodney W. Grimes struct fs sb; 748fae3551SRodney W. Grimes char pad[MAXBSIZE]; 758fae3551SRodney W. Grimes } sbun; 768fae3551SRodney W. Grimes #define sblock sbun.sb 778fae3551SRodney W. Grimes 788fae3551SRodney W. Grimes int fi; 798fae3551SRodney W. Grimes long dev_bsize = 1; 808fae3551SRodney W. Grimes 811c85e6a3SKirk McKusick void bwrite(ufs2_daddr_t, const char *, int); 821c85e6a3SKirk McKusick int bread(ufs2_daddr_t, char *, int); 83d476a036SWarner Losh void getsb(struct fs *, const char *); 84d476a036SWarner Losh void putsb(struct fs *, const char *, int); 85d476a036SWarner Losh void usage(void); 86d476a036SWarner Losh void printfs(void); 878fae3551SRodney W. Grimes 888fae3551SRodney W. Grimes int 898fae3551SRodney W. Grimes main(argc, argv) 908fae3551SRodney W. Grimes int argc; 918fae3551SRodney W. Grimes char *argv[]; 928fae3551SRodney W. Grimes { 93c33fa91fSDima Dorfman char *special; 94c33fa91fSDima Dorfman const char *name; 958fae3551SRodney W. Grimes struct stat st; 96289e09eeSRobert Watson int Aflag = 0, active = 0, aflag = 0; 97289e09eeSRobert Watson int eflag = 0, fflag = 0, lflag = 0, mflag = 0; 98a61ab64aSKirk McKusick int nflag = 0, oflag = 0, pflag = 0, sflag = 0; 99a9098c89SPoul-Henning Kamp int evalue = 0, fvalue = 0; 100a61ab64aSKirk McKusick int mvalue = 0, ovalue = 0, svalue = 0; 101289e09eeSRobert Watson char *avalue = NULL, *lvalue = NULL, *nvalue = NULL; 1028fae3551SRodney W. Grimes struct fstab *fs; 103c33fa91fSDima Dorfman const char *chg[2]; 104c33fa91fSDima Dorfman char device[MAXPATHLEN]; 1057382c45aSLuoqi Chen struct ufs_args args; 1067382c45aSLuoqi Chen struct statfs stfs; 1072af14b60SPhilippe Charnier int found_arg, ch; 1088fae3551SRodney W. Grimes 1092af14b60SPhilippe Charnier if (argc < 3) 1108fae3551SRodney W. Grimes usage(); 11177edab90SPhilippe Charnier found_arg = 0; /* at least one arg is required */ 112a2325efeSRobert Watson while ((ch = getopt(argc, argv, "Aa:e:f:l:m:n:o:ps:")) != -1) 11377edab90SPhilippe Charnier switch (ch) { 114a2325efeSRobert Watson case 'A': 115a2325efeSRobert Watson found_arg = 1; 116a2325efeSRobert Watson Aflag++; 117a2325efeSRobert Watson break; 118289e09eeSRobert Watson case 'a': 119289e09eeSRobert Watson found_arg = 1; 120289e09eeSRobert Watson name = "ACLs"; 121289e09eeSRobert Watson avalue = optarg; 122289e09eeSRobert Watson if (strcmp(avalue, "enable") && strcmp(avalue, "disable")) { 123289e09eeSRobert Watson errx(10, "bad %s (options are %s)", name, 124289e09eeSRobert Watson "`enable' or `disable'"); 125289e09eeSRobert Watson } 126289e09eeSRobert Watson aflag = 1; 127289e09eeSRobert Watson break; 12877edab90SPhilippe Charnier case 'e': 12977edab90SPhilippe Charnier found_arg = 1; 13077edab90SPhilippe Charnier name = "maximum blocks per file in a cylinder group"; 13177edab90SPhilippe Charnier evalue = atoi(optarg); 13277edab90SPhilippe Charnier if (evalue < 1) 13377edab90SPhilippe Charnier errx(10, "%s must be >= 1 (was %s)", name, optarg); 13477edab90SPhilippe Charnier eflag = 1; 13577edab90SPhilippe Charnier break; 136a61ab64aSKirk McKusick case 'f': 137a61ab64aSKirk McKusick found_arg = 1; 138a61ab64aSKirk McKusick name = "average file size"; 139a61ab64aSKirk McKusick fvalue = atoi(optarg); 140a61ab64aSKirk McKusick if (fvalue < 1) 141a61ab64aSKirk McKusick errx(10, "%s must be >= 1 (was %s)", name, optarg); 142a61ab64aSKirk McKusick fflag = 1; 143a61ab64aSKirk McKusick break; 144289e09eeSRobert Watson case 'l': 145289e09eeSRobert Watson found_arg = 1; 146289e09eeSRobert Watson name = "multilabel MAC file system"; 147289e09eeSRobert Watson lvalue = optarg; 148289e09eeSRobert Watson if (strcmp(lvalue, "enable") && strcmp(lvalue, "disable")) { 149289e09eeSRobert Watson errx(10, "bad %s (options are %s)", name, 150289e09eeSRobert Watson "`enable' or `disable'"); 151289e09eeSRobert Watson } 152289e09eeSRobert Watson lflag = 1; 153289e09eeSRobert Watson break; 15477edab90SPhilippe Charnier case 'm': 15577edab90SPhilippe Charnier found_arg = 1; 15677edab90SPhilippe Charnier name = "minimum percentage of free space"; 15777edab90SPhilippe Charnier mvalue = atoi(optarg); 15877edab90SPhilippe Charnier if (mvalue < 0 || mvalue > 99) 15977edab90SPhilippe Charnier errx(10, "bad %s (%s)", name, optarg); 16077edab90SPhilippe Charnier mflag = 1; 16177edab90SPhilippe Charnier break; 16277edab90SPhilippe Charnier case 'n': 16377edab90SPhilippe Charnier found_arg = 1; 16477edab90SPhilippe Charnier name = "soft updates"; 16577edab90SPhilippe Charnier nvalue = optarg; 16677edab90SPhilippe Charnier if (strcmp(nvalue, "enable") && strcmp(nvalue, "disable")) { 16777edab90SPhilippe Charnier errx(10, "bad %s (options are %s)", 16877edab90SPhilippe Charnier name, "`enable' or `disable'"); 16977edab90SPhilippe Charnier } 17077edab90SPhilippe Charnier nflag = 1; 17177edab90SPhilippe Charnier break; 17277edab90SPhilippe Charnier case 'o': 17377edab90SPhilippe Charnier found_arg = 1; 17477edab90SPhilippe Charnier name = "optimization preference"; 17577edab90SPhilippe Charnier chg[FS_OPTSPACE] = "space"; 17677edab90SPhilippe Charnier chg[FS_OPTTIME] = "time"; 17777edab90SPhilippe Charnier if (strcmp(optarg, chg[FS_OPTSPACE]) == 0) 17877edab90SPhilippe Charnier ovalue = FS_OPTSPACE; 17977edab90SPhilippe Charnier else if (strcmp(optarg, chg[FS_OPTTIME]) == 0) 18077edab90SPhilippe Charnier ovalue = FS_OPTTIME; 18177edab90SPhilippe Charnier else 18277edab90SPhilippe Charnier errx(10, "bad %s (options are `space' or `time')", 18377edab90SPhilippe Charnier name); 18477edab90SPhilippe Charnier oflag = 1; 18577edab90SPhilippe Charnier break; 18677edab90SPhilippe Charnier case 'p': 187e50fa3d2SBen Smithurst found_arg = 1; 18877edab90SPhilippe Charnier pflag = 1; 18977edab90SPhilippe Charnier break; 190a61ab64aSKirk McKusick case 's': 191a61ab64aSKirk McKusick found_arg = 1; 192a61ab64aSKirk McKusick name = "expected number of files per directory"; 193a61ab64aSKirk McKusick svalue = atoi(optarg); 194a61ab64aSKirk McKusick if (svalue < 1) 195a61ab64aSKirk McKusick errx(10, "%s must be >= 1 (was %s)", name, optarg); 196a61ab64aSKirk McKusick sflag = 1; 197a61ab64aSKirk McKusick break; 19877edab90SPhilippe Charnier default: 19977edab90SPhilippe Charnier usage(); 20077edab90SPhilippe Charnier } 20177edab90SPhilippe Charnier argc -= optind; 20277edab90SPhilippe Charnier argv += optind; 20377edab90SPhilippe Charnier 20477edab90SPhilippe Charnier if (found_arg == 0 || argc != 1) 20577edab90SPhilippe Charnier usage(); 20677edab90SPhilippe Charnier 20777edab90SPhilippe Charnier special = argv[0]; 2088fae3551SRodney W. Grimes fs = getfsfile(special); 2097382c45aSLuoqi Chen if (fs) { 2109ea6e95eSLuoqi Chen if (statfs(special, &stfs) == 0 && 2119ea6e95eSLuoqi Chen strcmp(special, stfs.f_mntonname) == 0) { 2127382c45aSLuoqi Chen active = 1; 213b20ae6a0SLuoqi Chen } 2148fae3551SRodney W. Grimes special = fs->fs_spec; 2157382c45aSLuoqi Chen } 2168fae3551SRodney W. Grimes again: 2178fae3551SRodney W. Grimes if (stat(special, &st) < 0) { 2188fae3551SRodney W. Grimes if (*special != '/') { 2198fae3551SRodney W. Grimes if (*special == 'r') 2208fae3551SRodney W. Grimes special++; 22147f07d95SIan Dowse (void)snprintf(device, sizeof(device), "%s%s", 22255fd28c8SKris Kennaway _PATH_DEV, special); 2238fae3551SRodney W. Grimes special = device; 2248fae3551SRodney W. Grimes goto again; 2258fae3551SRodney W. Grimes } 2268fae3551SRodney W. Grimes err(1, "%s", special); 2278fae3551SRodney W. Grimes } 22847f07d95SIan Dowse if (fs == NULL && (st.st_mode & S_IFMT) == S_IFDIR) 22947f07d95SIan Dowse errx(10, "%s: unknown file system", special); 2308fae3551SRodney W. Grimes getsb(&sblock, special); 2318fae3551SRodney W. Grimes 23277edab90SPhilippe Charnier if (pflag) { 23377edab90SPhilippe Charnier printfs(); 23477edab90SPhilippe Charnier exit(0); 23577edab90SPhilippe Charnier } 236289e09eeSRobert Watson if (aflag) { 237289e09eeSRobert Watson name = "ACLs"; 238289e09eeSRobert Watson if (strcmp(avalue, "enable") == 0) { 239289e09eeSRobert Watson if (sblock.fs_flags & FS_ACLS) { 240289e09eeSRobert Watson warnx("%s remains unchanged as enabled", name); 241289e09eeSRobert Watson } else { 242289e09eeSRobert Watson sblock.fs_flags |= FS_ACLS; 243289e09eeSRobert Watson warnx("%s set", name); 244289e09eeSRobert Watson } 245289e09eeSRobert Watson } else if (strcmp(avalue, "disable") == 0) { 246289e09eeSRobert Watson if ((~sblock.fs_flags & FS_ACLS) == 247289e09eeSRobert Watson FS_ACLS) { 248289e09eeSRobert Watson warnx("%s remains unchanged as disabled", 249289e09eeSRobert Watson name); 250289e09eeSRobert Watson } else { 251289e09eeSRobert Watson sblock.fs_flags &= ~FS_ACLS; 252289e09eeSRobert Watson warnx("%s set", name); 253289e09eeSRobert Watson } 254289e09eeSRobert Watson } 255289e09eeSRobert Watson } 25677edab90SPhilippe Charnier if (eflag) { 2572af14b60SPhilippe Charnier name = "maximum blocks per file in a cylinder group"; 25877edab90SPhilippe Charnier if (sblock.fs_maxbpg == evalue) { 25977edab90SPhilippe Charnier warnx("%s remains unchanged as %d", name, evalue); 2602af14b60SPhilippe Charnier } 26177edab90SPhilippe Charnier else { 26277edab90SPhilippe Charnier warnx("%s changes from %d to %d", 26377edab90SPhilippe Charnier name, sblock.fs_maxbpg, evalue); 26477edab90SPhilippe Charnier sblock.fs_maxbpg = evalue; 26577edab90SPhilippe Charnier } 26677edab90SPhilippe Charnier } 267a61ab64aSKirk McKusick if (fflag) { 268a61ab64aSKirk McKusick name = "average file size"; 269a61ab64aSKirk McKusick if (sblock.fs_avgfilesize == fvalue) { 270a61ab64aSKirk McKusick warnx("%s remains unchanged as %d", name, fvalue); 271a61ab64aSKirk McKusick } 272a61ab64aSKirk McKusick else { 273a61ab64aSKirk McKusick warnx("%s changes from %d to %d", 274a61ab64aSKirk McKusick name, sblock.fs_avgfilesize, fvalue); 275a61ab64aSKirk McKusick sblock.fs_avgfilesize = fvalue; 276a61ab64aSKirk McKusick } 277a61ab64aSKirk McKusick } 278289e09eeSRobert Watson if (lflag) { 279289e09eeSRobert Watson name = "multilabel"; 280289e09eeSRobert Watson if (strcmp(lvalue, "enable") == 0) { 281289e09eeSRobert Watson if (sblock.fs_flags & FS_MULTILABEL) { 282289e09eeSRobert Watson warnx("%s remains unchanged as enabled", name); 283289e09eeSRobert Watson } else { 284289e09eeSRobert Watson sblock.fs_flags |= FS_MULTILABEL; 285289e09eeSRobert Watson warnx("%s set", name); 286289e09eeSRobert Watson } 287289e09eeSRobert Watson } else if (strcmp(lvalue, "disable") == 0) { 288289e09eeSRobert Watson if ((~sblock.fs_flags & FS_MULTILABEL) == 289289e09eeSRobert Watson FS_MULTILABEL) { 290289e09eeSRobert Watson warnx("%s remains unchanged as disabled", 291289e09eeSRobert Watson name); 292289e09eeSRobert Watson } else { 293289e09eeSRobert Watson sblock.fs_flags &= ~FS_MULTILABEL; 294289e09eeSRobert Watson warnx("%s set", name); 295289e09eeSRobert Watson } 296289e09eeSRobert Watson } 297289e09eeSRobert Watson } 29877edab90SPhilippe Charnier if (mflag) { 2998fae3551SRodney W. Grimes name = "minimum percentage of free space"; 30077edab90SPhilippe Charnier if (sblock.fs_minfree == mvalue) { 30177edab90SPhilippe Charnier warnx("%s remains unchanged as %d%%", name, mvalue); 3022af14b60SPhilippe Charnier } 30377edab90SPhilippe Charnier else { 3048fae3551SRodney W. Grimes warnx("%s changes from %d%% to %d%%", 30577edab90SPhilippe Charnier name, sblock.fs_minfree, mvalue); 30677edab90SPhilippe Charnier sblock.fs_minfree = mvalue; 30777edab90SPhilippe Charnier if (mvalue >= MINFREE && sblock.fs_optim == FS_OPTSPACE) 3088fae3551SRodney W. Grimes warnx(OPTWARN, "time", ">=", MINFREE); 30977edab90SPhilippe Charnier if (mvalue < MINFREE && sblock.fs_optim == FS_OPTTIME) 3108fae3551SRodney W. Grimes warnx(OPTWARN, "space", "<", MINFREE); 311b1897c19SJulian Elischer } 31277edab90SPhilippe Charnier } 31377edab90SPhilippe Charnier if (nflag) { 31477edab90SPhilippe Charnier name = "soft updates"; 31577edab90SPhilippe Charnier if (strcmp(nvalue, "enable") == 0) { 31677edab90SPhilippe Charnier if (sblock.fs_flags & FS_DOSOFTDEP) { 31777edab90SPhilippe Charnier warnx("%s remains unchanged as enabled", name); 3181c2665d8SKirk McKusick } else if (sblock.fs_clean == 0) { 3191c2665d8SKirk McKusick warnx("%s cannot be enabled until fsck is run", 3201c2665d8SKirk McKusick name); 32177edab90SPhilippe Charnier } else { 32277edab90SPhilippe Charnier sblock.fs_flags |= FS_DOSOFTDEP; 32377edab90SPhilippe Charnier warnx("%s set", name); 32477edab90SPhilippe Charnier } 32577edab90SPhilippe Charnier } else if (strcmp(nvalue, "disable") == 0) { 32677edab90SPhilippe Charnier if ((~sblock.fs_flags & FS_DOSOFTDEP) == FS_DOSOFTDEP) { 32777edab90SPhilippe Charnier warnx("%s remains unchanged as disabled", name); 32877edab90SPhilippe Charnier } else { 32977edab90SPhilippe Charnier sblock.fs_flags &= ~FS_DOSOFTDEP; 33077edab90SPhilippe Charnier warnx("%s cleared", name); 33177edab90SPhilippe Charnier } 33277edab90SPhilippe Charnier } 33377edab90SPhilippe Charnier } 33477edab90SPhilippe Charnier if (oflag) { 3358fae3551SRodney W. Grimes name = "optimization preference"; 3368fae3551SRodney W. Grimes chg[FS_OPTSPACE] = "space"; 3378fae3551SRodney W. Grimes chg[FS_OPTTIME] = "time"; 33877edab90SPhilippe Charnier if (sblock.fs_optim == ovalue) { 33977edab90SPhilippe Charnier warnx("%s remains unchanged as %s", name, chg[ovalue]); 3408fae3551SRodney W. Grimes } 34177edab90SPhilippe Charnier else { 3428fae3551SRodney W. Grimes warnx("%s changes from %s to %s", 34377edab90SPhilippe Charnier name, chg[sblock.fs_optim], chg[ovalue]); 34477edab90SPhilippe Charnier sblock.fs_optim = ovalue; 34577edab90SPhilippe Charnier if (sblock.fs_minfree >= MINFREE && 34677edab90SPhilippe Charnier ovalue == FS_OPTSPACE) 3478fae3551SRodney W. Grimes warnx(OPTWARN, "time", ">=", MINFREE); 34877edab90SPhilippe Charnier if (sblock.fs_minfree < MINFREE && 34977edab90SPhilippe Charnier ovalue == FS_OPTTIME) 3508fae3551SRodney W. Grimes warnx(OPTWARN, "space", "<", MINFREE); 3518fae3551SRodney W. Grimes } 35277edab90SPhilippe Charnier } 353a61ab64aSKirk McKusick if (sflag) { 354a61ab64aSKirk McKusick name = "expected number of files per directory"; 355a61ab64aSKirk McKusick if (sblock.fs_avgfpdir == svalue) { 356a61ab64aSKirk McKusick warnx("%s remains unchanged as %d", name, svalue); 357a61ab64aSKirk McKusick } 358a61ab64aSKirk McKusick else { 359a61ab64aSKirk McKusick warnx("%s changes from %d to %d", 360a61ab64aSKirk McKusick name, sblock.fs_avgfpdir, svalue); 361a61ab64aSKirk McKusick sblock.fs_avgfpdir = svalue; 362a61ab64aSKirk McKusick } 363a61ab64aSKirk McKusick } 3642af14b60SPhilippe Charnier 365060ac658SSheldon Hearn putsb(&sblock, special, Aflag); 3667382c45aSLuoqi Chen if (active) { 3677382c45aSLuoqi Chen bzero(&args, sizeof(args)); 3687382c45aSLuoqi Chen if (mount("ufs", fs->fs_file, 3697382c45aSLuoqi Chen stfs.f_flags | MNT_UPDATE | MNT_RELOAD, &args) < 0) 3707382c45aSLuoqi Chen err(9, "%s: reload", special); 3717382c45aSLuoqi Chen warnx("file system reloaded"); 3727382c45aSLuoqi Chen } 3738fae3551SRodney W. Grimes exit(0); 3748fae3551SRodney W. Grimes } 3758fae3551SRodney W. Grimes 3768fae3551SRodney W. Grimes void 3778fae3551SRodney W. Grimes usage() 3788fae3551SRodney W. Grimes { 3798679b1b4SPhilippe Charnier fprintf(stderr, "%s\n%s\n%s\n", 380a2325efeSRobert Watson "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]", 381289e09eeSRobert Watson " [-l enable | disable] [-m minfree] [-n enable | disable]", 382289e09eeSRobert Watson " [-o space | time] [-p] [-s avgfpdir] special | filesystem"); 3838fae3551SRodney W. Grimes exit(2); 3848fae3551SRodney W. Grimes } 3858fae3551SRodney W. Grimes 3861c85e6a3SKirk McKusick /* 3871c85e6a3SKirk McKusick * Possible superblock locations ordered from most to least likely. 3881c85e6a3SKirk McKusick */ 3891c85e6a3SKirk McKusick static int sblock_try[] = SBLOCKSEARCH; 3901c85e6a3SKirk McKusick static ufs2_daddr_t sblockloc; 3911c85e6a3SKirk McKusick 3928fae3551SRodney W. Grimes void 3938fae3551SRodney W. Grimes getsb(fs, file) 394c33fa91fSDima Dorfman struct fs *fs; 395c33fa91fSDima Dorfman const char *file; 3968fae3551SRodney W. Grimes { 3971c85e6a3SKirk McKusick int i; 3988fae3551SRodney W. Grimes 399060ac658SSheldon Hearn fi = open(file, O_RDONLY); 4008fae3551SRodney W. Grimes if (fi < 0) 4018fae3551SRodney W. Grimes err(3, "cannot open %s", file); 4021c85e6a3SKirk McKusick for (i = 0; sblock_try[i] != -1; i++) { 4031c85e6a3SKirk McKusick if (bread(sblock_try[i], (char *)fs, SBLOCKSIZE)) 4048fae3551SRodney W. Grimes err(4, "%s: bad super block", file); 4051c85e6a3SKirk McKusick if ((fs->fs_magic == FS_UFS1_MAGIC || 4061c85e6a3SKirk McKusick (fs->fs_magic == FS_UFS2_MAGIC && 4071c85e6a3SKirk McKusick fs->fs_sblockloc == numfrags(fs, sblock_try[i]))) && 4081c85e6a3SKirk McKusick fs->fs_bsize <= MAXBSIZE && 4091c85e6a3SKirk McKusick fs->fs_bsize >= sizeof(struct fs)) 4101c85e6a3SKirk McKusick break; 4111c85e6a3SKirk McKusick } 4121c85e6a3SKirk McKusick if (sblock_try[i] == -1) 4131c85e6a3SKirk McKusick err(5, "Cannot find file system superblock"); 4148fae3551SRodney W. Grimes dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 4151c85e6a3SKirk McKusick sblockloc = sblock_try[i] / dev_bsize; 4168fae3551SRodney W. Grimes } 4178fae3551SRodney W. Grimes 4188fae3551SRodney W. Grimes void 419060ac658SSheldon Hearn putsb(fs, file, all) 420c33fa91fSDima Dorfman struct fs *fs; 421c33fa91fSDima Dorfman const char *file; 422060ac658SSheldon Hearn int all; 423060ac658SSheldon Hearn { 424060ac658SSheldon Hearn int i; 425060ac658SSheldon Hearn 426060ac658SSheldon Hearn /* 427060ac658SSheldon Hearn * Re-open the device read-write. Use the read-only file 428060ac658SSheldon Hearn * descriptor as an interlock to prevent the device from 429060ac658SSheldon Hearn * being mounted while we are switching mode. 430060ac658SSheldon Hearn */ 431060ac658SSheldon Hearn i = fi; 432060ac658SSheldon Hearn fi = open(file, O_RDWR); 433060ac658SSheldon Hearn close(i); 434060ac658SSheldon Hearn if (fi < 0) 435060ac658SSheldon Hearn err(3, "cannot open %s", file); 4361c85e6a3SKirk McKusick bwrite(sblockloc, (const char *)fs, SBLOCKSIZE); 437060ac658SSheldon Hearn if (all) 438060ac658SSheldon Hearn for (i = 0; i < fs->fs_ncg; i++) 439060ac658SSheldon Hearn bwrite(fsbtodb(fs, cgsblock(fs, i)), 4401c85e6a3SKirk McKusick (const char *)fs, SBLOCKSIZE); 441060ac658SSheldon Hearn close(fi); 442060ac658SSheldon Hearn } 443060ac658SSheldon Hearn 444060ac658SSheldon Hearn void 44516a7269eSJoerg Wunsch printfs() 44616a7269eSJoerg Wunsch { 447b1897c19SJulian Elischer warnx("soft updates: (-n) %s", 448b1897c19SJulian Elischer (sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled"); 44916a7269eSJoerg Wunsch warnx("maximum blocks per file in a cylinder group: (-e) %d", 45016a7269eSJoerg Wunsch sblock.fs_maxbpg); 451a61ab64aSKirk McKusick warnx("average file size: (-f) %d", 452a61ab64aSKirk McKusick sblock.fs_avgfilesize); 453a61ab64aSKirk McKusick warnx("average number of files in a directory: (-s) %d", 454a61ab64aSKirk McKusick sblock.fs_avgfpdir); 45516a7269eSJoerg Wunsch warnx("minimum percentage of free space: (-m) %d%%", 45616a7269eSJoerg Wunsch sblock.fs_minfree); 45716a7269eSJoerg Wunsch warnx("optimization preference: (-o) %s", 45816a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTSPACE ? "space" : "time"); 45916a7269eSJoerg Wunsch if (sblock.fs_minfree >= MINFREE && 46016a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTSPACE) 46116a7269eSJoerg Wunsch warnx(OPTWARN, "time", ">=", MINFREE); 46216a7269eSJoerg Wunsch if (sblock.fs_minfree < MINFREE && 46316a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTTIME) 46416a7269eSJoerg Wunsch warnx(OPTWARN, "space", "<", MINFREE); 46516a7269eSJoerg Wunsch } 46616a7269eSJoerg Wunsch 46716a7269eSJoerg Wunsch void 4688fae3551SRodney W. Grimes bwrite(blk, buf, size) 4691c85e6a3SKirk McKusick ufs2_daddr_t blk; 470c33fa91fSDima Dorfman const char *buf; 4718fae3551SRodney W. Grimes int size; 4728fae3551SRodney W. Grimes { 4738fae3551SRodney W. Grimes 4748fae3551SRodney W. Grimes if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0) 4758fae3551SRodney W. Grimes err(6, "FS SEEK"); 4768fae3551SRodney W. Grimes if (write(fi, buf, size) != size) 4778fae3551SRodney W. Grimes err(7, "FS WRITE"); 4788fae3551SRodney W. Grimes } 4798fae3551SRodney W. Grimes 4808fae3551SRodney W. Grimes int 4818fae3551SRodney W. Grimes bread(bno, buf, cnt) 4821c85e6a3SKirk McKusick ufs2_daddr_t bno; 4838fae3551SRodney W. Grimes char *buf; 4848fae3551SRodney W. Grimes int cnt; 4858fae3551SRodney W. Grimes { 4868fae3551SRodney W. Grimes int i; 4878fae3551SRodney W. Grimes 4888fae3551SRodney W. Grimes if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0) 4898fae3551SRodney W. Grimes return(1); 4908fae3551SRodney W. Grimes if ((i = read(fi, buf, cnt)) != cnt) { 4918fae3551SRodney W. Grimes for(i=0; i<sblock.fs_bsize; i++) 4928fae3551SRodney W. Grimes buf[i] = 0; 4938fae3551SRodney W. Grimes return (1); 4948fae3551SRodney W. Grimes } 4958fae3551SRodney W. Grimes return (0); 4968fae3551SRodney W. Grimes } 497