ffs_balloc.c (98658) | ffs_balloc.c (100344) |
---|---|
1/* 2 * Copyright (c) 2002 Networks Associates Technology, Inc. 3 * All rights reserved. 4 * 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 --- 29 unchanged lines hidden (view full) --- 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 * SUCH DAMAGE. 44 * 45 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95 | 1/* 2 * Copyright (c) 2002 Networks Associates Technology, Inc. 3 * All rights reserved. 4 * 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 --- 29 unchanged lines hidden (view full) --- 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 * SUCH DAMAGE. 44 * 45 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95 |
46 * $FreeBSD: head/sys/ufs/ffs/ffs_balloc.c 98658 2002-06-23 06:12:22Z dillon $ | 46 * $FreeBSD: head/sys/ufs/ffs/ffs_balloc.c 100344 2002-07-19 07:29:39Z mckusick $ |
47 */ 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/bio.h> 52#include <sys/buf.h> 53#include <sys/lock.h> 54#include <sys/mount.h> --- 13 unchanged lines hidden (view full) --- 68 * This is the allocation strategy for UFS1. Below is 69 * the allocation strategy for UFS2. 70 */ 71int 72ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, 73 struct ucred *cred, int flags, struct buf **bpp) 74{ 75 struct inode *ip; | 47 */ 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/bio.h> 52#include <sys/buf.h> 53#include <sys/lock.h> 54#include <sys/mount.h> --- 13 unchanged lines hidden (view full) --- 68 * This is the allocation strategy for UFS1. Below is 69 * the allocation strategy for UFS2. 70 */ 71int 72ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, 73 struct ucred *cred, int flags, struct buf **bpp) 74{ 75 struct inode *ip; |
76 struct ufs1_dinode *dp; |
|
76 ufs_lbn_t lbn, lastlbn; 77 struct fs *fs; 78 ufs1_daddr_t nb; 79 struct buf *bp, *nbp; 80 struct indir indirs[NIADDR + 2]; 81 int deallocated, osize, nsize, num, i, error; 82 ufs2_daddr_t newb; 83 ufs1_daddr_t *bap, pref; 84 ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; 85 int unwindidx = -1; 86 struct thread *td = curthread; /* XXX */ 87 88 ip = VTOI(vp); | 77 ufs_lbn_t lbn, lastlbn; 78 struct fs *fs; 79 ufs1_daddr_t nb; 80 struct buf *bp, *nbp; 81 struct indir indirs[NIADDR + 2]; 82 int deallocated, osize, nsize, num, i, error; 83 ufs2_daddr_t newb; 84 ufs1_daddr_t *bap, pref; 85 ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; 86 int unwindidx = -1; 87 struct thread *td = curthread; /* XXX */ 88 89 ip = VTOI(vp); |
90 dp = ip->i_din1; |
|
89 fs = ip->i_fs; 90 lbn = lblkno(fs, startoffset); 91 size = blkoff(fs, startoffset) + size; 92 if (size > fs->fs_bsize) 93 panic("ffs_balloc_ufs1: blk too big"); 94 *bpp = NULL; | 91 fs = ip->i_fs; 92 lbn = lblkno(fs, startoffset); 93 size = blkoff(fs, startoffset) + size; 94 if (size > fs->fs_bsize) 95 panic("ffs_balloc_ufs1: blk too big"); 96 *bpp = NULL; |
97 if (flags & IO_EXT) 98 return (EOPNOTSUPP); |
|
95 if (lbn < 0) 96 return (EFBIG); 97 98 /* 99 * If the next write will extend the file into a new block, 100 * and the file is currently composed of a fragment 101 * this fragment has to be extended to be a full block. 102 */ 103 lastlbn = lblkno(fs, ip->i_size); 104 if (lastlbn < NDADDR && lastlbn < lbn) { 105 nb = lastlbn; 106 osize = blksize(fs, ip, nb); 107 if (osize < fs->fs_bsize && osize > 0) { | 99 if (lbn < 0) 100 return (EFBIG); 101 102 /* 103 * If the next write will extend the file into a new block, 104 * and the file is currently composed of a fragment 105 * this fragment has to be extended to be a full block. 106 */ 107 lastlbn = lblkno(fs, ip->i_size); 108 if (lastlbn < NDADDR && lastlbn < lbn) { 109 nb = lastlbn; 110 osize = blksize(fs, ip, nb); 111 if (osize < fs->fs_bsize && osize > 0) { |
108 error = ffs_realloccg(ip, nb, 109 ffs_blkpref_ufs1(ip, lastlbn, (int)nb, 110 &ip->i_din1->di_db[0]), 111 osize, (int)fs->fs_bsize, cred, &bp); | 112 error = ffs_realloccg(ip, nb, dp->di_db[nb], 113 ffs_blkpref_ufs1(ip, lastlbn, (int)nb, 114 &dp->di_db[0]), osize, (int)fs->fs_bsize, cred, &bp); |
112 if (error) 113 return (error); 114 if (DOINGSOFTDEP(vp)) 115 softdep_setup_allocdirect(ip, nb, | 115 if (error) 116 return (error); 117 if (DOINGSOFTDEP(vp)) 118 softdep_setup_allocdirect(ip, nb, |
116 dbtofsb(fs, bp->b_blkno), 117 ip->i_din1->di_db[nb], | 119 dbtofsb(fs, bp->b_blkno), dp->di_db[nb], |
118 fs->fs_bsize, osize, bp); 119 ip->i_size = smalllblktosize(fs, nb + 1); | 120 fs->fs_bsize, osize, bp); 121 ip->i_size = smalllblktosize(fs, nb + 1); |
120 ip->i_din1->di_size = ip->i_size; 121 ip->i_din1->di_db[nb] = dbtofsb(fs, bp->b_blkno); | 122 dp->di_size = ip->i_size; 123 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno); |
122 ip->i_flag |= IN_CHANGE | IN_UPDATE; | 124 ip->i_flag |= IN_CHANGE | IN_UPDATE; |
123 if (flags & BA_SYNC) | 125 if (flags & IO_SYNC) |
124 bwrite(bp); 125 else 126 bawrite(bp); 127 } 128 } 129 /* 130 * The first NDADDR blocks are direct blocks 131 */ 132 if (lbn < NDADDR) { 133 if (flags & BA_METAONLY) 134 panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); | 126 bwrite(bp); 127 else 128 bawrite(bp); 129 } 130 } 131 /* 132 * The first NDADDR blocks are direct blocks 133 */ 134 if (lbn < NDADDR) { 135 if (flags & BA_METAONLY) 136 panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); |
135 nb = ip->i_din1->di_db[lbn]; | 137 nb = dp->di_db[lbn]; |
136 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { 137 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); 138 if (error) { 139 brelse(bp); 140 return (error); 141 } 142 bp->b_blkno = fsbtodb(fs, nb); 143 *bpp = bp; --- 8 unchanged lines hidden (view full) --- 152 if (nsize <= osize) { 153 error = bread(vp, lbn, osize, NOCRED, &bp); 154 if (error) { 155 brelse(bp); 156 return (error); 157 } 158 bp->b_blkno = fsbtodb(fs, nb); 159 } else { | 138 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { 139 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); 140 if (error) { 141 brelse(bp); 142 return (error); 143 } 144 bp->b_blkno = fsbtodb(fs, nb); 145 *bpp = bp; --- 8 unchanged lines hidden (view full) --- 154 if (nsize <= osize) { 155 error = bread(vp, lbn, osize, NOCRED, &bp); 156 if (error) { 157 brelse(bp); 158 return (error); 159 } 160 bp->b_blkno = fsbtodb(fs, nb); 161 } else { |
160 error = ffs_realloccg(ip, lbn, | 162 error = ffs_realloccg(ip, lbn, dp->di_db[lbn], |
161 ffs_blkpref_ufs1(ip, lbn, (int)lbn, | 163 ffs_blkpref_ufs1(ip, lbn, (int)lbn, |
162 &ip->i_din1->di_db[0]), 163 osize, nsize, cred, &bp); | 164 &dp->di_db[0]), osize, nsize, cred, &bp); |
164 if (error) 165 return (error); 166 if (DOINGSOFTDEP(vp)) 167 softdep_setup_allocdirect(ip, lbn, 168 dbtofsb(fs, bp->b_blkno), nb, 169 nsize, osize, bp); 170 } 171 } else { 172 if (ip->i_size < smalllblktosize(fs, lbn + 1)) 173 nsize = fragroundup(fs, size); 174 else 175 nsize = fs->fs_bsize; 176 error = ffs_alloc(ip, lbn, | 165 if (error) 166 return (error); 167 if (DOINGSOFTDEP(vp)) 168 softdep_setup_allocdirect(ip, lbn, 169 dbtofsb(fs, bp->b_blkno), nb, 170 nsize, osize, bp); 171 } 172 } else { 173 if (ip->i_size < smalllblktosize(fs, lbn + 1)) 174 nsize = fragroundup(fs, size); 175 else 176 nsize = fs->fs_bsize; 177 error = ffs_alloc(ip, lbn, |
177 ffs_blkpref_ufs1(ip, lbn, (int)lbn, 178 &ip->i_din1->di_db[0]), | 178 ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]), |
179 nsize, cred, &newb); 180 if (error) 181 return (error); 182 bp = getblk(vp, lbn, nsize, 0, 0); 183 bp->b_blkno = fsbtodb(fs, newb); 184 if (flags & BA_CLRBUF) 185 vfs_bio_clrbuf(bp); 186 if (DOINGSOFTDEP(vp)) 187 softdep_setup_allocdirect(ip, lbn, newb, 0, 188 nsize, 0, bp); 189 } | 179 nsize, cred, &newb); 180 if (error) 181 return (error); 182 bp = getblk(vp, lbn, nsize, 0, 0); 183 bp->b_blkno = fsbtodb(fs, newb); 184 if (flags & BA_CLRBUF) 185 vfs_bio_clrbuf(bp); 186 if (DOINGSOFTDEP(vp)) 187 softdep_setup_allocdirect(ip, lbn, newb, 0, 188 nsize, 0, bp); 189 } |
190 ip->i_din1->di_db[lbn] = dbtofsb(fs, bp->b_blkno); | 190 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno); |
191 ip->i_flag |= IN_CHANGE | IN_UPDATE; 192 *bpp = bp; 193 return (0); 194 } 195 /* 196 * Determine the number of levels of indirection. 197 */ 198 pref = 0; 199 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 200 return(error); 201#ifdef DIAGNOSTIC 202 if (num < 1) 203 panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block"); 204#endif 205 /* 206 * Fetch the first indirect block allocating if necessary. 207 */ 208 --num; | 191 ip->i_flag |= IN_CHANGE | IN_UPDATE; 192 *bpp = bp; 193 return (0); 194 } 195 /* 196 * Determine the number of levels of indirection. 197 */ 198 pref = 0; 199 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 200 return(error); 201#ifdef DIAGNOSTIC 202 if (num < 1) 203 panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block"); 204#endif 205 /* 206 * Fetch the first indirect block allocating if necessary. 207 */ 208 --num; |
209 nb = ip->i_din1->di_ib[indirs[0].in_off]; | 209 nb = dp->di_ib[indirs[0].in_off]; |
210 allocib = NULL; 211 allocblk = allociblk; 212 if (nb == 0) { 213 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0); 214 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, 215 cred, &newb)) != 0) 216 return (error); 217 nb = newb; --- 10 unchanged lines hidden (view full) --- 228 * Write synchronously so that indirect blocks 229 * never point at garbage. 230 */ 231 if (DOINGASYNC(vp)) 232 bdwrite(bp); 233 else if ((error = bwrite(bp)) != 0) 234 goto fail; 235 } | 210 allocib = NULL; 211 allocblk = allociblk; 212 if (nb == 0) { 213 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0); 214 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, 215 cred, &newb)) != 0) 216 return (error); 217 nb = newb; --- 10 unchanged lines hidden (view full) --- 228 * Write synchronously so that indirect blocks 229 * never point at garbage. 230 */ 231 if (DOINGASYNC(vp)) 232 bdwrite(bp); 233 else if ((error = bwrite(bp)) != 0) 234 goto fail; 235 } |
236 allocib = &ip->i_din1->di_ib[indirs[0].in_off]; | 236 allocib = &dp->di_ib[indirs[0].in_off]; |
237 *allocib = nb; 238 ip->i_flag |= IN_CHANGE | IN_UPDATE; 239 } 240 /* 241 * Fetch through the indirect blocks, allocating as necessary. 242 */ 243 for (i = 1;;) { 244 error = bread(vp, --- 39 unchanged lines hidden (view full) --- 284 } 285 bap[indirs[i - 1].in_off] = nb; 286 if (allocib == NULL && unwindidx < 0) 287 unwindidx = i - 1; 288 /* 289 * If required, write synchronously, otherwise use 290 * delayed write. 291 */ | 237 *allocib = nb; 238 ip->i_flag |= IN_CHANGE | IN_UPDATE; 239 } 240 /* 241 * Fetch through the indirect blocks, allocating as necessary. 242 */ 243 for (i = 1;;) { 244 error = bread(vp, --- 39 unchanged lines hidden (view full) --- 284 } 285 bap[indirs[i - 1].in_off] = nb; 286 if (allocib == NULL && unwindidx < 0) 287 unwindidx = i - 1; 288 /* 289 * If required, write synchronously, otherwise use 290 * delayed write. 291 */ |
292 if (flags & BA_SYNC) { | 292 if (flags & IO_SYNC) { |
293 bwrite(bp); 294 } else { 295 if (bp->b_bufsize == fs->fs_bsize) 296 bp->b_flags |= B_CLUSTEROK; 297 bdwrite(bp); 298 } 299 } 300 /* --- 23 unchanged lines hidden (view full) --- 324 if (DOINGSOFTDEP(vp)) 325 softdep_setup_allocindir_page(ip, lbn, bp, 326 indirs[i].in_off, nb, 0, nbp); 327 bap[indirs[i].in_off] = nb; 328 /* 329 * If required, write synchronously, otherwise use 330 * delayed write. 331 */ | 293 bwrite(bp); 294 } else { 295 if (bp->b_bufsize == fs->fs_bsize) 296 bp->b_flags |= B_CLUSTEROK; 297 bdwrite(bp); 298 } 299 } 300 /* --- 23 unchanged lines hidden (view full) --- 324 if (DOINGSOFTDEP(vp)) 325 softdep_setup_allocindir_page(ip, lbn, bp, 326 indirs[i].in_off, nb, 0, nbp); 327 bap[indirs[i].in_off] = nb; 328 /* 329 * If required, write synchronously, otherwise use 330 * delayed write. 331 */ |
332 if (flags & BA_SYNC) { | 332 if (flags & IO_SYNC) { |
333 bwrite(bp); 334 } else { 335 if (bp->b_bufsize == fs->fs_bsize) 336 bp->b_flags |= B_CLUSTEROK; 337 bdwrite(bp); 338 } 339 *bpp = nbp; 340 return (0); --- 36 unchanged lines hidden (view full) --- 377 r = bread(vp, indirs[unwindidx].in_lbn, 378 (int)fs->fs_bsize, NOCRED, &bp); 379 if (r) { 380 panic("Could not unwind indirect block, error %d", r); 381 brelse(bp); 382 } else { 383 bap = (ufs1_daddr_t *)bp->b_data; 384 bap[indirs[unwindidx].in_off] = 0; | 333 bwrite(bp); 334 } else { 335 if (bp->b_bufsize == fs->fs_bsize) 336 bp->b_flags |= B_CLUSTEROK; 337 bdwrite(bp); 338 } 339 *bpp = nbp; 340 return (0); --- 36 unchanged lines hidden (view full) --- 377 r = bread(vp, indirs[unwindidx].in_lbn, 378 (int)fs->fs_bsize, NOCRED, &bp); 379 if (r) { 380 panic("Could not unwind indirect block, error %d", r); 381 brelse(bp); 382 } else { 383 bap = (ufs1_daddr_t *)bp->b_data; 384 bap[indirs[unwindidx].in_off] = 0; |
385 if (flags & BA_SYNC) { | 385 if (flags & IO_SYNC) { |
386 bwrite(bp); 387 } else { 388 if (bp->b_bufsize == fs->fs_bsize) 389 bp->b_flags |= B_CLUSTEROK; 390 bdwrite(bp); 391 } 392 } 393 } 394 if (deallocated) { 395#ifdef QUOTA 396 /* 397 * Restore user's disk quota because allocation failed. 398 */ 399 (void) chkdq(ip, -btodb(deallocated), cred, FORCE); 400#endif | 386 bwrite(bp); 387 } else { 388 if (bp->b_bufsize == fs->fs_bsize) 389 bp->b_flags |= B_CLUSTEROK; 390 bdwrite(bp); 391 } 392 } 393 } 394 if (deallocated) { 395#ifdef QUOTA 396 /* 397 * Restore user's disk quota because allocation failed. 398 */ 399 (void) chkdq(ip, -btodb(deallocated), cred, FORCE); 400#endif |
401 ip->i_din1->di_blocks -= btodb(deallocated); | 401 dp->di_blocks -= btodb(deallocated); |
402 ip->i_flag |= IN_CHANGE | IN_UPDATE; 403 } 404 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td); 405 return (error); 406} 407 408/* 409 * Balloc defines the structure of file system storage 410 * by allocating the physical blocks on a device given 411 * the inode and the logical block number in a file. 412 * This is the allocation strategy for UFS2. Above is 413 * the allocation strategy for UFS1. 414 */ 415int 416ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, 417 struct ucred *cred, int flags, struct buf **bpp) 418{ 419 struct inode *ip; | 402 ip->i_flag |= IN_CHANGE | IN_UPDATE; 403 } 404 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td); 405 return (error); 406} 407 408/* 409 * Balloc defines the structure of file system storage 410 * by allocating the physical blocks on a device given 411 * the inode and the logical block number in a file. 412 * This is the allocation strategy for UFS2. Above is 413 * the allocation strategy for UFS1. 414 */ 415int 416ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, 417 struct ucred *cred, int flags, struct buf **bpp) 418{ 419 struct inode *ip; |
420 struct ufs2_dinode *dp; |
|
420 ufs_lbn_t lbn, lastlbn; 421 struct fs *fs; 422 struct buf *bp, *nbp; 423 struct indir indirs[NIADDR + 2]; 424 ufs2_daddr_t nb, newb, *bap, pref; 425 ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; 426 int deallocated, osize, nsize, num, i, error; 427 int unwindidx = -1; 428 struct thread *td = curthread; /* XXX */ 429 430 ip = VTOI(vp); | 421 ufs_lbn_t lbn, lastlbn; 422 struct fs *fs; 423 struct buf *bp, *nbp; 424 struct indir indirs[NIADDR + 2]; 425 ufs2_daddr_t nb, newb, *bap, pref; 426 ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; 427 int deallocated, osize, nsize, num, i, error; 428 int unwindidx = -1; 429 struct thread *td = curthread; /* XXX */ 430 431 ip = VTOI(vp); |
432 dp = ip->i_din2; |
|
431 fs = ip->i_fs; 432 lbn = lblkno(fs, startoffset); 433 size = blkoff(fs, startoffset) + size; 434 if (size > fs->fs_bsize) 435 panic("ffs_balloc_ufs2: blk too big"); 436 *bpp = NULL; 437 if (lbn < 0) 438 return (EFBIG); 439 440 /* | 433 fs = ip->i_fs; 434 lbn = lblkno(fs, startoffset); 435 size = blkoff(fs, startoffset) + size; 436 if (size > fs->fs_bsize) 437 panic("ffs_balloc_ufs2: blk too big"); 438 *bpp = NULL; 439 if (lbn < 0) 440 return (EFBIG); 441 442 /* |
443 * Check for allocating external data. 444 */ 445 if (flags & IO_EXT) { 446 if (lbn >= NXADDR) 447 return (EFBIG); 448 /* 449 * If the next write will extend the data into a new block, 450 * and the data is currently composed of a fragment 451 * this fragment has to be extended to be a full block. 452 */ 453 lastlbn = lblkno(fs, dp->di_extsize); 454 if (lastlbn < lbn) { 455 nb = lastlbn; 456 osize = sblksize(fs, dp->di_extsize, nb); 457 if (osize < fs->fs_bsize && osize > 0) { 458 error = ffs_realloccg(ip, -1 - nb, 459 dp->di_extb[nb], 460 ffs_blkpref_ufs2(ip, lastlbn, (int)nb, 461 &dp->di_extb[0]), osize, 462 (int)fs->fs_bsize, cred, &bp); 463 if (error) 464 return (error); 465 if (DOINGSOFTDEP(vp)) 466 softdep_setup_allocext(ip, nb, 467 dbtofsb(fs, bp->b_blkno), 468 dp->di_extb[nb], 469 fs->fs_bsize, osize, bp); 470 dp->di_extsize = smalllblktosize(fs, nb + 1); 471 dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno); 472 bp->b_xflags |= BX_ALTDATA; 473 ip->i_flag |= IN_CHANGE | IN_UPDATE; 474 if (flags & IO_SYNC) 475 bwrite(bp); 476 else 477 bawrite(bp); 478 } 479 } 480 /* 481 * All blocks are direct blocks 482 */ 483 if (flags & BA_METAONLY) 484 panic("ffs_balloc_ufs2: BA_METAONLY for ext block"); 485 nb = dp->di_extb[lbn]; 486 if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) { 487 error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp); 488 if (error) { 489 brelse(bp); 490 return (error); 491 } 492 bp->b_blkno = fsbtodb(fs, nb); 493 bp->b_xflags |= BX_ALTDATA; 494 *bpp = bp; 495 return (0); 496 } 497 if (nb != 0) { 498 /* 499 * Consider need to reallocate a fragment. 500 */ 501 osize = fragroundup(fs, blkoff(fs, dp->di_extsize)); 502 nsize = fragroundup(fs, size); 503 if (nsize <= osize) { 504 error = bread(vp, -1 - lbn, osize, NOCRED, &bp); 505 if (error) { 506 brelse(bp); 507 return (error); 508 } 509 bp->b_blkno = fsbtodb(fs, nb); 510 bp->b_xflags |= BX_ALTDATA; 511 } else { 512 error = ffs_realloccg(ip, -1 - lbn, 513 dp->di_extb[lbn], 514 ffs_blkpref_ufs2(ip, lbn, (int)lbn, 515 &dp->di_extb[0]), osize, nsize, cred, &bp); 516 if (error) 517 return (error); 518 bp->b_xflags |= BX_ALTDATA; 519 if (DOINGSOFTDEP(vp)) 520 softdep_setup_allocext(ip, lbn, 521 dbtofsb(fs, bp->b_blkno), nb, 522 nsize, osize, bp); 523 } 524 } else { 525 if (dp->di_extsize < smalllblktosize(fs, lbn + 1)) 526 nsize = fragroundup(fs, size); 527 else 528 nsize = fs->fs_bsize; 529 error = ffs_alloc(ip, lbn, 530 ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]), 531 nsize, cred, &newb); 532 if (error) 533 return (error); 534 bp = getblk(vp, -1 - lbn, nsize, 0, 0); 535 bp->b_blkno = fsbtodb(fs, newb); 536 bp->b_xflags |= BX_ALTDATA; 537 if (flags & BA_CLRBUF) 538 vfs_bio_clrbuf(bp); 539 if (DOINGSOFTDEP(vp)) 540 softdep_setup_allocext(ip, lbn, newb, 0, 541 nsize, 0, bp); 542 } 543 dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno); 544 ip->i_flag |= IN_CHANGE | IN_UPDATE; 545 *bpp = bp; 546 return (0); 547 } 548 /* |
|
441 * If the next write will extend the file into a new block, 442 * and the file is currently composed of a fragment 443 * this fragment has to be extended to be a full block. 444 */ 445 lastlbn = lblkno(fs, ip->i_size); 446 if (lastlbn < NDADDR && lastlbn < lbn) { 447 nb = lastlbn; 448 osize = blksize(fs, ip, nb); 449 if (osize < fs->fs_bsize && osize > 0) { | 549 * If the next write will extend the file into a new block, 550 * and the file is currently composed of a fragment 551 * this fragment has to be extended to be a full block. 552 */ 553 lastlbn = lblkno(fs, ip->i_size); 554 if (lastlbn < NDADDR && lastlbn < lbn) { 555 nb = lastlbn; 556 osize = blksize(fs, ip, nb); 557 if (osize < fs->fs_bsize && osize > 0) { |
450 error = ffs_realloccg(ip, nb, | 558 error = ffs_realloccg(ip, nb, dp->di_db[nb], |
451 ffs_blkpref_ufs2(ip, lastlbn, (int)nb, | 559 ffs_blkpref_ufs2(ip, lastlbn, (int)nb, |
452 &ip->i_din2->di_db[0]), 453 osize, (int)fs->fs_bsize, cred, &bp); | 560 &dp->di_db[0]), osize, (int)fs->fs_bsize, 561 cred, &bp); |
454 if (error) 455 return (error); 456 if (DOINGSOFTDEP(vp)) 457 softdep_setup_allocdirect(ip, nb, 458 dbtofsb(fs, bp->b_blkno), | 562 if (error) 563 return (error); 564 if (DOINGSOFTDEP(vp)) 565 softdep_setup_allocdirect(ip, nb, 566 dbtofsb(fs, bp->b_blkno), |
459 ip->i_din2->di_db[nb], | 567 dp->di_db[nb], |
460 fs->fs_bsize, osize, bp); 461 ip->i_size = smalllblktosize(fs, nb + 1); | 568 fs->fs_bsize, osize, bp); 569 ip->i_size = smalllblktosize(fs, nb + 1); |
462 ip->i_din2->di_size = ip->i_size; 463 ip->i_din2->di_db[nb] = dbtofsb(fs, bp->b_blkno); | 570 dp->di_size = ip->i_size; 571 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno); |
464 ip->i_flag |= IN_CHANGE | IN_UPDATE; | 572 ip->i_flag |= IN_CHANGE | IN_UPDATE; |
465 if (flags & BA_SYNC) | 573 if (flags & IO_SYNC) |
466 bwrite(bp); 467 else 468 bawrite(bp); 469 } 470 } 471 /* 472 * The first NDADDR blocks are direct blocks 473 */ 474 if (lbn < NDADDR) { 475 if (flags & BA_METAONLY) 476 panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); | 574 bwrite(bp); 575 else 576 bawrite(bp); 577 } 578 } 579 /* 580 * The first NDADDR blocks are direct blocks 581 */ 582 if (lbn < NDADDR) { 583 if (flags & BA_METAONLY) 584 panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); |
477 nb = ip->i_din2->di_db[lbn]; | 585 nb = dp->di_db[lbn]; |
478 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { 479 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); 480 if (error) { 481 brelse(bp); 482 return (error); 483 } 484 bp->b_blkno = fsbtodb(fs, nb); 485 *bpp = bp; --- 8 unchanged lines hidden (view full) --- 494 if (nsize <= osize) { 495 error = bread(vp, lbn, osize, NOCRED, &bp); 496 if (error) { 497 brelse(bp); 498 return (error); 499 } 500 bp->b_blkno = fsbtodb(fs, nb); 501 } else { | 586 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { 587 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); 588 if (error) { 589 brelse(bp); 590 return (error); 591 } 592 bp->b_blkno = fsbtodb(fs, nb); 593 *bpp = bp; --- 8 unchanged lines hidden (view full) --- 602 if (nsize <= osize) { 603 error = bread(vp, lbn, osize, NOCRED, &bp); 604 if (error) { 605 brelse(bp); 606 return (error); 607 } 608 bp->b_blkno = fsbtodb(fs, nb); 609 } else { |
502 error = ffs_realloccg(ip, lbn, | 610 error = ffs_realloccg(ip, lbn, dp->di_db[lbn], |
503 ffs_blkpref_ufs2(ip, lbn, (int)lbn, | 611 ffs_blkpref_ufs2(ip, lbn, (int)lbn, |
504 &ip->i_din2->di_db[0]), 505 osize, nsize, cred, &bp); | 612 &dp->di_db[0]), osize, nsize, cred, &bp); |
506 if (error) 507 return (error); 508 if (DOINGSOFTDEP(vp)) 509 softdep_setup_allocdirect(ip, lbn, 510 dbtofsb(fs, bp->b_blkno), nb, 511 nsize, osize, bp); 512 } 513 } else { 514 if (ip->i_size < smalllblktosize(fs, lbn + 1)) 515 nsize = fragroundup(fs, size); 516 else 517 nsize = fs->fs_bsize; 518 error = ffs_alloc(ip, lbn, 519 ffs_blkpref_ufs2(ip, lbn, (int)lbn, | 613 if (error) 614 return (error); 615 if (DOINGSOFTDEP(vp)) 616 softdep_setup_allocdirect(ip, lbn, 617 dbtofsb(fs, bp->b_blkno), nb, 618 nsize, osize, bp); 619 } 620 } else { 621 if (ip->i_size < smalllblktosize(fs, lbn + 1)) 622 nsize = fragroundup(fs, size); 623 else 624 nsize = fs->fs_bsize; 625 error = ffs_alloc(ip, lbn, 626 ffs_blkpref_ufs2(ip, lbn, (int)lbn, |
520 &ip->i_din2->di_db[0]), 521 nsize, cred, &newb); | 627 &dp->di_db[0]), nsize, cred, &newb); |
522 if (error) 523 return (error); 524 bp = getblk(vp, lbn, nsize, 0, 0); 525 bp->b_blkno = fsbtodb(fs, newb); 526 if (flags & BA_CLRBUF) 527 vfs_bio_clrbuf(bp); 528 if (DOINGSOFTDEP(vp)) 529 softdep_setup_allocdirect(ip, lbn, newb, 0, 530 nsize, 0, bp); 531 } | 628 if (error) 629 return (error); 630 bp = getblk(vp, lbn, nsize, 0, 0); 631 bp->b_blkno = fsbtodb(fs, newb); 632 if (flags & BA_CLRBUF) 633 vfs_bio_clrbuf(bp); 634 if (DOINGSOFTDEP(vp)) 635 softdep_setup_allocdirect(ip, lbn, newb, 0, 636 nsize, 0, bp); 637 } |
532 ip->i_din2->di_db[lbn] = dbtofsb(fs, bp->b_blkno); | 638 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno); |
533 ip->i_flag |= IN_CHANGE | IN_UPDATE; 534 *bpp = bp; 535 return (0); 536 } 537 /* 538 * Determine the number of levels of indirection. 539 */ 540 pref = 0; 541 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 542 return(error); 543#ifdef DIAGNOSTIC 544 if (num < 1) 545 panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block"); 546#endif 547 /* 548 * Fetch the first indirect block allocating if necessary. 549 */ 550 --num; | 639 ip->i_flag |= IN_CHANGE | IN_UPDATE; 640 *bpp = bp; 641 return (0); 642 } 643 /* 644 * Determine the number of levels of indirection. 645 */ 646 pref = 0; 647 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 648 return(error); 649#ifdef DIAGNOSTIC 650 if (num < 1) 651 panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block"); 652#endif 653 /* 654 * Fetch the first indirect block allocating if necessary. 655 */ 656 --num; |
551 nb = ip->i_din2->di_ib[indirs[0].in_off]; | 657 nb = dp->di_ib[indirs[0].in_off]; |
552 allocib = NULL; 553 allocblk = allociblk; 554 if (nb == 0) { 555 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0); 556 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, 557 cred, &newb)) != 0) 558 return (error); 559 nb = newb; --- 10 unchanged lines hidden (view full) --- 570 * Write synchronously so that indirect blocks 571 * never point at garbage. 572 */ 573 if (DOINGASYNC(vp)) 574 bdwrite(bp); 575 else if ((error = bwrite(bp)) != 0) 576 goto fail; 577 } | 658 allocib = NULL; 659 allocblk = allociblk; 660 if (nb == 0) { 661 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0); 662 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, 663 cred, &newb)) != 0) 664 return (error); 665 nb = newb; --- 10 unchanged lines hidden (view full) --- 676 * Write synchronously so that indirect blocks 677 * never point at garbage. 678 */ 679 if (DOINGASYNC(vp)) 680 bdwrite(bp); 681 else if ((error = bwrite(bp)) != 0) 682 goto fail; 683 } |
578 allocib = &ip->i_din2->di_ib[indirs[0].in_off]; | 684 allocib = &dp->di_ib[indirs[0].in_off]; |
579 *allocib = nb; 580 ip->i_flag |= IN_CHANGE | IN_UPDATE; 581 } 582 /* 583 * Fetch through the indirect blocks, allocating as necessary. 584 */ 585 for (i = 1;;) { 586 error = bread(vp, --- 39 unchanged lines hidden (view full) --- 626 } 627 bap[indirs[i - 1].in_off] = nb; 628 if (allocib == NULL && unwindidx < 0) 629 unwindidx = i - 1; 630 /* 631 * If required, write synchronously, otherwise use 632 * delayed write. 633 */ | 685 *allocib = nb; 686 ip->i_flag |= IN_CHANGE | IN_UPDATE; 687 } 688 /* 689 * Fetch through the indirect blocks, allocating as necessary. 690 */ 691 for (i = 1;;) { 692 error = bread(vp, --- 39 unchanged lines hidden (view full) --- 732 } 733 bap[indirs[i - 1].in_off] = nb; 734 if (allocib == NULL && unwindidx < 0) 735 unwindidx = i - 1; 736 /* 737 * If required, write synchronously, otherwise use 738 * delayed write. 739 */ |
634 if (flags & BA_SYNC) { | 740 if (flags & IO_SYNC) { |
635 bwrite(bp); 636 } else { 637 if (bp->b_bufsize == fs->fs_bsize) 638 bp->b_flags |= B_CLUSTEROK; 639 bdwrite(bp); 640 } 641 } 642 /* --- 23 unchanged lines hidden (view full) --- 666 if (DOINGSOFTDEP(vp)) 667 softdep_setup_allocindir_page(ip, lbn, bp, 668 indirs[i].in_off, nb, 0, nbp); 669 bap[indirs[i].in_off] = nb; 670 /* 671 * If required, write synchronously, otherwise use 672 * delayed write. 673 */ | 741 bwrite(bp); 742 } else { 743 if (bp->b_bufsize == fs->fs_bsize) 744 bp->b_flags |= B_CLUSTEROK; 745 bdwrite(bp); 746 } 747 } 748 /* --- 23 unchanged lines hidden (view full) --- 772 if (DOINGSOFTDEP(vp)) 773 softdep_setup_allocindir_page(ip, lbn, bp, 774 indirs[i].in_off, nb, 0, nbp); 775 bap[indirs[i].in_off] = nb; 776 /* 777 * If required, write synchronously, otherwise use 778 * delayed write. 779 */ |
674 if (flags & BA_SYNC) { | 780 if (flags & IO_SYNC) { |
675 bwrite(bp); 676 } else { 677 if (bp->b_bufsize == fs->fs_bsize) 678 bp->b_flags |= B_CLUSTEROK; 679 bdwrite(bp); 680 } 681 *bpp = nbp; 682 return (0); --- 36 unchanged lines hidden (view full) --- 719 r = bread(vp, indirs[unwindidx].in_lbn, 720 (int)fs->fs_bsize, NOCRED, &bp); 721 if (r) { 722 panic("Could not unwind indirect block, error %d", r); 723 brelse(bp); 724 } else { 725 bap = (ufs2_daddr_t *)bp->b_data; 726 bap[indirs[unwindidx].in_off] = 0; | 781 bwrite(bp); 782 } else { 783 if (bp->b_bufsize == fs->fs_bsize) 784 bp->b_flags |= B_CLUSTEROK; 785 bdwrite(bp); 786 } 787 *bpp = nbp; 788 return (0); --- 36 unchanged lines hidden (view full) --- 825 r = bread(vp, indirs[unwindidx].in_lbn, 826 (int)fs->fs_bsize, NOCRED, &bp); 827 if (r) { 828 panic("Could not unwind indirect block, error %d", r); 829 brelse(bp); 830 } else { 831 bap = (ufs2_daddr_t *)bp->b_data; 832 bap[indirs[unwindidx].in_off] = 0; |
727 if (flags & BA_SYNC) { | 833 if (flags & IO_SYNC) { |
728 bwrite(bp); 729 } else { 730 if (bp->b_bufsize == fs->fs_bsize) 731 bp->b_flags |= B_CLUSTEROK; 732 bdwrite(bp); 733 } 734 } 735 } 736 if (deallocated) { 737#ifdef QUOTA 738 /* 739 * Restore user's disk quota because allocation failed. 740 */ 741 (void) chkdq(ip, -btodb(deallocated), cred, FORCE); 742#endif | 834 bwrite(bp); 835 } else { 836 if (bp->b_bufsize == fs->fs_bsize) 837 bp->b_flags |= B_CLUSTEROK; 838 bdwrite(bp); 839 } 840 } 841 } 842 if (deallocated) { 843#ifdef QUOTA 844 /* 845 * Restore user's disk quota because allocation failed. 846 */ 847 (void) chkdq(ip, -btodb(deallocated), cred, FORCE); 848#endif |
743 ip->i_din2->di_blocks -= btodb(deallocated); | 849 dp->di_blocks -= btodb(deallocated); |
744 ip->i_flag |= IN_CHANGE | IN_UPDATE; 745 } 746 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td); 747 return (error); 748} | 850 ip->i_flag |= IN_CHANGE | IN_UPDATE; 851 } 852 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td); 853 return (error); 854} |