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.1 (Berkeley) 05/28/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 char device[MAXPATHLEN]; 46 extern char *sprintf(); 47 struct fstab *fs; 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 continue; 136 137 default: 138 fatal("-%c: unknown flag", *cp); 139 } 140 } 141 if (argc != 1) 142 goto usage; 143 bwrite(SBLOCK, (char *)&sblock, SBSIZE); 144 if (Aflag) 145 for (i = 0; i < sblock.fs_ncg; i++) 146 bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 147 (char *)&sblock, SBSIZE); 148 close(fi); 149 exit(0); 150 usage: 151 fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 152 fprintf(stderr, "where tuneup-options are:\n"); 153 fprintf(stderr, "\t-a maximum contiguous blocks\n"); 154 fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 155 fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 156 fprintf(stderr, "\t-m minimum percentage of free space\n"); 157 exit(2); 158 } 159 160 getsb(fs, file) 161 register struct fs *fs; 162 char *file; 163 { 164 165 fi = open(file, 2); 166 if (fi < 0) { 167 fprintf(stderr, "cannot open"); 168 perror(file); 169 exit(3); 170 } 171 if (bread(SBLOCK, (char *)fs, SBSIZE)) { 172 fprintf(stderr, "bad super block"); 173 perror(file); 174 exit(4); 175 } 176 if (fs->fs_magic != FS_MAGIC) { 177 fprintf(stderr, "%s: bad magic number\n", file); 178 exit(5); 179 } 180 } 181 182 bwrite(blk, buf, size) 183 char *buf; 184 daddr_t blk; 185 register size; 186 { 187 if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 188 perror("FS SEEK"); 189 exit(6); 190 } 191 if (write(fi, buf, size) != size) { 192 perror("FS WRITE"); 193 exit(7); 194 } 195 } 196 197 bread(bno, buf, cnt) 198 daddr_t bno; 199 char *buf; 200 { 201 register i; 202 203 if (lseek(fi, bno * DEV_BSIZE, 0) < 0) 204 return(1); 205 if ((i = read(fi, buf, cnt)) != cnt) { 206 for(i=0; i<sblock.fs_bsize; i++) 207 buf[i] = 0; 208 return (1); 209 } 210 return (0); 211 } 212 213 /* VARARGS1 */ 214 fatal(fmt, arg1, arg2) 215 char *fmt, *arg1, *arg2; 216 { 217 218 fprintf(stderr, "tunefs: "); 219 fprintf(stderr, fmt, arg1, arg2); 220 putc('\n', stderr); 221 exit(10); 222 } 223