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