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