xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 5377)
1 /* Copyright (c) 1981 Regents of the University of California */
2 
3 static char vers[] = "@(#)lfs_alloc.c 1.15 01/12/82";
4 
5 /*	alloc.c	4.8	81/03/08	*/
6 
7 #include "../h/param.h"
8 #include "../h/systm.h"
9 #include "../h/mount.h"
10 #include "../h/fs.h"
11 #include "../h/conf.h"
12 #include "../h/buf.h"
13 #include "../h/inode.h"
14 #include "../h/dir.h"
15 #include "../h/user.h"
16 
17 extern u_long		hashalloc();
18 extern ino_t		ialloccg();
19 extern daddr_t		alloccg();
20 extern daddr_t		alloccgblk();
21 extern daddr_t		fragextend();
22 extern daddr_t		blkpref();
23 extern daddr_t		mapsearch();
24 extern int		inside[], around[];
25 extern unsigned char	*fragtbl[];
26 
27 /*
28  * Allocate a block in the file system.
29  *
30  * The size of the requested block is given, which must be some
31  * multiple of fs_fsize and <= fs_bsize.
32  * A preference may be optionally specified. If a preference is given
33  * the following hierarchy is used to allocate a block:
34  *   1) allocate the requested block.
35  *   2) allocate a rotationally optimal block in the same cylinder.
36  *   3) allocate a block in the same cylinder group.
37  *   4) quadradically rehash into other cylinder groups, until an
38  *      available block is located.
39  * If no block preference is given the following heirarchy is used
40  * to allocate a block:
41  *   1) allocate a block in the cylinder group that contains the
42  *      inode for the file.
43  *   2) quadradically rehash into other cylinder groups, until an
44  *      available block is located.
45  */
46 struct buf *
47 alloc(dev, ip, bpref, size)
48 	dev_t dev;
49 	register struct inode *ip;
50 	daddr_t bpref;
51 	int size;
52 {
53 	daddr_t bno;
54 	register struct fs *fs;
55 	register struct buf *bp;
56 	int cg;
57 
58 	fs = getfs(dev);
59 	if ((unsigned)size > fs->fs_bsize || size % fs->fs_fsize != 0)
60 		panic("alloc: bad size");
61 	if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
62 		goto nospace;
63 	if (u.u_uid != 0 &&
64 	    fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
65 	      fs->fs_dsize * fs->fs_minfree / 100)
66 		goto nospace;
67 	if (bpref >= fs->fs_size)
68 		bpref = 0;
69 	if (bpref == 0)
70 		cg = itog(fs, ip->i_number);
71 	else
72 		cg = dtog(fs, bpref);
73 	bno = (daddr_t)hashalloc(dev, fs, cg, (long)bpref, size, alloccg);
74 	if (bno == 0)
75 		goto nospace;
76 	bp = getblk(dev, fsbtodb(fs, bno), size);
77 	clrbuf(bp);
78 	return (bp);
79 nospace:
80 	fserr(fs, "file system full");
81 	uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
82 	u.u_error = ENOSPC;
83 	return (NULL);
84 }
85 
86 /*
87  * Reallocate a fragment to a bigger size
88  *
89  * The number and size of the old block is given, and a preference
90  * and new size is also specified. The allocator attempts to extend
91  * the original block. Failing that, the regular block allocator is
92  * invoked to get an appropriate block.
93  */
94 struct buf *
95 realloccg(dev, bprev, bpref, osize, nsize)
96 	dev_t dev;
97 	daddr_t bprev, bpref;
98 	int osize, nsize;
99 {
100 	daddr_t bno;
101 	register struct fs *fs;
102 	register struct buf *bp, *obp;
103 	caddr_t cp;
104 	int cg;
105 
106 	fs = getfs(dev);
107 	if ((unsigned)osize > fs->fs_bsize || osize % fs->fs_fsize != 0 ||
108 	    (unsigned)nsize > fs->fs_bsize || nsize % fs->fs_fsize != 0)
109 		panic("realloccg: bad size");
110 	if (u.u_uid != 0 &&
111 	    fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
112 	      fs->fs_dsize * fs->fs_minfree / 100)
113 		goto nospace;
114 	if (bprev != 0)
115 		cg = dtog(fs, bprev);
116 	else
117 		panic("realloccg: bad bprev");
118 	bno = fragextend(dev, fs, cg, (long)bprev, osize, nsize);
119 	if (bno != 0) {
120 		bp = bread(dev, fsbtodb(fs, bno), osize);
121 		if (bp->b_flags & B_ERROR)
122 			return (0);
123 		bp->b_bcount = nsize;
124 		blkclr(bp->b_un.b_addr + osize, nsize - osize);
125 		return (bp);
126 	}
127 	if (bpref >= fs->fs_size)
128 		bpref = 0;
129 	bno = (daddr_t)hashalloc(dev, fs, cg, (long)bpref, nsize, alloccg);
130 	if (bno != 0) {
131 		/*
132 		 * make a new copy
133 		 */
134 		obp = bread(dev, fsbtodb(fs, bprev), osize);
135 		if (obp->b_flags & B_ERROR)
136 			return (0);
137 		bp = getblk(dev, fsbtodb(fs, bno), nsize);
138 		cp = bp->b_un.b_addr;
139 		bp->b_un.b_addr = obp->b_un.b_addr;
140 		obp->b_un.b_addr = cp;
141 		obp->b_flags |= B_INVAL;
142 		brelse(obp);
143 		fre(dev, bprev, (off_t)osize);
144 		blkclr(bp->b_un.b_addr + osize, nsize - osize);
145 		return(bp);
146 	}
147 nospace:
148 	/*
149 	 * no space available
150 	 */
151 	fserr(fs, "file system full");
152 	uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
153 	u.u_error = ENOSPC;
154 	return (NULL);
155 }
156 
157 /*
158  * Allocate an inode in the file system.
159  *
160  * A preference may be optionally specified. If a preference is given
161  * the following hierarchy is used to allocate an inode:
162  *   1) allocate the requested inode.
163  *   2) allocate an inode in the same cylinder group.
164  *   3) quadradically rehash into other cylinder groups, until an
165  *      available inode is located.
166  * If no inode preference is given the following heirarchy is used
167  * to allocate an inode:
168  *   1) allocate an inode in cylinder group 0.
169  *   2) quadradically rehash into other cylinder groups, until an
170  *      available inode is located.
171  */
172 struct inode *
173 ialloc(dev, ipref, mode)
174 	dev_t dev;
175 	ino_t ipref;
176 	int mode;
177 {
178 	ino_t ino;
179 	register struct fs *fs;
180 	register struct inode *ip;
181 	int cg;
182 
183 	fs = getfs(dev);
184 	if (fs->fs_cstotal.cs_nifree == 0)
185 		goto noinodes;
186 	if (ipref >= fs->fs_ncg * fs->fs_ipg)
187 		ipref = 0;
188 	cg = itog(fs, ipref);
189 	ino = (ino_t)hashalloc(dev, fs, cg, (long)ipref, mode, ialloccg);
190 	if (ino == 0)
191 		goto noinodes;
192 	ip = iget(dev, ino);
193 	if (ip == NULL) {
194 		ifree(dev, ino, 0);
195 		return (NULL);
196 	}
197 	if (ip->i_mode)
198 		panic("ialloc: dup alloc");
199 	return (ip);
200 noinodes:
201 	fserr(fs, "out of inodes");
202 	uprintf("\n%s: create failed, no inodes free\n", fs->fs_fsmnt);
203 	u.u_error = ENOSPC;
204 	return (NULL);
205 }
206 
207 /*
208  * Find a cylinder to place a directory.
209  *
210  * The policy implemented by this algorithm is to select from
211  * among those cylinder groups with above the average number of
212  * free inodes, the one with the smallest number of directories.
213  */
214 dirpref(dev)
215 	dev_t dev;
216 {
217 	register struct fs *fs;
218 	int cg, minndir, mincg, avgifree;
219 
220 	fs = getfs(dev);
221 	avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg;
222 	minndir = fs->fs_ipg;
223 	mincg = 0;
224 	for (cg = 0; cg < fs->fs_ncg; cg++)
225 		if (fs->fs_cs(fs, cg).cs_ndir < minndir &&
226 		    fs->fs_cs(fs, cg).cs_nifree >= avgifree) {
227 			mincg = cg;
228 			minndir = fs->fs_cs(fs, cg).cs_ndir;
229 		}
230 	return (fs->fs_ipg * mincg);
231 }
232 
233 /*
234  * Select a cylinder to place a large block of data.
235  *
236  * The policy implemented by this algorithm is to maintain a
237  * rotor that sweeps the cylinder groups. When a block is
238  * needed, the rotor is advanced until a cylinder group with
239  * greater than the average number of free blocks is found.
240  */
241 daddr_t
242 blkpref(dev)
243 	dev_t dev;
244 {
245 	register struct fs *fs;
246 	int cg, avgbfree;
247 
248 	fs = getfs(dev);
249 	avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
250 	for (cg = fs->fs_cgrotor + 1; cg < fs->fs_ncg; cg++)
251 		if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
252 			fs->fs_cgrotor = cg;
253 			return (fs->fs_fpg * cg + fs->fs_frag);
254 		}
255 	for (cg = 0; cg <= fs->fs_cgrotor; cg++)
256 		if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
257 			fs->fs_cgrotor = cg;
258 			return (fs->fs_fpg * cg + fs->fs_frag);
259 		}
260 	return (0);
261 }
262 
263 /*
264  * Implement the cylinder overflow algorithm.
265  *
266  * The policy implemented by this algorithm is:
267  *   1) allocate the block in its requested cylinder group.
268  *   2) quadradically rehash on the cylinder group number.
269  *   3) brute force search for a free block.
270  */
271 /*VARARGS5*/
272 u_long
273 hashalloc(dev, fs, cg, pref, size, allocator)
274 	dev_t dev;
275 	register struct fs *fs;
276 	int cg;
277 	long pref;
278 	int size;	/* size for data blocks, mode for inodes */
279 	u_long (*allocator)();
280 {
281 	long result;
282 	int i, icg = cg;
283 
284 	/*
285 	 * 1: preferred cylinder group
286 	 */
287 	result = (*allocator)(dev, fs, cg, pref, size);
288 	if (result)
289 		return (result);
290 	/*
291 	 * 2: quadratic rehash
292 	 */
293 	for (i = 1; i < fs->fs_ncg; i *= 2) {
294 		cg += i;
295 		if (cg >= fs->fs_ncg)
296 			cg -= fs->fs_ncg;
297 		result = (*allocator)(dev, fs, cg, 0, size);
298 		if (result)
299 			return (result);
300 	}
301 	/*
302 	 * 3: brute force search
303 	 */
304 	cg = icg;
305 	for (i = 0; i < fs->fs_ncg; i++) {
306 		result = (*allocator)(dev, fs, cg, 0, size);
307 		if (result)
308 			return (result);
309 		cg++;
310 		if (cg == fs->fs_ncg)
311 			cg = 0;
312 	}
313 	return (0);
314 }
315 
316 /*
317  * Determine whether a fragment can be extended.
318  *
319  * Check to see if the necessary fragments are available, and
320  * if they are, allocate them.
321  */
322 daddr_t
323 fragextend(dev, fs, cg, bprev, osize, nsize)
324 	dev_t dev;
325 	register struct fs *fs;
326 	int cg;
327 	long bprev;
328 	int osize, nsize;
329 {
330 	register struct buf *bp;
331 	register struct cg *cgp;
332 	long bno;
333 	int frags, bbase;
334 	int i;
335 
336 	frags = nsize / fs->fs_fsize;
337 	bbase = bprev % fs->fs_frag;
338 	if (bbase > (bprev + frags - 1) % fs->fs_frag) {
339 		/* cannot extend across a block boundry */
340 		return (0);
341 	}
342 	bp = bread(dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
343 	if (bp->b_flags & B_ERROR)
344 		return (0);
345 	cgp = bp->b_un.b_cg;
346 	bno = dtogd(fs, bprev);
347 	for (i = osize / fs->fs_fsize; i < frags; i++)
348 		if (isclr(cgp->cg_free, bno + i)) {
349 			brelse(bp);
350 			return (0);
351 		}
352 	/*
353 	 * the current fragment can be extended
354 	 * deduct the count on fragment being extended into
355 	 * increase the count on the remaining fragment (if any)
356 	 * allocate the extended piece
357 	 */
358 	for (i = frags; i < fs->fs_frag - bbase; i++)
359 		if (isclr(cgp->cg_free, bno + i))
360 			break;
361 	cgp->cg_frsum[i - osize / fs->fs_fsize]--;
362 	if (i != frags)
363 		cgp->cg_frsum[i - frags]++;
364 	for (i = osize / fs->fs_fsize; i < frags; i++) {
365 		clrbit(cgp->cg_free, bno + i);
366 		cgp->cg_cs.cs_nffree--;
367 		fs->fs_cstotal.cs_nffree--;
368 		fs->fs_cs(fs, cg).cs_nffree--;
369 	}
370 	fs->fs_fmod++;
371 	bdwrite(bp);
372 	return (bprev);
373 }
374 
375 /*
376  * Determine whether a block can be allocated.
377  *
378  * Check to see if a block of the apprpriate size is available,
379  * and if it is, allocate it.
380  */
381 daddr_t
382 alloccg(dev, fs, cg, bpref, size)
383 	dev_t dev;
384 	register struct fs *fs;
385 	int cg;
386 	daddr_t bpref;
387 	int size;
388 {
389 	register struct buf *bp;
390 	register struct cg *cgp;
391 	int bno, frags;
392 	int allocsiz;
393 	register int i;
394 
395 	if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
396 		return (0);
397 	bp = bread(dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
398 	if (bp->b_flags & B_ERROR)
399 		return (0);
400 	cgp = bp->b_un.b_cg;
401 	if (size == fs->fs_bsize) {
402 		bno = alloccgblk(fs, cgp, bpref);
403 		bdwrite(bp);
404 		return (bno);
405 	}
406 	/*
407 	 * check to see if any fragments are already available
408 	 * allocsiz is the size which will be allocated, hacking
409 	 * it down to a smaller size if necessary
410 	 */
411 	frags = size / fs->fs_fsize;
412 	for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++)
413 		if (cgp->cg_frsum[allocsiz] != 0)
414 			break;
415 	if (allocsiz == fs->fs_frag) {
416 		/*
417 		 * no fragments were available, so a block will be
418 		 * allocated, and hacked up
419 		 */
420 		if (cgp->cg_cs.cs_nbfree == 0) {
421 			brelse(bp);
422 			return (0);
423 		}
424 		bno = alloccgblk(fs, cgp, bpref);
425 		bpref = dtogd(fs, bno);
426 		for (i = frags; i < fs->fs_frag; i++)
427 			setbit(cgp->cg_free, bpref + i);
428 		i = fs->fs_frag - frags;
429 		cgp->cg_cs.cs_nffree += i;
430 		fs->fs_cstotal.cs_nffree += i;
431 		fs->fs_cs(fs, cg).cs_nffree += i;
432 		cgp->cg_frsum[i]++;
433 		bdwrite(bp);
434 		return (bno);
435 	}
436 	bno = mapsearch(fs, cgp, bpref, allocsiz);
437 	if (bno == 0)
438 		return (0);
439 	for (i = 0; i < frags; i++)
440 		clrbit(cgp->cg_free, bno + i);
441 	cgp->cg_cs.cs_nffree -= frags;
442 	fs->fs_cstotal.cs_nffree -= frags;
443 	fs->fs_cs(fs, cg).cs_nffree -= frags;
444 	cgp->cg_frsum[allocsiz]--;
445 	if (frags != allocsiz)
446 		cgp->cg_frsum[allocsiz - frags]++;
447 	bdwrite(bp);
448 	return (cg * fs->fs_fpg + bno);
449 }
450 
451 /*
452  * Allocate a block in a cylinder group.
453  *
454  * This algorithm implements the following policy:
455  *   1) allocate the requested block.
456  *   2) allocate a rotationally optimal block in the same cylinder.
457  *   3) allocate the next available block on the block rotor for the
458  *      specified cylinder group.
459  * Note that this routine only allocates fs_bsize blocks; these
460  * blocks may be fragmented by the routine that allocates them.
461  */
462 daddr_t
463 alloccgblk(fs, cgp, bpref)
464 	struct fs *fs;
465 	register struct cg *cgp;
466 	daddr_t bpref;
467 {
468 	daddr_t bno;
469 	int cylno, pos;
470 	short *cylbp;
471 	register int i;
472 
473 	if (bpref == 0) {
474 		bpref = cgp->cg_rotor;
475 		goto norot;
476 	}
477 	bpref &= ~(fs->fs_frag - 1);
478 	bpref = dtogd(fs, bpref);
479 	/*
480 	 * if the requested block is available, use it
481 	 */
482 	if (isblock(fs, cgp->cg_free, bpref/fs->fs_frag)) {
483 		bno = bpref;
484 		goto gotit;
485 	}
486 	/*
487 	 * check for a block available on the same cylinder
488 	 */
489 	cylno = cbtocylno(fs, bpref);
490 	if (cgp->cg_btot[cylno] == 0)
491 		goto norot;
492 	if (fs->fs_cpc == 0) {
493 		/*
494 		 * block layout info is not available, so just have
495 		 * to take any block in this cylinder.
496 		 */
497 		bpref = howmany(fs->fs_spc * cylno, NSPF(fs));
498 		goto norot;
499 	}
500 	/*
501 	 * find a block that is rotationally optimal
502 	 */
503 	cylbp = cgp->cg_b[cylno];
504 	if (fs->fs_rotdelay == 0) {
505 		pos = cbtorpos(fs, bpref);
506 	} else {
507 		/*
508 		 * here we convert ms of delay to frags as:
509 		 * (frags) = (ms) * (rev/sec) * (sect/rev) /
510 		 *	((sect/frag) * (ms/sec))
511 		 * then round up to the next rotational position
512 		 */
513 		bpref += fs->fs_rotdelay * fs->fs_rps * fs->fs_nsect /
514 		    (NSPF(fs) * 1000);
515 		pos = cbtorpos(fs, bpref);
516 		pos = (pos + 1) % NRPOS;
517 	}
518 	/*
519 	 * check the summary information to see if a block is
520 	 * available in the requested cylinder starting at the
521 	 * optimal rotational position and proceeding around.
522 	 */
523 	for (i = pos; i < NRPOS; i++)
524 		if (cylbp[i] > 0)
525 			break;
526 	if (i == NRPOS)
527 		for (i = 0; i < pos; i++)
528 			if (cylbp[i] > 0)
529 				break;
530 	if (cylbp[i] > 0) {
531 		/*
532 		 * found a rotational position, now find the actual
533 		 * block. A panic if none is actually there.
534 		 */
535 		pos = cylno % fs->fs_cpc;
536 		bno = (cylno - pos) * fs->fs_spc / NSPB(fs);
537 		if (fs->fs_postbl[pos][i] == -1)
538 			panic("alloccgblk: cyl groups corrupted");
539 		for (i = fs->fs_postbl[pos][i]; ; i += fs->fs_rotbl[i]) {
540 			if (isblock(fs, cgp->cg_free, bno + i)) {
541 				bno = (bno + i) * fs->fs_frag;
542 				goto gotit;
543 			}
544 			if (fs->fs_rotbl[i] == 0)
545 				break;
546 		}
547 		panic("alloccgblk: can't find blk in cyl");
548 	}
549 norot:
550 	/*
551 	 * no blocks in the requested cylinder, so take next
552 	 * available one in this cylinder group.
553 	 */
554 	bno = mapsearch(fs, cgp, bpref, fs->fs_frag);
555 	if (bno == 0)
556 		return (0);
557 	cgp->cg_rotor = bno;
558 gotit:
559 	clrblock(fs, cgp->cg_free, bno/fs->fs_frag);
560 	cgp->cg_cs.cs_nbfree--;
561 	fs->fs_cstotal.cs_nbfree--;
562 	fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--;
563 	cylno = cbtocylno(fs, bno);
564 	cgp->cg_b[cylno][cbtorpos(fs, bno)]--;
565 	cgp->cg_btot[cylno]--;
566 	fs->fs_fmod++;
567 	return (cgp->cg_cgx * fs->fs_fpg + bno);
568 }
569 
570 /*
571  * Determine whether an inode can be allocated.
572  *
573  * Check to see if an inode is available, and if it is,
574  * allocate it using the following policy:
575  *   1) allocate the requested inode.
576  *   2) allocate the next available inode after the requested
577  *      inode in the specified cylinder group.
578  */
579 ino_t
580 ialloccg(dev, fs, cg, ipref, mode)
581 	dev_t dev;
582 	register struct fs *fs;
583 	int cg;
584 	daddr_t ipref;
585 	int mode;
586 {
587 	register struct buf *bp;
588 	register struct cg *cgp;
589 	int i;
590 
591 	if (fs->fs_cs(fs, cg).cs_nifree == 0)
592 		return (0);
593 	bp = bread(dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
594 	if (bp->b_flags & B_ERROR)
595 		return (0);
596 	cgp = bp->b_un.b_cg;
597 	if (ipref) {
598 		ipref %= fs->fs_ipg;
599 		if (isclr(cgp->cg_iused, ipref))
600 			goto gotit;
601 	} else
602 		ipref = cgp->cg_irotor;
603 	for (i = 0; i < fs->fs_ipg; i++) {
604 		ipref++;
605 		if (ipref >= fs->fs_ipg)
606 			ipref = 0;
607 		if (isclr(cgp->cg_iused, ipref)) {
608 			cgp->cg_irotor = ipref;
609 			goto gotit;
610 		}
611 	}
612 	brelse(bp);
613 	return (0);
614 gotit:
615 	setbit(cgp->cg_iused, ipref);
616 	cgp->cg_cs.cs_nifree--;
617 	fs->fs_cstotal.cs_nifree--;
618 	fs->fs_cs(fs, cg).cs_nifree--;
619 	fs->fs_fmod++;
620 	if ((mode & IFMT) == IFDIR) {
621 		cgp->cg_cs.cs_ndir++;
622 		fs->fs_cstotal.cs_ndir++;
623 		fs->fs_cs(fs, cg).cs_ndir++;
624 	}
625 	bdwrite(bp);
626 	return (cg * fs->fs_ipg + ipref);
627 }
628 
629 /*
630  * Free a block or fragment.
631  *
632  * The specified block or fragment is placed back in the
633  * free map. If a fragment is deallocated, a possible
634  * block reassembly is checked.
635  */
636 fre(dev, bno, size)
637 	dev_t dev;
638 	daddr_t bno;
639 	off_t size;
640 {
641 	register struct fs *fs;
642 	register struct cg *cgp;
643 	register struct buf *bp;
644 	int cg, blk, frags, bbase;
645 	register int i;
646 
647 	fs = getfs(dev);
648 	if ((unsigned)size > fs->fs_bsize || size % fs->fs_fsize != 0)
649 		panic("free: bad size");
650 	cg = dtog(fs, bno);
651 	if (badblock(fs, bno))
652 		return;
653 	bp = bread(dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
654 	if (bp->b_flags & B_ERROR)
655 		return;
656 	cgp = bp->b_un.b_cg;
657 	bno = dtogd(fs, bno);
658 	if (size == fs->fs_bsize) {
659 		if (isblock(fs, cgp->cg_free, bno/fs->fs_frag))
660 			panic("free: freeing free block");
661 		setblock(fs, cgp->cg_free, bno/fs->fs_frag);
662 		cgp->cg_cs.cs_nbfree++;
663 		fs->fs_cstotal.cs_nbfree++;
664 		fs->fs_cs(fs, cg).cs_nbfree++;
665 		i = cbtocylno(fs, bno);
666 		cgp->cg_b[i][cbtorpos(fs, bno)]++;
667 		cgp->cg_btot[i]++;
668 	} else {
669 		bbase = bno - (bno % fs->fs_frag);
670 		/*
671 		 * decrement the counts associated with the old frags
672 		 */
673 		blk = ((cgp->cg_free[bbase / NBBY] >> (bbase % NBBY)) &
674 		       (0xff >> (NBBY - fs->fs_frag)));
675 		fragacct(fs, blk, cgp->cg_frsum, -1);
676 		/*
677 		 * deallocate the fragment
678 		 */
679 		frags = size / fs->fs_fsize;
680 		for (i = 0; i < frags; i++) {
681 			if (isset(cgp->cg_free, bno + i))
682 				panic("free: freeing free frag");
683 			setbit(cgp->cg_free, bno + i);
684 			cgp->cg_cs.cs_nffree++;
685 			fs->fs_cstotal.cs_nffree++;
686 			fs->fs_cs(fs, cg).cs_nffree++;
687 		}
688 		/*
689 		 * add back in counts associated with the new frags
690 		 */
691 		blk = ((cgp->cg_free[bbase / NBBY] >> (bbase % NBBY)) &
692 		       (0xff >> (NBBY - fs->fs_frag)));
693 		fragacct(fs, blk, cgp->cg_frsum, 1);
694 		/*
695 		 * if a complete block has been reassembled, account for it
696 		 */
697 		if (isblock(fs, cgp->cg_free, bbase / fs->fs_frag)) {
698 			cgp->cg_cs.cs_nffree -= fs->fs_frag;
699 			fs->fs_cstotal.cs_nffree -= fs->fs_frag;
700 			fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;
701 			cgp->cg_cs.cs_nbfree++;
702 			fs->fs_cstotal.cs_nbfree++;
703 			fs->fs_cs(fs, cg).cs_nbfree++;
704 			i = cbtocylno(fs, bbase);
705 			cgp->cg_b[i][cbtorpos(fs, bbase)]++;
706 			cgp->cg_btot[i]++;
707 		}
708 	}
709 	fs->fs_fmod++;
710 	bdwrite(bp);
711 }
712 
713 /*
714  * Free an inode.
715  *
716  * The specified inode is placed back in the free map.
717  */
718 ifree(dev, ino, mode)
719 	dev_t dev;
720 	ino_t ino;
721 	int mode;
722 {
723 	register struct fs *fs;
724 	register struct cg *cgp;
725 	register struct buf *bp;
726 	int cg;
727 
728 	fs = getfs(dev);
729 	if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg)
730 		panic("ifree: range");
731 	cg = itog(fs, ino);
732 	bp = bread(dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
733 	if (bp->b_flags & B_ERROR)
734 		return;
735 	cgp = bp->b_un.b_cg;
736 	ino %= fs->fs_ipg;
737 	if (isclr(cgp->cg_iused, ino))
738 		panic("ifree: freeing free inode");
739 	clrbit(cgp->cg_iused, ino);
740 	cgp->cg_cs.cs_nifree++;
741 	fs->fs_cstotal.cs_nifree++;
742 	fs->fs_cs(fs, cg).cs_nifree++;
743 	if ((mode & IFMT) == IFDIR) {
744 		cgp->cg_cs.cs_ndir--;
745 		fs->fs_cstotal.cs_ndir--;
746 		fs->fs_cs(fs, cg).cs_ndir--;
747 	}
748 	fs->fs_fmod++;
749 	bdwrite(bp);
750 }
751 
752 /*
753  * Find a block of the specified size in the specified cylinder group.
754  *
755  * It is a panic if a request is made to find a block if none are
756  * available.
757  */
758 daddr_t
759 mapsearch(fs, cgp, bpref, allocsiz)
760 	register struct fs *fs;
761 	register struct cg *cgp;
762 	daddr_t bpref;
763 	int allocsiz;
764 {
765 	daddr_t bno;
766 	int start, len, loc, i;
767 	int blk, field, subfield, pos;
768 
769 	/*
770 	 * find the fragment by searching through the free block
771 	 * map for an appropriate bit pattern
772 	 */
773 	if (bpref)
774 		start = dtogd(fs, bpref) / NBBY;
775 	else
776 		start = cgp->cg_frotor / NBBY;
777 	len = roundup(fs->fs_fpg - 1, NBBY) / NBBY - start;
778 	loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
779 		1 << (allocsiz - 1));
780 	if (loc == 0) {
781 		len = start - 1;
782 		start = fs->fs_dblkno / NBBY;
783 		loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
784 			1 << (allocsiz - 1));
785 		if (loc == 0) {
786 			panic("alloccg: map corrupted");
787 			return (0);
788 		}
789 	}
790 	bno = (start + len - loc) * NBBY;
791 	cgp->cg_frotor = bno;
792 	/*
793 	 * found the byte in the map
794 	 * sift through the bits to find the selected frag
795 	 */
796 	for (i = 0; i < NBBY; i += fs->fs_frag) {
797 		blk = (cgp->cg_free[bno / NBBY] >> i) &
798 		      (0xff >> NBBY - fs->fs_frag);
799 		blk <<= 1;
800 		field = around[allocsiz];
801 		subfield = inside[allocsiz];
802 		for (pos = 0; pos <= fs->fs_frag - allocsiz; pos++) {
803 			if ((blk & field) == subfield) {
804 				return (bno + i + pos);
805 			}
806 			field <<= 1;
807 			subfield <<= 1;
808 		}
809 	}
810 	panic("alloccg: block not in map");
811 	return (0);
812 }
813 
814 /*
815  * Update the frsum fields to reflect addition or deletion
816  * of some frags.
817  */
818 fragacct(fs, fragmap, fraglist, cnt)
819 	struct fs *fs;
820 	int fragmap;
821 	long fraglist[];
822 	int cnt;
823 {
824 	int inblk;
825 	register int field, subfield;
826 	register int siz, pos;
827 
828 	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
829 	fragmap <<= 1;
830 	for (siz = 1; siz < fs->fs_frag; siz++) {
831 		if (((1 << siz) & inblk) == 0)
832 			continue;
833 		field = around[siz];
834 		subfield = inside[siz];
835 		for (pos = siz; pos <= fs->fs_frag; pos++) {
836 			if ((fragmap & field) == subfield) {
837 				fraglist[siz] += cnt;
838 				pos += siz;
839 				field <<= siz;
840 				subfield <<= siz;
841 			}
842 			field <<= 1;
843 			subfield <<= 1;
844 		}
845 	}
846 }
847 
848 /*
849  * Check that a specified block number is in range.
850  */
851 badblock(fs, bn)
852 	register struct fs *fs;
853 	daddr_t bn;
854 {
855 
856 	if ((unsigned)bn >= fs->fs_size || bn < cgdmin(fs, dtog(fs, bn))) {
857 		fserr(fs, "bad block");
858 		return (1);
859 	}
860 	return (0);
861 }
862 
863 /*
864  * Getfs maps a device number into a pointer to the incore super block.
865  *
866  * The algorithm is a linear search through the mount table. A
867  * consistency check of the super block magic number is performed.
868  *
869  * panic: no fs -- the device is not mounted.
870  *	this "cannot happen"
871  */
872 struct fs *
873 getfs(dev)
874 	dev_t dev;
875 {
876 	register struct mount *mp;
877 	register struct fs *fs;
878 
879 	for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
880 		if (mp->m_bufp != NULL && mp->m_dev == dev) {
881 			fs = mp->m_bufp->b_un.b_fs;
882 			if (fs->fs_magic != FS_MAGIC)
883 				panic("getfs: bad magic");
884 			return (fs);
885 		}
886 	panic("getfs: no fs");
887 	return (NULL);
888 }
889 
890 /*
891  * Fserr prints the name of a file system with an error diagnostic.
892  *
893  * The form of the error message is:
894  *	fs: error message
895  */
896 fserr(fs, cp)
897 	struct fs *fs;
898 	char *cp;
899 {
900 
901 	printf("%s: %s\n", fs->fs_fsmnt, cp);
902 }
903 
904 /*
905  * Getfsx returns the index in the file system
906  * table of the specified device.  The swap device
907  * is also assigned a pseudo-index.  The index may
908  * be used as a compressed indication of the location
909  * of a block, recording
910  *	<getfsx(dev),blkno>
911  * rather than
912  *	<dev, blkno>
913  * provided the information need remain valid only
914  * as long as the file system is mounted.
915  */
916 getfsx(dev)
917 	dev_t dev;
918 {
919 	register struct mount *mp;
920 
921 	if (dev == swapdev)
922 		return (MSWAPX);
923 	for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
924 		if (mp->m_dev == dev)
925 			return (mp - &mount[0]);
926 	return (-1);
927 }
928 
929 /*
930  * Update is the internal name of 'sync'.  It goes through the disk
931  * queues to initiate sandbagged IO; goes through the inodes to write
932  * modified nodes; and it goes through the mount table to initiate
933  * the writing of the modified super blocks.
934  */
935 update()
936 {
937 	register struct inode *ip;
938 	register struct mount *mp;
939 	register struct buf *bp;
940 	struct fs *fs;
941 	time_t tim;
942 	int i, blks;
943 
944 	if (updlock)
945 		return;
946 	updlock++;
947 	/*
948 	 * Write back modified superblocks.
949 	 * Consistency check that the superblock
950 	 * of each file system is still in the buffer cache.
951 	 */
952 	for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
953 		if (mp->m_bufp != NULL) {
954 			fs = mp->m_bufp->b_un.b_fs;
955 			if (fs->fs_fmod == 0)
956 				continue;
957 			if (fs->fs_ronly != 0)
958 				panic("update: rofs mod");
959 			bp = getblk(mp->m_dev, SBLOCK, SBSIZE);
960 			fs->fs_fmod = 0;
961 			fs->fs_time = TIME;
962 			if (bp->b_un.b_fs != fs)
963 				panic("update: bad b_fs");
964 			bwrite(bp);
965 			blks = howmany(fs->fs_cssize, fs->fs_bsize);
966 			for (i = 0; i < blks; i++) {
967 				bp = getblk(mp->m_dev,
968 				    fsbtodb(fs, fs->fs_csaddr + (i * fs->fs_frag)),
969 				    fs->fs_bsize);
970 				bwrite(bp);
971 			}
972 		}
973 	/*
974 	 * Write back each (modified) inode.
975 	 */
976 	for (ip = inode; ip < inodeNINODE; ip++)
977 		if((ip->i_flag&ILOCK)==0 && ip->i_count) {
978 			ip->i_flag |= ILOCK;
979 			ip->i_count++;
980 			tim = TIME;
981 			iupdat(ip, &tim, &tim, 0);
982 			iput(ip);
983 		}
984 	updlock = 0;
985 	/*
986 	 * Force stale buffer cache information to be flushed,
987 	 * for all devices.
988 	 */
989 	bflush(NODEV);
990 }
991 
992 /*
993  * block operations
994  *
995  * check if a block is available
996  */
997 isblock(fs, cp, h)
998 	struct fs *fs;
999 	unsigned char *cp;
1000 	int h;
1001 {
1002 	unsigned char mask;
1003 
1004 	switch (fs->fs_frag) {
1005 	case 8:
1006 		return (cp[h] == 0xff);
1007 	case 4:
1008 		mask = 0x0f << ((h & 0x1) << 2);
1009 		return ((cp[h >> 1] & mask) == mask);
1010 	case 2:
1011 		mask = 0x03 << ((h & 0x3) << 1);
1012 		return ((cp[h >> 2] & mask) == mask);
1013 	case 1:
1014 		mask = 0x01 << (h & 0x7);
1015 		return ((cp[h >> 3] & mask) == mask);
1016 	default:
1017 		panic("isblock bad fs_frag");
1018 		return;
1019 	}
1020 }
1021 
1022 /*
1023  * take a block out of the map
1024  */
1025 clrblock(fs, cp, h)
1026 	struct fs *fs;
1027 	unsigned char *cp;
1028 	int h;
1029 {
1030 	switch ((fs)->fs_frag) {
1031 	case 8:
1032 		cp[h] = 0;
1033 		return;
1034 	case 4:
1035 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1036 		return;
1037 	case 2:
1038 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1039 		return;
1040 	case 1:
1041 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
1042 		return;
1043 	default:
1044 		panic("clrblock bad fs_frag");
1045 		return;
1046 	}
1047 }
1048 
1049 /*
1050  * put a block into the map
1051  */
1052 setblock(fs, cp, h)
1053 	struct fs *fs;
1054 	unsigned char *cp;
1055 	int h;
1056 {
1057 	switch (fs->fs_frag) {
1058 	case 8:
1059 		cp[h] = 0xff;
1060 		return;
1061 	case 4:
1062 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
1063 		return;
1064 	case 2:
1065 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
1066 		return;
1067 	case 1:
1068 		cp[h >> 3] |= (0x01 << (h & 0x7));
1069 		return;
1070 	default:
1071 		panic("setblock bad fs_frag");
1072 		return;
1073 	}
1074 }
1075