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