1 /* $NetBSD: ffs_balloc.c,v 1.37 2004/12/15 07:11:51 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Networks Associates Technology, Inc. 5 * All rights reserved. 6 * 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 11 * research program 12 * 13 * Copyright (c) 1982, 1986, 1989, 1993 14 * The Regents of the University of California. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 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. 27 * 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 38 * SUCH DAMAGE. 39 * 40 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.37 2004/12/15 07:11:51 mycroft Exp $"); 45 46 #if defined(_KERNEL_OPT) 47 #include "opt_quota.h" 48 #endif 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/buf.h> 53 #include <sys/file.h> 54 #include <sys/mount.h> 55 #include <sys/vnode.h> 56 #include <sys/mount.h> 57 58 #include <ufs/ufs/quota.h> 59 #include <ufs/ufs/ufsmount.h> 60 #include <ufs/ufs/inode.h> 61 #include <ufs/ufs/ufs_extern.h> 62 #include <ufs/ufs/ufs_bswap.h> 63 64 #include <ufs/ffs/fs.h> 65 #include <ufs/ffs/ffs_extern.h> 66 67 #include <uvm/uvm.h> 68 69 static int ffs_balloc_ufs1(void *); 70 static int ffs_balloc_ufs2(void *); 71 72 /* 73 * Balloc defines the structure of file system storage 74 * by allocating the physical blocks on a device given 75 * the inode and the logical block number in a file. 76 */ 77 78 int 79 ffs_balloc(v) 80 void *v; 81 { 82 struct vop_balloc_args *ap = v; 83 84 if (VTOI(ap->a_vp)->i_fs->fs_magic == FS_UFS2_MAGIC) 85 return ffs_balloc_ufs2(v); 86 else 87 return ffs_balloc_ufs1(v); 88 } 89 90 static int 91 ffs_balloc_ufs1(v) 92 void *v; 93 { 94 struct vop_balloc_args /* { 95 struct vnode *a_vp; 96 off_t a_startoffset; 97 int a_size; 98 struct ucred *a_cred; 99 int a_flags; 100 struct buf **a_bpp; 101 } */ *ap = v; 102 daddr_t lbn, lastlbn; 103 int size; 104 struct ucred *cred; 105 int flags; 106 struct buf *bp, *nbp; 107 struct vnode *vp = ap->a_vp; 108 struct inode *ip = VTOI(vp); 109 struct fs *fs = ip->i_fs; 110 struct indir indirs[NIADDR + 2]; 111 daddr_t newb, pref, nb; 112 int32_t *bap; /* XXX ondisk32 */ 113 int deallocated, osize, nsize, num, i, error; 114 int32_t *blkp, *allocblk, allociblk[NIADDR + 1]; 115 int32_t *allocib; 116 int unwindidx = -1; 117 struct buf **bpp = ap->a_bpp; 118 #ifdef FFS_EI 119 const int needswap = UFS_FSNEEDSWAP(fs); 120 #endif 121 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist); 122 123 lbn = lblkno(fs, ap->a_startoffset); 124 size = blkoff(fs, ap->a_startoffset) + ap->a_size; 125 if (size > fs->fs_bsize) 126 panic("ffs_balloc: blk too big"); 127 if (bpp != NULL) { 128 *bpp = NULL; 129 } 130 UVMHIST_LOG(ubchist, "vp %p lbn 0x%x size 0x%x", vp, lbn, size,0); 131 132 KASSERT(size <= fs->fs_bsize); 133 if (lbn < 0) 134 return (EFBIG); 135 cred = ap->a_cred; 136 flags = ap->a_flags; 137 138 /* 139 * If the next write will extend the file into a new block, 140 * and the file is currently composed of a fragment 141 * this fragment has to be extended to be a full block. 142 */ 143 144 lastlbn = lblkno(fs, ip->i_size); 145 if (lastlbn < NDADDR && lastlbn < lbn) { 146 nb = lastlbn; 147 osize = blksize(fs, ip, nb); 148 if (osize < fs->fs_bsize && osize > 0) { 149 error = ffs_realloccg(ip, nb, 150 ffs_blkpref_ufs1(ip, lastlbn, nb, 151 &ip->i_ffs1_db[0]), 152 osize, (int)fs->fs_bsize, cred, bpp, &newb); 153 if (error) 154 return (error); 155 if (DOINGSOFTDEP(vp)) 156 softdep_setup_allocdirect(ip, nb, newb, 157 ufs_rw32(ip->i_ffs1_db[nb], needswap), 158 fs->fs_bsize, osize, bpp ? *bpp : NULL); 159 ip->i_size = lblktosize(fs, nb + 1); 160 ip->i_ffs1_size = ip->i_size; 161 uvm_vnp_setsize(vp, ip->i_ffs1_size); 162 ip->i_ffs1_db[nb] = ufs_rw32((u_int32_t)newb, needswap); 163 ip->i_flag |= IN_CHANGE | IN_UPDATE; 164 if (bpp) { 165 if (flags & B_SYNC) 166 bwrite(*bpp); 167 else 168 bawrite(*bpp); 169 } 170 } 171 } 172 173 /* 174 * The first NDADDR blocks are direct blocks 175 */ 176 177 if (lbn < NDADDR) { 178 nb = ufs_rw32(ip->i_ffs1_db[lbn], needswap); 179 if (nb != 0 && ip->i_size >= lblktosize(fs, lbn + 1)) { 180 181 /* 182 * The block is an already-allocated direct block 183 * and the file already extends past this block, 184 * thus this must be a whole block. 185 * Just read the block (if requested). 186 */ 187 188 if (bpp != NULL) { 189 error = bread(vp, lbn, fs->fs_bsize, NOCRED, 190 bpp); 191 if (error) { 192 brelse(*bpp); 193 return (error); 194 } 195 } 196 return (0); 197 } 198 if (nb != 0) { 199 200 /* 201 * Consider need to reallocate a fragment. 202 */ 203 204 osize = fragroundup(fs, blkoff(fs, ip->i_size)); 205 nsize = fragroundup(fs, size); 206 if (nsize <= osize) { 207 208 /* 209 * The existing block is already 210 * at least as big as we want. 211 * Just read the block (if requested). 212 */ 213 214 if (bpp != NULL) { 215 error = bread(vp, lbn, osize, NOCRED, 216 bpp); 217 if (error) { 218 brelse(*bpp); 219 return (error); 220 } 221 } 222 return 0; 223 } else { 224 225 /* 226 * The existing block is smaller than we want, 227 * grow it. 228 */ 229 230 error = ffs_realloccg(ip, lbn, 231 ffs_blkpref_ufs1(ip, lbn, (int)lbn, 232 &ip->i_ffs1_db[0]), osize, nsize, cred, 233 bpp, &newb); 234 if (error) 235 return (error); 236 if (DOINGSOFTDEP(vp)) 237 softdep_setup_allocdirect(ip, lbn, 238 newb, nb, nsize, osize, 239 bpp ? *bpp : NULL); 240 } 241 } else { 242 243 /* 244 * the block was not previously allocated, 245 * allocate a new block or fragment. 246 */ 247 248 if (ip->i_size < lblktosize(fs, lbn + 1)) 249 nsize = fragroundup(fs, size); 250 else 251 nsize = fs->fs_bsize; 252 error = ffs_alloc(ip, lbn, 253 ffs_blkpref_ufs1(ip, lbn, (int)lbn, 254 &ip->i_ffs1_db[0]), 255 nsize, cred, &newb); 256 if (error) 257 return (error); 258 if (bpp != NULL) { 259 bp = getblk(vp, lbn, nsize, 0, 0); 260 bp->b_blkno = fsbtodb(fs, newb); 261 if (flags & B_CLRBUF) 262 clrbuf(bp); 263 *bpp = bp; 264 } 265 if (DOINGSOFTDEP(vp)) { 266 softdep_setup_allocdirect(ip, lbn, newb, 0, 267 nsize, 0, bpp ? *bpp : NULL); 268 } 269 } 270 ip->i_ffs1_db[lbn] = ufs_rw32((u_int32_t)newb, needswap); 271 ip->i_flag |= IN_CHANGE | IN_UPDATE; 272 return (0); 273 } 274 275 /* 276 * Determine the number of levels of indirection. 277 */ 278 279 pref = 0; 280 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 281 return (error); 282 283 /* 284 * Fetch the first indirect block allocating if necessary. 285 */ 286 287 --num; 288 nb = ufs_rw32(ip->i_ffs1_ib[indirs[0].in_off], needswap); 289 allocib = NULL; 290 allocblk = allociblk; 291 if (nb == 0) { 292 pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0); 293 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 294 &newb); 295 if (error) 296 goto fail; 297 nb = newb; 298 *allocblk++ = nb; 299 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); 300 bp->b_blkno = fsbtodb(fs, nb); 301 clrbuf(bp); 302 if (DOINGSOFTDEP(vp)) { 303 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, 304 newb, 0, fs->fs_bsize, 0, bp); 305 bdwrite(bp); 306 } else { 307 308 /* 309 * Write synchronously so that indirect blocks 310 * never point at garbage. 311 */ 312 313 if ((error = bwrite(bp)) != 0) 314 goto fail; 315 } 316 unwindidx = 0; 317 allocib = &ip->i_ffs1_ib[indirs[0].in_off]; 318 *allocib = ufs_rw32(nb, needswap); 319 ip->i_flag |= IN_CHANGE | IN_UPDATE; 320 } 321 322 /* 323 * Fetch through the indirect blocks, allocating as necessary. 324 */ 325 326 for (i = 1;;) { 327 error = bread(vp, 328 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp); 329 if (error) { 330 brelse(bp); 331 goto fail; 332 } 333 bap = (int32_t *)bp->b_data; /* XXX ondisk32 */ 334 nb = ufs_rw32(bap[indirs[i].in_off], needswap); 335 if (i == num) 336 break; 337 i++; 338 if (nb != 0) { 339 brelse(bp); 340 continue; 341 } 342 if (pref == 0) 343 pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0); 344 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 345 &newb); 346 if (error) { 347 brelse(bp); 348 goto fail; 349 } 350 nb = newb; 351 *allocblk++ = nb; 352 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); 353 nbp->b_blkno = fsbtodb(fs, nb); 354 clrbuf(nbp); 355 if (DOINGSOFTDEP(vp)) { 356 softdep_setup_allocindir_meta(nbp, ip, bp, 357 indirs[i - 1].in_off, nb); 358 bdwrite(nbp); 359 } else { 360 361 /* 362 * Write synchronously so that indirect blocks 363 * never point at garbage. 364 */ 365 366 if ((error = bwrite(nbp)) != 0) { 367 brelse(bp); 368 goto fail; 369 } 370 } 371 if (unwindidx < 0) 372 unwindidx = i - 1; 373 bap[indirs[i - 1].in_off] = ufs_rw32(nb, needswap); 374 375 /* 376 * If required, write synchronously, otherwise use 377 * delayed write. 378 */ 379 380 if (flags & B_SYNC) { 381 bwrite(bp); 382 } else { 383 bdwrite(bp); 384 } 385 } 386 387 if (flags & B_METAONLY) { 388 *bpp = bp; 389 return (0); 390 } 391 392 /* 393 * Get the data block, allocating if necessary. 394 */ 395 396 if (nb == 0) { 397 pref = ffs_blkpref_ufs1(ip, lbn, indirs[num].in_off, &bap[0]); 398 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 399 &newb); 400 if (error) { 401 brelse(bp); 402 goto fail; 403 } 404 nb = newb; 405 *allocblk++ = nb; 406 if (bpp != NULL) { 407 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); 408 nbp->b_blkno = fsbtodb(fs, nb); 409 if (flags & B_CLRBUF) 410 clrbuf(nbp); 411 *bpp = nbp; 412 } 413 if (DOINGSOFTDEP(vp)) 414 softdep_setup_allocindir_page(ip, lbn, bp, 415 indirs[num].in_off, nb, 0, bpp ? *bpp : NULL); 416 bap[indirs[num].in_off] = ufs_rw32(nb, needswap); 417 if (allocib == NULL && unwindidx < 0) { 418 unwindidx = i - 1; 419 } 420 421 /* 422 * If required, write synchronously, otherwise use 423 * delayed write. 424 */ 425 426 if (flags & B_SYNC) { 427 bwrite(bp); 428 } else { 429 bdwrite(bp); 430 } 431 return (0); 432 } 433 brelse(bp); 434 if (bpp != NULL) { 435 if (flags & B_CLRBUF) { 436 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp); 437 if (error) { 438 brelse(nbp); 439 goto fail; 440 } 441 } else { 442 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); 443 nbp->b_blkno = fsbtodb(fs, nb); 444 clrbuf(nbp); 445 } 446 *bpp = nbp; 447 } 448 return (0); 449 450 fail: 451 /* 452 * If we have failed part way through block allocation, we 453 * have to deallocate any indirect blocks that we have allocated. 454 */ 455 456 if (unwindidx >= 0) { 457 458 /* 459 * First write out any buffers we've created to resolve their 460 * softdeps. This must be done in reverse order of creation 461 * so that we resolve the dependencies in one pass. 462 * Write the cylinder group buffers for these buffers too. 463 */ 464 465 for (i = num; i >= unwindidx; i--) { 466 if (i == 0) { 467 break; 468 } 469 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, 470 0); 471 if (bp->b_flags & B_DELWRI) { 472 nb = fsbtodb(fs, cgtod(fs, dtog(fs, 473 dbtofsb(fs, bp->b_blkno)))); 474 bwrite(bp); 475 bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize, 476 0, 0); 477 if (bp->b_flags & B_DELWRI) { 478 bwrite(bp); 479 } else { 480 bp->b_flags |= B_INVAL; 481 brelse(bp); 482 } 483 } else { 484 bp->b_flags |= B_INVAL; 485 brelse(bp); 486 } 487 } 488 if (DOINGSOFTDEP(vp) && unwindidx == 0) { 489 ip->i_flag |= IN_CHANGE | IN_UPDATE; 490 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT); 491 } 492 493 /* 494 * Now that any dependencies that we created have been 495 * resolved, we can undo the partial allocation. 496 */ 497 498 if (unwindidx == 0) { 499 *allocib = 0; 500 ip->i_flag |= IN_CHANGE | IN_UPDATE; 501 if (DOINGSOFTDEP(vp)) 502 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT); 503 } else { 504 int r; 505 506 r = bread(vp, indirs[unwindidx].in_lbn, 507 (int)fs->fs_bsize, NOCRED, &bp); 508 if (r) { 509 panic("Could not unwind indirect block, error %d", r); 510 brelse(bp); 511 } else { 512 bap = (int32_t *)bp->b_data; /* XXX ondisk32 */ 513 bap[indirs[unwindidx].in_off] = 0; 514 bwrite(bp); 515 } 516 } 517 for (i = unwindidx + 1; i <= num; i++) { 518 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, 519 0); 520 bp->b_flags |= B_INVAL; 521 brelse(bp); 522 } 523 } 524 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { 525 ffs_blkfree(fs, ip->i_devvp, *blkp, fs->fs_bsize, ip->i_number); 526 deallocated += fs->fs_bsize; 527 } 528 if (deallocated) { 529 #ifdef QUOTA 530 /* 531 * Restore user's disk quota because allocation failed. 532 */ 533 (void)chkdq(ip, -btodb(deallocated), cred, FORCE); 534 #endif 535 ip->i_ffs1_blocks -= btodb(deallocated); 536 ip->i_flag |= IN_CHANGE | IN_UPDATE; 537 } 538 return (error); 539 } 540 541 static int 542 ffs_balloc_ufs2(v) 543 void *v; 544 { 545 struct vop_balloc_args /* { 546 struct vnode *a_vp; 547 off_t a_startoffset; 548 int a_size; 549 struct ucred *a_cred; 550 int a_flags; 551 struct buf **a_bpp; 552 } */ *ap = v; 553 daddr_t lbn, lastlbn; 554 int size; 555 struct ucred *cred; 556 int flags; 557 struct buf *bp, *nbp; 558 struct vnode *vp = ap->a_vp; 559 struct inode *ip = VTOI(vp); 560 struct fs *fs = ip->i_fs; 561 struct indir indirs[NIADDR + 2]; 562 daddr_t newb, pref, nb; 563 int64_t *bap; 564 int deallocated, osize, nsize, num, i, error; 565 daddr_t *blkp, *allocblk, allociblk[NIADDR + 1]; 566 int64_t *allocib; 567 int unwindidx = -1; 568 struct buf **bpp = ap->a_bpp; 569 #ifdef FFS_EI 570 const int needswap = UFS_FSNEEDSWAP(fs); 571 #endif 572 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist); 573 574 lbn = lblkno(fs, ap->a_startoffset); 575 size = blkoff(fs, ap->a_startoffset) + ap->a_size; 576 if (size > fs->fs_bsize) 577 panic("ffs_balloc: blk too big"); 578 if (bpp != NULL) { 579 *bpp = NULL; 580 } 581 UVMHIST_LOG(ubchist, "vp %p lbn 0x%x size 0x%x", vp, lbn, size,0); 582 583 KASSERT(size <= fs->fs_bsize); 584 if (lbn < 0) 585 return (EFBIG); 586 cred = ap->a_cred; 587 flags = ap->a_flags; 588 589 #ifdef notyet 590 /* 591 * Check for allocating external data. 592 */ 593 if (flags & IO_EXT) { 594 if (lbn >= NXADDR) 595 return (EFBIG); 596 /* 597 * If the next write will extend the data into a new block, 598 * and the data is currently composed of a fragment 599 * this fragment has to be extended to be a full block. 600 */ 601 lastlbn = lblkno(fs, dp->di_extsize); 602 if (lastlbn < lbn) { 603 nb = lastlbn; 604 osize = sblksize(fs, dp->di_extsize, nb); 605 if (osize < fs->fs_bsize && osize > 0) { 606 error = ffs_realloccg(ip, -1 - nb, 607 dp->di_extb[nb], 608 ffs_blkpref_ufs2(ip, lastlbn, (int)nb, 609 &dp->di_extb[0]), osize, 610 (int)fs->fs_bsize, cred, &bp); 611 if (error) 612 return (error); 613 if (DOINGSOFTDEP(vp)) 614 softdep_setup_allocext(ip, nb, 615 dbtofsb(fs, bp->b_blkno), 616 dp->di_extb[nb], 617 fs->fs_bsize, osize, bp); 618 dp->di_extsize = smalllblktosize(fs, nb + 1); 619 dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno); 620 bp->b_xflags |= BX_ALTDATA; 621 ip->i_flag |= IN_CHANGE | IN_UPDATE; 622 if (flags & IO_SYNC) 623 bwrite(bp); 624 else 625 bawrite(bp); 626 } 627 } 628 /* 629 * All blocks are direct blocks 630 */ 631 if (flags & BA_METAONLY) 632 panic("ffs_balloc_ufs2: BA_METAONLY for ext block"); 633 nb = dp->di_extb[lbn]; 634 if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) { 635 error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp); 636 if (error) { 637 brelse(bp); 638 return (error); 639 } 640 bp->b_blkno = fsbtodb(fs, nb); 641 bp->b_xflags |= BX_ALTDATA; 642 *bpp = bp; 643 return (0); 644 } 645 if (nb != 0) { 646 /* 647 * Consider need to reallocate a fragment. 648 */ 649 osize = fragroundup(fs, blkoff(fs, dp->di_extsize)); 650 nsize = fragroundup(fs, size); 651 if (nsize <= osize) { 652 error = bread(vp, -1 - lbn, osize, NOCRED, &bp); 653 if (error) { 654 brelse(bp); 655 return (error); 656 } 657 bp->b_blkno = fsbtodb(fs, nb); 658 bp->b_xflags |= BX_ALTDATA; 659 } else { 660 error = ffs_realloccg(ip, -1 - lbn, 661 dp->di_extb[lbn], 662 ffs_blkpref_ufs2(ip, lbn, (int)lbn, 663 &dp->di_extb[0]), osize, nsize, cred, &bp); 664 if (error) 665 return (error); 666 bp->b_xflags |= BX_ALTDATA; 667 if (DOINGSOFTDEP(vp)) 668 softdep_setup_allocext(ip, lbn, 669 dbtofsb(fs, bp->b_blkno), nb, 670 nsize, osize, bp); 671 } 672 } else { 673 if (dp->di_extsize < smalllblktosize(fs, lbn + 1)) 674 nsize = fragroundup(fs, size); 675 else 676 nsize = fs->fs_bsize; 677 error = ffs_alloc(ip, lbn, 678 ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]), 679 nsize, cred, &newb); 680 if (error) 681 return (error); 682 bp = getblk(vp, -1 - lbn, nsize, 0, 0); 683 bp->b_blkno = fsbtodb(fs, newb); 684 bp->b_xflags |= BX_ALTDATA; 685 if (flags & BA_CLRBUF) 686 vfs_bio_clrbuf(bp); 687 if (DOINGSOFTDEP(vp)) 688 softdep_setup_allocext(ip, lbn, newb, 0, 689 nsize, 0, bp); 690 } 691 dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno); 692 ip->i_flag |= IN_CHANGE | IN_UPDATE; 693 *bpp = bp; 694 return (0); 695 } 696 #endif 697 /* 698 * If the next write will extend the file into a new block, 699 * and the file is currently composed of a fragment 700 * this fragment has to be extended to be a full block. 701 */ 702 703 lastlbn = lblkno(fs, ip->i_size); 704 if (lastlbn < NDADDR && lastlbn < lbn) { 705 nb = lastlbn; 706 osize = blksize(fs, ip, nb); 707 if (osize < fs->fs_bsize && osize > 0) { 708 error = ffs_realloccg(ip, nb, 709 ffs_blkpref_ufs2(ip, lastlbn, nb, 710 &ip->i_ffs2_db[0]), 711 osize, (int)fs->fs_bsize, cred, bpp, &newb); 712 if (error) 713 return (error); 714 if (DOINGSOFTDEP(vp)) 715 softdep_setup_allocdirect(ip, nb, newb, 716 ufs_rw64(ip->i_ffs2_db[nb], needswap), 717 fs->fs_bsize, osize, bpp ? *bpp : NULL); 718 ip->i_size = lblktosize(fs, nb + 1); 719 ip->i_ffs2_size = ip->i_size; 720 uvm_vnp_setsize(vp, ip->i_size); 721 ip->i_ffs2_db[nb] = ufs_rw64(newb, needswap); 722 ip->i_flag |= IN_CHANGE | IN_UPDATE; 723 if (bpp) { 724 if (flags & B_SYNC) 725 bwrite(*bpp); 726 else 727 bawrite(*bpp); 728 } 729 } 730 } 731 732 /* 733 * The first NDADDR blocks are direct blocks 734 */ 735 736 if (lbn < NDADDR) { 737 nb = ufs_rw64(ip->i_ffs2_db[lbn], needswap); 738 if (nb != 0 && ip->i_size >= lblktosize(fs, lbn + 1)) { 739 740 /* 741 * The block is an already-allocated direct block 742 * and the file already extends past this block, 743 * thus this must be a whole block. 744 * Just read the block (if requested). 745 */ 746 747 if (bpp != NULL) { 748 error = bread(vp, lbn, fs->fs_bsize, NOCRED, 749 bpp); 750 if (error) { 751 brelse(*bpp); 752 return (error); 753 } 754 } 755 return (0); 756 } 757 if (nb != 0) { 758 759 /* 760 * Consider need to reallocate a fragment. 761 */ 762 763 osize = fragroundup(fs, blkoff(fs, ip->i_size)); 764 nsize = fragroundup(fs, size); 765 if (nsize <= osize) { 766 767 /* 768 * The existing block is already 769 * at least as big as we want. 770 * Just read the block (if requested). 771 */ 772 773 if (bpp != NULL) { 774 error = bread(vp, lbn, osize, NOCRED, 775 bpp); 776 if (error) { 777 brelse(*bpp); 778 return (error); 779 } 780 } 781 return 0; 782 } else { 783 784 /* 785 * The existing block is smaller than we want, 786 * grow it. 787 */ 788 789 error = ffs_realloccg(ip, lbn, 790 ffs_blkpref_ufs2(ip, lbn, (int)lbn, 791 &ip->i_ffs2_db[0]), osize, nsize, cred, 792 bpp, &newb); 793 if (error) 794 return (error); 795 if (DOINGSOFTDEP(vp)) 796 softdep_setup_allocdirect(ip, lbn, 797 newb, nb, nsize, osize, 798 bpp ? *bpp : NULL); 799 } 800 } else { 801 802 /* 803 * the block was not previously allocated, 804 * allocate a new block or fragment. 805 */ 806 807 if (ip->i_size < lblktosize(fs, lbn + 1)) 808 nsize = fragroundup(fs, size); 809 else 810 nsize = fs->fs_bsize; 811 error = ffs_alloc(ip, lbn, 812 ffs_blkpref_ufs2(ip, lbn, (int)lbn, 813 &ip->i_ffs2_db[0]), nsize, cred, &newb); 814 if (error) 815 return (error); 816 if (bpp != NULL) { 817 bp = getblk(vp, lbn, nsize, 0, 0); 818 bp->b_blkno = fsbtodb(fs, newb); 819 if (flags & B_CLRBUF) 820 clrbuf(bp); 821 *bpp = bp; 822 } 823 if (DOINGSOFTDEP(vp)) { 824 softdep_setup_allocdirect(ip, lbn, newb, 0, 825 nsize, 0, bpp ? *bpp : NULL); 826 } 827 } 828 ip->i_ffs2_db[lbn] = ufs_rw64(newb, needswap); 829 ip->i_flag |= IN_CHANGE | IN_UPDATE; 830 return (0); 831 } 832 833 /* 834 * Determine the number of levels of indirection. 835 */ 836 837 pref = 0; 838 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 839 return (error); 840 841 /* 842 * Fetch the first indirect block allocating if necessary. 843 */ 844 845 --num; 846 nb = ufs_rw64(ip->i_ffs2_ib[indirs[0].in_off], needswap); 847 allocib = NULL; 848 allocblk = allociblk; 849 if (nb == 0) { 850 pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0); 851 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 852 &newb); 853 if (error) 854 goto fail; 855 nb = newb; 856 *allocblk++ = nb; 857 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); 858 bp->b_blkno = fsbtodb(fs, nb); 859 clrbuf(bp); 860 if (DOINGSOFTDEP(vp)) { 861 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, 862 newb, 0, fs->fs_bsize, 0, bp); 863 bdwrite(bp); 864 } else { 865 866 /* 867 * Write synchronously so that indirect blocks 868 * never point at garbage. 869 */ 870 871 if ((error = bwrite(bp)) != 0) 872 goto fail; 873 } 874 unwindidx = 0; 875 allocib = &ip->i_ffs2_ib[indirs[0].in_off]; 876 *allocib = ufs_rw64(nb, needswap); 877 ip->i_flag |= IN_CHANGE | IN_UPDATE; 878 } 879 880 /* 881 * Fetch through the indirect blocks, allocating as necessary. 882 */ 883 884 for (i = 1;;) { 885 error = bread(vp, 886 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp); 887 if (error) { 888 brelse(bp); 889 goto fail; 890 } 891 bap = (int64_t *)bp->b_data; 892 nb = ufs_rw64(bap[indirs[i].in_off], needswap); 893 if (i == num) 894 break; 895 i++; 896 if (nb != 0) { 897 brelse(bp); 898 continue; 899 } 900 if (pref == 0) 901 pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0); 902 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 903 &newb); 904 if (error) { 905 brelse(bp); 906 goto fail; 907 } 908 nb = newb; 909 *allocblk++ = nb; 910 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); 911 nbp->b_blkno = fsbtodb(fs, nb); 912 clrbuf(nbp); 913 if (DOINGSOFTDEP(vp)) { 914 softdep_setup_allocindir_meta(nbp, ip, bp, 915 indirs[i - 1].in_off, nb); 916 bdwrite(nbp); 917 } else { 918 919 /* 920 * Write synchronously so that indirect blocks 921 * never point at garbage. 922 */ 923 924 if ((error = bwrite(nbp)) != 0) { 925 brelse(bp); 926 goto fail; 927 } 928 } 929 if (unwindidx < 0) 930 unwindidx = i - 1; 931 bap[indirs[i - 1].in_off] = ufs_rw64(nb, needswap); 932 933 /* 934 * If required, write synchronously, otherwise use 935 * delayed write. 936 */ 937 938 if (flags & B_SYNC) { 939 bwrite(bp); 940 } else { 941 bdwrite(bp); 942 } 943 } 944 945 if (flags & B_METAONLY) { 946 *bpp = bp; 947 return (0); 948 } 949 950 /* 951 * Get the data block, allocating if necessary. 952 */ 953 954 if (nb == 0) { 955 pref = ffs_blkpref_ufs2(ip, lbn, indirs[num].in_off, &bap[0]); 956 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 957 &newb); 958 if (error) { 959 brelse(bp); 960 goto fail; 961 } 962 nb = newb; 963 *allocblk++ = nb; 964 if (bpp != NULL) { 965 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); 966 nbp->b_blkno = fsbtodb(fs, nb); 967 if (flags & B_CLRBUF) 968 clrbuf(nbp); 969 *bpp = nbp; 970 } 971 if (DOINGSOFTDEP(vp)) 972 softdep_setup_allocindir_page(ip, lbn, bp, 973 indirs[num].in_off, nb, 0, bpp ? *bpp : NULL); 974 bap[indirs[num].in_off] = ufs_rw64(nb, needswap); 975 if (allocib == NULL && unwindidx < 0) { 976 unwindidx = i - 1; 977 } 978 979 /* 980 * If required, write synchronously, otherwise use 981 * delayed write. 982 */ 983 984 if (flags & B_SYNC) { 985 bwrite(bp); 986 } else { 987 bdwrite(bp); 988 } 989 return (0); 990 } 991 brelse(bp); 992 if (bpp != NULL) { 993 if (flags & B_CLRBUF) { 994 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp); 995 if (error) { 996 brelse(nbp); 997 goto fail; 998 } 999 } else { 1000 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); 1001 nbp->b_blkno = fsbtodb(fs, nb); 1002 clrbuf(nbp); 1003 } 1004 *bpp = nbp; 1005 } 1006 return (0); 1007 1008 fail: 1009 /* 1010 * If we have failed part way through block allocation, we 1011 * have to deallocate any indirect blocks that we have allocated. 1012 */ 1013 1014 if (unwindidx >= 0) { 1015 1016 /* 1017 * First write out any buffers we've created to resolve their 1018 * softdeps. This must be done in reverse order of creation 1019 * so that we resolve the dependencies in one pass. 1020 * Write the cylinder group buffers for these buffers too. 1021 */ 1022 1023 for (i = num; i >= unwindidx; i--) { 1024 if (i == 0) { 1025 break; 1026 } 1027 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, 1028 0); 1029 if (bp->b_flags & B_DELWRI) { 1030 nb = fsbtodb(fs, cgtod(fs, dtog(fs, 1031 dbtofsb(fs, bp->b_blkno)))); 1032 bwrite(bp); 1033 bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize, 1034 0, 0); 1035 if (bp->b_flags & B_DELWRI) { 1036 bwrite(bp); 1037 } else { 1038 bp->b_flags |= B_INVAL; 1039 brelse(bp); 1040 } 1041 } else { 1042 bp->b_flags |= B_INVAL; 1043 brelse(bp); 1044 } 1045 } 1046 if (DOINGSOFTDEP(vp) && unwindidx == 0) { 1047 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1048 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT); 1049 } 1050 1051 /* 1052 * Now that any dependencies that we created have been 1053 * resolved, we can undo the partial allocation. 1054 */ 1055 1056 if (unwindidx == 0) { 1057 *allocib = 0; 1058 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1059 if (DOINGSOFTDEP(vp)) 1060 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT); 1061 } else { 1062 int r; 1063 1064 r = bread(vp, indirs[unwindidx].in_lbn, 1065 (int)fs->fs_bsize, NOCRED, &bp); 1066 if (r) { 1067 panic("Could not unwind indirect block, error %d", r); 1068 brelse(bp); 1069 } else { 1070 bap = (int64_t *)bp->b_data; 1071 bap[indirs[unwindidx].in_off] = 0; 1072 bwrite(bp); 1073 } 1074 } 1075 for (i = unwindidx + 1; i <= num; i++) { 1076 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, 1077 0); 1078 bp->b_flags |= B_INVAL; 1079 brelse(bp); 1080 } 1081 } 1082 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { 1083 ffs_blkfree(fs, ip->i_devvp, *blkp, fs->fs_bsize, ip->i_number); 1084 deallocated += fs->fs_bsize; 1085 } 1086 if (deallocated) { 1087 #ifdef QUOTA 1088 /* 1089 * Restore user's disk quota because allocation failed. 1090 */ 1091 (void)chkdq(ip, -btodb(deallocated), cred, FORCE); 1092 #endif 1093 ip->i_ffs2_blocks -= btodb(deallocated); 1094 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1095 } 1096 return (error); 1097 } 1098