tunefs.c revision 9315
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1983, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 351558Srgrimesstatic char copyright[] = 361558Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 371558Srgrimes The Regents of the University of California. All rights reserved.\n"; 381558Srgrimes#endif /* not lint */ 391558Srgrimes 401558Srgrimes#ifndef lint 411558Srgrimesstatic char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) 4/19/94"; 421558Srgrimes#endif /* not lint */ 431558Srgrimes 441558Srgrimes/* 451558Srgrimes * tunefs: change layout parameters to an existing file system. 461558Srgrimes */ 471558Srgrimes#include <sys/param.h> 481558Srgrimes#include <sys/stat.h> 491558Srgrimes 501558Srgrimes#include <ufs/ffs/fs.h> 511558Srgrimes 521558Srgrimes#include <errno.h> 531558Srgrimes#include <err.h> 541558Srgrimes#include <fcntl.h> 551558Srgrimes#include <fstab.h> 561558Srgrimes#include <stdio.h> 571558Srgrimes#include <paths.h> 581558Srgrimes#include <stdlib.h> 591558Srgrimes#include <unistd.h> 601558Srgrimes 611558Srgrimes/* the optimization warning string template */ 621558Srgrimes#define OPTWARN "should optimize for %s with minfree %s %d%%" 631558Srgrimes 641558Srgrimesunion { 651558Srgrimes struct fs sb; 661558Srgrimes char pad[MAXBSIZE]; 671558Srgrimes} sbun; 681558Srgrimes#define sblock sbun.sb 691558Srgrimes 701558Srgrimesint fi; 711558Srgrimeslong dev_bsize = 1; 721558Srgrimes 731558Srgrimesvoid bwrite(daddr_t, char *, int); 741558Srgrimesint bread(daddr_t, char *, int); 751558Srgrimesvoid getsb(struct fs *, char *); 761558Srgrimesvoid usage __P((void)); 779315Sjoergvoid printfs __P((void)); 781558Srgrimes 791558Srgrimesint 801558Srgrimesmain(argc, argv) 811558Srgrimes int argc; 821558Srgrimes char *argv[]; 831558Srgrimes{ 841558Srgrimes char *cp, *special, *name; 851558Srgrimes struct stat st; 861558Srgrimes int i; 871558Srgrimes int Aflag = 0; 881558Srgrimes struct fstab *fs; 891558Srgrimes char *chg[2], device[MAXPATHLEN]; 901558Srgrimes 918871Srgrimes argc--, argv++; 921558Srgrimes if (argc < 2) 931558Srgrimes usage(); 941558Srgrimes special = argv[argc - 1]; 951558Srgrimes fs = getfsfile(special); 961558Srgrimes if (fs) 971558Srgrimes special = fs->fs_spec; 981558Srgrimesagain: 991558Srgrimes if (stat(special, &st) < 0) { 1001558Srgrimes if (*special != '/') { 1011558Srgrimes if (*special == 'r') 1021558Srgrimes special++; 1031558Srgrimes (void)sprintf(device, "%s/%s", _PATH_DEV, special); 1041558Srgrimes special = device; 1051558Srgrimes goto again; 1061558Srgrimes } 1071558Srgrimes err(1, "%s", special); 1081558Srgrimes } 1091558Srgrimes if ((st.st_mode & S_IFMT) != S_IFBLK && 1101558Srgrimes (st.st_mode & S_IFMT) != S_IFCHR) 1111558Srgrimes errx(10, "%s: not a block or character device", special); 1121558Srgrimes getsb(&sblock, special); 1131558Srgrimes for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 1141558Srgrimes for (cp = &argv[0][1]; *cp; cp++) 1151558Srgrimes switch (*cp) { 1161558Srgrimes 1171558Srgrimes case 'A': 1181558Srgrimes Aflag++; 1191558Srgrimes continue; 1201558Srgrimes 1219315Sjoerg case 'p': 1229315Sjoerg printfs(); 1239315Sjoerg exit(0); 1249315Sjoerg 1251558Srgrimes case 'a': 1261558Srgrimes name = "maximum contiguous block count"; 1271558Srgrimes if (argc < 1) 1281558Srgrimes errx(10, "-a: missing %s", name); 1291558Srgrimes argc--, argv++; 1301558Srgrimes i = atoi(*argv); 1311558Srgrimes if (i < 1) 1321558Srgrimes errx(10, "%s must be >= 1 (was %s)", 1331558Srgrimes name, *argv); 1341558Srgrimes warnx("%s changes from %d to %d", 1351558Srgrimes name, sblock.fs_maxcontig, i); 1361558Srgrimes sblock.fs_maxcontig = i; 1371558Srgrimes continue; 1381558Srgrimes 1391558Srgrimes case 'd': 1401558Srgrimes name = 1411558Srgrimes "rotational delay between contiguous blocks"; 1421558Srgrimes if (argc < 1) 1431558Srgrimes errx(10, "-d: missing %s", name); 1441558Srgrimes argc--, argv++; 1451558Srgrimes i = atoi(*argv); 1461558Srgrimes warnx("%s changes from %dms to %dms", 1471558Srgrimes name, sblock.fs_rotdelay, i); 1481558Srgrimes sblock.fs_rotdelay = i; 1491558Srgrimes continue; 1501558Srgrimes 1511558Srgrimes case 'e': 1521558Srgrimes name = 1531558Srgrimes "maximum blocks per file in a cylinder group"; 1541558Srgrimes if (argc < 1) 1551558Srgrimes errx(10, "-e: missing %s", name); 1561558Srgrimes argc--, argv++; 1571558Srgrimes i = atoi(*argv); 1581558Srgrimes if (i < 1) 1591558Srgrimes errx(10, "%s must be >= 1 (was %s)", 1601558Srgrimes name, *argv); 1611558Srgrimes warnx("%s changes from %d to %d", 1621558Srgrimes name, sblock.fs_maxbpg, i); 1631558Srgrimes sblock.fs_maxbpg = i; 1641558Srgrimes continue; 1651558Srgrimes 1661558Srgrimes case 'm': 1671558Srgrimes name = "minimum percentage of free space"; 1681558Srgrimes if (argc < 1) 1691558Srgrimes errx(10, "-m: missing %s", name); 1701558Srgrimes argc--, argv++; 1711558Srgrimes i = atoi(*argv); 1721558Srgrimes if (i < 0 || i > 99) 1731558Srgrimes errx(10, "bad %s (%s)", name, *argv); 1741558Srgrimes warnx("%s changes from %d%% to %d%%", 1751558Srgrimes name, sblock.fs_minfree, i); 1761558Srgrimes sblock.fs_minfree = i; 1771558Srgrimes if (i >= MINFREE && 1781558Srgrimes sblock.fs_optim == FS_OPTSPACE) 1791558Srgrimes warnx(OPTWARN, "time", ">=", MINFREE); 1801558Srgrimes if (i < MINFREE && 1811558Srgrimes sblock.fs_optim == FS_OPTTIME) 1821558Srgrimes warnx(OPTWARN, "space", "<", MINFREE); 1831558Srgrimes continue; 1841558Srgrimes 1851558Srgrimes case 'o': 1861558Srgrimes name = "optimization preference"; 1871558Srgrimes if (argc < 1) 1881558Srgrimes errx(10, "-o: missing %s", name); 1891558Srgrimes argc--, argv++; 1901558Srgrimes chg[FS_OPTSPACE] = "space"; 1911558Srgrimes chg[FS_OPTTIME] = "time"; 1921558Srgrimes if (strcmp(*argv, chg[FS_OPTSPACE]) == 0) 1931558Srgrimes i = FS_OPTSPACE; 1941558Srgrimes else if (strcmp(*argv, chg[FS_OPTTIME]) == 0) 1951558Srgrimes i = FS_OPTTIME; 1961558Srgrimes else 1971558Srgrimes errx(10, "bad %s (options are `space' or `time')", 1981558Srgrimes name); 1991558Srgrimes if (sblock.fs_optim == i) { 2001558Srgrimes warnx("%s remains unchanged as %s", 2011558Srgrimes name, chg[i]); 2021558Srgrimes continue; 2031558Srgrimes } 2041558Srgrimes warnx("%s changes from %s to %s", 2051558Srgrimes name, chg[sblock.fs_optim], chg[i]); 2061558Srgrimes sblock.fs_optim = i; 2071558Srgrimes if (sblock.fs_minfree >= MINFREE && 2081558Srgrimes i == FS_OPTSPACE) 2091558Srgrimes warnx(OPTWARN, "time", ">=", MINFREE); 2101558Srgrimes if (sblock.fs_minfree < MINFREE && 2111558Srgrimes i == FS_OPTTIME) 2121558Srgrimes warnx(OPTWARN, "space", "<", MINFREE); 2131558Srgrimes continue; 2141558Srgrimes 2151558Srgrimes default: 2161558Srgrimes usage(); 2171558Srgrimes } 2181558Srgrimes } 2191558Srgrimes if (argc != 1) 2201558Srgrimes usage(); 2211558Srgrimes bwrite((daddr_t)SBOFF / dev_bsize, (char *)&sblock, SBSIZE); 2221558Srgrimes if (Aflag) 2231558Srgrimes for (i = 0; i < sblock.fs_ncg; i++) 2241558Srgrimes bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 2251558Srgrimes (char *)&sblock, SBSIZE); 2261558Srgrimes close(fi); 2271558Srgrimes exit(0); 2281558Srgrimes} 2291558Srgrimes 2301558Srgrimesvoid 2311558Srgrimesusage() 2321558Srgrimes{ 2331558Srgrimes 2341558Srgrimes fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 2351558Srgrimes fprintf(stderr, "where tuneup-options are:\n"); 2361558Srgrimes fprintf(stderr, "\t-a maximum contiguous blocks\n"); 2371558Srgrimes fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 2381558Srgrimes fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 2391558Srgrimes fprintf(stderr, "\t-m minimum percentage of free space\n"); 2401558Srgrimes fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 2419315Sjoerg fprintf(stderr, "\t-p no change - just prints current tuneable settings\n"); 2421558Srgrimes exit(2); 2431558Srgrimes} 2441558Srgrimes 2451558Srgrimesvoid 2461558Srgrimesgetsb(fs, file) 2471558Srgrimes register struct fs *fs; 2481558Srgrimes char *file; 2491558Srgrimes{ 2501558Srgrimes 2511558Srgrimes fi = open(file, 2); 2521558Srgrimes if (fi < 0) 2531558Srgrimes err(3, "cannot open %s", file); 2541558Srgrimes if (bread((daddr_t)SBOFF, (char *)fs, SBSIZE)) 2551558Srgrimes err(4, "%s: bad super block", file); 2561558Srgrimes if (fs->fs_magic != FS_MAGIC) 2571558Srgrimes err(5, "%s: bad magic number", file); 2581558Srgrimes dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 2591558Srgrimes} 2601558Srgrimes 2611558Srgrimesvoid 2629315Sjoergprintfs() 2639315Sjoerg{ 2649315Sjoerg warnx("maximum contiguous block count: (-a) %d", 2659315Sjoerg sblock.fs_maxcontig); 2669315Sjoerg warnx("rotational delay between contiguous blocks: (-d) %d ms", 2679315Sjoerg sblock.fs_rotdelay); 2689315Sjoerg warnx("maximum blocks per file in a cylinder group: (-e) %d", 2699315Sjoerg sblock.fs_maxbpg); 2709315Sjoerg warnx("minimum percentage of free space: (-m) %d%%", 2719315Sjoerg sblock.fs_minfree); 2729315Sjoerg warnx("optimization preference: (-o) %s", 2739315Sjoerg sblock.fs_optim == FS_OPTSPACE ? "space" : "time"); 2749315Sjoerg if (sblock.fs_minfree >= MINFREE && 2759315Sjoerg sblock.fs_optim == FS_OPTSPACE) 2769315Sjoerg warnx(OPTWARN, "time", ">=", MINFREE); 2779315Sjoerg if (sblock.fs_minfree < MINFREE && 2789315Sjoerg sblock.fs_optim == FS_OPTTIME) 2799315Sjoerg warnx(OPTWARN, "space", "<", MINFREE); 2809315Sjoerg} 2819315Sjoerg 2829315Sjoergvoid 2831558Srgrimesbwrite(blk, buf, size) 2841558Srgrimes daddr_t blk; 2851558Srgrimes char *buf; 2861558Srgrimes int size; 2871558Srgrimes{ 2881558Srgrimes 2891558Srgrimes if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0) 2901558Srgrimes err(6, "FS SEEK"); 2911558Srgrimes if (write(fi, buf, size) != size) 2921558Srgrimes err(7, "FS WRITE"); 2931558Srgrimes} 2941558Srgrimes 2951558Srgrimesint 2961558Srgrimesbread(bno, buf, cnt) 2971558Srgrimes daddr_t bno; 2981558Srgrimes char *buf; 2991558Srgrimes int cnt; 3001558Srgrimes{ 3011558Srgrimes int i; 3021558Srgrimes 3031558Srgrimes if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0) 3041558Srgrimes return(1); 3051558Srgrimes if ((i = read(fi, buf, cnt)) != cnt) { 3061558Srgrimes for(i=0; i<sblock.fs_bsize; i++) 3071558Srgrimes buf[i] = 0; 3081558Srgrimes return (1); 3091558Srgrimes } 3101558Srgrimes return (0); 3111558Srgrimes} 312