2 * Copyright (c) 2002 Networks Associates Technology, Inc.
5 * This software was developed for the FreeBSD Project by Marshall
6 * Kirk McKusick and Network Associates Laboratories, the Security
7 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
8 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * Copyright (c) 1982, 1986, 1989, 1993
33 * The Regents of the University of California. All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
62 #include <sys/cdefs.h>
63 __FBSDID("$FreeBSD$");
65 #include <sys/param.h>
66 #include <sys/systm.h>
70 #include <sys/mount.h>
71 #include <sys/vnode.h>
73 #include <ufs/ufs/quota.h>
74 #include <ufs/ufs/inode.h>
75 #include <ufs/ufs/ufs_extern.h>
76 #include <ufs/ufs/extattr.h>
77 #include <ufs/ufs/ufsmount.h>
79 #include <ufs/ffs/fs.h>
80 #include <ufs/ffs/ffs_extern.h>
83 * Balloc defines the structure of filesystem storage
84 * by allocating the physical blocks on a device given
85 * the inode and the logical block number in a file.
86 * This is the allocation strategy for UFS1. Below is
87 * the allocation strategy for UFS2.
90 ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
91 struct ucred *cred, int flags, struct buf **bpp)
94 struct ufs1_dinode *dp;
95 ufs_lbn_t lbn, lastlbn;
100 struct indir indirs[NIADDR + 2];
101 int deallocated, osize, nsize, num, i, error;
103 ufs1_daddr_t *bap, pref;
104 ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
105 ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1];
113 lbn = lblkno(fs, startoffset);
114 size = blkoff(fs, startoffset) + size;
115 if (size > fs->fs_bsize)
116 panic("ffs_balloc_ufs1: blk too big");
124 * If the next write will extend the file into a new block,
125 * and the file is currently composed of a fragment
126 * this fragment has to be extended to be a full block.
128 lastlbn = lblkno(fs, ip->i_size);
129 if (lastlbn < NDADDR && lastlbn < lbn) {
131 osize = blksize(fs, ip, nb);
132 if (osize < fs->fs_bsize && osize > 0) {
134 error = ffs_realloccg(ip, nb, dp->di_db[nb],
135 ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
136 &dp->di_db[0]), osize, (int)fs->fs_bsize, flags,
140 if (DOINGSOFTDEP(vp))
141 softdep_setup_allocdirect(ip, nb,
142 dbtofsb(fs, bp->b_blkno), dp->di_db[nb],
143 fs->fs_bsize, osize, bp);
144 ip->i_size = smalllblktosize(fs, nb + 1);
145 dp->di_size = ip->i_size;
146 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
147 ip->i_flag |= IN_CHANGE | IN_UPDATE;
155 * The first NDADDR blocks are direct blocks
158 if (flags & BA_METAONLY)
159 panic("ffs_balloc_ufs1: BA_METAONLY for direct block");
161 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
162 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
167 bp->b_blkno = fsbtodb(fs, nb);
173 * Consider need to reallocate a fragment.
175 osize = fragroundup(fs, blkoff(fs, ip->i_size));
176 nsize = fragroundup(fs, size);
177 if (nsize <= osize) {
178 error = bread(vp, lbn, osize, NOCRED, &bp);
183 bp->b_blkno = fsbtodb(fs, nb);
186 error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
187 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
188 &dp->di_db[0]), osize, nsize, flags,
192 if (DOINGSOFTDEP(vp))
193 softdep_setup_allocdirect(ip, lbn,
194 dbtofsb(fs, bp->b_blkno), nb,
198 if (ip->i_size < smalllblktosize(fs, lbn + 1))
199 nsize = fragroundup(fs, size);
201 nsize = fs->fs_bsize;
203 error = ffs_alloc(ip, lbn,
204 ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
205 nsize, flags, cred, &newb);
208 bp = getblk(vp, lbn, nsize, 0, 0, 0);
209 bp->b_blkno = fsbtodb(fs, newb);
210 if (flags & BA_CLRBUF)
212 if (DOINGSOFTDEP(vp))
213 softdep_setup_allocdirect(ip, lbn, newb, 0,
216 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
217 ip->i_flag |= IN_CHANGE | IN_UPDATE;
222 * Determine the number of levels of indirection.
225 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
229 panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block");
231 saved_inbdflush = ~TDP_INBDFLUSH | (curthread->td_pflags &
233 curthread->td_pflags |= TDP_INBDFLUSH;
235 * Fetch the first indirect block allocating if necessary.
238 nb = dp->di_ib[indirs[0].in_off];
240 allocblk = allociblk;
244 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
245 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
246 flags, cred, &newb)) != 0) {
247 curthread->td_pflags &= saved_inbdflush;
252 *lbns_remfree++ = indirs[1].in_lbn;
253 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
254 bp->b_blkno = fsbtodb(fs, nb);
256 if (DOINGSOFTDEP(vp)) {
257 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
258 newb, 0, fs->fs_bsize, 0, bp);
262 * Write synchronously so that indirect blocks
263 * never point at garbage.
267 else if ((error = bwrite(bp)) != 0)
270 allocib = &dp->di_ib[indirs[0].in_off];
272 ip->i_flag |= IN_CHANGE | IN_UPDATE;
275 * Fetch through the indirect blocks, allocating as necessary.
279 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
284 bap = (ufs1_daddr_t *)bp->b_data;
285 nb = bap[indirs[i].in_off];
295 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
296 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
297 flags, cred, &newb)) != 0) {
303 *lbns_remfree++ = indirs[i].in_lbn;
304 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, 0);
305 nbp->b_blkno = fsbtodb(fs, nb);
307 if (DOINGSOFTDEP(vp)) {
308 softdep_setup_allocindir_meta(nbp, ip, bp,
309 indirs[i - 1].in_off, nb);
313 * Write synchronously so that indirect blocks
314 * never point at garbage.
316 if ((error = bwrite(nbp)) != 0) {
321 bap[indirs[i - 1].in_off] = nb;
322 if (allocib == NULL && unwindidx < 0)
325 * If required, write synchronously, otherwise use
328 if (flags & IO_SYNC) {
331 if (bp->b_bufsize == fs->fs_bsize)
332 bp->b_flags |= B_CLUSTEROK;
337 * If asked only for the indirect block, then return it.
339 if (flags & BA_METAONLY) {
340 curthread->td_pflags &= saved_inbdflush;
345 * Get the data block, allocating if necessary.
349 pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, &bap[0]);
350 error = ffs_alloc(ip,
351 lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
358 *lbns_remfree++ = lbn;
359 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
360 nbp->b_blkno = fsbtodb(fs, nb);
361 if (flags & BA_CLRBUF)
363 if (DOINGSOFTDEP(vp))
364 softdep_setup_allocindir_page(ip, lbn, bp,
365 indirs[i].in_off, nb, 0, nbp);
366 bap[indirs[i].in_off] = nb;
368 * If required, write synchronously, otherwise use
371 if (flags & IO_SYNC) {
374 if (bp->b_bufsize == fs->fs_bsize)
375 bp->b_flags |= B_CLUSTEROK;
378 curthread->td_pflags &= saved_inbdflush;
383 if (flags & BA_CLRBUF) {
384 int seqcount = (flags & BA_SEQMASK) >> BA_SEQSHIFT;
385 if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
386 error = cluster_read(vp, ip->i_size, lbn,
387 (int)fs->fs_bsize, NOCRED,
388 MAXBSIZE, seqcount, &nbp);
390 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
397 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
398 nbp->b_blkno = fsbtodb(fs, nb);
400 curthread->td_pflags &= saved_inbdflush;
404 curthread->td_pflags &= saved_inbdflush;
406 * If we have failed to allocate any blocks, simply return the error.
407 * This is the usual case and avoids the need to fsync the file.
409 if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
412 * If we have failed part way through block allocation, we
413 * have to deallocate any indirect blocks that we have allocated.
414 * We have to fsync the file before we start to get rid of all
415 * of its dependencies so that we do not leave them dangling.
416 * We have to sync it at the end so that the soft updates code
417 * does not find any untracked changes. Although this is really
418 * slow, running out of disk space is not expected to be a common
419 * occurence. The error return from fsync is ignored as we already
420 * have an error to return to the user.
422 (void) ffs_syncvnode(vp, MNT_WAIT);
423 for (deallocated = 0, blkp = allociblk, lbns_remfree = lbns;
424 blkp < allocblk; blkp++, lbns_remfree++) {
426 * We shall not leave the freed blocks on the vnode
427 * buffer object lists.
429 bp = getblk(vp, *lbns_remfree, fs->fs_bsize, 0, 0, GB_NOCREAT);
431 bp->b_flags |= (B_INVAL | B_RELBUF);
432 bp->b_flags &= ~B_ASYNC;
435 deallocated += fs->fs_bsize;
437 if (allocib != NULL) {
439 } else if (unwindidx >= 0) {
442 r = bread(vp, indirs[unwindidx].in_lbn,
443 (int)fs->fs_bsize, NOCRED, &bp);
445 panic("Could not unwind indirect block, error %d", r);
448 bap = (ufs1_daddr_t *)bp->b_data;
449 bap[indirs[unwindidx].in_off] = 0;
450 if (flags & IO_SYNC) {
453 if (bp->b_bufsize == fs->fs_bsize)
454 bp->b_flags |= B_CLUSTEROK;
462 * Restore user's disk quota because allocation failed.
464 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
466 dp->di_blocks -= btodb(deallocated);
467 ip->i_flag |= IN_CHANGE | IN_UPDATE;
469 (void) ffs_syncvnode(vp, MNT_WAIT);
471 * After the buffers are invalidated and on-disk pointers are
472 * cleared, free the blocks.
474 for (blkp = allociblk; blkp < allocblk; blkp++) {
475 ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,
482 * Balloc defines the structure of file system storage
483 * by allocating the physical blocks on a device given
484 * the inode and the logical block number in a file.
485 * This is the allocation strategy for UFS2. Above is
486 * the allocation strategy for UFS1.
489 ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
490 struct ucred *cred, int flags, struct buf **bpp)
493 struct ufs2_dinode *dp;
494 ufs_lbn_t lbn, lastlbn;
496 struct buf *bp, *nbp;
497 struct ufsmount *ump;
498 struct indir indirs[NIADDR + 2];
499 ufs2_daddr_t nb, newb, *bap, pref;
500 ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
501 ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1];
502 int deallocated, osize, nsize, num, i, error;
510 lbn = lblkno(fs, startoffset);
511 size = blkoff(fs, startoffset) + size;
512 if (size > fs->fs_bsize)
513 panic("ffs_balloc_ufs2: blk too big");
519 * Check for allocating external data.
521 if (flags & IO_EXT) {
525 * If the next write will extend the data into a new block,
526 * and the data is currently composed of a fragment
527 * this fragment has to be extended to be a full block.
529 lastlbn = lblkno(fs, dp->di_extsize);
532 osize = sblksize(fs, dp->di_extsize, nb);
533 if (osize < fs->fs_bsize && osize > 0) {
535 error = ffs_realloccg(ip, -1 - nb,
537 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
538 &dp->di_extb[0]), osize,
539 (int)fs->fs_bsize, flags, cred, &bp);
542 if (DOINGSOFTDEP(vp))
543 softdep_setup_allocext(ip, nb,
544 dbtofsb(fs, bp->b_blkno),
546 fs->fs_bsize, osize, bp);
547 dp->di_extsize = smalllblktosize(fs, nb + 1);
548 dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
549 bp->b_xflags |= BX_ALTDATA;
550 ip->i_flag |= IN_CHANGE;
558 * All blocks are direct blocks
560 if (flags & BA_METAONLY)
561 panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
562 nb = dp->di_extb[lbn];
563 if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
564 error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp);
569 bp->b_blkno = fsbtodb(fs, nb);
570 bp->b_xflags |= BX_ALTDATA;
576 * Consider need to reallocate a fragment.
578 osize = fragroundup(fs, blkoff(fs, dp->di_extsize));
579 nsize = fragroundup(fs, size);
580 if (nsize <= osize) {
581 error = bread(vp, -1 - lbn, osize, NOCRED, &bp);
586 bp->b_blkno = fsbtodb(fs, nb);
587 bp->b_xflags |= BX_ALTDATA;
590 error = ffs_realloccg(ip, -1 - lbn,
592 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
593 &dp->di_extb[0]), osize, nsize, flags,
597 bp->b_xflags |= BX_ALTDATA;
598 if (DOINGSOFTDEP(vp))
599 softdep_setup_allocext(ip, lbn,
600 dbtofsb(fs, bp->b_blkno), nb,
604 if (dp->di_extsize < smalllblktosize(fs, lbn + 1))
605 nsize = fragroundup(fs, size);
607 nsize = fs->fs_bsize;
609 error = ffs_alloc(ip, lbn,
610 ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
611 nsize, flags, cred, &newb);
614 bp = getblk(vp, -1 - lbn, nsize, 0, 0, 0);
615 bp->b_blkno = fsbtodb(fs, newb);
616 bp->b_xflags |= BX_ALTDATA;
617 if (flags & BA_CLRBUF)
619 if (DOINGSOFTDEP(vp))
620 softdep_setup_allocext(ip, lbn, newb, 0,
623 dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
624 ip->i_flag |= IN_CHANGE;
629 * If the next write will extend the file into a new block,
630 * and the file is currently composed of a fragment
631 * this fragment has to be extended to be a full block.
633 lastlbn = lblkno(fs, ip->i_size);
634 if (lastlbn < NDADDR && lastlbn < lbn) {
636 osize = blksize(fs, ip, nb);
637 if (osize < fs->fs_bsize && osize > 0) {
639 error = ffs_realloccg(ip, nb, dp->di_db[nb],
640 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
641 &dp->di_db[0]), osize, (int)fs->fs_bsize,
645 if (DOINGSOFTDEP(vp))
646 softdep_setup_allocdirect(ip, nb,
647 dbtofsb(fs, bp->b_blkno),
649 fs->fs_bsize, osize, bp);
650 ip->i_size = smalllblktosize(fs, nb + 1);
651 dp->di_size = ip->i_size;
652 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
653 ip->i_flag |= IN_CHANGE | IN_UPDATE;
661 * The first NDADDR blocks are direct blocks
664 if (flags & BA_METAONLY)
665 panic("ffs_balloc_ufs2: BA_METAONLY for direct block");
667 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
668 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
673 bp->b_blkno = fsbtodb(fs, nb);
679 * Consider need to reallocate a fragment.
681 osize = fragroundup(fs, blkoff(fs, ip->i_size));
682 nsize = fragroundup(fs, size);
683 if (nsize <= osize) {
684 error = bread(vp, lbn, osize, NOCRED, &bp);
689 bp->b_blkno = fsbtodb(fs, nb);
692 error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
693 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
694 &dp->di_db[0]), osize, nsize, flags,
698 if (DOINGSOFTDEP(vp))
699 softdep_setup_allocdirect(ip, lbn,
700 dbtofsb(fs, bp->b_blkno), nb,
704 if (ip->i_size < smalllblktosize(fs, lbn + 1))
705 nsize = fragroundup(fs, size);
707 nsize = fs->fs_bsize;
709 error = ffs_alloc(ip, lbn,
710 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
711 &dp->di_db[0]), nsize, flags, cred, &newb);
714 bp = getblk(vp, lbn, nsize, 0, 0, 0);
715 bp->b_blkno = fsbtodb(fs, newb);
716 if (flags & BA_CLRBUF)
718 if (DOINGSOFTDEP(vp))
719 softdep_setup_allocdirect(ip, lbn, newb, 0,
722 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
723 ip->i_flag |= IN_CHANGE | IN_UPDATE;
728 * Determine the number of levels of indirection.
731 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
735 panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
737 saved_inbdflush = ~TDP_INBDFLUSH | (curthread->td_pflags &
739 curthread->td_pflags |= TDP_INBDFLUSH;
741 * Fetch the first indirect block allocating if necessary.
744 nb = dp->di_ib[indirs[0].in_off];
746 allocblk = allociblk;
750 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
751 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
752 flags, cred, &newb)) != 0) {
753 curthread->td_pflags &= saved_inbdflush;
758 *lbns_remfree++ = indirs[1].in_lbn;
759 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
760 bp->b_blkno = fsbtodb(fs, nb);
762 if (DOINGSOFTDEP(vp)) {
763 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
764 newb, 0, fs->fs_bsize, 0, bp);
768 * Write synchronously so that indirect blocks
769 * never point at garbage.
773 else if ((error = bwrite(bp)) != 0)
776 allocib = &dp->di_ib[indirs[0].in_off];
778 ip->i_flag |= IN_CHANGE | IN_UPDATE;
781 * Fetch through the indirect blocks, allocating as necessary.
785 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
790 bap = (ufs2_daddr_t *)bp->b_data;
791 nb = bap[indirs[i].in_off];
801 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
802 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
803 flags, cred, &newb)) != 0) {
809 *lbns_remfree++ = indirs[i].in_lbn;
810 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, 0);
811 nbp->b_blkno = fsbtodb(fs, nb);
813 if (DOINGSOFTDEP(vp)) {
814 softdep_setup_allocindir_meta(nbp, ip, bp,
815 indirs[i - 1].in_off, nb);
819 * Write synchronously so that indirect blocks
820 * never point at garbage.
822 if ((error = bwrite(nbp)) != 0) {
827 bap[indirs[i - 1].in_off] = nb;
828 if (allocib == NULL && unwindidx < 0)
831 * If required, write synchronously, otherwise use
834 if (flags & IO_SYNC) {
837 if (bp->b_bufsize == fs->fs_bsize)
838 bp->b_flags |= B_CLUSTEROK;
843 * If asked only for the indirect block, then return it.
845 if (flags & BA_METAONLY) {
846 curthread->td_pflags &= saved_inbdflush;
851 * Get the data block, allocating if necessary.
855 pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, &bap[0]);
856 error = ffs_alloc(ip,
857 lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
864 *lbns_remfree++ = lbn;
865 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
866 nbp->b_blkno = fsbtodb(fs, nb);
867 if (flags & BA_CLRBUF)
869 if (DOINGSOFTDEP(vp))
870 softdep_setup_allocindir_page(ip, lbn, bp,
871 indirs[i].in_off, nb, 0, nbp);
872 bap[indirs[i].in_off] = nb;
874 * If required, write synchronously, otherwise use
877 if (flags & IO_SYNC) {
880 if (bp->b_bufsize == fs->fs_bsize)
881 bp->b_flags |= B_CLUSTEROK;
884 curthread->td_pflags &= saved_inbdflush;
890 * If requested clear invalid portions of the buffer. If we
891 * have to do a read-before-write (typical if BA_CLRBUF is set),
892 * try to do some read-ahead in the sequential case to reduce
893 * the number of I/O transactions.
895 if (flags & BA_CLRBUF) {
896 int seqcount = (flags & BA_SEQMASK) >> BA_SEQSHIFT;
897 if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
898 error = cluster_read(vp, ip->i_size, lbn,
899 (int)fs->fs_bsize, NOCRED,
900 MAXBSIZE, seqcount, &nbp);
902 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
909 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
910 nbp->b_blkno = fsbtodb(fs, nb);
912 curthread->td_pflags &= saved_inbdflush;
916 curthread->td_pflags &= saved_inbdflush;
918 * If we have failed to allocate any blocks, simply return the error.
919 * This is the usual case and avoids the need to fsync the file.
921 if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
924 * If we have failed part way through block allocation, we
925 * have to deallocate any indirect blocks that we have allocated.
926 * We have to fsync the file before we start to get rid of all
927 * of its dependencies so that we do not leave them dangling.
928 * We have to sync it at the end so that the soft updates code
929 * does not find any untracked changes. Although this is really
930 * slow, running out of disk space is not expected to be a common
931 * occurence. The error return from fsync is ignored as we already
932 * have an error to return to the user.
934 (void) ffs_syncvnode(vp, MNT_WAIT);
935 for (deallocated = 0, blkp = allociblk, lbns_remfree = lbns;
936 blkp < allocblk; blkp++, lbns_remfree++) {
938 * We shall not leave the freed blocks on the vnode
939 * buffer object lists.
941 bp = getblk(vp, *lbns_remfree, fs->fs_bsize, 0, 0, GB_NOCREAT);
943 bp->b_flags |= (B_INVAL | B_RELBUF);
944 bp->b_flags &= ~B_ASYNC;
947 deallocated += fs->fs_bsize;
949 if (allocib != NULL) {
951 } else if (unwindidx >= 0) {
954 r = bread(vp, indirs[unwindidx].in_lbn,
955 (int)fs->fs_bsize, NOCRED, &bp);
957 panic("Could not unwind indirect block, error %d", r);
960 bap = (ufs2_daddr_t *)bp->b_data;
961 bap[indirs[unwindidx].in_off] = 0;
962 if (flags & IO_SYNC) {
965 if (bp->b_bufsize == fs->fs_bsize)
966 bp->b_flags |= B_CLUSTEROK;
974 * Restore user's disk quota because allocation failed.
976 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
978 dp->di_blocks -= btodb(deallocated);
979 ip->i_flag |= IN_CHANGE | IN_UPDATE;
981 (void) ffs_syncvnode(vp, MNT_WAIT);
983 * After the buffers are invalidated and on-disk pointers are
984 * cleared, free the blocks.
986 for (blkp = allociblk; blkp < allocblk; blkp++) {
987 ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,