Commit | Line | Data |
---|---|---|
8c5eec2f | 1 | /* |
60e33d38 KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that the above copyright notice and this paragraph are | |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
8c5eec2f DF |
16 | */ |
17 | ||
18 | #ifndef lint | |
19 | char copyright[] = | |
60e33d38 | 20 | "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ |
8c5eec2f | 21 | All rights reserved.\n"; |
60e33d38 | 22 | #endif /* not lint */ |
8c5eec2f | 23 | |
029a3235 | 24 | #ifndef lint |
aed516fd | 25 | static char sccsid[] = "@(#)tunefs.c 5.9 (Berkeley) %G%"; |
60e33d38 | 26 | #endif /* not lint */ |
029a3235 KM |
27 | |
28 | /* | |
29 | * tunefs: change layout parameters to an existing file system. | |
30 | */ | |
029a3235 KM |
31 | #include <sys/param.h> |
32 | #include <sys/stat.h> | |
aed516fd KB |
33 | #include <sys/time.h> |
34 | #include <sys/vnode.h> | |
35 | #include <ufs/inode.h> | |
36 | #include <ufs/fs.h> | |
90354149 | 37 | #include <fstab.h> |
7abf8d65 KB |
38 | #include <stdio.h> |
39 | #include <paths.h> | |
90354149 | 40 | |
029a3235 KM |
41 | union { |
42 | struct fs sb; | |
43 | char pad[MAXBSIZE]; | |
44 | } sbun; | |
45 | #define sblock sbun.sb | |
46 | ||
47 | int fi; | |
a66ab591 | 48 | long dev_bsize = 1; |
029a3235 KM |
49 | |
50 | main(argc, argv) | |
51 | int argc; | |
52 | char *argv[]; | |
53 | { | |
54 | char *cp, *special, *name; | |
55 | struct stat st; | |
56 | int i; | |
57 | int Aflag = 0; | |
90354149 | 58 | struct fstab *fs; |
39fe0dd1 | 59 | char *chg[2], device[MAXPATHLEN]; |
029a3235 KM |
60 | |
61 | argc--, argv++; | |
62 | if (argc < 2) | |
63 | goto usage; | |
64 | special = argv[argc - 1]; | |
90354149 SL |
65 | fs = getfsfile(special); |
66 | if (fs) | |
67 | special = fs->fs_spec; | |
029a3235 KM |
68 | again: |
69 | if (stat(special, &st) < 0) { | |
70 | if (*special != '/') { | |
71 | if (*special == 'r') | |
72 | special++; | |
7abf8d65 | 73 | (void)sprintf(device, "%s/%s", _PATH_DEV, special); |
9bd38ba8 | 74 | special = device; |
029a3235 KM |
75 | goto again; |
76 | } | |
77 | fprintf(stderr, "tunefs: "); perror(special); | |
78 | exit(1); | |
79 | } | |
80 | if ((st.st_mode & S_IFMT) != S_IFBLK && | |
81 | (st.st_mode & S_IFMT) != S_IFCHR) | |
82 | fatal("%s: not a block or character device", special); | |
83 | getsb(&sblock, special); | |
84 | for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { | |
85 | for (cp = &argv[0][1]; *cp; cp++) | |
86 | switch (*cp) { | |
87 | ||
88 | case 'A': | |
89 | Aflag++; | |
90 | continue; | |
91 | ||
92 | case 'a': | |
93 | name = "maximum contiguous block count"; | |
94 | if (argc < 1) | |
95 | fatal("-a: missing %s", name); | |
96 | argc--, argv++; | |
97 | i = atoi(*argv); | |
98 | if (i < 1) | |
99 | fatal("%s: %s must be >= 1", | |
100 | *argv, name); | |
101 | fprintf(stdout, "%s changes from %d to %d\n", | |
102 | name, sblock.fs_maxcontig, i); | |
103 | sblock.fs_maxcontig = i; | |
104 | continue; | |
105 | ||
106 | case 'd': | |
107 | name = | |
108 | "rotational delay between contiguous blocks"; | |
109 | if (argc < 1) | |
110 | fatal("-d: missing %s", name); | |
111 | argc--, argv++; | |
112 | i = atoi(*argv); | |
029a3235 KM |
113 | fprintf(stdout, |
114 | "%s changes from %dms to %dms\n", | |
115 | name, sblock.fs_rotdelay, i); | |
116 | sblock.fs_rotdelay = i; | |
117 | continue; | |
118 | ||
119 | case 'e': | |
120 | name = | |
121 | "maximum blocks per file in a cylinder group"; | |
122 | if (argc < 1) | |
123 | fatal("-e: missing %s", name); | |
124 | argc--, argv++; | |
125 | i = atoi(*argv); | |
126 | if (i < 1) | |
127 | fatal("%s: %s must be >= 1", | |
128 | *argv, name); | |
129 | fprintf(stdout, "%s changes from %d to %d\n", | |
130 | name, sblock.fs_maxbpg, i); | |
131 | sblock.fs_maxbpg = i; | |
132 | continue; | |
133 | ||
134 | case 'm': | |
135 | name = "minimum percentage of free space"; | |
136 | if (argc < 1) | |
137 | fatal("-m: missing %s", name); | |
138 | argc--, argv++; | |
139 | i = atoi(*argv); | |
140 | if (i < 0 || i > 99) | |
141 | fatal("%s: bad %s", *argv, name); | |
142 | fprintf(stdout, | |
143 | "%s changes from %d%% to %d%%\n", | |
144 | name, sblock.fs_minfree, i); | |
145 | sblock.fs_minfree = i; | |
509355c0 KM |
146 | if (i >= 10 && sblock.fs_optim == FS_OPTSPACE) |
147 | fprintf(stdout, "should optimize %s", | |
148 | "for time with minfree >= 10%\n"); | |
149 | if (i < 10 && sblock.fs_optim == FS_OPTTIME) | |
150 | fprintf(stdout, "should optimize %s", | |
151 | "for space with minfree < 10%\n"); | |
029a3235 KM |
152 | continue; |
153 | ||
39fe0dd1 KM |
154 | case 'o': |
155 | name = "optimization preference"; | |
156 | if (argc < 1) | |
157 | fatal("-o: missing %s", name); | |
158 | argc--, argv++; | |
159 | chg[FS_OPTSPACE] = "space"; | |
160 | chg[FS_OPTTIME] = "time"; | |
161 | if (strcmp(*argv, chg[FS_OPTSPACE]) == 0) | |
162 | i = FS_OPTSPACE; | |
163 | else if (strcmp(*argv, chg[FS_OPTTIME]) == 0) | |
164 | i = FS_OPTTIME; | |
165 | else | |
166 | fatal("%s: bad %s (options are `space' or `time')", | |
167 | *argv, name); | |
168 | if (sblock.fs_optim == i) { | |
169 | fprintf(stdout, | |
170 | "%s remains unchanged as %s\n", | |
171 | name, chg[i]); | |
172 | continue; | |
173 | } | |
174 | fprintf(stdout, | |
175 | "%s changes from %s to %s\n", | |
176 | name, chg[sblock.fs_optim], chg[i]); | |
177 | sblock.fs_optim = i; | |
509355c0 KM |
178 | if (sblock.fs_minfree >= 10 && i == FS_OPTSPACE) |
179 | fprintf(stdout, "should optimize %s", | |
180 | "for time with minfree >= 10%\n"); | |
181 | if (sblock.fs_minfree < 10 && i == FS_OPTTIME) | |
182 | fprintf(stdout, "should optimize %s", | |
183 | "for space with minfree < 10%\n"); | |
39fe0dd1 KM |
184 | continue; |
185 | ||
029a3235 KM |
186 | default: |
187 | fatal("-%c: unknown flag", *cp); | |
188 | } | |
189 | } | |
190 | if (argc != 1) | |
191 | goto usage; | |
a66ab591 | 192 | bwrite(SBOFF / dev_bsize, (char *)&sblock, SBSIZE); |
029a3235 KM |
193 | if (Aflag) |
194 | for (i = 0; i < sblock.fs_ncg; i++) | |
195 | bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), | |
196 | (char *)&sblock, SBSIZE); | |
197 | close(fi); | |
198 | exit(0); | |
199 | usage: | |
200 | fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); | |
201 | fprintf(stderr, "where tuneup-options are:\n"); | |
1c04f08d | 202 | fprintf(stderr, "\t-a maximum contiguous blocks\n"); |
029a3235 KM |
203 | fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); |
204 | fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); | |
205 | fprintf(stderr, "\t-m minimum percentage of free space\n"); | |
39fe0dd1 | 206 | fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); |
029a3235 KM |
207 | exit(2); |
208 | } | |
209 | ||
210 | getsb(fs, file) | |
211 | register struct fs *fs; | |
212 | char *file; | |
213 | { | |
214 | ||
215 | fi = open(file, 2); | |
216 | if (fi < 0) { | |
217 | fprintf(stderr, "cannot open"); | |
218 | perror(file); | |
219 | exit(3); | |
220 | } | |
a66ab591 | 221 | if (bread(SBOFF, (char *)fs, SBSIZE)) { |
029a3235 KM |
222 | fprintf(stderr, "bad super block"); |
223 | perror(file); | |
224 | exit(4); | |
225 | } | |
226 | if (fs->fs_magic != FS_MAGIC) { | |
227 | fprintf(stderr, "%s: bad magic number\n", file); | |
228 | exit(5); | |
229 | } | |
a66ab591 | 230 | dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); |
029a3235 KM |
231 | } |
232 | ||
233 | bwrite(blk, buf, size) | |
234 | char *buf; | |
235 | daddr_t blk; | |
236 | register size; | |
237 | { | |
a66ab591 | 238 | if (lseek(fi, blk * dev_bsize, 0) < 0) { |
029a3235 KM |
239 | perror("FS SEEK"); |
240 | exit(6); | |
241 | } | |
242 | if (write(fi, buf, size) != size) { | |
243 | perror("FS WRITE"); | |
244 | exit(7); | |
245 | } | |
246 | } | |
247 | ||
248 | bread(bno, buf, cnt) | |
249 | daddr_t bno; | |
250 | char *buf; | |
251 | { | |
252 | register i; | |
253 | ||
a66ab591 | 254 | if (lseek(fi, bno * dev_bsize, 0) < 0) |
029a3235 KM |
255 | return(1); |
256 | if ((i = read(fi, buf, cnt)) != cnt) { | |
257 | for(i=0; i<sblock.fs_bsize; i++) | |
258 | buf[i] = 0; | |
259 | return (1); | |
260 | } | |
261 | return (0); | |
262 | } | |
263 | ||
264 | /* VARARGS1 */ | |
265 | fatal(fmt, arg1, arg2) | |
266 | char *fmt, *arg1, *arg2; | |
267 | { | |
268 | ||
fbe74678 | 269 | fprintf(stderr, "tunefs: "); |
029a3235 KM |
270 | fprintf(stderr, fmt, arg1, arg2); |
271 | putc('\n', stderr); | |
272 | exit(10); | |
273 | } |