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 358fae3551SRodney W. Grimes static 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 418fae3551SRodney W. Grimes static char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) 4/19/94"; 428fae3551SRodney W. Grimes #endif /* not lint */ 438fae3551SRodney W. Grimes 448fae3551SRodney W. Grimes /* 458fae3551SRodney W. Grimes * tunefs: change layout parameters to an existing file system. 468fae3551SRodney W. Grimes */ 478fae3551SRodney W. Grimes #include <sys/param.h> 488fae3551SRodney W. Grimes #include <sys/stat.h> 498fae3551SRodney W. Grimes 508fae3551SRodney W. Grimes #include <ufs/ffs/fs.h> 518fae3551SRodney W. Grimes 528fae3551SRodney W. Grimes #include <errno.h> 538fae3551SRodney W. Grimes #include <err.h> 548fae3551SRodney W. Grimes #include <fcntl.h> 558fae3551SRodney W. Grimes #include <fstab.h> 568fae3551SRodney W. Grimes #include <stdio.h> 578fae3551SRodney W. Grimes #include <paths.h> 588fae3551SRodney W. Grimes #include <stdlib.h> 598fae3551SRodney W. Grimes #include <unistd.h> 608fae3551SRodney W. Grimes 618fae3551SRodney W. Grimes /* the optimization warning string template */ 628fae3551SRodney W. Grimes #define OPTWARN "should optimize for %s with minfree %s %d%%" 638fae3551SRodney W. Grimes 648fae3551SRodney W. Grimes union { 658fae3551SRodney W. Grimes struct fs sb; 668fae3551SRodney W. Grimes char pad[MAXBSIZE]; 678fae3551SRodney W. Grimes } sbun; 688fae3551SRodney W. Grimes #define sblock sbun.sb 698fae3551SRodney W. Grimes 708fae3551SRodney W. Grimes int fi; 718fae3551SRodney W. Grimes long dev_bsize = 1; 728fae3551SRodney W. Grimes 738fae3551SRodney W. Grimes void bwrite(daddr_t, char *, int); 748fae3551SRodney W. Grimes int bread(daddr_t, char *, int); 758fae3551SRodney W. Grimes void getsb(struct fs *, char *); 768fae3551SRodney W. Grimes void usage __P((void)); 7716a7269eSJoerg Wunsch void printfs __P((void)); 788fae3551SRodney W. Grimes 798fae3551SRodney W. Grimes int 808fae3551SRodney W. Grimes main(argc, argv) 818fae3551SRodney W. Grimes int argc; 828fae3551SRodney W. Grimes char *argv[]; 838fae3551SRodney W. Grimes { 84b1897c19SJulian Elischer char *cp, *special, *name, *action; 858fae3551SRodney W. Grimes struct stat st; 868fae3551SRodney W. Grimes int i; 878fae3551SRodney W. Grimes int Aflag = 0; 888fae3551SRodney W. Grimes struct fstab *fs; 898fae3551SRodney W. Grimes char *chg[2], device[MAXPATHLEN]; 908fae3551SRodney W. Grimes 918fae3551SRodney W. Grimes argc--, argv++; 928fae3551SRodney W. Grimes if (argc < 2) 938fae3551SRodney W. Grimes usage(); 948fae3551SRodney W. Grimes special = argv[argc - 1]; 958fae3551SRodney W. Grimes fs = getfsfile(special); 968fae3551SRodney W. Grimes if (fs) 978fae3551SRodney W. Grimes special = fs->fs_spec; 988fae3551SRodney W. Grimes again: 998fae3551SRodney W. Grimes if (stat(special, &st) < 0) { 1008fae3551SRodney W. Grimes if (*special != '/') { 1018fae3551SRodney W. Grimes if (*special == 'r') 1028fae3551SRodney W. Grimes special++; 1038fae3551SRodney W. Grimes (void)sprintf(device, "%s/%s", _PATH_DEV, special); 1048fae3551SRodney W. Grimes special = device; 1058fae3551SRodney W. Grimes goto again; 1068fae3551SRodney W. Grimes } 1078fae3551SRodney W. Grimes err(1, "%s", special); 1088fae3551SRodney W. Grimes } 1098fae3551SRodney W. Grimes if ((st.st_mode & S_IFMT) != S_IFBLK && 1108fae3551SRodney W. Grimes (st.st_mode & S_IFMT) != S_IFCHR) 1118fae3551SRodney W. Grimes errx(10, "%s: not a block or character device", special); 1128fae3551SRodney W. Grimes getsb(&sblock, special); 1138fae3551SRodney W. Grimes for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 1148fae3551SRodney W. Grimes for (cp = &argv[0][1]; *cp; cp++) 1158fae3551SRodney W. Grimes switch (*cp) { 1168fae3551SRodney W. Grimes 1178fae3551SRodney W. Grimes case 'A': 1188fae3551SRodney W. Grimes Aflag++; 1198fae3551SRodney W. Grimes continue; 1208fae3551SRodney W. Grimes 12116a7269eSJoerg Wunsch case 'p': 12216a7269eSJoerg Wunsch printfs(); 12316a7269eSJoerg Wunsch exit(0); 12416a7269eSJoerg Wunsch 1258fae3551SRodney W. Grimes case 'a': 1268fae3551SRodney W. Grimes name = "maximum contiguous block count"; 1278fae3551SRodney W. Grimes if (argc < 1) 1288fae3551SRodney W. Grimes errx(10, "-a: missing %s", name); 1298fae3551SRodney W. Grimes argc--, argv++; 1308fae3551SRodney W. Grimes i = atoi(*argv); 1318fae3551SRodney W. Grimes if (i < 1) 1328fae3551SRodney W. Grimes errx(10, "%s must be >= 1 (was %s)", 1338fae3551SRodney W. Grimes name, *argv); 1348fae3551SRodney W. Grimes warnx("%s changes from %d to %d", 1358fae3551SRodney W. Grimes name, sblock.fs_maxcontig, i); 1368fae3551SRodney W. Grimes sblock.fs_maxcontig = i; 1378fae3551SRodney W. Grimes continue; 1388fae3551SRodney W. Grimes 1398fae3551SRodney W. Grimes case 'd': 1408fae3551SRodney W. Grimes name = 1418fae3551SRodney W. Grimes "rotational delay between contiguous blocks"; 1428fae3551SRodney W. Grimes if (argc < 1) 1438fae3551SRodney W. Grimes errx(10, "-d: missing %s", name); 1448fae3551SRodney W. Grimes argc--, argv++; 1458fae3551SRodney W. Grimes i = atoi(*argv); 1468fae3551SRodney W. Grimes warnx("%s changes from %dms to %dms", 1478fae3551SRodney W. Grimes name, sblock.fs_rotdelay, i); 1488fae3551SRodney W. Grimes sblock.fs_rotdelay = i; 1498fae3551SRodney W. Grimes continue; 1508fae3551SRodney W. Grimes 1518fae3551SRodney W. Grimes case 'e': 1528fae3551SRodney W. Grimes name = 1538fae3551SRodney W. Grimes "maximum blocks per file in a cylinder group"; 1548fae3551SRodney W. Grimes if (argc < 1) 1558fae3551SRodney W. Grimes errx(10, "-e: missing %s", name); 1568fae3551SRodney W. Grimes argc--, argv++; 1578fae3551SRodney W. Grimes i = atoi(*argv); 1588fae3551SRodney W. Grimes if (i < 1) 1598fae3551SRodney W. Grimes errx(10, "%s must be >= 1 (was %s)", 1608fae3551SRodney W. Grimes name, *argv); 1618fae3551SRodney W. Grimes warnx("%s changes from %d to %d", 1628fae3551SRodney W. Grimes name, sblock.fs_maxbpg, i); 1638fae3551SRodney W. Grimes sblock.fs_maxbpg = i; 1648fae3551SRodney W. Grimes continue; 1658fae3551SRodney W. Grimes 1668fae3551SRodney W. Grimes case 'm': 1678fae3551SRodney W. Grimes name = "minimum percentage of free space"; 1688fae3551SRodney W. Grimes if (argc < 1) 1698fae3551SRodney W. Grimes errx(10, "-m: missing %s", name); 1708fae3551SRodney W. Grimes argc--, argv++; 1718fae3551SRodney W. Grimes i = atoi(*argv); 1728fae3551SRodney W. Grimes if (i < 0 || i > 99) 1738fae3551SRodney W. Grimes errx(10, "bad %s (%s)", name, *argv); 1748fae3551SRodney W. Grimes warnx("%s changes from %d%% to %d%%", 1758fae3551SRodney W. Grimes name, sblock.fs_minfree, i); 1768fae3551SRodney W. Grimes sblock.fs_minfree = i; 1778fae3551SRodney W. Grimes if (i >= MINFREE && 1788fae3551SRodney W. Grimes sblock.fs_optim == FS_OPTSPACE) 1798fae3551SRodney W. Grimes warnx(OPTWARN, "time", ">=", MINFREE); 1808fae3551SRodney W. Grimes if (i < MINFREE && 1818fae3551SRodney W. Grimes sblock.fs_optim == FS_OPTTIME) 1828fae3551SRodney W. Grimes warnx(OPTWARN, "space", "<", MINFREE); 1838fae3551SRodney W. Grimes continue; 1848fae3551SRodney W. Grimes 185b1897c19SJulian Elischer case 'n': 186b1897c19SJulian Elischer name = "soft updates"; 187b1897c19SJulian Elischer if (argc < 1) 188b1897c19SJulian Elischer errx(10, "-s: missing %s", name); 189b1897c19SJulian Elischer argc--, argv++; 190b1897c19SJulian Elischer if (strcmp(*argv, "enable") == 0) { 191b1897c19SJulian Elischer sblock.fs_flags |= FS_DOSOFTDEP; 192b1897c19SJulian Elischer action = "set"; 193b1897c19SJulian Elischer } else if (strcmp(*argv, "disable") == 0) { 194b1897c19SJulian Elischer sblock.fs_flags &= ~FS_DOSOFTDEP; 195b1897c19SJulian Elischer action = "cleared"; 196b1897c19SJulian Elischer } else { 197b1897c19SJulian Elischer errx(10, "bad %s (options are %s)", 198b1897c19SJulian Elischer name, "`enable' or `disable'"); 199b1897c19SJulian Elischer } 200b1897c19SJulian Elischer warnx("%s %s", name, action); 201b1897c19SJulian Elischer continue; 202b1897c19SJulian Elischer 2038fae3551SRodney W. Grimes case 'o': 2048fae3551SRodney W. Grimes name = "optimization preference"; 2058fae3551SRodney W. Grimes if (argc < 1) 2068fae3551SRodney W. Grimes errx(10, "-o: missing %s", name); 2078fae3551SRodney W. Grimes argc--, argv++; 2088fae3551SRodney W. Grimes chg[FS_OPTSPACE] = "space"; 2098fae3551SRodney W. Grimes chg[FS_OPTTIME] = "time"; 2108fae3551SRodney W. Grimes if (strcmp(*argv, chg[FS_OPTSPACE]) == 0) 2118fae3551SRodney W. Grimes i = FS_OPTSPACE; 2128fae3551SRodney W. Grimes else if (strcmp(*argv, chg[FS_OPTTIME]) == 0) 2138fae3551SRodney W. Grimes i = FS_OPTTIME; 2148fae3551SRodney W. Grimes else 2158fae3551SRodney W. Grimes errx(10, "bad %s (options are `space' or `time')", 2168fae3551SRodney W. Grimes name); 2178fae3551SRodney W. Grimes if (sblock.fs_optim == i) { 2188fae3551SRodney W. Grimes warnx("%s remains unchanged as %s", 2198fae3551SRodney W. Grimes name, chg[i]); 2208fae3551SRodney W. Grimes continue; 2218fae3551SRodney W. Grimes } 2228fae3551SRodney W. Grimes warnx("%s changes from %s to %s", 2238fae3551SRodney W. Grimes name, chg[sblock.fs_optim], chg[i]); 2248fae3551SRodney W. Grimes sblock.fs_optim = i; 2258fae3551SRodney W. Grimes if (sblock.fs_minfree >= MINFREE && 2268fae3551SRodney W. Grimes i == FS_OPTSPACE) 2278fae3551SRodney W. Grimes warnx(OPTWARN, "time", ">=", MINFREE); 2288fae3551SRodney W. Grimes if (sblock.fs_minfree < MINFREE && 2298fae3551SRodney W. Grimes i == FS_OPTTIME) 2308fae3551SRodney W. Grimes warnx(OPTWARN, "space", "<", MINFREE); 2318fae3551SRodney W. Grimes continue; 2328fae3551SRodney W. Grimes 2338fae3551SRodney W. Grimes default: 2348fae3551SRodney W. Grimes usage(); 2358fae3551SRodney W. Grimes } 2368fae3551SRodney W. Grimes } 2378fae3551SRodney W. Grimes if (argc != 1) 2388fae3551SRodney W. Grimes usage(); 2398fae3551SRodney W. Grimes bwrite((daddr_t)SBOFF / dev_bsize, (char *)&sblock, SBSIZE); 2408fae3551SRodney W. Grimes if (Aflag) 2418fae3551SRodney W. Grimes for (i = 0; i < sblock.fs_ncg; i++) 2428fae3551SRodney W. Grimes bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 2438fae3551SRodney W. Grimes (char *)&sblock, SBSIZE); 2448fae3551SRodney W. Grimes close(fi); 2458fae3551SRodney W. Grimes exit(0); 2468fae3551SRodney W. Grimes } 2478fae3551SRodney W. Grimes 2488fae3551SRodney W. Grimes void 2498fae3551SRodney W. Grimes usage() 2508fae3551SRodney W. Grimes { 2518fae3551SRodney W. Grimes 25249d430ccSPhilippe Charnier fprintf(stderr, "usage: tunefs tuneup-options special-device\n"); 2538fae3551SRodney W. Grimes fprintf(stderr, "where tuneup-options are:\n"); 2548fae3551SRodney W. Grimes fprintf(stderr, "\t-a maximum contiguous blocks\n"); 2558fae3551SRodney W. Grimes fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 2568fae3551SRodney W. Grimes fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 2578fae3551SRodney W. Grimes fprintf(stderr, "\t-m minimum percentage of free space\n"); 258b1897c19SJulian Elischer fprintf(stderr, "\t-n soft updates (`enable' or `disable')\n"); 2598fae3551SRodney W. Grimes fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 26016a7269eSJoerg Wunsch fprintf(stderr, "\t-p no change - just prints current tuneable settings\n"); 2618fae3551SRodney W. Grimes exit(2); 2628fae3551SRodney W. Grimes } 2638fae3551SRodney W. Grimes 2648fae3551SRodney W. Grimes void 2658fae3551SRodney W. Grimes getsb(fs, file) 2668fae3551SRodney W. Grimes register struct fs *fs; 2678fae3551SRodney W. Grimes char *file; 2688fae3551SRodney W. Grimes { 2698fae3551SRodney W. Grimes 2708fae3551SRodney W. Grimes fi = open(file, 2); 2718fae3551SRodney W. Grimes if (fi < 0) 2728fae3551SRodney W. Grimes err(3, "cannot open %s", file); 2738fae3551SRodney W. Grimes if (bread((daddr_t)SBOFF, (char *)fs, SBSIZE)) 2748fae3551SRodney W. Grimes err(4, "%s: bad super block", file); 2758fae3551SRodney W. Grimes if (fs->fs_magic != FS_MAGIC) 2768fae3551SRodney W. Grimes err(5, "%s: bad magic number", file); 2778fae3551SRodney W. Grimes dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 2788fae3551SRodney W. Grimes } 2798fae3551SRodney W. Grimes 2808fae3551SRodney W. Grimes void 28116a7269eSJoerg Wunsch printfs() 28216a7269eSJoerg Wunsch { 283b1897c19SJulian Elischer warnx("soft updates: (-n) %s", 284b1897c19SJulian Elischer (sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled"); 28516a7269eSJoerg Wunsch warnx("maximum contiguous block count: (-a) %d", 28616a7269eSJoerg Wunsch sblock.fs_maxcontig); 28716a7269eSJoerg Wunsch warnx("rotational delay between contiguous blocks: (-d) %d ms", 28816a7269eSJoerg Wunsch sblock.fs_rotdelay); 28916a7269eSJoerg Wunsch warnx("maximum blocks per file in a cylinder group: (-e) %d", 29016a7269eSJoerg Wunsch sblock.fs_maxbpg); 29116a7269eSJoerg Wunsch warnx("minimum percentage of free space: (-m) %d%%", 29216a7269eSJoerg Wunsch sblock.fs_minfree); 29316a7269eSJoerg Wunsch warnx("optimization preference: (-o) %s", 29416a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTSPACE ? "space" : "time"); 29516a7269eSJoerg Wunsch if (sblock.fs_minfree >= MINFREE && 29616a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTSPACE) 29716a7269eSJoerg Wunsch warnx(OPTWARN, "time", ">=", MINFREE); 29816a7269eSJoerg Wunsch if (sblock.fs_minfree < MINFREE && 29916a7269eSJoerg Wunsch sblock.fs_optim == FS_OPTTIME) 30016a7269eSJoerg Wunsch warnx(OPTWARN, "space", "<", MINFREE); 30116a7269eSJoerg Wunsch } 30216a7269eSJoerg Wunsch 30316a7269eSJoerg Wunsch void 3048fae3551SRodney W. Grimes bwrite(blk, buf, size) 3058fae3551SRodney W. Grimes daddr_t blk; 3068fae3551SRodney W. Grimes char *buf; 3078fae3551SRodney W. Grimes int size; 3088fae3551SRodney W. Grimes { 3098fae3551SRodney W. Grimes 3108fae3551SRodney W. Grimes if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0) 3118fae3551SRodney W. Grimes err(6, "FS SEEK"); 3128fae3551SRodney W. Grimes if (write(fi, buf, size) != size) 3138fae3551SRodney W. Grimes err(7, "FS WRITE"); 3148fae3551SRodney W. Grimes } 3158fae3551SRodney W. Grimes 3168fae3551SRodney W. Grimes int 3178fae3551SRodney W. Grimes bread(bno, buf, cnt) 3188fae3551SRodney W. Grimes daddr_t bno; 3198fae3551SRodney W. Grimes char *buf; 3208fae3551SRodney W. Grimes int cnt; 3218fae3551SRodney W. Grimes { 3228fae3551SRodney W. Grimes int i; 3238fae3551SRodney W. Grimes 3248fae3551SRodney W. Grimes if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0) 3258fae3551SRodney W. Grimes return(1); 3268fae3551SRodney W. Grimes if ((i = read(fi, buf, cnt)) != cnt) { 3278fae3551SRodney W. Grimes for(i=0; i<sblock.fs_bsize; i++) 3288fae3551SRodney W. Grimes buf[i] = 0; 3298fae3551SRodney W. Grimes return (1); 3308fae3551SRodney W. Grimes } 3318fae3551SRodney W. Grimes return (0); 3328fae3551SRodney W. Grimes } 333