@@ -585,13 +585,17 @@ static int udf_do_extend_file(struct inode *inode,
585
585
static void udf_do_extend_final_block (struct inode * inode ,
586
586
struct extent_position * last_pos ,
587
587
struct kernel_long_ad * last_ext ,
588
- uint32_t final_block_len )
588
+ uint32_t new_elen )
589
589
{
590
- struct super_block * sb = inode -> i_sb ;
591
590
uint32_t added_bytes ;
592
591
593
- added_bytes = final_block_len -
594
- (last_ext -> extLength & (sb -> s_blocksize - 1 ));
592
+ /*
593
+ * Extent already large enough? It may be already rounded up to block
594
+ * size...
595
+ */
596
+ if (new_elen <= (last_ext -> extLength & UDF_EXTENT_LENGTH_MASK ))
597
+ return ;
598
+ added_bytes = (last_ext -> extLength & UDF_EXTENT_LENGTH_MASK ) - new_elen ;
595
599
last_ext -> extLength += added_bytes ;
596
600
UDF_I (inode )-> i_lenExtents += added_bytes ;
597
601
@@ -608,12 +612,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
608
612
int8_t etype ;
609
613
struct super_block * sb = inode -> i_sb ;
610
614
sector_t first_block = newsize >> sb -> s_blocksize_bits , offset ;
611
- unsigned long partial_final_block ;
615
+ loff_t new_elen ;
612
616
int adsize ;
613
617
struct udf_inode_info * iinfo = UDF_I (inode );
614
618
struct kernel_long_ad extent ;
615
619
int err = 0 ;
616
- int within_final_block ;
620
+ bool within_last_ext ;
617
621
618
622
if (iinfo -> i_alloc_type == ICBTAG_FLAG_AD_SHORT )
619
623
adsize = sizeof (struct short_ad );
@@ -629,9 +633,9 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
629
633
udf_discard_prealloc (inode );
630
634
631
635
etype = inode_bmap (inode , first_block , & epos , & eloc , & elen , & offset );
632
- within_final_block = (etype != -1 );
636
+ within_last_ext = (etype != -1 );
633
637
/* We don't expect extents past EOF... */
634
- WARN_ON_ONCE (etype != -1 &&
638
+ WARN_ON_ONCE (within_last_ext &&
635
639
elen > ((loff_t )offset + 1 ) << inode -> i_blkbits );
636
640
637
641
if ((!epos .bh && epos .offset == udf_file_entry_alloc_offset (inode )) ||
@@ -648,19 +652,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
648
652
extent .extLength |= etype << 30 ;
649
653
}
650
654
651
- partial_final_block = newsize & (sb -> s_blocksize - 1 );
655
+ new_elen = ((loff_t )offset << inode -> i_blkbits ) |
656
+ (newsize & (sb -> s_blocksize - 1 ));
652
657
653
658
/* File has extent covering the new size (could happen when extending
654
659
* inside a block)?
655
660
*/
656
- if (within_final_block ) {
661
+ if (within_last_ext ) {
657
662
/* Extending file within the last file block */
658
- udf_do_extend_final_block (inode , & epos , & extent ,
659
- partial_final_block );
663
+ udf_do_extend_final_block (inode , & epos , & extent , new_elen );
660
664
} else {
661
- loff_t add = ((loff_t )offset << sb -> s_blocksize_bits ) |
662
- partial_final_block ;
663
- err = udf_do_extend_file (inode , & epos , & extent , add );
665
+ err = udf_do_extend_file (inode , & epos , & extent , new_elen );
664
666
}
665
667
666
668
if (err < 0 )
0 commit comments