allow negative rotational delays (for torek)
[unix-history] / usr / src / sbin / tunefs / tunefs.c
CommitLineData
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
8char 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 14static 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
29union {
30 struct fs sb;
31 char pad[MAXBSIZE];
32} sbun;
33#define sblock sbun.sb
34
35int fi;
a66ab591 36long dev_bsize = 1;
029a3235
KM
37
38main(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
56again:
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);
187usage:
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
198getsb(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
221bwrite(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
236bread(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 */
253fatal(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}