need init of fromlen once per loop
[unix-history] / usr / src / sbin / tunefs / tunefs.c
CommitLineData
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
19char 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 25static 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
41union {
42 struct fs sb;
43 char pad[MAXBSIZE];
44} sbun;
45#define sblock sbun.sb
46
47int fi;
a66ab591 48long dev_bsize = 1;
029a3235
KM
49
50main(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
68again:
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);
199usage:
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
210getsb(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
233bwrite(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
248bread(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 */
265fatal(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}