xref: /csrg-svn/usr.sbin/mkproto/mkproto.c (revision 8142)
1*8142Smckusick /* Copyright (c) 1982 Regents of the University of California */
2*8142Smckusick 
3*8142Smckusick static char sccsid[] = "@(#)mkproto.c	4.1	(Berkeley)	09/10/82";
4*8142Smckusick 
5*8142Smckusick /*
6*8142Smckusick  * Make a file system prototype.
7*8142Smckusick  * usage: mkproto filsys proto
8*8142Smckusick  */
9*8142Smckusick #include <stdio.h>
10*8142Smckusick #include <sys/param.h>
11*8142Smckusick #include <sys/inode.h>
12*8142Smckusick #include <sys/fs.h>
13*8142Smckusick #include <sys/dir.h>
14*8142Smckusick 
15*8142Smckusick union {
16*8142Smckusick 	struct	fs fs;
17*8142Smckusick 	char	fsx[SBSIZE];
18*8142Smckusick } ufs;
19*8142Smckusick #define sblock	ufs.fs
20*8142Smckusick union {
21*8142Smckusick 	struct	cg cg;
22*8142Smckusick 	char	cgx[MAXBSIZE];
23*8142Smckusick } ucg;
24*8142Smckusick #define	acg	ucg.cg
25*8142Smckusick struct	fs *fs;
26*8142Smckusick struct	csum *fscs;
27*8142Smckusick int	fso, fsi;
28*8142Smckusick FILE	*proto;
29*8142Smckusick char	token[BUFSIZ];
30*8142Smckusick int	errs;
31*8142Smckusick int	ino = 10;
32*8142Smckusick long	getnum();
33*8142Smckusick char	*strcpy();
34*8142Smckusick 
35*8142Smckusick main(argc, argv)
36*8142Smckusick 	int argc;
37*8142Smckusick 	char *argv[];
38*8142Smckusick {
39*8142Smckusick 	int i;
40*8142Smckusick 
41*8142Smckusick 	if (argc != 3) {
42*8142Smckusick 		fprintf(stderr, "usage: mkproto filsys proto\n");
43*8142Smckusick 		exit(1);
44*8142Smckusick 	}
45*8142Smckusick 	fso = open(argv[1], 1);
46*8142Smckusick 	fsi = open(argv[1], 0);
47*8142Smckusick 	if (fso < 0 || fsi < 0) {
48*8142Smckusick 		perror(argv[1]);
49*8142Smckusick 		exit(1);
50*8142Smckusick 	}
51*8142Smckusick 	fs = &sblock;
52*8142Smckusick 	rdfs(SBLOCK, SBSIZE, (char *)fs);
53*8142Smckusick 	fscs = (struct csum *)calloc(1, fs->fs_cssize);
54*8142Smckusick 	for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
55*8142Smckusick 		rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
56*8142Smckusick 			(int)(fs->fs_cssize - i < fs->fs_bsize ?
57*8142Smckusick 			    fs->fs_cssize - i : fs->fs_bsize),
58*8142Smckusick 			((char *)fscs) + i);
59*8142Smckusick 	proto = fopen(argv[2], "r");
60*8142Smckusick 	descend((struct inode *)0);
61*8142Smckusick 	wtfs(SBLOCK, SBSIZE, (char *)fs);
62*8142Smckusick 	for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
63*8142Smckusick 		wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)),
64*8142Smckusick 			(int)(fs->fs_cssize - i < fs->fs_bsize ?
65*8142Smckusick 			    fs->fs_cssize - i : fs->fs_bsize),
66*8142Smckusick 			((char *)fscs) + i);
67*8142Smckusick 	exit(errs);
68*8142Smckusick }
69*8142Smckusick 
70*8142Smckusick descend(par)
71*8142Smckusick 	struct inode *par;
72*8142Smckusick {
73*8142Smckusick 	struct inode in;
74*8142Smckusick 	int ibc = 0;
75*8142Smckusick 	int i, f, c;
76*8142Smckusick 	struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
77*8142Smckusick 	daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
78*8142Smckusick 	char buf[MAXBSIZE];
79*8142Smckusick 
80*8142Smckusick 	getstr();
81*8142Smckusick 	in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
82*8142Smckusick 	in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
83*8142Smckusick 	in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
84*8142Smckusick 	for (i = 3; i < 6; i++) {
85*8142Smckusick 		c = token[i];
86*8142Smckusick 		if (c < '0' || c > '7') {
87*8142Smckusick 			printf("%c/%s: bad octal mode digit\n", c, token);
88*8142Smckusick 			errs++;
89*8142Smckusick 			c = 0;
90*8142Smckusick 		}
91*8142Smckusick 		in.i_mode |= (c-'0')<<(15-3*i);
92*8142Smckusick 	}
93*8142Smckusick 	in.i_uid = getnum(); in.i_gid = getnum();
94*8142Smckusick 	for (i = 0; i < fs->fs_bsize; i++)
95*8142Smckusick 		buf[i] = 0;
96*8142Smckusick 	for (i = 0; i < NINDIR(fs); i++)
97*8142Smckusick 		ib[i] = (daddr_t)0;
98*8142Smckusick 	in.i_nlink = 1;
99*8142Smckusick 	in.i_size = 0;
100*8142Smckusick 	for (i = 0; i < NDADDR; i++)
101*8142Smckusick 		in.i_db[i] = (daddr_t)0;
102*8142Smckusick 	for (i = 0; i < NIADDR; i++)
103*8142Smckusick 		in.i_ib[i] = (daddr_t)0;
104*8142Smckusick 	if (par != (struct inode *)0) {
105*8142Smckusick 		ialloc(&in);
106*8142Smckusick 	} else {
107*8142Smckusick 		par = &in;
108*8142Smckusick 		i = itod(fs, ROOTINO);
109*8142Smckusick 		rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos);
110*8142Smckusick 		dip = &inos[ROOTINO % INOPB(fs)];
111*8142Smckusick 		in.i_number = ROOTINO;
112*8142Smckusick 		in.i_nlink = dip->di_nlink;
113*8142Smckusick 		in.i_size = dip->di_size;
114*8142Smckusick 		in.i_db[0] = dip->di_db[0];
115*8142Smckusick 		rdfs(fsbtodb(fs, in.i_db[0]), fs->fs_bsize, buf);
116*8142Smckusick 	}
117*8142Smckusick 
118*8142Smckusick 	switch (in.i_mode&IFMT) {
119*8142Smckusick 
120*8142Smckusick 	case IFREG:
121*8142Smckusick 		getstr();
122*8142Smckusick 		f = open(token, 0);
123*8142Smckusick 		if (f < 0) {
124*8142Smckusick 			printf("%s: cannot open\n", token);
125*8142Smckusick 			errs++;
126*8142Smckusick 			break;
127*8142Smckusick 		}
128*8142Smckusick 		while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) {
129*8142Smckusick 			in.i_size += i;
130*8142Smckusick 			newblk(buf, &ibc, ib, (int)blksize(fs, &in, ibc));
131*8142Smckusick 		}
132*8142Smckusick 		close(f);
133*8142Smckusick 		break;
134*8142Smckusick 
135*8142Smckusick 	case IFBLK:
136*8142Smckusick 	case IFCHR:
137*8142Smckusick 		/*
138*8142Smckusick 		 * special file
139*8142Smckusick 		 * content is maj/min types
140*8142Smckusick 		 */
141*8142Smckusick 
142*8142Smckusick 		i = getnum() & 0377;
143*8142Smckusick 		f = getnum() & 0377;
144*8142Smckusick 		in.i_dev = (i << 8) | f;
145*8142Smckusick 		break;
146*8142Smckusick 
147*8142Smckusick 	case IFDIR:
148*8142Smckusick 		/*
149*8142Smckusick 		 * directory
150*8142Smckusick 		 * put in extra links
151*8142Smckusick 		 * call recursively until
152*8142Smckusick 		 * name of "$" found
153*8142Smckusick 		 */
154*8142Smckusick 
155*8142Smckusick 		if (in.i_number != ROOTINO) {
156*8142Smckusick 			par->i_nlink++;
157*8142Smckusick 			in.i_nlink++;
158*8142Smckusick 			entry(&in, in.i_number, ".", buf);
159*8142Smckusick 			entry(&in, par->i_number, "..", buf);
160*8142Smckusick 		}
161*8142Smckusick 		for (;;) {
162*8142Smckusick 			getstr();
163*8142Smckusick 			if (token[0]=='$' && token[1]=='\0')
164*8142Smckusick 				break;
165*8142Smckusick 			entry(&in, (ino_t)(ino+1), token, buf);
166*8142Smckusick 			descend(&in);
167*8142Smckusick 		}
168*8142Smckusick 		if (in.i_number != ROOTINO)
169*8142Smckusick 			newblk(buf, &ibc, ib, (int)blksize(fs, &in, 0));
170*8142Smckusick 		else
171*8142Smckusick 			wtfs(fsbtodb(fs, in.i_db[0]), (int)fs->fs_bsize, buf);
172*8142Smckusick 		break;
173*8142Smckusick 	}
174*8142Smckusick 	iput(&in, &ibc, ib);
175*8142Smckusick }
176*8142Smckusick 
177*8142Smckusick /*ARGSUSED*/
178*8142Smckusick gmode(c, s, m0, m1, m2, m3)
179*8142Smckusick 	char c, *s;
180*8142Smckusick {
181*8142Smckusick 	int i;
182*8142Smckusick 
183*8142Smckusick 	for (i = 0; s[i]; i++)
184*8142Smckusick 		if (c == s[i])
185*8142Smckusick 			return((&m0)[i]);
186*8142Smckusick 	printf("%c/%s: bad mode\n", c, token);
187*8142Smckusick 	errs++;
188*8142Smckusick 	return(0);
189*8142Smckusick }
190*8142Smckusick 
191*8142Smckusick long
192*8142Smckusick getnum()
193*8142Smckusick {
194*8142Smckusick 	int i, c;
195*8142Smckusick 	long n;
196*8142Smckusick 
197*8142Smckusick 	getstr();
198*8142Smckusick 	n = 0;
199*8142Smckusick 	i = 0;
200*8142Smckusick 	for (i = 0; c=token[i]; i++) {
201*8142Smckusick 		if (c<'0' || c>'9') {
202*8142Smckusick 			printf("%s: bad number\n", token);
203*8142Smckusick 			errs++;
204*8142Smckusick 			return((long)0);
205*8142Smckusick 		}
206*8142Smckusick 		n = n*10 + (c-'0');
207*8142Smckusick 	}
208*8142Smckusick 	return(n);
209*8142Smckusick }
210*8142Smckusick 
211*8142Smckusick getstr()
212*8142Smckusick {
213*8142Smckusick 	int i, c;
214*8142Smckusick 
215*8142Smckusick loop:
216*8142Smckusick 	switch (c = getc(proto)) {
217*8142Smckusick 
218*8142Smckusick 	case ' ':
219*8142Smckusick 	case '\t':
220*8142Smckusick 	case '\n':
221*8142Smckusick 		goto loop;
222*8142Smckusick 
223*8142Smckusick 	case EOF:
224*8142Smckusick 		printf("Unexpected EOF\n");
225*8142Smckusick 		exit(1);
226*8142Smckusick 
227*8142Smckusick 	case ':':
228*8142Smckusick 		while (getc(proto) != '\n')
229*8142Smckusick 			;
230*8142Smckusick 		goto loop;
231*8142Smckusick 
232*8142Smckusick 	}
233*8142Smckusick 	i = 0;
234*8142Smckusick 	do {
235*8142Smckusick 		token[i++] = c;
236*8142Smckusick 		c = getc(proto);
237*8142Smckusick 	} while (c != ' ' && c != '\t' && c != '\n' && c != '\0');
238*8142Smckusick 	token[i] = 0;
239*8142Smckusick }
240*8142Smckusick 
241*8142Smckusick entry(ip, inum, str, buf)
242*8142Smckusick 	struct inode *ip;
243*8142Smckusick 	ino_t inum;
244*8142Smckusick 	char *str;
245*8142Smckusick 	char *buf;
246*8142Smckusick {
247*8142Smckusick 	register struct direct *dp, *odp;
248*8142Smckusick 	int oldsize, newsize, freespace;
249*8142Smckusick 
250*8142Smckusick 	odp = dp = (struct direct *)buf;
251*8142Smckusick 	while ((int)dp - (int)buf < ip->i_size) {
252*8142Smckusick 		odp = dp;
253*8142Smckusick 		dp = (struct direct *)((int)dp + dp->d_reclen);
254*8142Smckusick 	}
255*8142Smckusick 	if (odp != dp)
256*8142Smckusick 		oldsize = DIRSIZ(odp);
257*8142Smckusick 	else
258*8142Smckusick 		oldsize = 0;
259*8142Smckusick 	freespace = odp->d_reclen - oldsize;
260*8142Smckusick 	dp = (struct direct *)((int)odp + oldsize);
261*8142Smckusick 	dp->d_ino = inum;
262*8142Smckusick 	dp->d_namlen = strlen(str);
263*8142Smckusick 	newsize = DIRSIZ(dp);
264*8142Smckusick 	if (freespace >= newsize) {
265*8142Smckusick 		odp->d_reclen = oldsize;
266*8142Smckusick 		dp->d_reclen = freespace;
267*8142Smckusick 	} else {
268*8142Smckusick 		dp = (struct direct *)((int)odp + odp->d_reclen);
269*8142Smckusick 		if ((int)dp - (int)buf >= fs->fs_bsize) {
270*8142Smckusick 			printf("directory too large\n");
271*8142Smckusick 			exit(1);
272*8142Smckusick 		}
273*8142Smckusick 		dp->d_ino = inum;
274*8142Smckusick 		dp->d_namlen = strlen(str);
275*8142Smckusick 		dp->d_reclen = DIRBLKSIZ;
276*8142Smckusick 	}
277*8142Smckusick 	strcpy(dp->d_name, str);
278*8142Smckusick 	ip->i_size = (int)dp - (int)buf + newsize;
279*8142Smckusick }
280*8142Smckusick 
281*8142Smckusick newblk(buf, aibc, ib, size)
282*8142Smckusick 	int *aibc;
283*8142Smckusick 	char *buf;
284*8142Smckusick 	daddr_t *ib;
285*8142Smckusick 	int size;
286*8142Smckusick {
287*8142Smckusick 	int i;
288*8142Smckusick 	daddr_t bno;
289*8142Smckusick 
290*8142Smckusick 	bno = alloc(size);
291*8142Smckusick 	wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf);
292*8142Smckusick 	for (i = 0; i < fs->fs_bsize; i++)
293*8142Smckusick 		buf[i] = 0;
294*8142Smckusick 	ib[(*aibc)++] = bno;
295*8142Smckusick 	if (*aibc >= NINDIR(fs)) {
296*8142Smckusick 		printf("indirect block full\n");
297*8142Smckusick 		errs++;
298*8142Smckusick 		*aibc = 0;
299*8142Smckusick 	}
300*8142Smckusick }
301*8142Smckusick 
302*8142Smckusick iput(ip, aibc, ib)
303*8142Smckusick 	struct inode *ip;
304*8142Smckusick 	int *aibc;
305*8142Smckusick 	daddr_t *ib;
306*8142Smckusick {
307*8142Smckusick 	daddr_t d;
308*8142Smckusick 	int i;
309*8142Smckusick 	struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
310*8142Smckusick 
311*8142Smckusick 	ip->i_atime = ip->i_mtime = ip->i_ctime = time((long *)0);
312*8142Smckusick 	switch (ip->i_mode&IFMT) {
313*8142Smckusick 
314*8142Smckusick 	case IFDIR:
315*8142Smckusick 	case IFREG:
316*8142Smckusick 		for (i = 0; i < *aibc; i++) {
317*8142Smckusick 			if (i >= NDADDR)
318*8142Smckusick 				break;
319*8142Smckusick 			ip->i_db[i] = ib[i];
320*8142Smckusick 		}
321*8142Smckusick 		if (*aibc > NDADDR) {
322*8142Smckusick 			ip->i_ib[0] = alloc((int)fs->fs_bsize);
323*8142Smckusick 			for (i = 0; i < NINDIR(fs) - NDADDR; i++) {
324*8142Smckusick 				ib[i] = ib[i+NDADDR];
325*8142Smckusick 				ib[i+NDADDR] = (daddr_t)0;
326*8142Smckusick 			}
327*8142Smckusick 			wtfs(fsbtodb(fs, ip->i_ib[0]),
328*8142Smckusick 			    (int)fs->fs_bsize, (char *)ib);
329*8142Smckusick 		}
330*8142Smckusick 		break;
331*8142Smckusick 
332*8142Smckusick 	case IFBLK:
333*8142Smckusick 	case IFCHR:
334*8142Smckusick 		break;
335*8142Smckusick 
336*8142Smckusick 	default:
337*8142Smckusick 		printf("bad mode %o\n", ip->i_mode);
338*8142Smckusick 		exit(1);
339*8142Smckusick 	}
340*8142Smckusick 	d = fsbtodb(fs, itod(fs, ip->i_number));
341*8142Smckusick 	rdfs(d, (int)fs->fs_bsize, (char *)buf);
342*8142Smckusick 	buf[itoo(fs, ip->i_number)].di_ic = ip->i_ic;
343*8142Smckusick 	wtfs(d, (int)fs->fs_bsize, (char *)buf);
344*8142Smckusick }
345*8142Smckusick 
346*8142Smckusick daddr_t
347*8142Smckusick alloc(size)
348*8142Smckusick 	int size;
349*8142Smckusick {
350*8142Smckusick 	int i, frag;
351*8142Smckusick 	daddr_t d;
352*8142Smckusick 	static int cg = 0;
353*8142Smckusick 
354*8142Smckusick again:
355*8142Smckusick 	rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
356*8142Smckusick 	    (char *)&acg);
357*8142Smckusick 	if (acg.cg_magic != CG_MAGIC) {
358*8142Smckusick 		printf("cg %d: bad magic number\n", cg);
359*8142Smckusick 		return (0);
360*8142Smckusick 	}
361*8142Smckusick 	if (acg.cg_cs.cs_nbfree == 0) {
362*8142Smckusick 		cg++;
363*8142Smckusick 		if (cg >= fs->fs_ncg) {
364*8142Smckusick 			printf("ran out of space\n");
365*8142Smckusick 			return (0);
366*8142Smckusick 		}
367*8142Smckusick 		goto again;
368*8142Smckusick 	}
369*8142Smckusick 	for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
370*8142Smckusick 		if (isblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag))
371*8142Smckusick 			goto goth;
372*8142Smckusick 	printf("internal error: can't find block in cyl %d\n", cg);
373*8142Smckusick 	return (0);
374*8142Smckusick goth:
375*8142Smckusick 	clrblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag);
376*8142Smckusick 	acg.cg_cs.cs_nbfree--;
377*8142Smckusick 	sblock.fs_cstotal.cs_nbfree--;
378*8142Smckusick 	fscs[cg].cs_nbfree--;
379*8142Smckusick 	acg.cg_btot[cbtocylno(&sblock, d)]--;
380*8142Smckusick 	acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--;
381*8142Smckusick 	if (size != sblock.fs_bsize) {
382*8142Smckusick 		frag = howmany(size, sblock.fs_fsize);
383*8142Smckusick 		fscs[cg].cs_nffree += sblock.fs_frag - frag;
384*8142Smckusick 		sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
385*8142Smckusick 		acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
386*8142Smckusick 		acg.cg_frsum[sblock.fs_frag - frag]++;
387*8142Smckusick 		for (i = frag; i < sblock.fs_frag; i++)
388*8142Smckusick 			setbit(acg.cg_free, d + i);
389*8142Smckusick 	}
390*8142Smckusick 	wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
391*8142Smckusick 	    (char *)&acg);
392*8142Smckusick 	return (acg.cg_cgx * fs->fs_fpg + d);
393*8142Smckusick }
394*8142Smckusick 
395*8142Smckusick /*
396*8142Smckusick  * Allocate an inode on the disk
397*8142Smckusick  */
398*8142Smckusick ialloc(ip)
399*8142Smckusick 	register struct inode *ip;
400*8142Smckusick {
401*8142Smckusick 	struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
402*8142Smckusick 	daddr_t d;
403*8142Smckusick 	int c;
404*8142Smckusick 
405*8142Smckusick 	ip->i_number = ++ino;
406*8142Smckusick 	c = itog(&sblock, ip->i_number);
407*8142Smckusick 	rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
408*8142Smckusick 	    (char *)&acg);
409*8142Smckusick 	if (acg.cg_magic != CG_MAGIC) {
410*8142Smckusick 		printf("cg %d: bad magic number\n", c);
411*8142Smckusick 		exit(1);
412*8142Smckusick 	}
413*8142Smckusick 	if (ip->i_mode & IFDIR) {
414*8142Smckusick 		acg.cg_cs.cs_ndir++;
415*8142Smckusick 		sblock.fs_cstotal.cs_ndir++;
416*8142Smckusick 		fscs[c].cs_ndir++;
417*8142Smckusick 	}
418*8142Smckusick 	acg.cg_cs.cs_nifree--;
419*8142Smckusick 	setbit(acg.cg_iused, ip->i_number);
420*8142Smckusick 	wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
421*8142Smckusick 	    (char *)&acg);
422*8142Smckusick 	sblock.fs_cstotal.cs_nifree--;
423*8142Smckusick 	fscs[c].cs_nifree--;
424*8142Smckusick 	if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) {
425*8142Smckusick 		printf("fsinit: inode value out of range (%d).\n",
426*8142Smckusick 		    ip->i_number);
427*8142Smckusick 		exit(1);
428*8142Smckusick 	}
429*8142Smckusick 	return (ip->i_number);
430*8142Smckusick }
431*8142Smckusick 
432*8142Smckusick /*
433*8142Smckusick  * read a block from the file system
434*8142Smckusick  */
435*8142Smckusick rdfs(bno, size, bf)
436*8142Smckusick 	int bno, size;
437*8142Smckusick 	char *bf;
438*8142Smckusick {
439*8142Smckusick 	int n;
440*8142Smckusick 
441*8142Smckusick 	if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) {
442*8142Smckusick 		printf("seek error: %ld\n", bno);
443*8142Smckusick 		perror("rdfs");
444*8142Smckusick 		exit(1);
445*8142Smckusick 	}
446*8142Smckusick 	n = read(fsi, bf, size);
447*8142Smckusick 	if(n != size) {
448*8142Smckusick 		printf("read error: %ld\n", bno);
449*8142Smckusick 		perror("rdfs");
450*8142Smckusick 		exit(1);
451*8142Smckusick 	}
452*8142Smckusick }
453*8142Smckusick 
454*8142Smckusick /*
455*8142Smckusick  * write a block to the file system
456*8142Smckusick  */
457*8142Smckusick wtfs(bno, size, bf)
458*8142Smckusick 	int bno, size;
459*8142Smckusick 	char *bf;
460*8142Smckusick {
461*8142Smckusick 	int n;
462*8142Smckusick 
463*8142Smckusick 	lseek(fso, bno * DEV_BSIZE, 0);
464*8142Smckusick 	if (lseek(fso, bno * DEV_BSIZE, 0) < 0) {
465*8142Smckusick 		printf("seek error: %ld\n", bno);
466*8142Smckusick 		perror("wtfs");
467*8142Smckusick 		exit(1);
468*8142Smckusick 	}
469*8142Smckusick 	n = write(fso, bf, size);
470*8142Smckusick 	if(n != size) {
471*8142Smckusick 		printf("write error: %D\n", bno);
472*8142Smckusick 		perror("wtfs");
473*8142Smckusick 		exit(1);
474*8142Smckusick 	}
475*8142Smckusick }
476*8142Smckusick /*
477*8142Smckusick  * check if a block is available
478*8142Smckusick  */
479*8142Smckusick isblock(fs, cp, h)
480*8142Smckusick 	struct fs *fs;
481*8142Smckusick 	unsigned char *cp;
482*8142Smckusick 	int h;
483*8142Smckusick {
484*8142Smckusick 	unsigned char mask;
485*8142Smckusick 
486*8142Smckusick 	switch (fs->fs_frag) {
487*8142Smckusick 	case 8:
488*8142Smckusick 		return (cp[h] == 0xff);
489*8142Smckusick 	case 4:
490*8142Smckusick 		mask = 0x0f << ((h & 0x1) << 2);
491*8142Smckusick 		return ((cp[h >> 1] & mask) == mask);
492*8142Smckusick 	case 2:
493*8142Smckusick 		mask = 0x03 << ((h & 0x3) << 1);
494*8142Smckusick 		return ((cp[h >> 2] & mask) == mask);
495*8142Smckusick 	case 1:
496*8142Smckusick 		mask = 0x01 << (h & 0x7);
497*8142Smckusick 		return ((cp[h >> 3] & mask) == mask);
498*8142Smckusick 	default:
499*8142Smckusick 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
500*8142Smckusick 		return (0);
501*8142Smckusick 	}
502*8142Smckusick 	/*NOTREACHED*/
503*8142Smckusick }
504*8142Smckusick 
505*8142Smckusick /*
506*8142Smckusick  * take a block out of the map
507*8142Smckusick  */
508*8142Smckusick clrblock(fs, cp, h)
509*8142Smckusick 	struct fs *fs;
510*8142Smckusick 	unsigned char *cp;
511*8142Smckusick 	int h;
512*8142Smckusick {
513*8142Smckusick 	switch ((fs)->fs_frag) {
514*8142Smckusick 	case 8:
515*8142Smckusick 		cp[h] = 0;
516*8142Smckusick 		return;
517*8142Smckusick 	case 4:
518*8142Smckusick 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
519*8142Smckusick 		return;
520*8142Smckusick 	case 2:
521*8142Smckusick 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
522*8142Smckusick 		return;
523*8142Smckusick 	case 1:
524*8142Smckusick 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
525*8142Smckusick 		return;
526*8142Smckusick 	default:
527*8142Smckusick 		fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
528*8142Smckusick 		return;
529*8142Smckusick 	}
530*8142Smckusick }
531*8142Smckusick 
532