Commit | Line | Data |
---|---|---|
8c5eec2f | 1 | /* |
d4ff4eac KB |
2 | * Copyright (c) 1983, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
60e33d38 | 4 | * |
d60d530a | 5 | * %sccs.include.redist.c% |
8c5eec2f DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
d4ff4eac KB |
9 | static char copyright[] = |
10 | "@(#) Copyright (c) 1983, 1993\n\ | |
11 | The Regents of the University of California. All rights reserved.\n"; | |
60e33d38 | 12 | #endif /* not lint */ |
8c5eec2f | 13 | |
029a3235 | 14 | #ifndef lint |
de3fa65d | 15 | static char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) %G%"; |
60e33d38 | 16 | #endif /* not lint */ |
029a3235 KM |
17 | |
18 | /* | |
19 | * tunefs: change layout parameters to an existing file system. | |
20 | */ | |
029a3235 KM |
21 | #include <sys/param.h> |
22 | #include <sys/stat.h> | |
cd2ee753 | 23 | |
54e63ce6 | 24 | #include <ufs/ffs/fs.h> |
cd2ee753 KB |
25 | |
26 | #include <errno.h> | |
de3fa65d KM |
27 | #include <err.h> |
28 | #include <fcntl.h> | |
90354149 | 29 | #include <fstab.h> |
7abf8d65 KB |
30 | #include <stdio.h> |
31 | #include <paths.h> | |
de3fa65d KM |
32 | #include <stdlib.h> |
33 | #include <unistd.h> | |
34 | ||
35 | /* the optimization warning string template */ | |
36 | #define OPTWARN "should optimize for %s with minfree %s %d%%" | |
90354149 | 37 | |
029a3235 KM |
38 | union { |
39 | struct fs sb; | |
40 | char pad[MAXBSIZE]; | |
41 | } sbun; | |
42 | #define sblock sbun.sb | |
43 | ||
44 | int fi; | |
a66ab591 | 45 | long dev_bsize = 1; |
029a3235 | 46 | |
de3fa65d KM |
47 | void bwrite(daddr_t, char *, int); |
48 | int bread(daddr_t, char *, int); | |
49 | void getsb(struct fs *, char *); | |
50 | void usage __P((void)); | |
51 | ||
52 | int | |
029a3235 KM |
53 | main(argc, argv) |
54 | int argc; | |
55 | char *argv[]; | |
56 | { | |
57 | char *cp, *special, *name; | |
58 | struct stat st; | |
59 | int i; | |
60 | int Aflag = 0; | |
90354149 | 61 | struct fstab *fs; |
39fe0dd1 | 62 | char *chg[2], device[MAXPATHLEN]; |
029a3235 KM |
63 | |
64 | argc--, argv++; | |
65 | if (argc < 2) | |
de3fa65d | 66 | usage(); |
029a3235 | 67 | special = argv[argc - 1]; |
90354149 SL |
68 | fs = getfsfile(special); |
69 | if (fs) | |
70 | special = fs->fs_spec; | |
029a3235 KM |
71 | again: |
72 | if (stat(special, &st) < 0) { | |
73 | if (*special != '/') { | |
74 | if (*special == 'r') | |
75 | special++; | |
7abf8d65 | 76 | (void)sprintf(device, "%s/%s", _PATH_DEV, special); |
9bd38ba8 | 77 | special = device; |
029a3235 KM |
78 | goto again; |
79 | } | |
de3fa65d | 80 | err(1, "%s", special); |
029a3235 KM |
81 | } |
82 | if ((st.st_mode & S_IFMT) != S_IFBLK && | |
83 | (st.st_mode & S_IFMT) != S_IFCHR) | |
de3fa65d | 84 | errx(10, "%s: not a block or character device", special); |
029a3235 KM |
85 | getsb(&sblock, special); |
86 | for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { | |
87 | for (cp = &argv[0][1]; *cp; cp++) | |
88 | switch (*cp) { | |
89 | ||
90 | case 'A': | |
91 | Aflag++; | |
92 | continue; | |
93 | ||
94 | case 'a': | |
95 | name = "maximum contiguous block count"; | |
96 | if (argc < 1) | |
de3fa65d | 97 | errx(10, "-a: missing %s", name); |
029a3235 KM |
98 | argc--, argv++; |
99 | i = atoi(*argv); | |
100 | if (i < 1) | |
de3fa65d KM |
101 | errx(10, "%s must be >= 1 (was %s)", |
102 | name, *argv); | |
103 | warnx("%s changes from %d to %d", | |
104 | name, sblock.fs_maxcontig, i); | |
029a3235 KM |
105 | sblock.fs_maxcontig = i; |
106 | continue; | |
107 | ||
108 | case 'd': | |
109 | name = | |
110 | "rotational delay between contiguous blocks"; | |
111 | if (argc < 1) | |
de3fa65d | 112 | errx(10, "-d: missing %s", name); |
029a3235 KM |
113 | argc--, argv++; |
114 | i = atoi(*argv); | |
de3fa65d KM |
115 | warnx("%s changes from %dms to %dms", |
116 | name, sblock.fs_rotdelay, i); | |
029a3235 KM |
117 | sblock.fs_rotdelay = i; |
118 | continue; | |
119 | ||
120 | case 'e': | |
121 | name = | |
122 | "maximum blocks per file in a cylinder group"; | |
123 | if (argc < 1) | |
de3fa65d | 124 | errx(10, "-e: missing %s", name); |
029a3235 KM |
125 | argc--, argv++; |
126 | i = atoi(*argv); | |
127 | if (i < 1) | |
de3fa65d KM |
128 | errx(10, "%s must be >= 1 (was %s)", |
129 | name, *argv); | |
130 | warnx("%s changes from %d to %d", | |
131 | name, sblock.fs_maxbpg, i); | |
029a3235 KM |
132 | sblock.fs_maxbpg = i; |
133 | continue; | |
134 | ||
135 | case 'm': | |
136 | name = "minimum percentage of free space"; | |
137 | if (argc < 1) | |
de3fa65d | 138 | errx(10, "-m: missing %s", name); |
029a3235 KM |
139 | argc--, argv++; |
140 | i = atoi(*argv); | |
141 | if (i < 0 || i > 99) | |
de3fa65d KM |
142 | errx(10, "bad %s (%s)", name, *argv); |
143 | warnx("%s changes from %d%% to %d%%", | |
144 | name, sblock.fs_minfree, i); | |
029a3235 | 145 | sblock.fs_minfree = i; |
de3fa65d KM |
146 | if (i >= MINFREE && |
147 | sblock.fs_optim == FS_OPTSPACE) | |
148 | warnx(OPTWARN, "time", ">=", MINFREE); | |
149 | if (i < MINFREE && | |
150 | sblock.fs_optim == FS_OPTTIME) | |
151 | warnx(OPTWARN, "space", "<", MINFREE); | |
029a3235 KM |
152 | continue; |
153 | ||
39fe0dd1 KM |
154 | case 'o': |
155 | name = "optimization preference"; | |
156 | if (argc < 1) | |
de3fa65d | 157 | errx(10, "-o: missing %s", name); |
39fe0dd1 KM |
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 | |
de3fa65d KM |
166 | errx(10, "bad %s (options are `space' or `time')", |
167 | name); | |
39fe0dd1 | 168 | if (sblock.fs_optim == i) { |
de3fa65d KM |
169 | warnx("%s remains unchanged as %s", |
170 | name, chg[i]); | |
39fe0dd1 KM |
171 | continue; |
172 | } | |
de3fa65d KM |
173 | warnx("%s changes from %s to %s", |
174 | name, chg[sblock.fs_optim], chg[i]); | |
39fe0dd1 | 175 | sblock.fs_optim = i; |
de3fa65d KM |
176 | if (sblock.fs_minfree >= MINFREE && |
177 | i == FS_OPTSPACE) | |
178 | warnx(OPTWARN, "time", ">=", MINFREE); | |
179 | if (sblock.fs_minfree < MINFREE && | |
180 | i == FS_OPTTIME) | |
181 | warnx(OPTWARN, "space", "<", MINFREE); | |
39fe0dd1 KM |
182 | continue; |
183 | ||
029a3235 | 184 | default: |
de3fa65d | 185 | usage(); |
029a3235 KM |
186 | } |
187 | } | |
188 | if (argc != 1) | |
de3fa65d | 189 | usage(); |
e19619c1 | 190 | bwrite((daddr_t)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); | |
de3fa65d KM |
197 | } |
198 | ||
199 | void | |
200 | usage() | |
201 | { | |
202 | ||
029a3235 KM |
203 | fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); |
204 | fprintf(stderr, "where tuneup-options are:\n"); | |
1c04f08d | 205 | fprintf(stderr, "\t-a maximum contiguous blocks\n"); |
029a3235 KM |
206 | fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); |
207 | fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); | |
208 | fprintf(stderr, "\t-m minimum percentage of free space\n"); | |
39fe0dd1 | 209 | fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); |
029a3235 KM |
210 | exit(2); |
211 | } | |
212 | ||
de3fa65d | 213 | void |
029a3235 KM |
214 | getsb(fs, file) |
215 | register struct fs *fs; | |
216 | char *file; | |
217 | { | |
218 | ||
219 | fi = open(file, 2); | |
de3fa65d KM |
220 | if (fi < 0) |
221 | err(3, "cannot open %s", file); | |
222 | if (bread((daddr_t)SBOFF, (char *)fs, SBSIZE)) | |
223 | err(4, "%s: bad super block", file); | |
224 | if (fs->fs_magic != FS_MAGIC) | |
225 | err(5, "%s: bad magic number", file); | |
a66ab591 | 226 | dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); |
029a3235 KM |
227 | } |
228 | ||
de3fa65d | 229 | void |
029a3235 | 230 | bwrite(blk, buf, size) |
029a3235 | 231 | daddr_t blk; |
de3fa65d KM |
232 | char *buf; |
233 | int size; | |
029a3235 | 234 | { |
de3fa65d KM |
235 | |
236 | if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0) | |
237 | err(6, "FS SEEK"); | |
238 | if (write(fi, buf, size) != size) | |
239 | err(7, "FS WRITE"); | |
029a3235 KM |
240 | } |
241 | ||
de3fa65d | 242 | int |
029a3235 KM |
243 | bread(bno, buf, cnt) |
244 | daddr_t bno; | |
245 | char *buf; | |
de3fa65d | 246 | int cnt; |
029a3235 | 247 | { |
de3fa65d | 248 | int i; |
029a3235 | 249 | |
28251b07 | 250 | if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0) |
029a3235 KM |
251 | return(1); |
252 | if ((i = read(fi, buf, cnt)) != cnt) { | |
253 | for(i=0; i<sblock.fs_bsize; i++) | |
254 | buf[i] = 0; | |
255 | return (1); | |
256 | } | |
257 | return (0); | |
258 | } |