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