1 /* $NetBSD: ffs_balloc.c,v 1.51 2008/07/31 05:38:06 simonb Exp $ */
4 * Copyright (c) 2002 Networks Associates Technology, Inc.
7 * This software was developed for the FreeBSD Project by Marshall
8 * Kirk McKusick and Network Associates Laboratories, the Security
9 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
10 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
13 * Copyright (c) 1982, 1986, 1989, 1993
14 * The Regents of the University of California. All rights reserved.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.51 2008/07/31 05:38:06 simonb Exp $");
46 #if defined(_KERNEL_OPT)
47 #include "opt_quota.h"
50 #include <sys/param.h>
51 #include <sys/systm.h>
54 #include <sys/mount.h>
55 #include <sys/vnode.h>
56 #include <sys/kauth.h>
57 #include <sys/fstrans.h>
59 #include <ufs/ufs/quota.h>
60 #include <ufs/ufs/ufsmount.h>
61 #include <ufs/ufs/inode.h>
62 #include <ufs/ufs/ufs_extern.h>
63 #include <ufs/ufs/ufs_bswap.h>
65 #include <ufs/ffs/fs.h>
66 #include <ufs/ffs/ffs_extern.h>
70 static int ffs_balloc_ufs1(struct vnode
*, off_t
, int, kauth_cred_t
, int,
72 static int ffs_balloc_ufs2(struct vnode
*, off_t
, int, kauth_cred_t
, int,
76 * Balloc defines the structure of file system storage
77 * by allocating the physical blocks on a device given
78 * the inode and the logical block number in a file.
82 ffs_balloc(struct vnode
*vp
, off_t off
, int size
, kauth_cred_t cred
, int flags
,
87 if (VTOI(vp
)->i_fs
->fs_magic
== FS_UFS2_MAGIC
)
88 error
= ffs_balloc_ufs2(vp
, off
, size
, cred
, flags
, bpp
);
90 error
= ffs_balloc_ufs1(vp
, off
, size
, cred
, flags
, bpp
);
92 if (error
== 0 && bpp
!= NULL
&& (error
= fscow_run(*bpp
, false)) != 0)
99 ffs_balloc_ufs1(struct vnode
*vp
, off_t off
, int size
, kauth_cred_t cred
,
100 int flags
, struct buf
**bpp
)
102 daddr_t lbn
, lastlbn
;
103 struct buf
*bp
, *nbp
;
104 struct inode
*ip
= VTOI(vp
);
105 struct fs
*fs
= ip
->i_fs
;
106 struct ufsmount
*ump
= ip
->i_ump
;
107 struct indir indirs
[NIADDR
+ 2];
108 daddr_t newb
, pref
, nb
;
109 int32_t *bap
; /* XXX ondisk32 */
110 int deallocated
, osize
, nsize
, num
, i
, error
;
111 int32_t *blkp
, *allocblk
, allociblk
[NIADDR
+ 1];
115 const int needswap
= UFS_FSNEEDSWAP(fs
);
117 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist
);
119 lbn
= lblkno(fs
, off
);
120 size
= blkoff(fs
, off
) + size
;
121 if (size
> fs
->fs_bsize
)
122 panic("ffs_balloc: blk too big");
126 UVMHIST_LOG(ubchist
, "vp %p lbn 0x%x size 0x%x", vp
, lbn
, size
,0);
132 * If the next write will extend the file into a new block,
133 * and the file is currently composed of a fragment
134 * this fragment has to be extended to be a full block.
137 lastlbn
= lblkno(fs
, ip
->i_size
);
138 if (lastlbn
< NDADDR
&& lastlbn
< lbn
) {
140 osize
= blksize(fs
, ip
, nb
);
141 if (osize
< fs
->fs_bsize
&& osize
> 0) {
142 mutex_enter(&ump
->um_lock
);
143 error
= ffs_realloccg(ip
, nb
,
144 ffs_blkpref_ufs1(ip
, lastlbn
, nb
, flags
,
146 osize
, (int)fs
->fs_bsize
, cred
, bpp
, &newb
);
149 ip
->i_size
= lblktosize(fs
, nb
+ 1);
150 ip
->i_ffs1_size
= ip
->i_size
;
151 uvm_vnp_setsize(vp
, ip
->i_ffs1_size
);
152 ip
->i_ffs1_db
[nb
] = ufs_rw32((u_int32_t
)newb
, needswap
);
153 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
164 * The first NDADDR blocks are direct blocks
168 nb
= ufs_rw32(ip
->i_ffs1_db
[lbn
], needswap
);
169 if (nb
!= 0 && ip
->i_size
>= lblktosize(fs
, lbn
+ 1)) {
172 * The block is an already-allocated direct block
173 * and the file already extends past this block,
174 * thus this must be a whole block.
175 * Just read the block (if requested).
179 error
= bread(vp
, lbn
, fs
->fs_bsize
, NOCRED
,
191 * Consider need to reallocate a fragment.
194 osize
= fragroundup(fs
, blkoff(fs
, ip
->i_size
));
195 nsize
= fragroundup(fs
, size
);
196 if (nsize
<= osize
) {
199 * The existing block is already
200 * at least as big as we want.
201 * Just read the block (if requested).
205 error
= bread(vp
, lbn
, osize
, NOCRED
,
216 * The existing block is smaller than we want,
219 mutex_enter(&ump
->um_lock
);
220 error
= ffs_realloccg(ip
, lbn
,
221 ffs_blkpref_ufs1(ip
, lbn
, (int)lbn
, flags
,
223 osize
, nsize
, cred
, bpp
, &newb
);
230 * the block was not previously allocated,
231 * allocate a new block or fragment.
234 if (ip
->i_size
< lblktosize(fs
, lbn
+ 1))
235 nsize
= fragroundup(fs
, size
);
237 nsize
= fs
->fs_bsize
;
238 mutex_enter(&ump
->um_lock
);
239 error
= ffs_alloc(ip
, lbn
,
240 ffs_blkpref_ufs1(ip
, lbn
, (int)lbn
, flags
,
242 nsize
, flags
, cred
, &newb
);
246 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, newb
),
247 nsize
, (flags
& B_CLRBUF
) != 0, bpp
);
252 ip
->i_ffs1_db
[lbn
] = ufs_rw32((u_int32_t
)newb
, needswap
);
253 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
258 * Determine the number of levels of indirection.
262 if ((error
= ufs_getlbns(vp
, lbn
, indirs
, &num
)) != 0)
266 * Fetch the first indirect block allocating if necessary.
270 nb
= ufs_rw32(ip
->i_ffs1_ib
[indirs
[0].in_off
], needswap
);
272 allocblk
= allociblk
;
274 mutex_enter(&ump
->um_lock
);
275 pref
= ffs_blkpref_ufs1(ip
, lbn
, 0, flags
| B_METAONLY
, NULL
);
276 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
277 flags
| B_METAONLY
, cred
, &newb
);
282 error
= ffs_getblk(vp
, indirs
[1].in_lbn
, fsbtodb(fs
, nb
),
283 fs
->fs_bsize
, true, &bp
);
287 * Write synchronously so that indirect blocks
288 * never point at garbage.
290 if ((error
= bwrite(bp
)) != 0)
293 allocib
= &ip
->i_ffs1_ib
[indirs
[0].in_off
];
294 *allocib
= ufs_rw32(nb
, needswap
);
295 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
299 * Fetch through the indirect blocks, allocating as necessary.
304 indirs
[i
].in_lbn
, (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
309 bap
= (int32_t *)bp
->b_data
; /* XXX ondisk32 */
310 nb
= ufs_rw32(bap
[indirs
[i
].in_off
], needswap
);
318 if (fscow_run(bp
, true) != 0) {
322 mutex_enter(&ump
->um_lock
);
324 pref
= ffs_blkpref_ufs1(ip
, lbn
, 0, flags
| B_METAONLY
,
326 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
327 flags
| B_METAONLY
, cred
, &newb
);
334 error
= ffs_getblk(vp
, indirs
[i
].in_lbn
, fsbtodb(fs
, nb
),
335 fs
->fs_bsize
, true, &nbp
);
341 * Write synchronously so that indirect blocks
342 * never point at garbage.
344 if ((error
= bwrite(nbp
)) != 0) {
350 bap
[indirs
[i
- 1].in_off
] = ufs_rw32(nb
, needswap
);
353 * If required, write synchronously, otherwise use
357 if (flags
& B_SYNC
) {
364 if (flags
& B_METAONLY
) {
365 KASSERT(bpp
!= NULL
);
371 * Get the data block, allocating if necessary.
375 if (fscow_run(bp
, true) != 0) {
379 mutex_enter(&ump
->um_lock
);
380 pref
= ffs_blkpref_ufs1(ip
, lbn
, indirs
[num
].in_off
, flags
,
382 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
, flags
, cred
,
391 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
392 fs
->fs_bsize
, (flags
& B_CLRBUF
) != 0, bpp
);
398 bap
[indirs
[num
].in_off
] = ufs_rw32(nb
, needswap
);
399 if (allocib
== NULL
&& unwindidx
< 0) {
404 * If required, write synchronously, otherwise use
408 if (flags
& B_SYNC
) {
417 if (flags
& B_CLRBUF
) {
418 error
= bread(vp
, lbn
, (int)fs
->fs_bsize
,
419 NOCRED
, B_MODIFY
, &nbp
);
425 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
426 fs
->fs_bsize
, true, &nbp
);
436 * If we have failed part way through block allocation, we
437 * have to deallocate any indirect blocks that we have allocated.
440 if (unwindidx
>= 0) {
443 * First write out any buffers we've created to resolve their
444 * softdeps. This must be done in reverse order of creation
445 * so that we resolve the dependencies in one pass.
446 * Write the cylinder group buffers for these buffers too.
449 for (i
= num
; i
>= unwindidx
; i
--) {
453 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
454 fs
->fs_bsize
, false, &bp
) != 0)
456 if (bp
->b_oflags
& BO_DELWRI
) {
457 nb
= fsbtodb(fs
, cgtod(fs
, dtog(fs
,
458 dbtofsb(fs
, bp
->b_blkno
))));
460 if (ffs_getblk(ip
->i_devvp
, nb
, FFS_NOBLK
,
461 fs
->fs_cgsize
, false, &bp
) != 0)
463 if (bp
->b_oflags
& BO_DELWRI
) {
466 brelse(bp
, BC_INVAL
);
469 brelse(bp
, BC_INVAL
);
474 * Undo the partial allocation.
476 if (unwindidx
== 0) {
478 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
482 r
= bread(vp
, indirs
[unwindidx
].in_lbn
,
483 (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
485 panic("Could not unwind indirect block, error %d", r
);
488 bap
= (int32_t *)bp
->b_data
; /* XXX ondisk32 */
489 bap
[indirs
[unwindidx
].in_off
] = 0;
493 for (i
= unwindidx
+ 1; i
<= num
; i
++) {
494 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
495 fs
->fs_bsize
, false, &bp
) == 0)
496 brelse(bp
, BC_INVAL
);
499 for (deallocated
= 0, blkp
= allociblk
; blkp
< allocblk
; blkp
++) {
500 ffs_blkfree(fs
, ip
->i_devvp
, *blkp
, fs
->fs_bsize
, ip
->i_number
);
501 deallocated
+= fs
->fs_bsize
;
506 * Restore user's disk quota because allocation failed.
508 (void)chkdq(ip
, -btodb(deallocated
), cred
, FORCE
);
510 ip
->i_ffs1_blocks
-= btodb(deallocated
);
511 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
517 ffs_balloc_ufs2(struct vnode
*vp
, off_t off
, int size
, kauth_cred_t cred
,
518 int flags
, struct buf
**bpp
)
520 daddr_t lbn
, lastlbn
;
521 struct buf
*bp
, *nbp
;
522 struct inode
*ip
= VTOI(vp
);
523 struct fs
*fs
= ip
->i_fs
;
524 struct ufsmount
*ump
= ip
->i_ump
;
525 struct indir indirs
[NIADDR
+ 2];
526 daddr_t newb
, pref
, nb
;
528 int deallocated
, osize
, nsize
, num
, i
, error
;
529 daddr_t
*blkp
, *allocblk
, allociblk
[NIADDR
+ 1];
533 const int needswap
= UFS_FSNEEDSWAP(fs
);
535 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist
);
537 lbn
= lblkno(fs
, off
);
538 size
= blkoff(fs
, off
) + size
;
539 if (size
> fs
->fs_bsize
)
540 panic("ffs_balloc: blk too big");
544 UVMHIST_LOG(ubchist
, "vp %p lbn 0x%x size 0x%x", vp
, lbn
, size
,0);
551 * Check for allocating external data.
553 if (flags
& IO_EXT
) {
557 * If the next write will extend the data into a new block,
558 * and the data is currently composed of a fragment
559 * this fragment has to be extended to be a full block.
561 lastlbn
= lblkno(fs
, dp
->di_extsize
);
564 osize
= sblksize(fs
, dp
->di_extsize
, nb
);
565 if (osize
< fs
->fs_bsize
&& osize
> 0) {
566 mutex_enter(&ump
->um_lock
);
567 error
= ffs_realloccg(ip
, -1 - nb
,
569 ffs_blkpref_ufs2(ip
, lastlbn
, (int)nb
,
570 flags
, &dp
->di_extb
[0]),
572 (int)fs
->fs_bsize
, cred
, &bp
);
575 dp
->di_extsize
= smalllblktosize(fs
, nb
+ 1);
576 dp
->di_extb
[nb
] = dbtofsb(fs
, bp
->b_blkno
);
577 bp
->b_xflags
|= BX_ALTDATA
;
578 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
586 * All blocks are direct blocks
588 if (flags
& BA_METAONLY
)
589 panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
590 nb
= dp
->di_extb
[lbn
];
591 if (nb
!= 0 && dp
->di_extsize
>= smalllblktosize(fs
, lbn
+ 1)) {
592 error
= bread(vp
, -1 - lbn
, fs
->fs_bsize
,
598 mutex_enter(&bp
->b_interlock
);
599 bp
->b_blkno
= fsbtodb(fs
, nb
);
600 bp
->b_xflags
|= BX_ALTDATA
;
601 mutex_exit(&bp
->b_interlock
);
607 * Consider need to reallocate a fragment.
609 osize
= fragroundup(fs
, blkoff(fs
, dp
->di_extsize
));
610 nsize
= fragroundup(fs
, size
);
611 if (nsize
<= osize
) {
612 error
= bread(vp
, -1 - lbn
, osize
,
618 mutex_enter(&bp
->b_interlock
);
619 bp
->b_blkno
= fsbtodb(fs
, nb
);
620 bp
->b_xflags
|= BX_ALTDATA
;
621 mutex_exit(&bp
->b_interlock
);
623 mutex_enter(&ump
->um_lock
);
624 error
= ffs_realloccg(ip
, -1 - lbn
,
626 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
628 osize
, nsize
, cred
, &bp
);
631 bp
->b_xflags
|= BX_ALTDATA
;
634 if (dp
->di_extsize
< smalllblktosize(fs
, lbn
+ 1))
635 nsize
= fragroundup(fs
, size
);
637 nsize
= fs
->fs_bsize
;
638 mutex_enter(&ump
->um_lock
);
639 error
= ffs_alloc(ip
, lbn
,
640 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
642 nsize
, flags
, cred
, &newb
);
645 error
= ffs_getblk(vp
, -1 - lbn
, fsbtodb(fs
, newb
),
646 nsize
, (flags
& BA_CLRBUF
) != 0, &bp
);
649 bp
->b_xflags
|= BX_ALTDATA
;
651 dp
->di_extb
[lbn
] = dbtofsb(fs
, bp
->b_blkno
);
652 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
658 * If the next write will extend the file into a new block,
659 * and the file is currently composed of a fragment
660 * this fragment has to be extended to be a full block.
663 lastlbn
= lblkno(fs
, ip
->i_size
);
664 if (lastlbn
< NDADDR
&& lastlbn
< lbn
) {
666 osize
= blksize(fs
, ip
, nb
);
667 if (osize
< fs
->fs_bsize
&& osize
> 0) {
668 mutex_enter(&ump
->um_lock
);
669 error
= ffs_realloccg(ip
, nb
,
670 ffs_blkpref_ufs2(ip
, lastlbn
, nb
, flags
,
672 osize
, (int)fs
->fs_bsize
, cred
, bpp
, &newb
);
675 ip
->i_size
= lblktosize(fs
, nb
+ 1);
676 ip
->i_ffs2_size
= ip
->i_size
;
677 uvm_vnp_setsize(vp
, ip
->i_size
);
678 ip
->i_ffs2_db
[nb
] = ufs_rw64(newb
, needswap
);
679 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
690 * The first NDADDR blocks are direct blocks
694 nb
= ufs_rw64(ip
->i_ffs2_db
[lbn
], needswap
);
695 if (nb
!= 0 && ip
->i_size
>= lblktosize(fs
, lbn
+ 1)) {
698 * The block is an already-allocated direct block
699 * and the file already extends past this block,
700 * thus this must be a whole block.
701 * Just read the block (if requested).
705 error
= bread(vp
, lbn
, fs
->fs_bsize
, NOCRED
,
717 * Consider need to reallocate a fragment.
720 osize
= fragroundup(fs
, blkoff(fs
, ip
->i_size
));
721 nsize
= fragroundup(fs
, size
);
722 if (nsize
<= osize
) {
725 * The existing block is already
726 * at least as big as we want.
727 * Just read the block (if requested).
731 error
= bread(vp
, lbn
, osize
, NOCRED
,
742 * The existing block is smaller than we want,
745 mutex_enter(&ump
->um_lock
);
746 error
= ffs_realloccg(ip
, lbn
,
747 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
749 osize
, nsize
, cred
, bpp
, &newb
);
756 * the block was not previously allocated,
757 * allocate a new block or fragment.
760 if (ip
->i_size
< lblktosize(fs
, lbn
+ 1))
761 nsize
= fragroundup(fs
, size
);
763 nsize
= fs
->fs_bsize
;
764 mutex_enter(&ump
->um_lock
);
765 error
= ffs_alloc(ip
, lbn
,
766 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
768 nsize
, flags
, cred
, &newb
);
772 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, newb
),
773 nsize
, (flags
& B_CLRBUF
) != 0, bpp
);
778 ip
->i_ffs2_db
[lbn
] = ufs_rw64(newb
, needswap
);
779 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
784 * Determine the number of levels of indirection.
788 if ((error
= ufs_getlbns(vp
, lbn
, indirs
, &num
)) != 0)
792 * Fetch the first indirect block allocating if necessary.
796 nb
= ufs_rw64(ip
->i_ffs2_ib
[indirs
[0].in_off
], needswap
);
798 allocblk
= allociblk
;
800 mutex_enter(&ump
->um_lock
);
801 pref
= ffs_blkpref_ufs2(ip
, lbn
, 0, flags
| B_METAONLY
, NULL
);
802 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
803 flags
| B_METAONLY
, cred
, &newb
);
808 error
= ffs_getblk(vp
, indirs
[1].in_lbn
, fsbtodb(fs
, nb
),
809 fs
->fs_bsize
, true, &bp
);
813 * Write synchronously so that indirect blocks
814 * never point at garbage.
816 if ((error
= bwrite(bp
)) != 0)
819 allocib
= &ip
->i_ffs2_ib
[indirs
[0].in_off
];
820 *allocib
= ufs_rw64(nb
, needswap
);
821 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
825 * Fetch through the indirect blocks, allocating as necessary.
830 indirs
[i
].in_lbn
, (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
835 bap
= (int64_t *)bp
->b_data
;
836 nb
= ufs_rw64(bap
[indirs
[i
].in_off
], needswap
);
844 if (fscow_run(bp
, true) != 0) {
848 mutex_enter(&ump
->um_lock
);
850 pref
= ffs_blkpref_ufs2(ip
, lbn
, 0, flags
| B_METAONLY
,
852 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
853 flags
| B_METAONLY
, cred
, &newb
);
860 error
= ffs_getblk(vp
, indirs
[i
].in_lbn
, fsbtodb(fs
, nb
),
861 fs
->fs_bsize
, true, &nbp
);
867 * Write synchronously so that indirect blocks
868 * never point at garbage.
870 if ((error
= bwrite(nbp
)) != 0) {
876 bap
[indirs
[i
- 1].in_off
] = ufs_rw64(nb
, needswap
);
879 * If required, write synchronously, otherwise use
883 if (flags
& B_SYNC
) {
890 if (flags
& B_METAONLY
) {
891 KASSERT(bpp
!= NULL
);
897 * Get the data block, allocating if necessary.
901 if (fscow_run(bp
, true) != 0) {
905 mutex_enter(&ump
->um_lock
);
906 pref
= ffs_blkpref_ufs2(ip
, lbn
, indirs
[num
].in_off
, flags
,
908 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
, flags
, cred
,
917 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
918 fs
->fs_bsize
, (flags
& B_CLRBUF
) != 0, bpp
);
924 bap
[indirs
[num
].in_off
] = ufs_rw64(nb
, needswap
);
925 if (allocib
== NULL
&& unwindidx
< 0) {
930 * If required, write synchronously, otherwise use
934 if (flags
& B_SYNC
) {
943 if (flags
& B_CLRBUF
) {
944 error
= bread(vp
, lbn
, (int)fs
->fs_bsize
,
945 NOCRED
, B_MODIFY
, &nbp
);
951 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
952 fs
->fs_bsize
, true, &nbp
);
962 * If we have failed part way through block allocation, we
963 * have to deallocate any indirect blocks that we have allocated.
966 if (unwindidx
>= 0) {
969 * First write out any buffers we've created to resolve their
970 * softdeps. This must be done in reverse order of creation
971 * so that we resolve the dependencies in one pass.
972 * Write the cylinder group buffers for these buffers too.
975 for (i
= num
; i
>= unwindidx
; i
--) {
979 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
980 fs
->fs_bsize
, false, &bp
) != 0)
982 if (bp
->b_oflags
& BO_DELWRI
) {
983 nb
= fsbtodb(fs
, cgtod(fs
, dtog(fs
,
984 dbtofsb(fs
, bp
->b_blkno
))));
986 if (ffs_getblk(ip
->i_devvp
, nb
, FFS_NOBLK
,
987 fs
->fs_cgsize
, false, &bp
) != 0)
989 if (bp
->b_oflags
& BO_DELWRI
) {
992 brelse(bp
, BC_INVAL
);
995 brelse(bp
, BC_INVAL
);
1000 * Now that any dependencies that we created have been
1001 * resolved, we can undo the partial allocation.
1004 if (unwindidx
== 0) {
1006 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
1010 r
= bread(vp
, indirs
[unwindidx
].in_lbn
,
1011 (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
1013 panic("Could not unwind indirect block, error %d", r
);
1016 bap
= (int64_t *)bp
->b_data
;
1017 bap
[indirs
[unwindidx
].in_off
] = 0;
1021 for (i
= unwindidx
+ 1; i
<= num
; i
++) {
1022 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
1023 fs
->fs_bsize
, false, &bp
) == 0)
1024 brelse(bp
, BC_INVAL
);
1027 for (deallocated
= 0, blkp
= allociblk
; blkp
< allocblk
; blkp
++) {
1028 ffs_blkfree(fs
, ip
->i_devvp
, *blkp
, fs
->fs_bsize
, ip
->i_number
);
1029 deallocated
+= fs
->fs_bsize
;
1034 * Restore user's disk quota because allocation failed.
1036 (void)chkdq(ip
, -btodb(deallocated
), cred
, FORCE
);
1038 ip
->i_ffs2_blocks
-= btodb(deallocated
);
1039 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;