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