1 /* $NetBSD: ffs_balloc.c,v 1.54 2011/04/23 07:36:02 hannken 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.54 2011/04/23 07:36:02 hannken 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
);
323 /* Try to keep snapshot indirect blocks contiguous. */
324 if (i
== num
&& (ip
->i_flags
& SF_SNAPSHOT
) != 0)
325 pref
= ffs_blkpref_ufs1(ip
, lbn
, indirs
[i
-1].in_off
,
326 flags
| B_METAONLY
, &bap
[0]);
328 pref
= ffs_blkpref_ufs1(ip
, lbn
, 0, flags
| B_METAONLY
,
330 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
331 flags
| B_METAONLY
, cred
, &newb
);
338 error
= ffs_getblk(vp
, indirs
[i
].in_lbn
, fsbtodb(fs
, nb
),
339 fs
->fs_bsize
, true, &nbp
);
345 * Write synchronously so that indirect blocks
346 * never point at garbage.
348 if ((error
= bwrite(nbp
)) != 0) {
354 bap
[indirs
[i
- 1].in_off
] = ufs_rw32(nb
, needswap
);
357 * If required, write synchronously, otherwise use
361 if (flags
& B_SYNC
) {
368 if (flags
& B_METAONLY
) {
369 KASSERT(bpp
!= NULL
);
375 * Get the data block, allocating if necessary.
379 if (fscow_run(bp
, true) != 0) {
383 mutex_enter(&ump
->um_lock
);
384 pref
= ffs_blkpref_ufs1(ip
, lbn
, indirs
[num
].in_off
, flags
,
386 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
, flags
, cred
,
395 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
396 fs
->fs_bsize
, (flags
& B_CLRBUF
) != 0, bpp
);
402 bap
[indirs
[num
].in_off
] = ufs_rw32(nb
, needswap
);
403 if (allocib
== NULL
&& unwindidx
< 0) {
408 * If required, write synchronously, otherwise use
412 if (flags
& B_SYNC
) {
421 if (flags
& B_CLRBUF
) {
422 error
= bread(vp
, lbn
, (int)fs
->fs_bsize
,
423 NOCRED
, B_MODIFY
, &nbp
);
429 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
430 fs
->fs_bsize
, true, &nbp
);
440 * If we have failed part way through block allocation, we
441 * have to deallocate any indirect blocks that we have allocated.
444 if (unwindidx
>= 0) {
447 * First write out any buffers we've created to resolve their
448 * softdeps. This must be done in reverse order of creation
449 * so that we resolve the dependencies in one pass.
450 * Write the cylinder group buffers for these buffers too.
453 for (i
= num
; i
>= unwindidx
; i
--) {
457 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
458 fs
->fs_bsize
, false, &bp
) != 0)
460 if (bp
->b_oflags
& BO_DELWRI
) {
461 nb
= fsbtodb(fs
, cgtod(fs
, dtog(fs
,
462 dbtofsb(fs
, bp
->b_blkno
))));
464 if (ffs_getblk(ip
->i_devvp
, nb
, FFS_NOBLK
,
465 fs
->fs_cgsize
, false, &bp
) != 0)
467 if (bp
->b_oflags
& BO_DELWRI
) {
470 brelse(bp
, BC_INVAL
);
473 brelse(bp
, BC_INVAL
);
478 * Undo the partial allocation.
480 if (unwindidx
== 0) {
482 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
486 r
= bread(vp
, indirs
[unwindidx
].in_lbn
,
487 (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
489 panic("Could not unwind indirect block, error %d", r
);
492 bap
= (int32_t *)bp
->b_data
; /* XXX ondisk32 */
493 bap
[indirs
[unwindidx
].in_off
] = 0;
497 for (i
= unwindidx
+ 1; i
<= num
; i
++) {
498 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
499 fs
->fs_bsize
, false, &bp
) == 0)
500 brelse(bp
, BC_INVAL
);
503 for (deallocated
= 0, blkp
= allociblk
; blkp
< allocblk
; blkp
++) {
504 ffs_blkfree(fs
, ip
->i_devvp
, *blkp
, fs
->fs_bsize
, ip
->i_number
);
505 deallocated
+= fs
->fs_bsize
;
508 #if defined(QUOTA) || defined(QUOTA2)
510 * Restore user's disk quota because allocation failed.
512 (void)chkdq(ip
, -btodb(deallocated
), cred
, FORCE
);
514 ip
->i_ffs1_blocks
-= btodb(deallocated
);
515 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
521 ffs_balloc_ufs2(struct vnode
*vp
, off_t off
, int size
, kauth_cred_t cred
,
522 int flags
, struct buf
**bpp
)
524 daddr_t lbn
, lastlbn
;
525 struct buf
*bp
, *nbp
;
526 struct inode
*ip
= VTOI(vp
);
527 struct fs
*fs
= ip
->i_fs
;
528 struct ufsmount
*ump
= ip
->i_ump
;
529 struct indir indirs
[NIADDR
+ 2];
530 daddr_t newb
, pref
, nb
;
532 int deallocated
, osize
, nsize
, num
, i
, error
;
533 daddr_t
*blkp
, *allocblk
, allociblk
[NIADDR
+ 1];
537 const int needswap
= UFS_FSNEEDSWAP(fs
);
539 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist
);
541 lbn
= lblkno(fs
, off
);
542 size
= blkoff(fs
, off
) + size
;
543 if (size
> fs
->fs_bsize
)
544 panic("ffs_balloc: blk too big");
548 UVMHIST_LOG(ubchist
, "vp %p lbn 0x%x size 0x%x", vp
, lbn
, size
,0);
555 * Check for allocating external data.
557 if (flags
& IO_EXT
) {
561 * If the next write will extend the data into a new block,
562 * and the data is currently composed of a fragment
563 * this fragment has to be extended to be a full block.
565 lastlbn
= lblkno(fs
, dp
->di_extsize
);
568 osize
= sblksize(fs
, dp
->di_extsize
, nb
);
569 if (osize
< fs
->fs_bsize
&& osize
> 0) {
570 mutex_enter(&ump
->um_lock
);
571 error
= ffs_realloccg(ip
, -1 - nb
,
573 ffs_blkpref_ufs2(ip
, lastlbn
, (int)nb
,
574 flags
, &dp
->di_extb
[0]),
576 (int)fs
->fs_bsize
, cred
, &bp
);
579 dp
->di_extsize
= smalllblktosize(fs
, nb
+ 1);
580 dp
->di_extb
[nb
] = dbtofsb(fs
, bp
->b_blkno
);
581 bp
->b_xflags
|= BX_ALTDATA
;
582 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
590 * All blocks are direct blocks
592 if (flags
& BA_METAONLY
)
593 panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
594 nb
= dp
->di_extb
[lbn
];
595 if (nb
!= 0 && dp
->di_extsize
>= smalllblktosize(fs
, lbn
+ 1)) {
596 error
= bread(vp
, -1 - lbn
, fs
->fs_bsize
,
602 mutex_enter(&bp
->b_interlock
);
603 bp
->b_blkno
= fsbtodb(fs
, nb
);
604 bp
->b_xflags
|= BX_ALTDATA
;
605 mutex_exit(&bp
->b_interlock
);
611 * Consider need to reallocate a fragment.
613 osize
= fragroundup(fs
, blkoff(fs
, dp
->di_extsize
));
614 nsize
= fragroundup(fs
, size
);
615 if (nsize
<= osize
) {
616 error
= bread(vp
, -1 - lbn
, osize
,
622 mutex_enter(&bp
->b_interlock
);
623 bp
->b_blkno
= fsbtodb(fs
, nb
);
624 bp
->b_xflags
|= BX_ALTDATA
;
625 mutex_exit(&bp
->b_interlock
);
627 mutex_enter(&ump
->um_lock
);
628 error
= ffs_realloccg(ip
, -1 - lbn
,
630 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
632 osize
, nsize
, cred
, &bp
);
635 bp
->b_xflags
|= BX_ALTDATA
;
638 if (dp
->di_extsize
< smalllblktosize(fs
, lbn
+ 1))
639 nsize
= fragroundup(fs
, size
);
641 nsize
= fs
->fs_bsize
;
642 mutex_enter(&ump
->um_lock
);
643 error
= ffs_alloc(ip
, lbn
,
644 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
646 nsize
, flags
, cred
, &newb
);
649 error
= ffs_getblk(vp
, -1 - lbn
, fsbtodb(fs
, newb
),
650 nsize
, (flags
& BA_CLRBUF
) != 0, &bp
);
653 bp
->b_xflags
|= BX_ALTDATA
;
655 dp
->di_extb
[lbn
] = dbtofsb(fs
, bp
->b_blkno
);
656 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
662 * If the next write will extend the file into a new block,
663 * and the file is currently composed of a fragment
664 * this fragment has to be extended to be a full block.
667 lastlbn
= lblkno(fs
, ip
->i_size
);
668 if (lastlbn
< NDADDR
&& lastlbn
< lbn
) {
670 osize
= blksize(fs
, ip
, nb
);
671 if (osize
< fs
->fs_bsize
&& osize
> 0) {
672 mutex_enter(&ump
->um_lock
);
673 error
= ffs_realloccg(ip
, nb
,
674 ffs_blkpref_ufs2(ip
, lastlbn
, nb
, flags
,
676 osize
, (int)fs
->fs_bsize
, cred
, bpp
, &newb
);
679 ip
->i_size
= lblktosize(fs
, nb
+ 1);
680 ip
->i_ffs2_size
= ip
->i_size
;
681 uvm_vnp_setsize(vp
, ip
->i_size
);
682 ip
->i_ffs2_db
[nb
] = ufs_rw64(newb
, needswap
);
683 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
694 * The first NDADDR blocks are direct blocks
698 nb
= ufs_rw64(ip
->i_ffs2_db
[lbn
], needswap
);
699 if (nb
!= 0 && ip
->i_size
>= lblktosize(fs
, lbn
+ 1)) {
702 * The block is an already-allocated direct block
703 * and the file already extends past this block,
704 * thus this must be a whole block.
705 * Just read the block (if requested).
709 error
= bread(vp
, lbn
, fs
->fs_bsize
, NOCRED
,
721 * Consider need to reallocate a fragment.
724 osize
= fragroundup(fs
, blkoff(fs
, ip
->i_size
));
725 nsize
= fragroundup(fs
, size
);
726 if (nsize
<= osize
) {
729 * The existing block is already
730 * at least as big as we want.
731 * Just read the block (if requested).
735 error
= bread(vp
, lbn
, osize
, NOCRED
,
746 * The existing block is smaller than we want,
749 mutex_enter(&ump
->um_lock
);
750 error
= ffs_realloccg(ip
, lbn
,
751 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
753 osize
, nsize
, cred
, bpp
, &newb
);
760 * the block was not previously allocated,
761 * allocate a new block or fragment.
764 if (ip
->i_size
< lblktosize(fs
, lbn
+ 1))
765 nsize
= fragroundup(fs
, size
);
767 nsize
= fs
->fs_bsize
;
768 mutex_enter(&ump
->um_lock
);
769 error
= ffs_alloc(ip
, lbn
,
770 ffs_blkpref_ufs2(ip
, lbn
, (int)lbn
, flags
,
772 nsize
, flags
, cred
, &newb
);
776 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, newb
),
777 nsize
, (flags
& B_CLRBUF
) != 0, bpp
);
782 ip
->i_ffs2_db
[lbn
] = ufs_rw64(newb
, needswap
);
783 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
788 * Determine the number of levels of indirection.
792 if ((error
= ufs_getlbns(vp
, lbn
, indirs
, &num
)) != 0)
796 * Fetch the first indirect block allocating if necessary.
800 nb
= ufs_rw64(ip
->i_ffs2_ib
[indirs
[0].in_off
], needswap
);
802 allocblk
= allociblk
;
804 mutex_enter(&ump
->um_lock
);
805 pref
= ffs_blkpref_ufs2(ip
, lbn
, 0, flags
| B_METAONLY
, NULL
);
806 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
807 flags
| B_METAONLY
, cred
, &newb
);
812 error
= ffs_getblk(vp
, indirs
[1].in_lbn
, fsbtodb(fs
, nb
),
813 fs
->fs_bsize
, true, &bp
);
817 * Write synchronously so that indirect blocks
818 * never point at garbage.
820 if ((error
= bwrite(bp
)) != 0)
823 allocib
= &ip
->i_ffs2_ib
[indirs
[0].in_off
];
824 *allocib
= ufs_rw64(nb
, needswap
);
825 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
829 * Fetch through the indirect blocks, allocating as necessary.
834 indirs
[i
].in_lbn
, (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
839 bap
= (int64_t *)bp
->b_data
;
840 nb
= ufs_rw64(bap
[indirs
[i
].in_off
], needswap
);
848 if (fscow_run(bp
, true) != 0) {
852 mutex_enter(&ump
->um_lock
);
853 /* Try to keep snapshot indirect blocks contiguous. */
854 if (i
== num
&& (ip
->i_flags
& SF_SNAPSHOT
) != 0)
855 pref
= ffs_blkpref_ufs2(ip
, lbn
, indirs
[i
-1].in_off
,
856 flags
| B_METAONLY
, &bap
[0]);
858 pref
= ffs_blkpref_ufs2(ip
, lbn
, 0, flags
| B_METAONLY
,
860 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
,
861 flags
| B_METAONLY
, cred
, &newb
);
868 error
= ffs_getblk(vp
, indirs
[i
].in_lbn
, fsbtodb(fs
, nb
),
869 fs
->fs_bsize
, true, &nbp
);
875 * Write synchronously so that indirect blocks
876 * never point at garbage.
878 if ((error
= bwrite(nbp
)) != 0) {
884 bap
[indirs
[i
- 1].in_off
] = ufs_rw64(nb
, needswap
);
887 * If required, write synchronously, otherwise use
891 if (flags
& B_SYNC
) {
898 if (flags
& B_METAONLY
) {
899 KASSERT(bpp
!= NULL
);
905 * Get the data block, allocating if necessary.
909 if (fscow_run(bp
, true) != 0) {
913 mutex_enter(&ump
->um_lock
);
914 pref
= ffs_blkpref_ufs2(ip
, lbn
, indirs
[num
].in_off
, flags
,
916 error
= ffs_alloc(ip
, lbn
, pref
, (int)fs
->fs_bsize
, flags
, cred
,
925 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
926 fs
->fs_bsize
, (flags
& B_CLRBUF
) != 0, bpp
);
932 bap
[indirs
[num
].in_off
] = ufs_rw64(nb
, needswap
);
933 if (allocib
== NULL
&& unwindidx
< 0) {
938 * If required, write synchronously, otherwise use
942 if (flags
& B_SYNC
) {
951 if (flags
& B_CLRBUF
) {
952 error
= bread(vp
, lbn
, (int)fs
->fs_bsize
,
953 NOCRED
, B_MODIFY
, &nbp
);
959 error
= ffs_getblk(vp
, lbn
, fsbtodb(fs
, nb
),
960 fs
->fs_bsize
, true, &nbp
);
970 * If we have failed part way through block allocation, we
971 * have to deallocate any indirect blocks that we have allocated.
974 if (unwindidx
>= 0) {
977 * First write out any buffers we've created to resolve their
978 * softdeps. This must be done in reverse order of creation
979 * so that we resolve the dependencies in one pass.
980 * Write the cylinder group buffers for these buffers too.
983 for (i
= num
; i
>= unwindidx
; i
--) {
987 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
988 fs
->fs_bsize
, false, &bp
) != 0)
990 if (bp
->b_oflags
& BO_DELWRI
) {
991 nb
= fsbtodb(fs
, cgtod(fs
, dtog(fs
,
992 dbtofsb(fs
, bp
->b_blkno
))));
994 if (ffs_getblk(ip
->i_devvp
, nb
, FFS_NOBLK
,
995 fs
->fs_cgsize
, false, &bp
) != 0)
997 if (bp
->b_oflags
& BO_DELWRI
) {
1000 brelse(bp
, BC_INVAL
);
1003 brelse(bp
, BC_INVAL
);
1008 * Now that any dependencies that we created have been
1009 * resolved, we can undo the partial allocation.
1012 if (unwindidx
== 0) {
1014 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;
1018 r
= bread(vp
, indirs
[unwindidx
].in_lbn
,
1019 (int)fs
->fs_bsize
, NOCRED
, 0, &bp
);
1021 panic("Could not unwind indirect block, error %d", r
);
1024 bap
= (int64_t *)bp
->b_data
;
1025 bap
[indirs
[unwindidx
].in_off
] = 0;
1029 for (i
= unwindidx
+ 1; i
<= num
; i
++) {
1030 if (ffs_getblk(vp
, indirs
[i
].in_lbn
, FFS_NOBLK
,
1031 fs
->fs_bsize
, false, &bp
) == 0)
1032 brelse(bp
, BC_INVAL
);
1035 for (deallocated
= 0, blkp
= allociblk
; blkp
< allocblk
; blkp
++) {
1036 ffs_blkfree(fs
, ip
->i_devvp
, *blkp
, fs
->fs_bsize
, ip
->i_number
);
1037 deallocated
+= fs
->fs_bsize
;
1040 #if defined(QUOTA) || defined(QUOTA2)
1042 * Restore user's disk quota because allocation failed.
1044 (void)chkdq(ip
, -btodb(deallocated
), cred
, FORCE
);
1046 ip
->i_ffs2_blocks
-= btodb(deallocated
);
1047 ip
->i_flag
|= IN_CHANGE
| IN_UPDATE
;