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