1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)tunefs.c 5.3 (Berkeley) 9/11/85"; 15: #endif not lint 16: 17: /* 18: * tunefs: change layout parameters to an existing file system. 19: */ 20: 21: #include <sys/param.h> 22: #include <sys/stat.h> 23: #include <sys/fs.h> 24: #include <sys/inode.h> 25: 26: #include <stdio.h> 27: #include <fstab.h> 28: 29: union { 30: struct fs sb; 31: char pad[MAXBSIZE]; 32: } sbun; 33: #define sblock sbun.sb 34: 35: int fi; 36: 37: main(argc, argv) 38: int argc; 39: char *argv[]; 40: { 41: char *cp, *special, *name; 42: struct stat st; 43: int i; 44: int Aflag = 0; 45: struct fstab *fs; 46: char *chg[2], device[MAXPATHLEN]; 47: extern char *sprintf(); 48: 49: argc--, argv++; 50: if (argc < 2) 51: goto usage; 52: special = argv[argc - 1]; 53: fs = getfsfile(special); 54: if (fs) 55: special = fs->fs_spec; 56: again: 57: if (stat(special, &st) < 0) { 58: if (*special != '/') { 59: if (*special == 'r') 60: special++; 61: special = sprintf(device, "/dev/%s", special); 62: goto again; 63: } 64: fprintf(stderr, "tunefs: "); perror(special); 65: exit(1); 66: } 67: if ((st.st_mode & S_IFMT) != S_IFBLK && 68: (st.st_mode & S_IFMT) != S_IFCHR) 69: fatal("%s: not a block or character device", special); 70: getsb(&sblock, special); 71: for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 72: for (cp = &argv[0][1]; *cp; cp++) 73: switch (*cp) { 74: 75: case 'A': 76: Aflag++; 77: continue; 78: 79: case 'a': 80: name = "maximum contiguous block count"; 81: if (argc < 1) 82: fatal("-a: missing %s", name); 83: argc--, argv++; 84: i = atoi(*argv); 85: if (i < 1) 86: fatal("%s: %s must be >= 1", 87: *argv, name); 88: fprintf(stdout, "%s changes from %d to %d\n", 89: name, sblock.fs_maxcontig, i); 90: sblock.fs_maxcontig = i; 91: continue; 92: 93: case 'd': 94: name = 95: "rotational delay between contiguous blocks"; 96: if (argc < 1) 97: fatal("-d: missing %s", name); 98: argc--, argv++; 99: i = atoi(*argv); 100: if (i < 0) 101: fatal("%s: bad %s", *argv, name); 102: fprintf(stdout, 103: "%s changes from %dms to %dms\n", 104: name, sblock.fs_rotdelay, i); 105: sblock.fs_rotdelay = i; 106: continue; 107: 108: case 'e': 109: name = 110: "maximum blocks per file in a cylinder group"; 111: if (argc < 1) 112: fatal("-e: missing %s", name); 113: argc--, argv++; 114: i = atoi(*argv); 115: if (i < 1) 116: fatal("%s: %s must be >= 1", 117: *argv, name); 118: fprintf(stdout, "%s changes from %d to %d\n", 119: name, sblock.fs_maxbpg, i); 120: sblock.fs_maxbpg = i; 121: continue; 122: 123: case 'm': 124: name = "minimum percentage of free space"; 125: if (argc < 1) 126: fatal("-m: missing %s", name); 127: argc--, argv++; 128: i = atoi(*argv); 129: if (i < 0 || i > 99) 130: fatal("%s: bad %s", *argv, name); 131: fprintf(stdout, 132: "%s changes from %d%% to %d%%\n", 133: name, sblock.fs_minfree, i); 134: sblock.fs_minfree = i; 135: if (i >= 10 && sblock.fs_optim == FS_OPTSPACE) 136: fprintf(stdout, "should optimize %s", 137: "for time with minfree >= 10%\n"); 138: if (i < 10 && sblock.fs_optim == FS_OPTTIME) 139: fprintf(stdout, "should optimize %s", 140: "for space with minfree < 10%\n"); 141: continue; 142: 143: case 'o': 144: name = "optimization preference"; 145: if (argc < 1) 146: fatal("-o: missing %s", name); 147: argc--, argv++; 148: chg[FS_OPTSPACE] = "space"; 149: chg[FS_OPTTIME] = "time"; 150: if (strcmp(*argv, chg[FS_OPTSPACE]) == 0) 151: i = FS_OPTSPACE; 152: else if (strcmp(*argv, chg[FS_OPTTIME]) == 0) 153: i = FS_OPTTIME; 154: else 155: fatal("%s: bad %s (options are `space' or `time')", 156: *argv, name); 157: if (sblock.fs_optim == i) { 158: fprintf(stdout, 159: "%s remains unchanged as %s\n", 160: name, chg[i]); 161: continue; 162: } 163: fprintf(stdout, 164: "%s changes from %s to %s\n", 165: name, chg[sblock.fs_optim], chg[i]); 166: sblock.fs_optim = i; 167: if (sblock.fs_minfree >= 10 && i == FS_OPTSPACE) 168: fprintf(stdout, "should optimize %s", 169: "for time with minfree >= 10%\n"); 170: if (sblock.fs_minfree < 10 && i == FS_OPTTIME) 171: fprintf(stdout, "should optimize %s", 172: "for space with minfree < 10%\n"); 173: continue; 174: 175: default: 176: fatal("-%c: unknown flag", *cp); 177: } 178: } 179: if (argc != 1) 180: goto usage; 181: bwrite(SBLOCK, (char *)&sblock, SBSIZE); 182: if (Aflag) 183: for (i = 0; i < sblock.fs_ncg; i++) 184: bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 185: (char *)&sblock, SBSIZE); 186: close(fi); 187: exit(0); 188: usage: 189: fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 190: fprintf(stderr, "where tuneup-options are:\n"); 191: fprintf(stderr, "\t-a maximum contiguous blocks\n"); 192: fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 193: fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 194: fprintf(stderr, "\t-m minimum percentage of free space\n"); 195: fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 196: exit(2); 197: } 198: 199: getsb(fs, file) 200: register struct fs *fs; 201: char *file; 202: { 203: 204: fi = open(file, 2); 205: if (fi < 0) { 206: fprintf(stderr, "cannot open"); 207: perror(file); 208: exit(3); 209: } 210: if (bread(SBLOCK, (char *)fs, SBSIZE)) { 211: fprintf(stderr, "bad super block"); 212: perror(file); 213: exit(4); 214: } 215: if (fs->fs_magic != FS_MAGIC) { 216: fprintf(stderr, "%s: bad magic number\n", file); 217: exit(5); 218: } 219: } 220: 221: bwrite(blk, buf, size) 222: char *buf; 223: daddr_t blk; 224: register size; 225: { 226: if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 227: perror("FS SEEK"); 228: exit(6); 229: } 230: if (write(fi, buf, size) != size) { 231: perror("FS WRITE"); 232: exit(7); 233: } 234: } 235: 236: bread(bno, buf, cnt) 237: daddr_t bno; 238: char *buf; 239: { 240: register i; 241: 242: if (lseek(fi, bno * DEV_BSIZE, 0) < 0) 243: return(1); 244: if ((i = read(fi, buf, cnt)) != cnt) { 245: for(i=0; i<sblock.fs_bsize; i++) 246: buf[i] = 0; 247: return (1); 248: } 249: return (0); 250: } 251: 252: /* VARARGS1 */ 253: fatal(fmt, arg1, arg2) 254: char *fmt, *arg1, *arg2; 255: { 256: 257: fprintf(stderr, "tunefs: "); 258: fprintf(stderr, fmt, arg1, arg2); 259: putc('\n', stderr); 260: exit(10); 261: }