Annotation of sys/ufs/ffs/ffs_alloc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ffs_alloc.c,v 1.78 2007/06/22 13:59:12 thib Exp $ */
2: /* $NetBSD: ffs_alloc.c,v 1.11 1996/05/11 18:27:09 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 2002 Networks Associates Technology, Inc.
6: * All rights reserved.
7: *
8: * This software was developed for the FreeBSD Project by Marshall
9: * Kirk McKusick and Network Associates Laboratories, the Security
10: * Research Division of Network Associates, Inc. under DARPA/SPAWAR
11: * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
12: * research program.
13: *
14: * Copyright (c) 1982, 1986, 1989, 1993
15: * The Regents of the University of California. All rights reserved.
16: *
17: * Redistribution and use in source and binary forms, with or without
18: * modification, are permitted provided that the following conditions
19: * are met:
20: * 1. Redistributions of source code must retain the above copyright
21: * notice, this list of conditions and the following disclaimer.
22: * 2. Redistributions in binary form must reproduce the above copyright
23: * notice, this list of conditions and the following disclaimer in the
24: * documentation and/or other materials provided with the distribution.
25: * 3. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: *
41: * @(#)ffs_alloc.c 8.11 (Berkeley) 10/27/94
42: */
43:
44: #include <sys/param.h>
45: #include <sys/systm.h>
46: #include <sys/buf.h>
47: #include <sys/proc.h>
48: #include <sys/vnode.h>
49: #include <sys/mount.h>
50: #include <sys/kernel.h>
51: #include <sys/syslog.h>
52: #include <sys/stdint.h>
53:
54: #include <uvm/uvm_extern.h>
55:
56: #include <dev/rndvar.h>
57:
58: #include <ufs/ufs/quota.h>
59: #include <ufs/ufs/inode.h>
60: #include <ufs/ufs/ufsmount.h>
61: #include <ufs/ufs/ufs_extern.h>
62:
63: #include <ufs/ffs/fs.h>
64: #include <ufs/ffs/ffs_extern.h>
65:
66: #define ffs_fserr(fs, uid, cp) do { \
67: log(LOG_ERR, "uid %u on %s: %s\n", (uid), \
68: (fs)->fs_fsmnt, (cp)); \
69: } while (0)
70:
71: daddr_t ffs_alloccg(struct inode *, int, daddr_t, int);
72: daddr_t ffs_alloccgblk(struct inode *, struct buf *, daddr_t);
73: daddr_t ffs_clusteralloc(struct inode *, int, daddr_t, int);
74: ino_t ffs_dirpref(struct inode *);
75: daddr_t ffs_fragextend(struct inode *, int, long, int, int);
76: u_long ffs_hashalloc(struct inode *, int, long, int,
77: daddr_t (*)(struct inode *, int, daddr_t, int));
78: daddr_t ffs_nodealloccg(struct inode *, int, daddr_t, int);
79: daddr_t ffs_mapsearch(struct fs *, struct cg *, daddr_t, int);
80:
81: int ffs1_reallocblks(void *);
82: #ifdef FFS2
83: int ffs2_reallocblks(void *);
84: #endif
85:
86: #ifdef DIAGNOSTIC
87: int ffs_checkblk(struct inode *, daddr_t, long);
88: #endif
89:
90: /*
91: * Allocate a block in the file system.
92: *
93: * The size of the requested block is given, which must be some
94: * multiple of fs_fsize and <= fs_bsize.
95: * A preference may be optionally specified. If a preference is given
96: * the following hierarchy is used to allocate a block:
97: * 1) allocate the requested block.
98: * 2) allocate a rotationally optimal block in the same cylinder.
99: * 3) allocate a block in the same cylinder group.
100: * 4) quadratically rehash into other cylinder groups, until an
101: * available block is located.
102: * If no block preference is given the following hierarchy is used
103: * to allocate a block:
104: * 1) allocate a block in the cylinder group that contains the
105: * inode for the file.
106: * 2) quadratically rehash into other cylinder groups, until an
107: * available block is located.
108: */
109: int
110: ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size,
111: struct ucred *cred, daddr_t *bnp)
112: {
113: struct fs *fs;
114: daddr_t bno;
115: int cg;
116: int error;
117:
118: *bnp = 0;
119: fs = ip->i_fs;
120: #ifdef DIAGNOSTIC
121: if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
122: printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n",
123: ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt);
124: panic("ffs_alloc: bad size");
125: }
126: if (cred == NOCRED)
127: panic("ffs_alloc: missing credential");
128: #endif /* DIAGNOSTIC */
129: if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
130: goto nospace;
131: if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0)
132: goto nospace;
133:
134: if ((error = ufs_quota_alloc_blocks(ip, btodb(size), cred)) != 0)
135: return (error);
136:
137: /*
138: * Start allocation in the preferred block's cylinder group or
139: * the file's inode's cylinder group if no preferred block was
140: * specified.
141: */
142: if (bpref >= fs->fs_size)
143: bpref = 0;
144: if (bpref == 0)
145: cg = ino_to_cg(fs, ip->i_number);
146: else
147: cg = dtog(fs, bpref);
148:
149: /* Try allocating a block. */
150: bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, size, ffs_alloccg);
151: if (bno > 0) {
152: /* allocation successful, update inode data */
153: DIP_ADD(ip, blocks, btodb(size));
154: ip->i_flag |= IN_CHANGE | IN_UPDATE;
155: *bnp = bno;
156: return (0);
157: }
158:
159: /* Restore user's disk quota because allocation failed. */
160: (void) ufs_quota_free_blocks(ip, btodb(size), cred);
161:
162: nospace:
163: ffs_fserr(fs, cred->cr_uid, "file system full");
164: uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
165: return (ENOSPC);
166: }
167:
168: /*
169: * Reallocate a fragment to a bigger size
170: *
171: * The number and size of the old block is given, and a preference
172: * and new size is also specified. The allocator attempts to extend
173: * the original block. Failing that, the regular block allocator is
174: * invoked to get an appropriate block.
175: */
176: int
177: ffs_realloccg(struct inode *ip, daddr_t lbprev, daddr_t bpref, int osize,
178: int nsize, struct ucred *cred, struct buf **bpp, daddr_t *blknop)
179: {
180: struct fs *fs;
181: struct buf *bp = NULL;
182: daddr_t quota_updated = 0;
183: int cg, request, error;
184: daddr_t bprev, bno;
185:
186: if (bpp != NULL)
187: *bpp = NULL;
188: fs = ip->i_fs;
189: #ifdef DIAGNOSTIC
190: if ((u_int)osize > fs->fs_bsize || fragoff(fs, osize) != 0 ||
191: (u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) {
192: printf(
193: "dev = 0x%x, bsize = %d, osize = %d, nsize = %d, fs = %s\n",
194: ip->i_dev, fs->fs_bsize, osize, nsize, fs->fs_fsmnt);
195: panic("ffs_realloccg: bad size");
196: }
197: if (cred == NOCRED)
198: panic("ffs_realloccg: missing credential");
199: #endif /* DIAGNOSTIC */
200: if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0)
201: goto nospace;
202:
203: bprev = DIP(ip, db[lbprev]);
204:
205: if (bprev == 0) {
206: printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n",
207: ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt);
208: panic("ffs_realloccg: bad bprev");
209: }
210:
211: /*
212: * Allocate the extra space in the buffer.
213: */
214: if (bpp != NULL) {
215: if ((error = bread(ITOV(ip), lbprev, fs->fs_bsize,
216: NOCRED, &bp)) != 0)
217: goto error;
218: bp->b_bcount = osize;
219: }
220:
221: if ((error = ufs_quota_alloc_blocks(ip, btodb(nsize - osize), cred))
222: != 0)
223: goto error;
224:
225: quota_updated = btodb(nsize - osize);
226:
227: /*
228: * Check for extension in the existing location.
229: */
230: cg = dtog(fs, bprev);
231: if ((bno = ffs_fragextend(ip, cg, (long)bprev, osize, nsize)) != 0) {
232: DIP_ADD(ip, blocks, btodb(nsize - osize));
233: ip->i_flag |= IN_CHANGE | IN_UPDATE;
234: if (bpp != NULL) {
235: if (bp->b_blkno != fsbtodb(fs, bno))
236: panic("ffs_realloccg: bad blockno");
237: #ifdef DIAGNOSTIC
238: if (nsize > bp->b_bufsize)
239: panic("ffs_realloccg: small buf");
240: #endif
241: bp->b_bcount = nsize;
242: bp->b_flags |= B_DONE;
243: bzero(bp->b_data + osize, (u_int)nsize - osize);
244: *bpp = bp;
245: }
246: if (blknop != NULL) {
247: *blknop = bno;
248: }
249: return (0);
250: }
251: /*
252: * Allocate a new disk location.
253: */
254: if (bpref >= fs->fs_size)
255: bpref = 0;
256: switch (fs->fs_optim) {
257: case FS_OPTSPACE:
258: /*
259: * Allocate an exact sized fragment. Although this makes
260: * best use of space, we will waste time relocating it if
261: * the file continues to grow. If the fragmentation is
262: * less than half of the minimum free reserve, we choose
263: * to begin optimizing for time.
264: */
265: request = nsize;
266: if (fs->fs_minfree < 5 ||
267: fs->fs_cstotal.cs_nffree >
268: fs->fs_dsize * fs->fs_minfree / (2 * 100))
269: break;
270: fs->fs_optim = FS_OPTTIME;
271: break;
272: case FS_OPTTIME:
273: /*
274: * At this point we have discovered a file that is trying to
275: * grow a small fragment to a larger fragment. To save time,
276: * we allocate a full sized block, then free the unused portion.
277: * If the file continues to grow, the `ffs_fragextend' call
278: * above will be able to grow it in place without further
279: * copying. If aberrant programs cause disk fragmentation to
280: * grow within 2% of the free reserve, we choose to begin
281: * optimizing for space.
282: */
283: request = fs->fs_bsize;
284: if (fs->fs_cstotal.cs_nffree <
285: fs->fs_dsize * (fs->fs_minfree - 2) / 100)
286: break;
287: fs->fs_optim = FS_OPTSPACE;
288: break;
289: default:
290: printf("dev = 0x%x, optim = %d, fs = %s\n",
291: ip->i_dev, fs->fs_optim, fs->fs_fsmnt);
292: panic("ffs_realloccg: bad optim");
293: /* NOTREACHED */
294: }
295: bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request,
296: ffs_alloccg);
297: if (bno <= 0)
298: goto nospace;
299:
300: (void) uvm_vnp_uncache(ITOV(ip));
301: if (!DOINGSOFTDEP(ITOV(ip)))
302: ffs_blkfree(ip, bprev, (long)osize);
303: if (nsize < request)
304: ffs_blkfree(ip, bno + numfrags(fs, nsize),
305: (long)(request - nsize));
306: DIP_ADD(ip, blocks, btodb(nsize - osize));
307: ip->i_flag |= IN_CHANGE | IN_UPDATE;
308: if (bpp != NULL) {
309: bp->b_blkno = fsbtodb(fs, bno);
310: #ifdef DIAGNOSTIC
311: if (nsize > bp->b_bufsize)
312: panic("ffs_realloccg: small buf 2");
313: #endif
314: bp->b_bcount = nsize;
315: bp->b_flags |= B_DONE;
316: bzero(bp->b_data + osize, (u_int)nsize - osize);
317: *bpp = bp;
318: }
319: if (blknop != NULL) {
320: *blknop = bno;
321: }
322: return (0);
323:
324: nospace:
325: /*
326: * no space available
327: */
328: ffs_fserr(fs, cred->cr_uid, "file system full");
329: uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
330: error = ENOSPC;
331:
332: error:
333: if (bp != NULL) {
334: brelse(bp);
335: bp = NULL;
336: }
337:
338: /*
339: * Restore user's disk quota because allocation failed.
340: */
341: if (quota_updated != 0)
342: (void)ufs_quota_free_blocks(ip, quota_updated, cred);
343:
344: return error;
345: }
346:
347: /*
348: * Reallocate a sequence of blocks into a contiguous sequence of blocks.
349: *
350: * The vnode and an array of buffer pointers for a range of sequential
351: * logical blocks to be made contiguous are given. The allocator attempts
352: * to find a range of sequential blocks starting as close as possible to
353: * an fs_rotdelay offset from the end of the allocation for the logical
354: * block immediately preceding the current range. If successful, the
355: * physical block numbers in the buffer pointers and in the inode are
356: * changed to reflect the new allocation. If unsuccessful, the allocation
357: * is left unchanged. The success in doing the reallocation is returned.
358: * Note that the error return is not reflected back to the user. Rather
359: * the previous block allocation will be used.
360: */
361:
362: int doasyncfree = 1;
363: int doreallocblks = 1;
364: int prtrealloc = 0;
365:
366: int
367: ffs1_reallocblks(void *v)
368: {
369: struct vop_reallocblks_args *ap = v;
370: struct fs *fs;
371: struct inode *ip;
372: struct vnode *vp;
373: struct buf *sbp, *ebp;
374: daddr_t *bap, *sbap, *ebap = NULL;
375: struct cluster_save *buflist;
376: daddr_t start_lbn, end_lbn, soff, newblk, blkno;
377: struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
378: int i, len, start_lvl, end_lvl, pref, ssize;
379:
380: vp = ap->a_vp;
381: ip = VTOI(vp);
382: fs = ip->i_fs;
383: if (fs->fs_contigsumsize <= 0)
384: return (ENOSPC);
385: buflist = ap->a_buflist;
386: len = buflist->bs_nchildren;
387: start_lbn = buflist->bs_children[0]->b_lblkno;
388: end_lbn = start_lbn + len - 1;
389:
390: #ifdef DIAGNOSTIC
391: for (i = 0; i < len; i++)
392: if (!ffs_checkblk(ip,
393: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
394: panic("ffs1_reallocblks: unallocated block 1");
395:
396: for (i = 1; i < len; i++)
397: if (buflist->bs_children[i]->b_lblkno != start_lbn + i)
398: panic("ffs1_reallocblks: non-logical cluster");
399:
400: blkno = buflist->bs_children[0]->b_blkno;
401: ssize = fsbtodb(fs, fs->fs_frag);
402: for (i = 1; i < len - 1; i++)
403: if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize))
404: panic("ffs1_reallocblks: non-physical cluster %d", i);
405: #endif
406: /*
407: * If the latest allocation is in a new cylinder group, assume that
408: * the filesystem has decided to move and do not force it back to
409: * the previous cylinder group.
410: */
411: if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) !=
412: dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno)))
413: return (ENOSPC);
414: if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
415: ufs_getlbns(vp, end_lbn, end_ap, &end_lvl))
416: return (ENOSPC);
417: /*
418: * Get the starting offset and block map for the first block.
419: */
420: if (start_lvl == 0) {
421: sbap = &ip->i_ffs1_db[0];
422: soff = start_lbn;
423: } else {
424: idp = &start_ap[start_lvl - 1];
425: if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &sbp)) {
426: brelse(sbp);
427: return (ENOSPC);
428: }
429: sbap = (daddr_t *)sbp->b_data;
430: soff = idp->in_off;
431: }
432: /*
433: * Find the preferred location for the cluster.
434: */
435: pref = ffs1_blkpref(ip, start_lbn, soff, sbap);
436: /*
437: * If the block range spans two block maps, get the second map.
438: */
439: if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
440: ssize = len;
441: } else {
442: #ifdef DIAGNOSTIC
443: if (start_lvl > 1 &&
444: start_ap[start_lvl-1].in_lbn == idp->in_lbn)
445: panic("ffs1_reallocblk: start == end");
446: #endif
447: ssize = len - (idp->in_off + 1);
448: if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &ebp))
449: goto fail;
450: ebap = (daddr_t *)ebp->b_data;
451: }
452: /*
453: * Search the block map looking for an allocation of the desired size.
454: */
455: if ((newblk = (daddr_t)ffs_hashalloc(ip, dtog(fs, pref), (long)pref,
456: len, ffs_clusteralloc)) == 0)
457: goto fail;
458: /*
459: * We have found a new contiguous block.
460: *
461: * First we have to replace the old block pointers with the new
462: * block pointers in the inode and indirect blocks associated
463: * with the file.
464: */
465: #ifdef DEBUG
466: if (prtrealloc)
467: printf("realloc: ino %d, lbns %d-%d\n\told:", ip->i_number,
468: start_lbn, end_lbn);
469: #endif
470: blkno = newblk;
471: for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {
472: if (i == ssize) {
473: bap = ebap;
474: soff = -i;
475: }
476: #ifdef DIAGNOSTIC
477: if (!ffs_checkblk(ip,
478: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
479: panic("ffs1_reallocblks: unallocated block 2");
480: if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap)
481: panic("ffs1_reallocblks: alloc mismatch");
482: #endif
483: #ifdef DEBUG
484: if (prtrealloc)
485: printf(" %d,", *bap);
486: #endif
487: if (DOINGSOFTDEP(vp)) {
488: if (sbap == &ip->i_ffs1_db[0] && i < ssize)
489: softdep_setup_allocdirect(ip, start_lbn + i,
490: blkno, *bap, fs->fs_bsize, fs->fs_bsize,
491: buflist->bs_children[i]);
492: else
493: softdep_setup_allocindir_page(ip, start_lbn + i,
494: i < ssize ? sbp : ebp, soff + i, blkno,
495: *bap, buflist->bs_children[i]);
496: }
497:
498: *bap++ = blkno;
499: }
500: /*
501: * Next we must write out the modified inode and indirect blocks.
502: * For strict correctness, the writes should be synchronous since
503: * the old block values may have been written to disk. In practise
504: * they are almost never written, but if we are concerned about
505: * strict correctness, the `doasyncfree' flag should be set to zero.
506: *
507: * The test on `doasyncfree' should be changed to test a flag
508: * that shows whether the associated buffers and inodes have
509: * been written. The flag should be set when the cluster is
510: * started and cleared whenever the buffer or inode is flushed.
511: * We can then check below to see if it is set, and do the
512: * synchronous write only when it has been cleared.
513: */
514: if (sbap != &ip->i_ffs1_db[0]) {
515: if (doasyncfree)
516: bdwrite(sbp);
517: else
518: bwrite(sbp);
519: } else {
520: ip->i_flag |= IN_CHANGE | IN_UPDATE;
521: if (!doasyncfree) {
522: UFS_UPDATE(ip, MNT_WAIT);
523: }
524: }
525: if (ssize < len) {
526: if (doasyncfree)
527: bdwrite(ebp);
528: else
529: bwrite(ebp);
530: }
531: /*
532: * Last, free the old blocks and assign the new blocks to the buffers.
533: */
534: #ifdef DEBUG
535: if (prtrealloc)
536: printf("\n\tnew:");
537: #endif
538: for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
539: if (!DOINGSOFTDEP(vp))
540: ffs_blkfree(ip,
541: dbtofsb(fs, buflist->bs_children[i]->b_blkno),
542: fs->fs_bsize);
543: buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
544: #ifdef DIAGNOSTIC
545: if (!ffs_checkblk(ip,
546: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
547: panic("ffs1_reallocblks: unallocated block 3");
548: if (prtrealloc)
549: printf(" %d,", blkno);
550: #endif
551: }
552: #ifdef DEBUG
553: if (prtrealloc) {
554: prtrealloc--;
555: printf("\n");
556: }
557: #endif
558: return (0);
559:
560: fail:
561: if (ssize < len)
562: brelse(ebp);
563: if (sbap != &ip->i_ffs1_db[0])
564: brelse(sbp);
565: return (ENOSPC);
566: }
567:
568: #ifdef FFS2
569: int
570: ffs2_reallocblks(void *v)
571: {
572: struct vop_reallocblks_args *ap = v;
573: struct fs *fs;
574: struct inode *ip;
575: struct vnode *vp;
576: struct buf *sbp, *ebp;
577: daddr64_t *bap, *sbap, *ebap = 0;
578: struct cluster_save *buflist;
579: struct ufsmount *ump;
580: daddr64_t start_lbn, end_lbn;
581: daddr64_t soff, newblk, blkno, pref;
582: struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
583: int i, len, start_lvl, end_lvl, ssize;
584:
585: vp = ap->a_vp;
586: ip = VTOI(vp);
587: fs = ip->i_fs;
588: ump = ip->i_ump;
589:
590: if (fs->fs_contigsumsize <= 0)
591: return (ENOSPC);
592:
593: buflist = ap->a_buflist;
594: len = buflist->bs_nchildren;
595: start_lbn = buflist->bs_children[0]->b_lblkno;
596: end_lbn = start_lbn + len - 1;
597:
598: #ifdef DIAGNOSTIC
599: for (i = 0; i < len; i++)
600: if (!ffs_checkblk(ip,
601: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
602: panic("ffs2_reallocblks: unallocated block 1");
603:
604: for (i = 1; i < len; i++)
605: if (buflist->bs_children[i]->b_lblkno != start_lbn + i)
606: panic("ffs2_reallocblks: non-logical cluster");
607:
608: blkno = buflist->bs_children[0]->b_blkno;
609: ssize = fsbtodb(fs, fs->fs_frag);
610:
611: for (i = 1; i < len - 1; i++)
612: if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize))
613: panic("ffs2_reallocblks: non-physical cluster %d", i);
614: #endif
615:
616: /*
617: * If the latest allocation is in a new cylinder group, assume that
618: * the filesystem has decided to move and do not force it back to
619: * the previous cylinder group.
620: */
621: if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) !=
622: dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno)))
623: return (ENOSPC);
624: if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
625: ufs_getlbns(vp, end_lbn, end_ap, &end_lvl))
626: return (ENOSPC);
627:
628: /*
629: * Get the starting offset and block map for the first block.
630: */
631: if (start_lvl == 0) {
632: sbap = &ip->i_din2->di_db[0];
633: soff = start_lbn;
634: } else {
635: idp = &start_ap[start_lvl - 1];
636: if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &sbp)) {
637: brelse(sbp);
638: return (ENOSPC);
639: }
640: sbap = (daddr64_t *)sbp->b_data;
641: soff = idp->in_off;
642: }
643:
644: /*
645: * If the block range spans two block maps, get the second map.
646: */
647: if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
648: ssize = len;
649: } else {
650: #ifdef DIAGNOSTIC
651: if (start_ap[start_lvl-1].in_lbn == idp->in_lbn)
652: panic("ffs2_reallocblk: start == end");
653: #endif
654: ssize = len - (idp->in_off + 1);
655: if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &ebp))
656: goto fail;
657: ebap = (daddr64_t *)ebp->b_data;
658: }
659:
660: /*
661: * Find the preferred location for the cluster.
662: */
663: pref = ffs2_blkpref(ip, start_lbn, soff, sbap);
664:
665: /*
666: * Search the block map looking for an allocation of the desired size.
667: */
668: if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
669: len, ffs_clusteralloc)) == 0)
670: goto fail;
671:
672: /*
673: * We have found a new contiguous block.
674: *
675: * First we have to replace the old block pointers with the new
676: * block pointers in the inode and indirect blocks associated
677: * with the file.
678: */
679: #ifdef DEBUG
680: if (prtrealloc)
681: printf("realloc: ino %d, lbns %jd-%jd\n\told:", ip->i_number,
682: (intmax_t)start_lbn, (intmax_t)end_lbn);
683: #endif
684:
685: blkno = newblk;
686:
687: for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {
688: if (i == ssize) {
689: bap = ebap;
690: soff = -i;
691: }
692: #ifdef DIAGNOSTIC
693: if (!ffs_checkblk(ip,
694: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
695: panic("ffs2_reallocblks: unallocated block 2");
696: if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap)
697: panic("ffs2_reallocblks: alloc mismatch");
698: #endif
699: #ifdef DEBUG
700: if (prtrealloc)
701: printf(" %jd,", (intmax_t)*bap);
702: #endif
703: if (DOINGSOFTDEP(vp)) {
704: if (sbap == &ip->i_din2->di_db[0] && i < ssize)
705: softdep_setup_allocdirect(ip, start_lbn + i,
706: blkno, *bap, fs->fs_bsize, fs->fs_bsize,
707: buflist->bs_children[i]);
708: else
709: softdep_setup_allocindir_page(ip, start_lbn + i,
710: i < ssize ? sbp : ebp, soff + i, blkno,
711: *bap, buflist->bs_children[i]);
712: }
713: *bap++ = blkno;
714: }
715:
716: /*
717: * Next we must write out the modified inode and indirect blocks.
718: * For strict correctness, the writes should be synchronous since
719: * the old block values may have been written to disk. In practise
720: * they are almost never written, but if we are concerned about
721: * strict correctness, the `doasyncfree' flag should be set to zero.
722: *
723: * The test on `doasyncfree' should be changed to test a flag
724: * that shows whether the associated buffers and inodes have
725: * been written. The flag should be set when the cluster is
726: * started and cleared whenever the buffer or inode is flushed.
727: * We can then check below to see if it is set, and do the
728: * synchronous write only when it has been cleared.
729: */
730: if (sbap != &ip->i_din2->di_db[0]) {
731: if (doasyncfree)
732: bdwrite(sbp);
733: else
734: bwrite(sbp);
735: } else {
736: ip->i_flag |= IN_CHANGE | IN_UPDATE;
737: if (!doasyncfree)
738: ffs_update(ip, NULL, NULL, MNT_WAIT);
739: }
740:
741: if (ssize < len) {
742: if (doasyncfree)
743: bdwrite(ebp);
744: else
745: bwrite(ebp);
746: }
747:
748: /*
749: * Last, free the old blocks and assign the new blocks to the buffers.
750: */
751: #ifdef DEBUG
752: if (prtrealloc)
753: printf("\n\tnew:");
754: #endif
755: for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
756: if (!DOINGSOFTDEP(vp))
757: ffs_blkfree(ip, dbtofsb(fs,
758: buflist->bs_children[i]->b_blkno), fs->fs_bsize);
759: buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
760: #ifdef DIAGNOSTIC
761: if (!ffs_checkblk(ip,
762: dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
763: panic("ffs2_reallocblks: unallocated block 3");
764: #endif
765: #ifdef DEBUG
766: if (prtrealloc)
767: printf(" %jd,", (intmax_t)blkno);
768: #endif
769: }
770: #ifdef DEBUG
771: if (prtrealloc) {
772: prtrealloc--;
773: printf("\n");
774: }
775: #endif
776:
777: return (0);
778:
779: fail:
780: if (ssize < len)
781: brelse(ebp);
782:
783: if (sbap != &ip->i_din2->di_db[0])
784: brelse(sbp);
785:
786: return (ENOSPC);
787: }
788: #endif /* FFS2 */
789:
790: int
791: ffs_reallocblks(void *v)
792: {
793: #ifdef FFS2
794: struct vop_reallocblks_args *ap = v;
795: #endif
796:
797: if (!doreallocblks)
798: return (ENOSPC);
799:
800: #ifdef FFS2
801: if (VTOI(ap->a_vp)->i_ump->um_fstype == UM_UFS2)
802: return (ffs2_reallocblks(v));
803: #endif
804:
805: return (ffs1_reallocblks(v));
806: }
807:
808: /*
809: * Allocate an inode in the file system.
810: *
811: * If allocating a directory, use ffs_dirpref to select the inode.
812: * If allocating in a directory, the following hierarchy is followed:
813: * 1) allocate the preferred inode.
814: * 2) allocate an inode in the same cylinder group.
815: * 3) quadratically rehash into other cylinder groups, until an
816: * available inode is located.
817: * If no inode preference is given the following hierarchy is used
818: * to allocate an inode:
819: * 1) allocate an inode in cylinder group 0.
820: * 2) quadratically rehash into other cylinder groups, until an
821: * available inode is located.
822: */
823: int
824: ffs_inode_alloc(struct inode *pip, mode_t mode, struct ucred *cred,
825: struct vnode **vpp)
826: {
827: struct vnode *pvp = ITOV(pip);
828: struct fs *fs;
829: struct inode *ip;
830: ino_t ino, ipref;
831: int cg, error;
832:
833: *vpp = NULL;
834: fs = pip->i_fs;
835: if (fs->fs_cstotal.cs_nifree == 0)
836: goto noinodes;
837:
838: if ((mode & IFMT) == IFDIR)
839: ipref = ffs_dirpref(pip);
840: else
841: ipref = pip->i_number;
842: if (ipref >= fs->fs_ncg * fs->fs_ipg)
843: ipref = 0;
844: cg = ino_to_cg(fs, ipref);
845:
846: /*
847: * Track number of dirs created one after another
848: * in a same cg without intervening by files.
849: */
850: if ((mode & IFMT) == IFDIR) {
851: if (fs->fs_contigdirs[cg] < 255)
852: fs->fs_contigdirs[cg]++;
853: } else {
854: if (fs->fs_contigdirs[cg] > 0)
855: fs->fs_contigdirs[cg]--;
856: }
857: ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, ffs_nodealloccg);
858: if (ino == 0)
859: goto noinodes;
860: error = VFS_VGET(pvp->v_mount, ino, vpp);
861: if (error) {
862: ffs_inode_free(pip, ino, mode);
863: return (error);
864: }
865:
866: ip = VTOI(*vpp);
867:
868: if (DIP(ip, mode)) {
869: printf("mode = 0%o, inum = %d, fs = %s\n",
870: DIP(ip, mode), ip->i_number, fs->fs_fsmnt);
871: panic("ffs_valloc: dup alloc");
872: }
873:
874: if (DIP(ip, blocks)) {
875: printf("free inode %s/%d had %d blocks\n",
876: fs->fs_fsmnt, ino, DIP(ip, blocks));
877: DIP_ASSIGN(ip, blocks, 0);
878: }
879:
880: DIP_ASSIGN(ip, flags, 0);
881:
882: /*
883: * Set up a new generation number for this inode.
884: * XXX - just increment for now, this is wrong! (millert)
885: * Need a way to preserve randomization.
886: */
887: if (DIP(ip, gen) == 0 || ++(DIP(ip, gen)) == 0)
888: DIP_ASSIGN(ip, gen, arc4random() & INT_MAX);
889:
890: if (DIP(ip, gen) == 0 || DIP(ip, gen) == -1)
891: DIP_ASSIGN(ip, gen, 1); /* Shouldn't happen */
892:
893: return (0);
894:
895: noinodes:
896: ffs_fserr(fs, cred->cr_uid, "out of inodes");
897: uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
898: return (ENOSPC);
899: }
900:
901: /*
902: * Find a cylinder group to place a directory.
903: *
904: * The policy implemented by this algorithm is to allocate a
905: * directory inode in the same cylinder group as its parent
906: * directory, but also to reserve space for its files inodes
907: * and data. Restrict the number of directories which may be
908: * allocated one after another in the same cylinder group
909: * without intervening allocation of files.
910: *
911: * If we allocate a first level directory then force allocation
912: * in another cylinder group.
913: */
914: ino_t
915: ffs_dirpref(struct inode *pip)
916: {
917: struct fs *fs;
918: int cg, prefcg, dirsize, cgsize;
919: int avgifree, avgbfree, avgndir, curdirsize;
920: int minifree, minbfree, maxndir;
921: int mincg, minndir;
922: int maxcontigdirs;
923:
924: fs = pip->i_fs;
925:
926: avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg;
927: avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
928: avgndir = fs->fs_cstotal.cs_ndir / fs->fs_ncg;
929: #if 1
930:
931: /*
932: * Force allocation in another cg if creating a first level dir.
933: */
934: if (ITOV(pip)->v_flag & VROOT) {
935: prefcg = (arc4random() & INT_MAX) % fs->fs_ncg;
936: mincg = prefcg;
937: minndir = fs->fs_ipg;
938: for (cg = prefcg; cg < fs->fs_ncg; cg++)
939: if (fs->fs_cs(fs, cg).cs_ndir < minndir &&
940: fs->fs_cs(fs, cg).cs_nifree >= avgifree &&
941: fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
942: mincg = cg;
943: minndir = fs->fs_cs(fs, cg).cs_ndir;
944: }
945: for (cg = 0; cg < prefcg; cg++)
946: if (fs->fs_cs(fs, cg).cs_ndir < minndir &&
947: fs->fs_cs(fs, cg).cs_nifree >= avgifree &&
948: fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
949: mincg = cg;
950: minndir = fs->fs_cs(fs, cg).cs_ndir;
951: }
952: cg = mincg;
953: goto end;
954: } else
955: prefcg = ino_to_cg(fs, pip->i_number);
956: #else
957: prefcg = ino_to_cg(fs, pip->i_number);
958: #endif
959:
960: /*
961: * Count various limits which used for
962: * optimal allocation of a directory inode.
963: */
964: #if 1
965: maxndir = min(avgndir + fs->fs_ipg / 16, fs->fs_ipg);
966: minifree = avgifree - fs->fs_ipg / 4;
967: if (minifree < 0)
968: minifree = 0;
969: minbfree = avgbfree - fs->fs_fpg / fs->fs_frag / 4;
970: if (minbfree < 0)
971: minbfree = 0;
972: #else
973: maxndir = avgndir + (fs->fs_ipg - avgndir) / 16;
974: minifree = avgifree * 3 / 4;
975: minbfree = avgbfree * 3 / 4;
976: #endif
977: cgsize = fs->fs_fsize * fs->fs_fpg;
978: dirsize = fs->fs_avgfilesize * fs->fs_avgfpdir;
979: curdirsize = avgndir ? (cgsize - avgbfree * fs->fs_bsize) / avgndir : 0;
980: if (dirsize < curdirsize)
981: dirsize = curdirsize;
982: maxcontigdirs = min(cgsize / dirsize, 255);
983: if (fs->fs_avgfpdir > 0)
984: maxcontigdirs = min(maxcontigdirs,
985: fs->fs_ipg / fs->fs_avgfpdir);
986: if (maxcontigdirs == 0)
987: maxcontigdirs = 1;
988:
989: /*
990: * Limit number of dirs in one cg and reserve space for
991: * regular files, but only if we have no deficit in
992: * inodes or space.
993: */
994: for (cg = prefcg; cg < fs->fs_ncg; cg++)
995: if (fs->fs_cs(fs, cg).cs_ndir < maxndir &&
996: fs->fs_cs(fs, cg).cs_nifree >= minifree &&
997: fs->fs_cs(fs, cg).cs_nbfree >= minbfree) {
998: if (fs->fs_contigdirs[cg] < maxcontigdirs)
999: goto end;
1000: }
1001: for (cg = 0; cg < prefcg; cg++)
1002: if (fs->fs_cs(fs, cg).cs_ndir < maxndir &&
1003: fs->fs_cs(fs, cg).cs_nifree >= minifree &&
1004: fs->fs_cs(fs, cg).cs_nbfree >= minbfree) {
1005: if (fs->fs_contigdirs[cg] < maxcontigdirs)
1006: goto end;
1007: }
1008: /*
1009: * This is a backstop when we have deficit in space.
1010: */
1011: for (cg = prefcg; cg < fs->fs_ncg; cg++)
1012: if (fs->fs_cs(fs, cg).cs_nifree >= avgifree)
1013: goto end;
1014: for (cg = 0; cg < prefcg; cg++)
1015: if (fs->fs_cs(fs, cg).cs_nifree >= avgifree)
1016: goto end;
1017: end:
1018: return ((ino_t)(fs->fs_ipg * cg));
1019: }
1020:
1021: /*
1022: * Select the desired position for the next block in a file. The file is
1023: * logically divided into sections. The first section is composed of the
1024: * direct blocks. Each additional section contains fs_maxbpg blocks.
1025: *
1026: * If no blocks have been allocated in the first section, the policy is to
1027: * request a block in the same cylinder group as the inode that describes
1028: * the file. If no blocks have been allocated in any other section, the
1029: * policy is to place the section in a cylinder group with a greater than
1030: * average number of free blocks. An appropriate cylinder group is found
1031: * by using a rotor that sweeps the cylinder groups. When a new group of
1032: * blocks is needed, the sweep begins in the cylinder group following the
1033: * cylinder group from which the previous allocation was made. The sweep
1034: * continues until a cylinder group with greater than the average number
1035: * of free blocks is found. If the allocation is for the first block in an
1036: * indirect block, the information on the previous allocation is unavailable;
1037: * here a best guess is made based upon the logical block number being
1038: * allocated.
1039: */
1040: int32_t
1041: ffs1_blkpref(struct inode *ip, daddr_t lbn, int indx, int32_t *bap)
1042: {
1043: struct fs *fs;
1044: int cg, avgbfree, startcg;
1045:
1046: fs = ip->i_fs;
1047: if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
1048: if (lbn < NDADDR + NINDIR(fs)) {
1049: cg = ino_to_cg(fs, ip->i_number);
1050: return (fs->fs_fpg * cg + fs->fs_frag);
1051: }
1052: /*
1053: * Find a cylinder with greater than average number of
1054: * unused data blocks.
1055: */
1056: if (indx == 0 || bap[indx - 1] == 0)
1057: startcg =
1058: ino_to_cg(fs, ip->i_number) + lbn / fs->fs_maxbpg;
1059: else
1060: startcg = dtog(fs, bap[indx - 1]) + 1;
1061: startcg %= fs->fs_ncg;
1062: avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
1063: for (cg = startcg; cg < fs->fs_ncg; cg++)
1064: if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
1065: fs->fs_cgrotor = cg;
1066: return (fs->fs_fpg * cg + fs->fs_frag);
1067: }
1068: for (cg = 0; cg <= startcg; cg++)
1069: if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
1070: fs->fs_cgrotor = cg;
1071: return (fs->fs_fpg * cg + fs->fs_frag);
1072: }
1073: return (0);
1074: }
1075:
1076: return (bap[indx - 1] + fs->fs_frag);
1077: }
1078:
1079: /*
1080: * Same as above, for UFS2.
1081: */
1082: #ifdef FFS2
1083: int64_t
1084: ffs2_blkpref(struct inode *ip, daddr_t lbn, int indx, int64_t *bap)
1085: {
1086: struct fs *fs;
1087: int cg, avgbfree, startcg;
1088:
1089: fs = ip->i_fs;
1090:
1091: if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
1092: if (lbn < NDADDR + NINDIR(fs)) {
1093: cg = ino_to_cg(fs, ip->i_number);
1094: return (fs->fs_fpg * cg + fs->fs_frag);
1095: }
1096:
1097: /*
1098: * Find a cylinder with greater than average number of
1099: * unused data blocks.
1100: */
1101: if (indx == 0 || bap[indx - 1] == 0)
1102: startcg = ino_to_cg(fs, ip->i_number) +
1103: lbn / fs->fs_maxbpg;
1104: else
1105: startcg = dtog(fs, bap[indx - 1] + 1);
1106:
1107: startcg %= fs->fs_ncg;
1108: avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
1109:
1110: for (cg = startcg; cg < fs->fs_ncg; cg++)
1111: if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree)
1112: return (fs->fs_fpg * cg + fs->fs_frag);
1113:
1114: for (cg = 0; cg < startcg; cg++)
1115: if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree)
1116: return (fs->fs_fpg * cg + fs->fs_frag);
1117:
1118: return (0);
1119: }
1120:
1121: /*
1122: * We always just try to lay things out contiguously.
1123: */
1124: return (bap[indx - 1] + fs->fs_frag);
1125: }
1126: #endif /* FFS2 */
1127:
1128: /*
1129: * Implement the cylinder overflow algorithm.
1130: *
1131: * The policy implemented by this algorithm is:
1132: * 1) allocate the block in its requested cylinder group.
1133: * 2) quadratically rehash on the cylinder group number.
1134: * 3) brute force search for a free block.
1135: */
1136: /*VARARGS5*/
1137: u_long
1138: ffs_hashalloc(struct inode *ip, int cg, long pref, int size,
1139: daddr_t (*allocator)(struct inode *, int, daddr_t, int))
1140: {
1141: struct fs *fs;
1142: long result;
1143: int i, icg = cg;
1144:
1145: fs = ip->i_fs;
1146: /*
1147: * 1: preferred cylinder group
1148: */
1149: result = (*allocator)(ip, cg, pref, size);
1150: if (result)
1151: return (result);
1152: /*
1153: * 2: quadratic rehash
1154: */
1155: for (i = 1; i < fs->fs_ncg; i *= 2) {
1156: cg += i;
1157: if (cg >= fs->fs_ncg)
1158: cg -= fs->fs_ncg;
1159: result = (*allocator)(ip, cg, 0, size);
1160: if (result)
1161: return (result);
1162: }
1163: /*
1164: * 3: brute force search
1165: * Note that we start at i == 2, since 0 was checked initially,
1166: * and 1 is always checked in the quadratic rehash.
1167: */
1168: cg = (icg + 2) % fs->fs_ncg;
1169: for (i = 2; i < fs->fs_ncg; i++) {
1170: result = (*allocator)(ip, cg, 0, size);
1171: if (result)
1172: return (result);
1173: cg++;
1174: if (cg == fs->fs_ncg)
1175: cg = 0;
1176: }
1177: return (0);
1178: }
1179:
1180: /*
1181: * Determine whether a fragment can be extended.
1182: *
1183: * Check to see if the necessary fragments are available, and
1184: * if they are, allocate them.
1185: */
1186: daddr_t
1187: ffs_fragextend(struct inode *ip, int cg, long bprev, int osize, int nsize)
1188: {
1189: struct fs *fs;
1190: struct cg *cgp;
1191: struct buf *bp;
1192: long bno;
1193: int frags, bbase;
1194: int i, error;
1195:
1196: fs = ip->i_fs;
1197: if (fs->fs_cs(fs, cg).cs_nffree < numfrags(fs, nsize - osize))
1198: return (0);
1199: frags = numfrags(fs, nsize);
1200: bbase = fragnum(fs, bprev);
1201: if (bbase > fragnum(fs, (bprev + frags - 1))) {
1202: /* cannot extend across a block boundary */
1203: return (0);
1204: }
1205: error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
1206: (int)fs->fs_cgsize, NOCRED, &bp);
1207: if (error) {
1208: brelse(bp);
1209: return (0);
1210: }
1211: cgp = (struct cg *)bp->b_data;
1212: if (!cg_chkmagic(cgp)) {
1213: brelse(bp);
1214: return (0);
1215: }
1216:
1217: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1218:
1219: bno = dtogd(fs, bprev);
1220: for (i = numfrags(fs, osize); i < frags; i++)
1221: if (isclr(cg_blksfree(cgp), bno + i)) {
1222: brelse(bp);
1223: return (0);
1224: }
1225: /*
1226: * the current fragment can be extended
1227: * deduct the count on fragment being extended into
1228: * increase the count on the remaining fragment (if any)
1229: * allocate the extended piece
1230: */
1231: for (i = frags; i < fs->fs_frag - bbase; i++)
1232: if (isclr(cg_blksfree(cgp), bno + i))
1233: break;
1234: cgp->cg_frsum[i - numfrags(fs, osize)]--;
1235: if (i != frags)
1236: cgp->cg_frsum[i - frags]++;
1237: for (i = numfrags(fs, osize); i < frags; i++) {
1238: clrbit(cg_blksfree(cgp), bno + i);
1239: cgp->cg_cs.cs_nffree--;
1240: fs->fs_cstotal.cs_nffree--;
1241: fs->fs_cs(fs, cg).cs_nffree--;
1242: }
1243: fs->fs_fmod = 1;
1244: if (DOINGSOFTDEP(ITOV(ip)))
1245: softdep_setup_blkmapdep(bp, fs, bprev);
1246:
1247: bdwrite(bp);
1248: return (bprev);
1249: }
1250:
1251: /*
1252: * Determine whether a block can be allocated.
1253: *
1254: * Check to see if a block of the appropriate size is available,
1255: * and if it is, allocate it.
1256: */
1257: daddr_t
1258: ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, int size)
1259: {
1260: struct fs *fs;
1261: struct cg *cgp;
1262: struct buf *bp;
1263: daddr_t bno, blkno;
1264: int error, i, frags, allocsiz;
1265:
1266: fs = ip->i_fs;
1267: if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
1268: return (0);
1269: /* read cylinder group block */
1270: error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
1271: (int)fs->fs_cgsize, NOCRED, &bp);
1272: if (error) {
1273: brelse(bp);
1274: return (0);
1275: }
1276: cgp = (struct cg *)bp->b_data;
1277: if (!cg_chkmagic(cgp) ||
1278: (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) {
1279: brelse(bp);
1280: return (0);
1281: }
1282:
1283: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1284:
1285: if (size == fs->fs_bsize) {
1286: /* allocate and return a complete data block */
1287: bno = ffs_alloccgblk(ip, bp, bpref);
1288: bdwrite(bp);
1289: return (bno);
1290: }
1291: /*
1292: * check to see if any fragments are already available
1293: * allocsiz is the size which will be allocated, hacking
1294: * it down to a smaller size if necessary
1295: */
1296: frags = numfrags(fs, size);
1297: for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++)
1298: if (cgp->cg_frsum[allocsiz] != 0)
1299: break;
1300: if (allocsiz == fs->fs_frag) {
1301: /*
1302: * no fragments were available, so a block will be
1303: * allocated, and hacked up
1304: */
1305: if (cgp->cg_cs.cs_nbfree == 0) {
1306: brelse(bp);
1307: return (0);
1308: }
1309: bno = ffs_alloccgblk(ip, bp, bpref);
1310: bpref = dtogd(fs, bno);
1311: for (i = frags; i < fs->fs_frag; i++)
1312: setbit(cg_blksfree(cgp), bpref + i);
1313: i = fs->fs_frag - frags;
1314: cgp->cg_cs.cs_nffree += i;
1315: fs->fs_cstotal.cs_nffree += i;
1316: fs->fs_cs(fs, cg).cs_nffree += i;
1317: fs->fs_fmod = 1;
1318: cgp->cg_frsum[i]++;
1319: bdwrite(bp);
1320: return (bno);
1321: }
1322: bno = ffs_mapsearch(fs, cgp, bpref, allocsiz);
1323: if (bno < 0) {
1324: brelse(bp);
1325: return (0);
1326: }
1327:
1328: for (i = 0; i < frags; i++)
1329: clrbit(cg_blksfree(cgp), bno + i);
1330: cgp->cg_cs.cs_nffree -= frags;
1331: fs->fs_cstotal.cs_nffree -= frags;
1332: fs->fs_cs(fs, cg).cs_nffree -= frags;
1333: fs->fs_fmod = 1;
1334: cgp->cg_frsum[allocsiz]--;
1335: if (frags != allocsiz)
1336: cgp->cg_frsum[allocsiz - frags]++;
1337:
1338: blkno = cg * fs->fs_fpg + bno;
1339: if (DOINGSOFTDEP(ITOV(ip)))
1340: softdep_setup_blkmapdep(bp, fs, blkno);
1341: bdwrite(bp);
1342: return ((u_long)blkno);
1343: }
1344:
1345: /*
1346: * Allocate a block in a cylinder group.
1347: * Note that this routine only allocates fs_bsize blocks; these
1348: * blocks may be fragmented by the routine that allocates them.
1349: */
1350: daddr_t
1351: ffs_alloccgblk(struct inode *ip, struct buf *bp, daddr_t bpref)
1352: {
1353: struct fs *fs;
1354: struct cg *cgp;
1355: daddr_t bno, blkno;
1356: u_int8_t *blksfree;
1357: int cylno;
1358:
1359: fs = ip->i_fs;
1360: cgp = (struct cg *) bp->b_data;
1361: blksfree = cg_blksfree(cgp);
1362:
1363: if (bpref == 0 || dtog(fs, bpref) != cgp->cg_cgx)
1364: bpref = cgp->cg_rotor;
1365: else {
1366: bpref = blknum(fs, bpref);
1367: bno = dtogd(fs, bpref);
1368: /*
1369: * If the requested block is available, use it.
1370: */
1371: if (ffs_isblock(fs, blksfree, fragstoblks(fs, bno)))
1372: goto gotit;
1373: }
1374:
1375: /*
1376: * Take the next available block in this cylinder group.
1377: */
1378: bno = ffs_mapsearch(fs, cgp, bpref, (int) fs->fs_frag);
1379: if (bno < 0)
1380: return (0);
1381:
1382: cgp->cg_rotor = bno;
1383:
1384: gotit:
1385: blkno = fragstoblks(fs, bno);
1386: ffs_clrblock(fs, blksfree, (long) blkno);
1387: ffs_clusteracct(fs, cgp, blkno, -1);
1388: cgp->cg_cs.cs_nbfree--;
1389: fs->fs_cstotal.cs_nbfree--;
1390: fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--;
1391:
1392: if (fs->fs_magic != FS_UFS2_MAGIC) {
1393: cylno = cbtocylno(fs, bno);
1394: cg_blks(fs, cgp, cylno)[cbtorpos(fs, bno)]--;
1395: cg_blktot(cgp)[cylno]--;
1396: }
1397:
1398: fs->fs_fmod = 1;
1399: blkno = cgp->cg_cgx * fs->fs_fpg + bno;
1400:
1401: if (DOINGSOFTDEP(ITOV(ip)))
1402: softdep_setup_blkmapdep(bp, fs, blkno);
1403:
1404: return (blkno);
1405: }
1406:
1407: /*
1408: * Determine whether a cluster can be allocated.
1409: *
1410: * We do not currently check for optimal rotational layout if there
1411: * are multiple choices in the same cylinder group. Instead we just
1412: * take the first one that we find following bpref.
1413: */
1414: daddr_t
1415: ffs_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len)
1416: {
1417: struct fs *fs;
1418: struct cg *cgp;
1419: struct buf *bp;
1420: int i, got, run, bno, bit, map;
1421: u_char *mapp;
1422: int32_t *lp;
1423:
1424: fs = ip->i_fs;
1425: if (fs->fs_maxcluster[cg] < len)
1426: return (0);
1427: if (bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
1428: NOCRED, &bp))
1429: goto fail;
1430: cgp = (struct cg *)bp->b_data;
1431: if (!cg_chkmagic(cgp))
1432: goto fail;
1433: /*
1434: * Check to see if a cluster of the needed size (or bigger) is
1435: * available in this cylinder group.
1436: */
1437: lp = &cg_clustersum(cgp)[len];
1438: for (i = len; i <= fs->fs_contigsumsize; i++)
1439: if (*lp++ > 0)
1440: break;
1441: if (i > fs->fs_contigsumsize) {
1442: /*
1443: * This is the first time looking for a cluster in this
1444: * cylinder group. Update the cluster summary information
1445: * to reflect the true maximum sized cluster so that
1446: * future cluster allocation requests can avoid reading
1447: * the cylinder group map only to find no clusters.
1448: */
1449: lp = &cg_clustersum(cgp)[len - 1];
1450: for (i = len - 1; i > 0; i--)
1451: if (*lp-- > 0)
1452: break;
1453: fs->fs_maxcluster[cg] = i;
1454: goto fail;
1455: }
1456: /*
1457: * Search the cluster map to find a big enough cluster.
1458: * We take the first one that we find, even if it is larger
1459: * than we need as we prefer to get one close to the previous
1460: * block allocation. We do not search before the current
1461: * preference point as we do not want to allocate a block
1462: * that is allocated before the previous one (as we will
1463: * then have to wait for another pass of the elevator
1464: * algorithm before it will be read). We prefer to fail and
1465: * be recalled to try an allocation in the next cylinder group.
1466: */
1467: if (dtog(fs, bpref) != cg)
1468: bpref = 0;
1469: else
1470: bpref = fragstoblks(fs, dtogd(fs, blknum(fs, bpref)));
1471: mapp = &cg_clustersfree(cgp)[bpref / NBBY];
1472: map = *mapp++;
1473: bit = 1 << (bpref % NBBY);
1474: for (run = 0, got = bpref; got < cgp->cg_nclusterblks; got++) {
1475: if ((map & bit) == 0) {
1476: run = 0;
1477: } else {
1478: run++;
1479: if (run == len)
1480: break;
1481: }
1482: if ((got & (NBBY - 1)) != (NBBY - 1)) {
1483: bit <<= 1;
1484: } else {
1485: map = *mapp++;
1486: bit = 1;
1487: }
1488: }
1489: if (got >= cgp->cg_nclusterblks)
1490: goto fail;
1491: /*
1492: * Allocate the cluster that we have found.
1493: */
1494: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1495:
1496: #ifdef DIAGNOSTIC
1497: for (i = 1; i <= len; i++)
1498: if (!ffs_isblock(fs, cg_blksfree(cgp), got - run + i))
1499: panic("ffs_clusteralloc: map mismatch");
1500: #endif
1501: bno = cg * fs->fs_fpg + blkstofrags(fs, got - run + 1);
1502: #ifdef DIAGNOSTIC
1503: if (dtog(fs, bno) != cg)
1504: panic("ffs_clusteralloc: allocated out of group");
1505: #endif
1506:
1507: len = blkstofrags(fs, len);
1508: for (i = 0; i < len; i += fs->fs_frag)
1509: if (ffs_alloccgblk(ip, bp, bno + i) != bno + i)
1510: panic("ffs_clusteralloc: lost block");
1511: bdwrite(bp);
1512: return (bno);
1513:
1514: fail:
1515: brelse(bp);
1516: return (0);
1517: }
1518:
1519: /* inode allocation routine */
1520: daddr_t
1521: ffs_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode)
1522: {
1523: struct fs *fs;
1524: struct cg *cgp;
1525: struct buf *bp;
1526: int error, start, len, loc, map, i;
1527: #ifdef FFS2
1528: struct buf *ibp = NULL;
1529: struct ufs2_dinode *dp2;
1530: #endif
1531:
1532: /*
1533: * For efficiency, before looking at the bitmaps for free inodes,
1534: * check the counters kept in the superblock cylinder group summaries,
1535: * and in the cylinder group itself.
1536: */
1537: fs = ip->i_fs;
1538: if (fs->fs_cs(fs, cg).cs_nifree == 0)
1539: return (0);
1540:
1541: error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
1542: (int)fs->fs_cgsize, NOCRED, &bp);
1543: if (error) {
1544: brelse(bp);
1545: return (0);
1546: }
1547:
1548: cgp = (struct cg *)bp->b_data;
1549: if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) {
1550: brelse(bp);
1551: return (0);
1552: }
1553:
1554: /*
1555: * We are committed to the allocation from now on, so update the time
1556: * on the cylinder group.
1557: */
1558: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1559:
1560: /*
1561: * If there was a preferred location for the new inode, try to find it.
1562: */
1563: if (ipref) {
1564: ipref %= fs->fs_ipg;
1565: if (isclr(cg_inosused(cgp), ipref))
1566: goto gotit; /* inode is free, grab it. */
1567: }
1568:
1569: /*
1570: * Otherwise, look for the next available inode, starting at cg_irotor
1571: * (the position in the bitmap of the last used inode).
1572: */
1573: start = cgp->cg_irotor / NBBY;
1574: len = howmany(fs->fs_ipg - cgp->cg_irotor, NBBY);
1575: loc = skpc(0xff, len, &cg_inosused(cgp)[start]);
1576: if (loc == 0) {
1577: /*
1578: * If we didn't find a free inode in the upper part of the
1579: * bitmap (from cg_irotor to the end), then look at the bottom
1580: * part (from 0 to cg_irotor).
1581: */
1582: len = start + 1;
1583: start = 0;
1584: loc = skpc(0xff, len, &cg_inosused(cgp)[0]);
1585: if (loc == 0) {
1586: /*
1587: * If we failed again, then either the bitmap or the
1588: * counters kept for the cylinder group are wrong.
1589: */
1590: printf("cg = %d, irotor = %d, fs = %s\n",
1591: cg, cgp->cg_irotor, fs->fs_fsmnt);
1592: panic("ffs_nodealloccg: map corrupted");
1593: /* NOTREACHED */
1594: }
1595: }
1596:
1597: /* skpc() returns the position relative to the end */
1598: i = start + len - loc;
1599:
1600: /*
1601: * Okay, so now in 'i' we have the location in the bitmap of a byte
1602: * holding a free inode. Find the corresponding bit and set it,
1603: * updating cg_irotor as well, accordingly.
1604: */
1605: map = cg_inosused(cgp)[i];
1606: ipref = i * NBBY;
1607: for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) {
1608: if ((map & i) == 0) {
1609: cgp->cg_irotor = ipref;
1610: goto gotit;
1611: }
1612: }
1613:
1614: printf("fs = %s\n", fs->fs_fsmnt);
1615: panic("ffs_nodealloccg: block not in map");
1616: /* NOTREACHED */
1617:
1618: gotit:
1619:
1620: #ifdef FFS2
1621: /*
1622: * For FFS2, check if all inodes in this cylinder group have been used
1623: * at least once. If they haven't, and we are allocating an inode past
1624: * the last allocated block of inodes, read in a block and initialize
1625: * all inodes in it.
1626: */
1627: if (fs->fs_magic == FS_UFS2_MAGIC &&
1628: /* Inode is beyond last initialized block of inodes? */
1629: ipref + INOPB(fs) > cgp->cg_initediblk &&
1630: /* Has any inode not been used at least once? */
1631: cgp->cg_initediblk < cgp->cg_ffs2_niblk) {
1632:
1633: ibp = getblk(ip->i_devvp, fsbtodb(fs,
1634: ino_to_fsba(fs, cg * fs->fs_ipg + cgp->cg_initediblk)),
1635: (int)fs->fs_bsize, 0, 0);
1636:
1637: bzero(ibp->b_data, (int)fs->fs_bsize);
1638: dp2 = (struct ufs2_dinode *)(ibp->b_data);
1639:
1640: /* Give each inode a positive generation number */
1641: for (i = 0; i < INOPB(fs); i++) {
1642: dp2->di_gen = (arc4random() & INT32_MAX) / 2 + 1;
1643: dp2++;
1644: }
1645:
1646: /* Update the counter of initialized inodes */
1647: cgp->cg_initediblk += INOPB(fs);
1648: }
1649: #endif /* FFS2 */
1650:
1651: if (DOINGSOFTDEP(ITOV(ip)))
1652: softdep_setup_inomapdep(bp, ip, cg * fs->fs_ipg + ipref);
1653:
1654: setbit(cg_inosused(cgp), ipref);
1655:
1656: /* Update the counters we keep on free inodes */
1657: cgp->cg_cs.cs_nifree--;
1658: fs->fs_cstotal.cs_nifree--;
1659: fs->fs_cs(fs, cg).cs_nifree--;
1660: fs->fs_fmod = 1; /* file system was modified */
1661:
1662: /* Update the counters we keep on allocated directories */
1663: if ((mode & IFMT) == IFDIR) {
1664: cgp->cg_cs.cs_ndir++;
1665: fs->fs_cstotal.cs_ndir++;
1666: fs->fs_cs(fs, cg).cs_ndir++;
1667: }
1668:
1669: bdwrite(bp);
1670:
1671: #ifdef FFS2
1672: if (ibp != NULL)
1673: bawrite(ibp);
1674: #endif
1675:
1676: /* Return the allocated inode number */
1677: return (cg * fs->fs_ipg + ipref);
1678: }
1679:
1680: /*
1681: * Free a block or fragment.
1682: *
1683: * The specified block or fragment is placed back in the
1684: * free map. If a fragment is deallocated, a possible
1685: * block reassembly is checked.
1686: */
1687: void
1688: ffs_blkfree(struct inode *ip, daddr64_t bno, long size)
1689: {
1690: struct fs *fs;
1691: struct cg *cgp;
1692: struct buf *bp;
1693: daddr_t blkno;
1694: int i, error, cg, blk, frags, bbase;
1695:
1696: fs = ip->i_fs;
1697: if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0 ||
1698: fragnum(fs, bno) + numfrags(fs, size) > fs->fs_frag) {
1699: printf("dev = 0x%x, bsize = %d, size = %ld, fs = %s\n",
1700: ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt);
1701: panic("ffs_blkfree: bad size");
1702: }
1703: cg = dtog(fs, bno);
1704: if ((u_int)bno >= fs->fs_size) {
1705: printf("bad block %d, ino %u\n", bno, ip->i_number);
1706: ffs_fserr(fs, DIP(ip, uid), "bad block");
1707: return;
1708: }
1709: error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
1710: (int)fs->fs_cgsize, NOCRED, &bp);
1711: if (error) {
1712: brelse(bp);
1713: return;
1714: }
1715: cgp = (struct cg *)bp->b_data;
1716: if (!cg_chkmagic(cgp)) {
1717: brelse(bp);
1718: return;
1719: }
1720:
1721: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1722:
1723: bno = dtogd(fs, bno);
1724: if (size == fs->fs_bsize) {
1725: blkno = fragstoblks(fs, bno);
1726: if (!ffs_isfreeblock(fs, cg_blksfree(cgp), blkno)) {
1727: printf("dev = 0x%x, block = %d, fs = %s\n",
1728: ip->i_dev, bno, fs->fs_fsmnt);
1729: panic("ffs_blkfree: freeing free block");
1730: }
1731: ffs_setblock(fs, cg_blksfree(cgp), blkno);
1732: ffs_clusteracct(fs, cgp, blkno, 1);
1733: cgp->cg_cs.cs_nbfree++;
1734: fs->fs_cstotal.cs_nbfree++;
1735: fs->fs_cs(fs, cg).cs_nbfree++;
1736:
1737: if (fs->fs_magic != FS_UFS2_MAGIC) {
1738: i = cbtocylno(fs, bno);
1739: cg_blks(fs, cgp, i)[cbtorpos(fs, bno)]++;
1740: cg_blktot(cgp)[i]++;
1741: }
1742:
1743: } else {
1744: bbase = bno - fragnum(fs, bno);
1745: /*
1746: * decrement the counts associated with the old frags
1747: */
1748: blk = blkmap(fs, cg_blksfree(cgp), bbase);
1749: ffs_fragacct(fs, blk, cgp->cg_frsum, -1);
1750: /*
1751: * deallocate the fragment
1752: */
1753: frags = numfrags(fs, size);
1754: for (i = 0; i < frags; i++) {
1755: if (isset(cg_blksfree(cgp), bno + i)) {
1756: printf("dev = 0x%x, block = %d, fs = %s\n",
1757: ip->i_dev, bno + i, fs->fs_fsmnt);
1758: panic("ffs_blkfree: freeing free frag");
1759: }
1760: setbit(cg_blksfree(cgp), bno + i);
1761: }
1762: cgp->cg_cs.cs_nffree += i;
1763: fs->fs_cstotal.cs_nffree += i;
1764: fs->fs_cs(fs, cg).cs_nffree += i;
1765: /*
1766: * add back in counts associated with the new frags
1767: */
1768: blk = blkmap(fs, cg_blksfree(cgp), bbase);
1769: ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
1770: /*
1771: * if a complete block has been reassembled, account for it
1772: */
1773: blkno = fragstoblks(fs, bbase);
1774: if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) {
1775: cgp->cg_cs.cs_nffree -= fs->fs_frag;
1776: fs->fs_cstotal.cs_nffree -= fs->fs_frag;
1777: fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;
1778: ffs_clusteracct(fs, cgp, blkno, 1);
1779: cgp->cg_cs.cs_nbfree++;
1780: fs->fs_cstotal.cs_nbfree++;
1781: fs->fs_cs(fs, cg).cs_nbfree++;
1782:
1783: if (fs->fs_magic != FS_UFS2_MAGIC) {
1784: i = cbtocylno(fs, bbase);
1785: cg_blks(fs, cgp, i)[cbtorpos(fs, bbase)]++;
1786: cg_blktot(cgp)[i]++;
1787: }
1788: }
1789: }
1790: fs->fs_fmod = 1;
1791: bdwrite(bp);
1792: }
1793:
1794: int
1795: ffs_inode_free(struct inode *pip, ino_t ino, mode_t mode)
1796: {
1797: struct vnode *pvp = ITOV(pip);
1798:
1799: if (DOINGSOFTDEP(pvp)) {
1800: softdep_freefile(pvp, ino, mode);
1801: return (0);
1802: }
1803:
1804: return (ffs_freefile(pip, ino, mode));
1805: }
1806:
1807: /*
1808: * Do the actual free operation.
1809: * The specified inode is placed back in the free map.
1810: */
1811: int
1812: ffs_freefile(struct inode *pip, ino_t ino, mode_t mode)
1813: {
1814: struct fs *fs;
1815: struct cg *cgp;
1816: struct buf *bp;
1817: int error, cg;
1818:
1819: fs = pip->i_fs;
1820: if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg)
1821: panic("ffs_freefile: range: dev = 0x%x, ino = %d, fs = %s",
1822: pip->i_dev, ino, fs->fs_fsmnt);
1823: cg = ino_to_cg(fs, ino);
1824: error = bread(pip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
1825: (int)fs->fs_cgsize, NOCRED, &bp);
1826: if (error) {
1827: brelse(bp);
1828: return (error);
1829: }
1830: cgp = (struct cg *)bp->b_data;
1831: if (!cg_chkmagic(cgp)) {
1832: brelse(bp);
1833: return (0);
1834: }
1835:
1836: cgp->cg_ffs2_time = cgp->cg_time = time_second;
1837:
1838: ino %= fs->fs_ipg;
1839: if (isclr(cg_inosused(cgp), ino)) {
1840: printf("dev = 0x%x, ino = %u, fs = %s\n",
1841: pip->i_dev, ino, fs->fs_fsmnt);
1842: if (fs->fs_ronly == 0)
1843: panic("ffs_freefile: freeing free inode");
1844: }
1845: clrbit(cg_inosused(cgp), ino);
1846: if (ino < cgp->cg_irotor)
1847: cgp->cg_irotor = ino;
1848: cgp->cg_cs.cs_nifree++;
1849: fs->fs_cstotal.cs_nifree++;
1850: fs->fs_cs(fs, cg).cs_nifree++;
1851: if ((mode & IFMT) == IFDIR) {
1852: cgp->cg_cs.cs_ndir--;
1853: fs->fs_cstotal.cs_ndir--;
1854: fs->fs_cs(fs, cg).cs_ndir--;
1855: }
1856: fs->fs_fmod = 1;
1857: bdwrite(bp);
1858: return (0);
1859: }
1860:
1861: #ifdef DIAGNOSTIC
1862: /*
1863: * Verify allocation of a block or fragment. Returns true if block or
1864: * fragment is allocated, false if it is free.
1865: */
1866: int
1867: ffs_checkblk(struct inode *ip, daddr_t bno, long size)
1868: {
1869: struct fs *fs;
1870: struct cg *cgp;
1871: struct buf *bp;
1872: int i, error, frags, free;
1873:
1874: fs = ip->i_fs;
1875: if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
1876: printf("bsize = %d, size = %ld, fs = %s\n",
1877: fs->fs_bsize, size, fs->fs_fsmnt);
1878: panic("ffs_checkblk: bad size");
1879: }
1880: if ((u_int)bno >= fs->fs_size)
1881: panic("ffs_checkblk: bad block %d", bno);
1882: error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, dtog(fs, bno))),
1883: (int)fs->fs_cgsize, NOCRED, &bp);
1884: if (error) {
1885: brelse(bp);
1886: return (0);
1887: }
1888:
1889: cgp = (struct cg *)bp->b_data;
1890: if (!cg_chkmagic(cgp)) {
1891: brelse(bp);
1892: return (0);
1893: }
1894:
1895: bno = dtogd(fs, bno);
1896: if (size == fs->fs_bsize) {
1897: free = ffs_isblock(fs, cg_blksfree(cgp), fragstoblks(fs, bno));
1898: } else {
1899: frags = numfrags(fs, size);
1900: for (free = 0, i = 0; i < frags; i++)
1901: if (isset(cg_blksfree(cgp), bno + i))
1902: free++;
1903: if (free != 0 && free != frags)
1904: panic("ffs_checkblk: partially free fragment");
1905: }
1906: brelse(bp);
1907: return (!free);
1908: }
1909: #endif /* DIAGNOSTIC */
1910:
1911:
1912: /*
1913: * Find a block of the specified size in the specified cylinder group.
1914: *
1915: * It is a panic if a request is made to find a block if none are
1916: * available.
1917: */
1918: daddr_t
1919: ffs_mapsearch(struct fs *fs, struct cg *cgp, daddr_t bpref, int allocsiz)
1920: {
1921: daddr_t bno;
1922: int start, len, loc, i;
1923: int blk, field, subfield, pos;
1924:
1925: /*
1926: * find the fragment by searching through the free block
1927: * map for an appropriate bit pattern
1928: */
1929: if (bpref)
1930: start = dtogd(fs, bpref) / NBBY;
1931: else
1932: start = cgp->cg_frotor / NBBY;
1933: len = howmany(fs->fs_fpg, NBBY) - start;
1934: loc = scanc((u_int)len, (u_char *)&cg_blksfree(cgp)[start],
1935: (u_char *)fragtbl[fs->fs_frag],
1936: (u_char)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
1937: if (loc == 0) {
1938: len = start + 1;
1939: start = 0;
1940: loc = scanc((u_int)len, (u_char *)&cg_blksfree(cgp)[0],
1941: (u_char *)fragtbl[fs->fs_frag],
1942: (u_char)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
1943: if (loc == 0) {
1944: printf("start = %d, len = %d, fs = %s\n",
1945: start, len, fs->fs_fsmnt);
1946: panic("ffs_alloccg: map corrupted");
1947: /* NOTREACHED */
1948: }
1949: }
1950: bno = (start + len - loc) * NBBY;
1951: cgp->cg_frotor = bno;
1952: /*
1953: * found the byte in the map
1954: * sift through the bits to find the selected frag
1955: */
1956: for (i = bno + NBBY; bno < i; bno += fs->fs_frag) {
1957: blk = blkmap(fs, cg_blksfree(cgp), bno);
1958: blk <<= 1;
1959: field = around[allocsiz];
1960: subfield = inside[allocsiz];
1961: for (pos = 0; pos <= fs->fs_frag - allocsiz; pos++) {
1962: if ((blk & field) == subfield)
1963: return (bno + pos);
1964: field <<= 1;
1965: subfield <<= 1;
1966: }
1967: }
1968: printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt);
1969: panic("ffs_alloccg: block not in map");
1970: return (-1);
1971: }
1972:
1973: /*
1974: * Update the cluster map because of an allocation or free.
1975: *
1976: * Cnt == 1 means free; cnt == -1 means allocating.
1977: */
1978: void
1979: ffs_clusteracct(struct fs *fs, struct cg *cgp, daddr_t blkno, int cnt)
1980: {
1981: int32_t *sump;
1982: int32_t *lp;
1983: u_char *freemapp, *mapp;
1984: int i, start, end, forw, back, map, bit;
1985:
1986: if (fs->fs_contigsumsize <= 0)
1987: return;
1988: freemapp = cg_clustersfree(cgp);
1989: sump = cg_clustersum(cgp);
1990: /*
1991: * Allocate or clear the actual block.
1992: */
1993: if (cnt > 0)
1994: setbit(freemapp, blkno);
1995: else
1996: clrbit(freemapp, blkno);
1997: /*
1998: * Find the size of the cluster going forward.
1999: */
2000: start = blkno + 1;
2001: end = start + fs->fs_contigsumsize;
2002: if (end >= cgp->cg_nclusterblks)
2003: end = cgp->cg_nclusterblks;
2004: mapp = &freemapp[start / NBBY];
2005: map = *mapp++;
2006: bit = 1 << (start % NBBY);
2007: for (i = start; i < end; i++) {
2008: if ((map & bit) == 0)
2009: break;
2010: if ((i & (NBBY - 1)) != (NBBY - 1)) {
2011: bit <<= 1;
2012: } else {
2013: map = *mapp++;
2014: bit = 1;
2015: }
2016: }
2017: forw = i - start;
2018: /*
2019: * Find the size of the cluster going backward.
2020: */
2021: start = blkno - 1;
2022: end = start - fs->fs_contigsumsize;
2023: if (end < 0)
2024: end = -1;
2025: mapp = &freemapp[start / NBBY];
2026: map = *mapp--;
2027: bit = 1 << (start % NBBY);
2028: for (i = start; i > end; i--) {
2029: if ((map & bit) == 0)
2030: break;
2031: if ((i & (NBBY - 1)) != 0) {
2032: bit >>= 1;
2033: } else {
2034: map = *mapp--;
2035: bit = 1 << (NBBY - 1);
2036: }
2037: }
2038: back = start - i;
2039: /*
2040: * Account for old cluster and the possibly new forward and
2041: * back clusters.
2042: */
2043: i = back + forw + 1;
2044: if (i > fs->fs_contigsumsize)
2045: i = fs->fs_contigsumsize;
2046: sump[i] += cnt;
2047: if (back > 0)
2048: sump[back] -= cnt;
2049: if (forw > 0)
2050: sump[forw] -= cnt;
2051: /*
2052: * Update cluster summary information.
2053: */
2054: lp = &sump[fs->fs_contigsumsize];
2055: for (i = fs->fs_contigsumsize; i > 0; i--)
2056: if (*lp-- > 0)
2057: break;
2058: fs->fs_maxcluster[cgp->cg_cgx] = i;
2059: }
CVSweb