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