xref: /csrg-svn/sbin/tunefs/tunefs.c (revision 66924)
121184Sdist /*
261556Sbostic  * Copyright (c) 1983, 1993
361556Sbostic  *	The Regents of the University of California.  All rights reserved.
435484Sbostic  *
542712Sbostic  * %sccs.include.redist.c%
621184Sdist  */
721184Sdist 
811288Smckusick #ifndef lint
961556Sbostic static char copyright[] =
1061556Sbostic "@(#) Copyright (c) 1983, 1993\n\
1161556Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1235484Sbostic #endif /* not lint */
1311288Smckusick 
1421184Sdist #ifndef lint
15*66924Smckusick static char sccsid[] = "@(#)tunefs.c	8.2 (Berkeley) 04/19/94";
1635484Sbostic #endif /* not lint */
1721184Sdist 
1811288Smckusick /*
1911288Smckusick  * tunefs: change layout parameters to an existing file system.
2011288Smckusick  */
2111288Smckusick #include <sys/param.h>
2211288Smckusick #include <sys/stat.h>
2355660Sbostic 
2451624Sbostic #include <ufs/ffs/fs.h>
2555660Sbostic 
2655660Sbostic #include <errno.h>
27*66924Smckusick #include <err.h>
28*66924Smckusick #include <fcntl.h>
2937959Sbostic #include <fstab.h>
3013120Ssam #include <stdio.h>
3137959Sbostic #include <paths.h>
32*66924Smckusick #include <stdlib.h>
33*66924Smckusick #include <unistd.h>
3413120Ssam 
35*66924Smckusick /* the optimization warning string template */
36*66924Smckusick #define	OPTWARN	"should optimize for %s with minfree %s %d%%"
37*66924Smckusick 
3811288Smckusick union {
3911288Smckusick 	struct	fs sb;
4011288Smckusick 	char pad[MAXBSIZE];
4111288Smckusick } sbun;
4211288Smckusick #define	sblock sbun.sb
4311288Smckusick 
4411288Smckusick int fi;
4530558Smckusick long dev_bsize = 1;
4611288Smckusick 
47*66924Smckusick void bwrite(daddr_t, char *, int);
48*66924Smckusick int bread(daddr_t, char *, int);
49*66924Smckusick void getsb(struct fs *, char *);
50*66924Smckusick void usage __P((void));
51*66924Smckusick 
52*66924Smckusick int
5311288Smckusick main(argc, argv)
5411288Smckusick 	int argc;
5511288Smckusick 	char *argv[];
5611288Smckusick {
5711288Smckusick 	char *cp, *special, *name;
5811288Smckusick 	struct stat st;
5911288Smckusick 	int i;
6011288Smckusick 	int Aflag = 0;
6124700Smckusick 	struct fstab *fs;
6224700Smckusick 	char *chg[2], device[MAXPATHLEN];
6311288Smckusick 
6411288Smckusick 	argc--, argv++;
6511288Smckusick 	if (argc < 2)
66*66924Smckusick 		usage();
6711288Smckusick 	special = argv[argc - 1];
6813120Ssam 	fs = getfsfile(special);
6913120Ssam 	if (fs)
7013120Ssam 		special = fs->fs_spec;
7111288Smckusick again:
7211288Smckusick 	if (stat(special, &st) < 0) {
7311288Smckusick 		if (*special != '/') {
7411288Smckusick 			if (*special == 'r')
7511288Smckusick 				special++;
7637959Sbostic 			(void)sprintf(device, "%s/%s", _PATH_DEV, special);
7732453Sbostic 			special = device;
7811288Smckusick 			goto again;
7911288Smckusick 		}
80*66924Smckusick 		err(1, "%s", special);
8111288Smckusick 	}
8211288Smckusick 	if ((st.st_mode & S_IFMT) != S_IFBLK &&
8311288Smckusick 	    (st.st_mode & S_IFMT) != S_IFCHR)
84*66924Smckusick 		errx(10, "%s: not a block or character device", special);
8511288Smckusick 	getsb(&sblock, special);
8611288Smckusick 	for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
8711288Smckusick 		for (cp = &argv[0][1]; *cp; cp++)
8811288Smckusick 			switch (*cp) {
8911288Smckusick 
9011288Smckusick 			case 'A':
9111288Smckusick 				Aflag++;
9211288Smckusick 				continue;
9311288Smckusick 
9411288Smckusick 			case 'a':
9511288Smckusick 				name = "maximum contiguous block count";
9611288Smckusick 				if (argc < 1)
97*66924Smckusick 					errx(10, "-a: missing %s", name);
9811288Smckusick 				argc--, argv++;
9911288Smckusick 				i = atoi(*argv);
10011288Smckusick 				if (i < 1)
101*66924Smckusick 					errx(10, "%s must be >= 1 (was %s)",
102*66924Smckusick 					    name, *argv);
103*66924Smckusick 				warnx("%s changes from %d to %d",
104*66924Smckusick 				    name, sblock.fs_maxcontig, i);
10511288Smckusick 				sblock.fs_maxcontig = i;
10611288Smckusick 				continue;
10711288Smckusick 
10811288Smckusick 			case 'd':
10911288Smckusick 				name =
11011288Smckusick 				   "rotational delay between contiguous blocks";
11111288Smckusick 				if (argc < 1)
112*66924Smckusick 					errx(10, "-d: missing %s", name);
11311288Smckusick 				argc--, argv++;
11411288Smckusick 				i = atoi(*argv);
115*66924Smckusick 				warnx("%s changes from %dms to %dms",
116*66924Smckusick 				    name, sblock.fs_rotdelay, i);
11711288Smckusick 				sblock.fs_rotdelay = i;
11811288Smckusick 				continue;
11911288Smckusick 
12011288Smckusick 			case 'e':
12111288Smckusick 				name =
12211288Smckusick 				  "maximum blocks per file in a cylinder group";
12311288Smckusick 				if (argc < 1)
124*66924Smckusick 					errx(10, "-e: missing %s", name);
12511288Smckusick 				argc--, argv++;
12611288Smckusick 				i = atoi(*argv);
12711288Smckusick 				if (i < 1)
128*66924Smckusick 					errx(10, "%s must be >= 1 (was %s)",
129*66924Smckusick 					    name, *argv);
130*66924Smckusick 				warnx("%s changes from %d to %d",
131*66924Smckusick 				    name, sblock.fs_maxbpg, i);
13211288Smckusick 				sblock.fs_maxbpg = i;
13311288Smckusick 				continue;
13411288Smckusick 
13511288Smckusick 			case 'm':
13611288Smckusick 				name = "minimum percentage of free space";
13711288Smckusick 				if (argc < 1)
138*66924Smckusick 					errx(10, "-m: missing %s", name);
13911288Smckusick 				argc--, argv++;
14011288Smckusick 				i = atoi(*argv);
14111288Smckusick 				if (i < 0 || i > 99)
142*66924Smckusick 					errx(10, "bad %s (%s)", name, *argv);
143*66924Smckusick 				warnx("%s changes from %d%% to %d%%",
144*66924Smckusick 				    name, sblock.fs_minfree, i);
14511288Smckusick 				sblock.fs_minfree = i;
146*66924Smckusick 				if (i >= MINFREE &&
147*66924Smckusick 				    sblock.fs_optim == FS_OPTSPACE)
148*66924Smckusick 					warnx(OPTWARN, "time", ">=", MINFREE);
149*66924Smckusick 				if (i < MINFREE &&
150*66924Smckusick 				    sblock.fs_optim == FS_OPTTIME)
151*66924Smckusick 					warnx(OPTWARN, "space", "<", MINFREE);
15211288Smckusick 				continue;
15311288Smckusick 
15424700Smckusick 			case 'o':
15524700Smckusick 				name = "optimization preference";
15624700Smckusick 				if (argc < 1)
157*66924Smckusick 					errx(10, "-o: missing %s", name);
15824700Smckusick 				argc--, argv++;
15924700Smckusick 				chg[FS_OPTSPACE] = "space";
16024700Smckusick 				chg[FS_OPTTIME] = "time";
16124700Smckusick 				if (strcmp(*argv, chg[FS_OPTSPACE]) == 0)
16224700Smckusick 					i = FS_OPTSPACE;
16324700Smckusick 				else if (strcmp(*argv, chg[FS_OPTTIME]) == 0)
16424700Smckusick 					i = FS_OPTTIME;
16524700Smckusick 				else
166*66924Smckusick 					errx(10, "bad %s (options are `space' or `time')",
167*66924Smckusick 					    name);
16824700Smckusick 				if (sblock.fs_optim == i) {
169*66924Smckusick 					warnx("%s remains unchanged as %s",
170*66924Smckusick 					    name, chg[i]);
17124700Smckusick 					continue;
17224700Smckusick 				}
173*66924Smckusick 				warnx("%s changes from %s to %s",
174*66924Smckusick 				    name, chg[sblock.fs_optim], chg[i]);
17524700Smckusick 				sblock.fs_optim = i;
176*66924Smckusick 				if (sblock.fs_minfree >= MINFREE &&
177*66924Smckusick 				    i == FS_OPTSPACE)
178*66924Smckusick 					warnx(OPTWARN, "time", ">=", MINFREE);
179*66924Smckusick 				if (sblock.fs_minfree < MINFREE &&
180*66924Smckusick 				    i == FS_OPTTIME)
181*66924Smckusick 					warnx(OPTWARN, "space", "<", MINFREE);
18224700Smckusick 				continue;
18324700Smckusick 
18411288Smckusick 			default:
185*66924Smckusick 				usage();
18611288Smckusick 			}
18711288Smckusick 	}
18811288Smckusick 	if (argc != 1)
189*66924Smckusick 		usage();
19056210Shibler 	bwrite((daddr_t)SBOFF / dev_bsize, (char *)&sblock, SBSIZE);
19111288Smckusick 	if (Aflag)
19211288Smckusick 		for (i = 0; i < sblock.fs_ncg; i++)
19311288Smckusick 			bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)),
19411288Smckusick 			    (char *)&sblock, SBSIZE);
19511288Smckusick 	close(fi);
19611288Smckusick 	exit(0);
197*66924Smckusick }
198*66924Smckusick 
199*66924Smckusick void
200*66924Smckusick usage()
201*66924Smckusick {
202*66924Smckusick 
20311288Smckusick 	fprintf(stderr, "Usage: tunefs tuneup-options special-device\n");
20411288Smckusick 	fprintf(stderr, "where tuneup-options are:\n");
20513555Ssam 	fprintf(stderr, "\t-a maximum contiguous blocks\n");
20611288Smckusick 	fprintf(stderr, "\t-d rotational delay between contiguous blocks\n");
20711288Smckusick 	fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n");
20811288Smckusick 	fprintf(stderr, "\t-m minimum percentage of free space\n");
20924700Smckusick 	fprintf(stderr, "\t-o optimization preference (`space' or `time')\n");
21011288Smckusick 	exit(2);
21111288Smckusick }
21211288Smckusick 
213*66924Smckusick void
21411288Smckusick getsb(fs, file)
21511288Smckusick 	register struct fs *fs;
21611288Smckusick 	char *file;
21711288Smckusick {
21811288Smckusick 
21911288Smckusick 	fi = open(file, 2);
220*66924Smckusick 	if (fi < 0)
221*66924Smckusick 		err(3, "cannot open %s", file);
222*66924Smckusick 	if (bread((daddr_t)SBOFF, (char *)fs, SBSIZE))
223*66924Smckusick 		err(4, "%s: bad super block", file);
224*66924Smckusick 	if (fs->fs_magic != FS_MAGIC)
225*66924Smckusick 		err(5, "%s: bad magic number", file);
22630558Smckusick 	dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
22711288Smckusick }
22811288Smckusick 
229*66924Smckusick void
23011288Smckusick bwrite(blk, buf, size)
231*66924Smckusick 	daddr_t blk;
23211288Smckusick 	char *buf;
233*66924Smckusick 	int size;
23411288Smckusick {
235*66924Smckusick 
236*66924Smckusick 	if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0)
237*66924Smckusick 		err(6, "FS SEEK");
238*66924Smckusick 	if (write(fi, buf, size) != size)
239*66924Smckusick 		err(7, "FS WRITE");
24011288Smckusick }
24111288Smckusick 
242*66924Smckusick int
24311288Smckusick bread(bno, buf, cnt)
24411288Smckusick 	daddr_t bno;
24511288Smckusick 	char *buf;
246*66924Smckusick 	int cnt;
24711288Smckusick {
248*66924Smckusick 	int i;
24911288Smckusick 
25058003Sralph 	if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0)
25111288Smckusick 		return(1);
25211288Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
25311288Smckusick 		for(i=0; i<sblock.fs_bsize; i++)
25411288Smckusick 			buf[i] = 0;
25511288Smckusick 		return (1);
25611288Smckusick 	}
25711288Smckusick 	return (0);
25811288Smckusick }
259