| .. | .. |
|---|
| 438 | 438 | iinfo->i_next_alloc_goal++; |
|---|
| 439 | 439 | } |
|---|
| 440 | 440 | |
|---|
| 441 | + /* |
|---|
| 442 | + * Block beyond EOF and prealloc extents? Just discard preallocation |
|---|
| 443 | + * as it is not useful and complicates things. |
|---|
| 444 | + */ |
|---|
| 445 | + if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents) |
|---|
| 446 | + udf_discard_prealloc(inode); |
|---|
| 441 | 447 | udf_clear_extent_cache(inode); |
|---|
| 442 | 448 | phys = inode_getblk(inode, block, &err, &new); |
|---|
| 443 | 449 | if (!phys) |
|---|
| .. | .. |
|---|
| 487 | 493 | uint32_t add; |
|---|
| 488 | 494 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
|---|
| 489 | 495 | struct super_block *sb = inode->i_sb; |
|---|
| 490 | | - struct kernel_lb_addr prealloc_loc = {}; |
|---|
| 491 | | - uint32_t prealloc_len = 0; |
|---|
| 492 | 496 | struct udf_inode_info *iinfo; |
|---|
| 493 | 497 | int err; |
|---|
| 494 | 498 | |
|---|
| .. | .. |
|---|
| 507 | 511 | iinfo->i_lenExtents = |
|---|
| 508 | 512 | (iinfo->i_lenExtents + sb->s_blocksize - 1) & |
|---|
| 509 | 513 | ~(sb->s_blocksize - 1); |
|---|
| 510 | | - } |
|---|
| 511 | | - |
|---|
| 512 | | - /* Last extent are just preallocated blocks? */ |
|---|
| 513 | | - if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == |
|---|
| 514 | | - EXT_NOT_RECORDED_ALLOCATED) { |
|---|
| 515 | | - /* Save the extent so that we can reattach it to the end */ |
|---|
| 516 | | - prealloc_loc = last_ext->extLocation; |
|---|
| 517 | | - prealloc_len = last_ext->extLength; |
|---|
| 518 | | - /* Mark the extent as a hole */ |
|---|
| 519 | | - last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
|---|
| 520 | | - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
|---|
| 521 | | - last_ext->extLocation.logicalBlockNum = 0; |
|---|
| 522 | | - last_ext->extLocation.partitionReferenceNum = 0; |
|---|
| 523 | 514 | } |
|---|
| 524 | 515 | |
|---|
| 525 | 516 | /* Can we merge with the previous extent? */ |
|---|
| .. | .. |
|---|
| 549 | 540 | * more extents, we may need to enter possible following |
|---|
| 550 | 541 | * empty indirect extent. |
|---|
| 551 | 542 | */ |
|---|
| 552 | | - if (new_block_bytes || prealloc_len) |
|---|
| 543 | + if (new_block_bytes) |
|---|
| 553 | 544 | udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); |
|---|
| 554 | 545 | } |
|---|
| 555 | 546 | |
|---|
| .. | .. |
|---|
| 583 | 574 | } |
|---|
| 584 | 575 | |
|---|
| 585 | 576 | out: |
|---|
| 586 | | - /* Do we have some preallocated blocks saved? */ |
|---|
| 587 | | - if (prealloc_len) { |
|---|
| 588 | | - err = udf_add_aext(inode, last_pos, &prealloc_loc, |
|---|
| 589 | | - prealloc_len, 1); |
|---|
| 590 | | - if (err) |
|---|
| 591 | | - return err; |
|---|
| 592 | | - last_ext->extLocation = prealloc_loc; |
|---|
| 593 | | - last_ext->extLength = prealloc_len; |
|---|
| 594 | | - count++; |
|---|
| 595 | | - } |
|---|
| 596 | | - |
|---|
| 597 | 577 | /* last_pos should point to the last written extent... */ |
|---|
| 598 | 578 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
|---|
| 599 | 579 | last_pos->offset -= sizeof(struct short_ad); |
|---|
| .. | .. |
|---|
| 609 | 589 | static void udf_do_extend_final_block(struct inode *inode, |
|---|
| 610 | 590 | struct extent_position *last_pos, |
|---|
| 611 | 591 | struct kernel_long_ad *last_ext, |
|---|
| 612 | | - uint32_t final_block_len) |
|---|
| 592 | + uint32_t new_elen) |
|---|
| 613 | 593 | { |
|---|
| 614 | | - struct super_block *sb = inode->i_sb; |
|---|
| 615 | 594 | uint32_t added_bytes; |
|---|
| 616 | 595 | |
|---|
| 617 | | - added_bytes = final_block_len - |
|---|
| 618 | | - (last_ext->extLength & (sb->s_blocksize - 1)); |
|---|
| 596 | + /* |
|---|
| 597 | + * Extent already large enough? It may be already rounded up to block |
|---|
| 598 | + * size... |
|---|
| 599 | + */ |
|---|
| 600 | + if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) |
|---|
| 601 | + return; |
|---|
| 602 | + added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen; |
|---|
| 619 | 603 | last_ext->extLength += added_bytes; |
|---|
| 620 | 604 | UDF_I(inode)->i_lenExtents += added_bytes; |
|---|
| 621 | 605 | |
|---|
| .. | .. |
|---|
| 632 | 616 | int8_t etype; |
|---|
| 633 | 617 | struct super_block *sb = inode->i_sb; |
|---|
| 634 | 618 | sector_t first_block = newsize >> sb->s_blocksize_bits, offset; |
|---|
| 635 | | - unsigned long partial_final_block; |
|---|
| 619 | + loff_t new_elen; |
|---|
| 636 | 620 | int adsize; |
|---|
| 637 | 621 | struct udf_inode_info *iinfo = UDF_I(inode); |
|---|
| 638 | 622 | struct kernel_long_ad extent; |
|---|
| 639 | 623 | int err = 0; |
|---|
| 640 | | - int within_final_block; |
|---|
| 624 | + bool within_last_ext; |
|---|
| 641 | 625 | |
|---|
| 642 | 626 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
|---|
| 643 | 627 | adsize = sizeof(struct short_ad); |
|---|
| .. | .. |
|---|
| 646 | 630 | else |
|---|
| 647 | 631 | BUG(); |
|---|
| 648 | 632 | |
|---|
| 633 | + /* |
|---|
| 634 | + * When creating hole in file, just don't bother with preserving |
|---|
| 635 | + * preallocation. It likely won't be very useful anyway. |
|---|
| 636 | + */ |
|---|
| 637 | + udf_discard_prealloc(inode); |
|---|
| 638 | + |
|---|
| 649 | 639 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
|---|
| 650 | | - within_final_block = (etype != -1); |
|---|
| 640 | + within_last_ext = (etype != -1); |
|---|
| 641 | + /* We don't expect extents past EOF... */ |
|---|
| 642 | + WARN_ON_ONCE(within_last_ext && |
|---|
| 643 | + elen > ((loff_t)offset + 1) << inode->i_blkbits); |
|---|
| 651 | 644 | |
|---|
| 652 | 645 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
|---|
| 653 | 646 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
|---|
| .. | .. |
|---|
| 663 | 656 | extent.extLength |= etype << 30; |
|---|
| 664 | 657 | } |
|---|
| 665 | 658 | |
|---|
| 666 | | - partial_final_block = newsize & (sb->s_blocksize - 1); |
|---|
| 659 | + new_elen = ((loff_t)offset << inode->i_blkbits) | |
|---|
| 660 | + (newsize & (sb->s_blocksize - 1)); |
|---|
| 667 | 661 | |
|---|
| 668 | 662 | /* File has extent covering the new size (could happen when extending |
|---|
| 669 | 663 | * inside a block)? |
|---|
| 670 | 664 | */ |
|---|
| 671 | | - if (within_final_block) { |
|---|
| 665 | + if (within_last_ext) { |
|---|
| 672 | 666 | /* Extending file within the last file block */ |
|---|
| 673 | | - udf_do_extend_final_block(inode, &epos, &extent, |
|---|
| 674 | | - partial_final_block); |
|---|
| 667 | + udf_do_extend_final_block(inode, &epos, &extent, new_elen); |
|---|
| 675 | 668 | } else { |
|---|
| 676 | | - loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | |
|---|
| 677 | | - partial_final_block; |
|---|
| 678 | | - err = udf_do_extend_file(inode, &epos, &extent, add); |
|---|
| 669 | + err = udf_do_extend_file(inode, &epos, &extent, new_elen); |
|---|
| 679 | 670 | } |
|---|
| 680 | 671 | |
|---|
| 681 | 672 | if (err < 0) |
|---|
| .. | .. |
|---|
| 776 | 767 | goto out_free; |
|---|
| 777 | 768 | } |
|---|
| 778 | 769 | |
|---|
| 779 | | - /* Are we beyond EOF? */ |
|---|
| 770 | + /* Are we beyond EOF and preallocated extent? */ |
|---|
| 780 | 771 | if (etype == -1) { |
|---|
| 781 | 772 | int ret; |
|---|
| 782 | 773 | loff_t hole_len; |
|---|
| 774 | + |
|---|
| 783 | 775 | isBeyondEOF = true; |
|---|
| 784 | 776 | if (count) { |
|---|
| 785 | 777 | if (c) |
|---|