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