xref: /csrg-svn/sbin/tunefs/tunefs.c (revision 11288)
1 #ifndef lint
2 static	char *sccsid = "@(#)tunefs.c	4.1 (Berkeley) 02/26/83";
3 #endif lint
4 
5 /*
6  * tunefs: change layout parameters to an existing file system.
7  */
8 
9 #include <stdio.h>
10 #include <sys/param.h>
11 #include <sys/stat.h>
12 #include <sys/fs.h>
13 #include <sys/inode.h>
14 
15 union {
16 	struct	fs sb;
17 	char pad[MAXBSIZE];
18 } sbun;
19 #define	sblock sbun.sb
20 
21 int fi;
22 
23 main(argc, argv)
24 	int argc;
25 	char *argv[];
26 {
27 	char *cp, *special, *name;
28 	struct stat st;
29 	int i;
30 	int Aflag = 0;
31 	char device[MAXPATHLEN];
32 	extern char *sprintf();
33 
34 	argc--, argv++;
35 	if (argc < 2)
36 		goto usage;
37 	special = argv[argc - 1];
38 again:
39 	if (stat(special, &st) < 0) {
40 		if (*special != '/') {
41 			if (*special == 'r')
42 				special++;
43 			special = sprintf(device, "/dev/%s", special);
44 			goto again;
45 		}
46 		fprintf(stderr, "tunefs: "); perror(special);
47 		exit(1);
48 	}
49 	if ((st.st_mode & S_IFMT) != S_IFBLK &&
50 	    (st.st_mode & S_IFMT) != S_IFCHR)
51 		fatal("%s: not a block or character device", special);
52 	getsb(&sblock, special);
53 	for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
54 		for (cp = &argv[0][1]; *cp; cp++)
55 			switch (*cp) {
56 
57 			case 'A':
58 				Aflag++;
59 				continue;
60 
61 			case 'a':
62 				name = "maximum contiguous block count";
63 				if (argc < 1)
64 					fatal("-a: missing %s", name);
65 				argc--, argv++;
66 				i = atoi(*argv);
67 				if (i < 1)
68 					fatal("%s: %s must be >= 1",
69 						*argv, name);
70 				fprintf(stdout, "%s changes from %d to %d\n",
71 					name, sblock.fs_maxcontig, i);
72 				sblock.fs_maxcontig = i;
73 				continue;
74 
75 			case 'd':
76 				name =
77 				   "rotational delay between contiguous blocks";
78 				if (argc < 1)
79 					fatal("-d: missing %s", name);
80 				argc--, argv++;
81 				i = atoi(*argv);
82 				if (i < 0)
83 					fatal("%s: bad %s", *argv, name);
84 				fprintf(stdout,
85 					"%s changes from %dms to %dms\n",
86 					name, sblock.fs_rotdelay, i);
87 				sblock.fs_rotdelay = i;
88 				continue;
89 
90 			case 'e':
91 				name =
92 				  "maximum blocks per file in a cylinder group";
93 				if (argc < 1)
94 					fatal("-e: missing %s", name);
95 				argc--, argv++;
96 				i = atoi(*argv);
97 				if (i < 1)
98 					fatal("%s: %s must be >= 1",
99 						*argv, name);
100 				fprintf(stdout, "%s changes from %d to %d\n",
101 					name, sblock.fs_maxbpg, i);
102 				sblock.fs_maxbpg = i;
103 				continue;
104 
105 			case 'm':
106 				name = "minimum percentage of free space";
107 				if (argc < 1)
108 					fatal("-m: missing %s", name);
109 				argc--, argv++;
110 				i = atoi(*argv);
111 				if (i < 0 || i > 99)
112 					fatal("%s: bad %s", *argv, name);
113 				fprintf(stdout,
114 					"%s changes from %d%% to %d%%\n",
115 					name, sblock.fs_minfree, i);
116 				sblock.fs_minfree = i;
117 				continue;
118 
119 			default:
120 				fatal("-%c: unknown flag", *cp);
121 			}
122 	}
123 	if (argc != 1)
124 		goto usage;
125 	bwrite(SBLOCK, (char *)&sblock, SBSIZE);
126 	if (Aflag)
127 		for (i = 0; i < sblock.fs_ncg; i++)
128 			bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)),
129 			    (char *)&sblock, SBSIZE);
130 	close(fi);
131 	exit(0);
132 usage:
133 	fprintf(stderr, "Usage: tunefs tuneup-options special-device\n");
134 	fprintf(stderr, "where tuneup-options are:\n");
135 	fprintf(stderr, "\t-a maximum contigouous blocks\n");
136 	fprintf(stderr, "\t-d rotational delay between contiguous blocks\n");
137 	fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n");
138 	fprintf(stderr, "\t-m minimum percentage of free space\n");
139 	exit(2);
140 }
141 
142 getsb(fs, file)
143 	register struct fs *fs;
144 	char *file;
145 {
146 
147 	fi = open(file, 2);
148 	if (fi < 0) {
149 		fprintf(stderr, "cannot open");
150 		perror(file);
151 		exit(3);
152 	}
153 	if (bread(SBLOCK, (char *)fs, SBSIZE)) {
154 		fprintf(stderr, "bad super block");
155 		perror(file);
156 		exit(4);
157 	}
158 	if (fs->fs_magic != FS_MAGIC) {
159 		fprintf(stderr, "%s: bad magic number\n", file);
160 		exit(5);
161 	}
162 }
163 
164 bwrite(blk, buf, size)
165 	char *buf;
166 	daddr_t blk;
167 	register size;
168 {
169 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
170 		perror("FS SEEK");
171 		exit(6);
172 	}
173 	if (write(fi, buf, size) != size) {
174 		perror("FS WRITE");
175 		exit(7);
176 	}
177 }
178 
179 bread(bno, buf, cnt)
180 	daddr_t bno;
181 	char *buf;
182 {
183 	register i;
184 
185 	if (lseek(fi, bno * DEV_BSIZE, 0) < 0)
186 		return(1);
187 	if ((i = read(fi, buf, cnt)) != cnt) {
188 		for(i=0; i<sblock.fs_bsize; i++)
189 			buf[i] = 0;
190 		return (1);
191 	}
192 	return (0);
193 }
194 
195 /* VARARGS1 */
196 fatal(fmt, arg1, arg2)
197 	char *fmt, *arg1, *arg2;
198 {
199 
200 	fprintf(stderr, "newfs: ");
201 	fprintf(stderr, fmt, arg1, arg2);
202 	putc('\n', stderr);
203 	exit(10);
204 }
205