upgraded to the latest NetBSD version
[unix-history] / usr / src / sbin / tunefs / tunefs.c
CommitLineData
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
9static 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 15static 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
38union {
39 struct fs sb;
40 char pad[MAXBSIZE];
41} sbun;
42#define sblock sbun.sb
43
44int fi;
a66ab591 45long dev_bsize = 1;
029a3235 46
de3fa65d
KM
47void bwrite(daddr_t, char *, int);
48int bread(daddr_t, char *, int);
49void getsb(struct fs *, char *);
50void usage __P((void));
51
52int
029a3235
KM
53main(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
71again:
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
199void
200usage()
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 213void
029a3235
KM
214getsb(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 229void
029a3235 230bwrite(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 242int
029a3235
KM
243bread(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}