1 /* $OpenBSD: ffs_balloc.c,v 1.45 2019/07/19 00:24:31 cheloha Exp $ */ 2 /* $NetBSD: ffs_balloc.c,v 1.3 1996/02/09 22:22:21 christos Exp $ */ 3 4 /* 5 * Copyright (c) 2002 Networks Associates Technology, Inc. 6 * All rights reserved. 7 * 8 * This software was developed for the FreeBSD Project by Marshall 9 * Kirk McKusick and Network Associates Laboratories, the Security 10 * Research Division of Network Associates, Inc. under DARPA/SPAWAR 11 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS 12 * research program. 13 * 14 * Copyright (c) 1982, 1986, 1989, 1993 15 * The Regents of the University of California. All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/buf.h> 47 #include <sys/proc.h> 48 #include <sys/mount.h> 49 #include <sys/vnode.h> 50 51 #include <ufs/ufs/quota.h> 52 #include <ufs/ufs/inode.h> 53 #include <ufs/ufs/ufsmount.h> 54 #include <ufs/ufs/ufs_extern.h> 55 56 #include <ufs/ffs/fs.h> 57 #include <ufs/ffs/ffs_extern.h> 58 59 int ffs1_balloc(struct inode *, off_t, int, struct ucred *, int, struct buf **); 60 #ifdef FFS2 61 int ffs2_balloc(struct inode *, off_t, int, struct ucred *, int, struct buf **); 62 #endif 63 64 /* 65 * Balloc defines the structure of file system storage 66 * by allocating the physical blocks on a device given 67 * the inode and the logical block number in a file. 68 */ 69 int 70 ffs1_balloc(struct inode *ip, off_t startoffset, int size, struct ucred *cred, 71 int flags, struct buf **bpp) 72 { 73 daddr_t lbn, nb, newb, pref; 74 struct fs *fs; 75 struct buf *bp, *nbp; 76 struct vnode *vp; 77 struct proc *p; 78 struct indir indirs[NIADDR + 2]; 79 int32_t *bap; 80 int deallocated, osize, nsize, num, i, error; 81 int32_t *allocib, *blkp, *allocblk, allociblk[NIADDR+1]; 82 int unwindidx = -1; 83 84 vp = ITOV(ip); 85 fs = ip->i_fs; 86 p = curproc; 87 lbn = lblkno(fs, startoffset); 88 size = blkoff(fs, startoffset) + size; 89 if (size > fs->fs_bsize) 90 panic("ffs1_balloc: blk too big"); 91 if (bpp != NULL) 92 *bpp = NULL; 93 if (lbn < 0) 94 return (EFBIG); 95 96 /* 97 * If the next write will extend the file into a new block, 98 * and the file is currently composed of a fragment 99 * this fragment has to be extended to be a full block. 100 */ 101 nb = lblkno(fs, ip->i_ffs1_size); 102 if (nb < NDADDR && nb < lbn) { 103 osize = blksize(fs, ip, nb); 104 if (osize < fs->fs_bsize && osize > 0) { 105 error = ffs_realloccg(ip, nb, 106 ffs1_blkpref(ip, nb, (int)nb, &ip->i_ffs1_db[0]), 107 osize, (int)fs->fs_bsize, cred, bpp, &newb); 108 if (error) 109 return (error); 110 if (DOINGSOFTDEP(vp)) 111 softdep_setup_allocdirect(ip, nb, newb, 112 ip->i_ffs1_db[nb], fs->fs_bsize, osize, 113 bpp ? *bpp : NULL); 114 115 ip->i_ffs1_size = lblktosize(fs, nb + 1); 116 uvm_vnp_setsize(vp, ip->i_ffs1_size); 117 ip->i_ffs1_db[nb] = newb; 118 ip->i_flag |= IN_CHANGE | IN_UPDATE; 119 if (bpp != NULL) { 120 if (flags & B_SYNC) 121 bwrite(*bpp); 122 else 123 bawrite(*bpp); 124 } 125 } 126 } 127 /* 128 * The first NDADDR blocks are direct blocks 129 */ 130 if (lbn < NDADDR) { 131 nb = ip->i_ffs1_db[lbn]; 132 if (nb != 0 && ip->i_ffs1_size >= lblktosize(fs, lbn + 1)) { 133 /* 134 * The block is an already-allocated direct block 135 * and the file already extends past this block, 136 * thus this must be a whole block. 137 * Just read the block (if requested). 138 */ 139 140 if (bpp != NULL) { 141 error = bread(vp, lbn, fs->fs_bsize, bpp); 142 if (error) { 143 brelse(*bpp); 144 return (error); 145 } 146 } 147 return (0); 148 } 149 if (nb != 0) { 150 /* 151 * Consider need to reallocate a fragment. 152 */ 153 osize = fragroundup(fs, blkoff(fs, ip->i_ffs1_size)); 154 nsize = fragroundup(fs, size); 155 if (nsize <= osize) { 156 /* 157 * The existing block is already 158 * at least as big as we want. 159 * Just read the block (if requested). 160 */ 161 if (bpp != NULL) { 162 error = bread(vp, lbn, fs->fs_bsize, 163 bpp); 164 if (error) { 165 brelse(*bpp); 166 return (error); 167 } 168 buf_adjcnt((*bpp), osize); 169 } 170 return (0); 171 } else { 172 /* 173 * The existing block is smaller than we 174 * want, grow it. 175 */ 176 error = ffs_realloccg(ip, lbn, 177 ffs1_blkpref(ip, lbn, (int)lbn, 178 &ip->i_ffs1_db[0]), 179 osize, nsize, cred, bpp, &newb); 180 if (error) 181 return (error); 182 if (DOINGSOFTDEP(vp)) 183 softdep_setup_allocdirect(ip, lbn, 184 newb, nb, nsize, osize, 185 bpp ? *bpp : NULL); 186 } 187 } else { 188 /* 189 * The block was not previously allocated, 190 * allocate a new block or fragment. 191 */ 192 193 if (ip->i_ffs1_size < lblktosize(fs, lbn + 1)) 194 nsize = fragroundup(fs, size); 195 else 196 nsize = fs->fs_bsize; 197 error = ffs_alloc(ip, lbn, 198 ffs1_blkpref(ip, lbn, (int)lbn, &ip->i_ffs1_db[0]), 199 nsize, cred, &newb); 200 if (error) 201 return (error); 202 if (bpp != NULL) { 203 *bpp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 204 if (nsize < fs->fs_bsize) 205 (*bpp)->b_bcount = nsize; 206 (*bpp)->b_blkno = fsbtodb(fs, newb); 207 if (flags & B_CLRBUF) 208 clrbuf(*bpp); 209 } 210 if (DOINGSOFTDEP(vp)) 211 softdep_setup_allocdirect(ip, lbn, newb, 0, 212 nsize, 0, bpp ? *bpp : NULL); 213 } 214 ip->i_ffs1_db[lbn] = newb; 215 ip->i_flag |= IN_CHANGE | IN_UPDATE; 216 return (0); 217 } 218 219 /* 220 * Determine the number of levels of indirection. 221 */ 222 pref = 0; 223 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 224 return(error); 225 #ifdef DIAGNOSTIC 226 if (num < 1) 227 panic ("ffs1_balloc: ufs_bmaparray returned indirect block"); 228 #endif 229 /* 230 * Fetch the first indirect block allocating if necessary. 231 */ 232 --num; 233 nb = ip->i_ffs1_ib[indirs[0].in_off]; 234 235 allocib = NULL; 236 allocblk = allociblk; 237 if (nb == 0) { 238 pref = ffs1_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL); 239 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, 240 cred, &newb); 241 if (error) 242 goto fail; 243 nb = newb; 244 245 *allocblk++ = nb; 246 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, INFSLP); 247 bp->b_blkno = fsbtodb(fs, nb); 248 clrbuf(bp); 249 250 if (DOINGSOFTDEP(vp)) { 251 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, 252 newb, 0, fs->fs_bsize, 0, bp); 253 bdwrite(bp); 254 } else { 255 /* 256 * Write synchronously so that indirect blocks 257 * never point at garbage. 258 */ 259 if ((error = bwrite(bp)) != 0) 260 goto fail; 261 } 262 allocib = &ip->i_ffs1_ib[indirs[0].in_off]; 263 *allocib = nb; 264 ip->i_flag |= IN_CHANGE | IN_UPDATE; 265 } 266 267 /* 268 * Fetch through the indirect blocks, allocating as necessary. 269 */ 270 for (i = 1;;) { 271 error = bread(vp, indirs[i].in_lbn, (int)fs->fs_bsize, &bp); 272 if (error) { 273 brelse(bp); 274 goto fail; 275 } 276 bap = (int32_t *)bp->b_data; 277 nb = bap[indirs[i].in_off]; 278 if (i == num) 279 break; 280 i++; 281 if (nb != 0) { 282 brelse(bp); 283 continue; 284 } 285 if (pref == 0) 286 pref = ffs1_blkpref(ip, lbn, i - num - 1, NULL); 287 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 288 &newb); 289 if (error) { 290 brelse(bp); 291 goto fail; 292 } 293 nb = newb; 294 *allocblk++ = nb; 295 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, INFSLP); 296 nbp->b_blkno = fsbtodb(fs, nb); 297 clrbuf(nbp); 298 299 if (DOINGSOFTDEP(vp)) { 300 softdep_setup_allocindir_meta(nbp, ip, bp, 301 indirs[i - 1].in_off, nb); 302 bdwrite(nbp); 303 } else { 304 /* 305 * Write synchronously so that indirect blocks 306 * never point at garbage. 307 */ 308 if ((error = bwrite(nbp)) != 0) { 309 brelse(bp); 310 goto fail; 311 } 312 } 313 bap[indirs[i - 1].in_off] = nb; 314 if (allocib == NULL && unwindidx < 0) 315 unwindidx = i - 1; 316 /* 317 * If required, write synchronously, otherwise use 318 * delayed write. 319 */ 320 if (flags & B_SYNC) { 321 bwrite(bp); 322 } else { 323 bdwrite(bp); 324 } 325 } 326 /* 327 * Get the data block, allocating if necessary. 328 */ 329 if (nb == 0) { 330 pref = ffs1_blkpref(ip, lbn, indirs[i].in_off, &bap[0]); 331 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 332 &newb); 333 if (error) { 334 brelse(bp); 335 goto fail; 336 } 337 nb = newb; 338 *allocblk++ = nb; 339 if (bpp != NULL) { 340 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 341 nbp->b_blkno = fsbtodb(fs, nb); 342 if (flags & B_CLRBUF) 343 clrbuf(nbp); 344 *bpp = nbp; 345 } 346 if (DOINGSOFTDEP(vp)) 347 softdep_setup_allocindir_page(ip, lbn, bp, 348 indirs[i].in_off, nb, 0, bpp ? *bpp : NULL); 349 bap[indirs[i].in_off] = nb; 350 /* 351 * If required, write synchronously, otherwise use 352 * delayed write. 353 */ 354 if (flags & B_SYNC) { 355 bwrite(bp); 356 } else { 357 bdwrite(bp); 358 } 359 return (0); 360 } 361 brelse(bp); 362 if (bpp != NULL) { 363 if (flags & B_CLRBUF) { 364 error = bread(vp, lbn, (int)fs->fs_bsize, &nbp); 365 if (error) { 366 brelse(nbp); 367 goto fail; 368 } 369 } else { 370 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 371 nbp->b_blkno = fsbtodb(fs, nb); 372 } 373 *bpp = nbp; 374 } 375 return (0); 376 377 fail: 378 /* 379 * If we have failed to allocate any blocks, simply return the error. 380 * This is the usual case and avoids the need to fsync the file. 381 */ 382 if (allocblk == allociblk && allocib == NULL && unwindidx == -1) 383 return (error); 384 /* 385 * If we have failed part way through block allocation, we have to 386 * deallocate any indirect blocks that we have allocated. We have to 387 * fsync the file before we start to get rid of all of its 388 * dependencies so that we do not leave them dangling. We have to sync 389 * it at the end so that the softdep code does not find any untracked 390 * changes. Although this is really slow, running out of disk space is 391 * not expected to be a common occurrence. The error return from fsync 392 * is ignored as we already have an error to return to the user. 393 */ 394 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p); 395 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { 396 ffs_blkfree(ip, *blkp, fs->fs_bsize); 397 deallocated += fs->fs_bsize; 398 } 399 if (allocib != NULL) { 400 *allocib = 0; 401 } else if (unwindidx >= 0) { 402 int r; 403 404 r = bread(vp, indirs[unwindidx].in_lbn, (int)fs->fs_bsize, &bp); 405 if (r) 406 panic("Could not unwind indirect block, error %d", r); 407 bap = (int32_t *)bp->b_data; 408 bap[indirs[unwindidx].in_off] = 0; 409 if (flags & B_SYNC) { 410 bwrite(bp); 411 } else { 412 bdwrite(bp); 413 } 414 } 415 if (deallocated) { 416 /* 417 * Restore user's disk quota because allocation failed. 418 */ 419 (void)ufs_quota_free_blocks(ip, btodb(deallocated), cred); 420 421 ip->i_ffs1_blocks -= btodb(deallocated); 422 ip->i_flag |= IN_CHANGE | IN_UPDATE; 423 } 424 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p); 425 return (error); 426 } 427 428 #ifdef FFS2 429 int 430 ffs2_balloc(struct inode *ip, off_t off, int size, struct ucred *cred, 431 int flags, struct buf **bpp) 432 { 433 daddr_t lbn, lastlbn, nb, newb, *blkp; 434 daddr_t pref, *allocblk, allociblk[NIADDR + 1]; 435 daddr_t *bap, *allocib; 436 int deallocated, osize, nsize, num, i, error, unwindidx, r; 437 struct buf *bp, *nbp; 438 struct indir indirs[NIADDR + 2]; 439 struct fs *fs; 440 struct vnode *vp; 441 struct proc *p; 442 443 vp = ITOV(ip); 444 fs = ip->i_fs; 445 p = curproc; 446 unwindidx = -1; 447 448 lbn = lblkno(fs, off); 449 size = blkoff(fs, off) + size; 450 451 if (size > fs->fs_bsize) 452 panic("ffs2_balloc: block too big"); 453 454 if (bpp != NULL) 455 *bpp = NULL; 456 457 if (lbn < 0) 458 return (EFBIG); 459 460 /* 461 * If the next write will extend the file into a new block, and the 462 * file is currently composed of a fragment, this fragment has to be 463 * extended to be a full block. 464 */ 465 lastlbn = lblkno(fs, ip->i_ffs2_size); 466 if (lastlbn < NDADDR && lastlbn < lbn) { 467 nb = lastlbn; 468 osize = blksize(fs, ip, nb); 469 if (osize < fs->fs_bsize && osize > 0) { 470 error = ffs_realloccg(ip, nb, ffs2_blkpref(ip, 471 lastlbn, nb, &ip->i_ffs2_db[0]), osize, 472 (int) fs->fs_bsize, cred, bpp, &newb); 473 if (error) 474 return (error); 475 476 if (DOINGSOFTDEP(vp)) 477 softdep_setup_allocdirect(ip, nb, newb, 478 ip->i_ffs2_db[nb], fs->fs_bsize, osize, 479 bpp ? *bpp : NULL); 480 481 ip->i_ffs2_size = lblktosize(fs, nb + 1); 482 uvm_vnp_setsize(vp, ip->i_ffs2_size); 483 ip->i_ffs2_db[nb] = newb; 484 ip->i_flag |= IN_CHANGE | IN_UPDATE; 485 486 if (bpp) { 487 if (flags & B_SYNC) 488 bwrite(*bpp); 489 else 490 bawrite(*bpp); 491 } 492 } 493 } 494 495 /* 496 * The first NDADDR blocks are direct. 497 */ 498 if (lbn < NDADDR) { 499 500 nb = ip->i_ffs2_db[lbn]; 501 502 if (nb != 0 && ip->i_ffs2_size >= lblktosize(fs, lbn + 1)) { 503 /* 504 * The direct block is already allocated and the file 505 * extends past this block, thus this must be a whole 506 * block. Just read it, if requested. 507 */ 508 if (bpp != NULL) { 509 error = bread(vp, lbn, fs->fs_bsize, bpp); 510 if (error) { 511 brelse(*bpp); 512 return (error); 513 } 514 } 515 516 return (0); 517 } 518 519 if (nb != 0) { 520 /* 521 * Consider the need to allocate a fragment. 522 */ 523 osize = fragroundup(fs, blkoff(fs, ip->i_ffs2_size)); 524 nsize = fragroundup(fs, size); 525 526 if (nsize <= osize) { 527 /* 528 * The existing block is already at least as 529 * big as we want. Just read it, if requested. 530 */ 531 if (bpp != NULL) { 532 error = bread(vp, lbn, fs->fs_bsize, 533 bpp); 534 if (error) { 535 brelse(*bpp); 536 return (error); 537 } 538 buf_adjcnt((*bpp), osize); 539 } 540 541 return (0); 542 } else { 543 /* 544 * The existing block is smaller than we want, 545 * grow it. 546 */ 547 error = ffs_realloccg(ip, lbn, 548 ffs2_blkpref(ip, lbn, (int) lbn, 549 &ip->i_ffs2_db[0]), osize, nsize, cred, 550 bpp, &newb); 551 if (error) 552 return (error); 553 554 if (DOINGSOFTDEP(vp)) 555 softdep_setup_allocdirect(ip, lbn, 556 newb, nb, nsize, osize, 557 bpp ? *bpp : NULL); 558 } 559 } else { 560 /* 561 * The block was not previously allocated, allocate a 562 * new block or fragment. 563 */ 564 if (ip->i_ffs2_size < lblktosize(fs, lbn + 1)) 565 nsize = fragroundup(fs, size); 566 else 567 nsize = fs->fs_bsize; 568 569 error = ffs_alloc(ip, lbn, ffs2_blkpref(ip, lbn, 570 (int) lbn, &ip->i_ffs2_db[0]), nsize, cred, &newb); 571 if (error) 572 return (error); 573 574 if (bpp != NULL) { 575 bp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 576 if (nsize < fs->fs_bsize) 577 bp->b_bcount = nsize; 578 bp->b_blkno = fsbtodb(fs, newb); 579 if (flags & B_CLRBUF) 580 clrbuf(bp); 581 *bpp = bp; 582 } 583 584 if (DOINGSOFTDEP(vp)) 585 softdep_setup_allocdirect(ip, lbn, newb, 0, 586 nsize, 0, bpp ? *bpp : NULL); 587 } 588 589 ip->i_ffs2_db[lbn] = newb; 590 ip->i_flag |= IN_CHANGE | IN_UPDATE; 591 592 return (0); 593 } 594 595 /* 596 * Determine the number of levels of indirection. 597 */ 598 pref = 0; 599 error = ufs_getlbns(vp, lbn, indirs, &num); 600 if (error) 601 return (error); 602 603 #ifdef DIAGNOSTIC 604 if (num < 1) 605 panic("ffs2_balloc: ufs_bmaparray returned indirect block"); 606 #endif 607 608 /* 609 * Fetch the first indirect block allocating it necessary. 610 */ 611 --num; 612 nb = ip->i_ffs2_ib[indirs[0].in_off]; 613 allocib = NULL; 614 allocblk = allociblk; 615 616 if (nb == 0) { 617 pref = ffs2_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL); 618 error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred, 619 &newb); 620 if (error) 621 goto fail; 622 623 nb = newb; 624 *allocblk++ = nb; 625 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, INFSLP); 626 bp->b_blkno = fsbtodb(fs, nb); 627 clrbuf(bp); 628 629 if (DOINGSOFTDEP(vp)) { 630 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, 631 newb, 0, fs->fs_bsize, 0, bp); 632 bdwrite(bp); 633 } else { 634 /* 635 * Write synchronously so that indirect blocks never 636 * point at garbage. 637 */ 638 error = bwrite(bp); 639 if (error) 640 goto fail; 641 } 642 643 unwindidx = 0; 644 allocib = &ip->i_ffs2_ib[indirs[0].in_off]; 645 *allocib = nb; 646 ip->i_flag |= IN_CHANGE | IN_UPDATE; 647 } 648 649 /* 650 * Fetch through the indirect blocks, allocating as necessary. 651 */ 652 for (i = 1;;) { 653 error = bread(vp, indirs[i].in_lbn, (int)fs->fs_bsize, &bp); 654 if (error) { 655 brelse(bp); 656 goto fail; 657 } 658 659 bap = (int64_t *) bp->b_data; 660 nb = bap[indirs[i].in_off]; 661 662 if (i == num) 663 break; 664 665 i++; 666 667 if (nb != 0) { 668 brelse(bp); 669 continue; 670 } 671 672 if (pref == 0) 673 pref = ffs2_blkpref(ip, lbn, i - num - 1, NULL); 674 675 error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred, 676 &newb); 677 if (error) { 678 brelse(bp); 679 goto fail; 680 } 681 682 nb = newb; 683 *allocblk++ = nb; 684 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, INFSLP); 685 nbp->b_blkno = fsbtodb(fs, nb); 686 clrbuf(nbp); 687 688 if (DOINGSOFTDEP(vp)) { 689 softdep_setup_allocindir_meta(nbp, ip, bp, 690 indirs[i - 1].in_off, nb); 691 bdwrite(nbp); 692 } else { 693 /* 694 * Write synchronously so that indirect blocks never 695 * point at garbage. 696 */ 697 error = bwrite(nbp); 698 if (error) { 699 brelse(bp); 700 goto fail; 701 } 702 } 703 704 if (unwindidx < 0) 705 unwindidx = i - 1; 706 707 bap[indirs[i - 1].in_off] = nb; 708 709 /* 710 * If required, write synchronously, otherwise use delayed 711 * write. 712 */ 713 if (flags & B_SYNC) 714 bwrite(bp); 715 else 716 bdwrite(bp); 717 } 718 719 /* 720 * Get the data block, allocating if necessary. 721 */ 722 if (nb == 0) { 723 pref = ffs2_blkpref(ip, lbn, indirs[num].in_off, &bap[0]); 724 725 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, 726 &newb); 727 if (error) { 728 brelse(bp); 729 goto fail; 730 } 731 732 nb = newb; 733 *allocblk++ = nb; 734 735 if (bpp != NULL) { 736 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 737 nbp->b_blkno = fsbtodb(fs, nb); 738 if (flags & B_CLRBUF) 739 clrbuf(nbp); 740 *bpp = nbp; 741 } 742 743 if (DOINGSOFTDEP(vp)) 744 softdep_setup_allocindir_page(ip, lbn, bp, 745 indirs[num].in_off, nb, 0, bpp ? *bpp : NULL); 746 747 bap[indirs[num].in_off] = nb; 748 749 if (allocib == NULL && unwindidx < 0) 750 unwindidx = i - 1; 751 752 /* 753 * If required, write synchronously, otherwise use delayed 754 * write. 755 */ 756 if (flags & B_SYNC) 757 bwrite(bp); 758 else 759 bdwrite(bp); 760 761 return (0); 762 } 763 764 brelse(bp); 765 766 if (bpp != NULL) { 767 if (flags & B_CLRBUF) { 768 error = bread(vp, lbn, (int)fs->fs_bsize, &nbp); 769 if (error) { 770 brelse(nbp); 771 goto fail; 772 } 773 } else { 774 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP); 775 nbp->b_blkno = fsbtodb(fs, nb); 776 clrbuf(nbp); 777 } 778 779 *bpp = nbp; 780 } 781 782 return (0); 783 784 fail: 785 /* 786 * If we have failed to allocate any blocks, simply return the error. 787 * This is the usual case and avoids the need to fsync the file. 788 */ 789 if (allocblk == allociblk && allocib == NULL && unwindidx == -1) 790 return (error); 791 /* 792 * If we have failed part way through block allocation, we have to 793 * deallocate any indirect blocks that we have allocated. We have to 794 * fsync the file before we start to get rid of all of its 795 * dependencies so that we do not leave them dangling. We have to sync 796 * it at the end so that the softdep code does not find any untracked 797 * changes. Although this is really slow, running out of disk space is 798 * not expected to be a common occurrence. The error return from fsync 799 * is ignored as we already have an error to return to the user. 800 */ 801 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p); 802 if (unwindidx >= 0) { 803 /* 804 * First write out any buffers we've created to resolve their 805 * softdeps. This must be done in reverse order of creation so 806 * that we resolve the dependencies in one pass. 807 * Write the cylinder group buffers for these buffers too. 808 */ 809 for (i = num; i >= unwindidx; i--) { 810 if (i == 0) 811 break; 812 813 bp = getblk(vp, indirs[i].in_lbn, (int) fs->fs_bsize, 814 0, INFSLP); 815 if (bp->b_flags & B_DELWRI) { 816 nb = fsbtodb(fs, cgtod(fs, dtog(fs, 817 dbtofsb(fs, bp->b_blkno)))); 818 bwrite(bp); 819 bp = getblk(ip->i_devvp, nb, 820 (int) fs->fs_cgsize, 0, INFSLP); 821 if (bp->b_flags & B_DELWRI) 822 bwrite(bp); 823 else { 824 bp->b_flags |= B_INVAL; 825 brelse(bp); 826 } 827 } else { 828 bp->b_flags |= B_INVAL; 829 brelse(bp); 830 } 831 } 832 833 if (DOINGSOFTDEP(vp) && unwindidx == 0) { 834 ip->i_flag |= IN_CHANGE | IN_UPDATE; 835 ffs_update(ip, 1); 836 } 837 838 /* 839 * Now that any dependencies that we created have been 840 * resolved, we can undo the partial allocation. 841 */ 842 if (unwindidx == 0) { 843 *allocib = 0; 844 ip->i_flag |= IN_CHANGE | IN_UPDATE; 845 if (DOINGSOFTDEP(vp)) 846 ffs_update(ip, 1); 847 } else { 848 r = bread(vp, indirs[unwindidx].in_lbn, 849 (int)fs->fs_bsize, &bp); 850 if (r) 851 panic("ffs2_balloc: unwind failed"); 852 853 bap = (int64_t *) bp->b_data; 854 bap[indirs[unwindidx].in_off] = 0; 855 bwrite(bp); 856 } 857 858 for (i = unwindidx + 1; i <= num; i++) { 859 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, 860 INFSLP); 861 bp->b_flags |= B_INVAL; 862 brelse(bp); 863 } 864 } 865 866 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { 867 ffs_blkfree(ip, *blkp, fs->fs_bsize); 868 deallocated += fs->fs_bsize; 869 } 870 871 if (deallocated) { 872 /* 873 * Restore user's disk quota because allocation failed. 874 */ 875 (void) ufs_quota_free_blocks(ip, btodb(deallocated), cred); 876 877 ip->i_ffs2_blocks -= btodb(deallocated); 878 ip->i_flag |= IN_CHANGE | IN_UPDATE; 879 } 880 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p); 881 return (error); 882 } 883 #endif /* FFS2 */ 884 885 /* 886 * Balloc defines the structure of file system storage by allocating the 887 * physical blocks given the inode and the logical block number in a file. 888 */ 889 int 890 ffs_balloc(struct inode *ip, off_t off, int size, struct ucred *cred, 891 int flags, struct buf **bpp) 892 { 893 #ifdef FFS2 894 if (ip->i_fs->fs_magic == FS_UFS2_MAGIC) 895 return (ffs2_balloc(ip, off, size, cred, flags, bpp)); 896 else 897 #endif 898 return (ffs1_balloc(ip, off, size, cred, flags, bpp)); 899 } 900