.. | .. |
---|
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) |
---|