On 6/12/26 19:58, Yongpeng Yang wrote:
> From: Yongpeng Yang <[email protected]>
> 
> Previously, when an extent being inserted overlaps with the largest
> extent, the largest extent is dropped entirely. This was done to handle

Please correct me if I missed anything, I remember that we will add largest
extent in below path?

- __update_extent_tree_range
 - __insert_extent_tree
  - __try_update_largest_extent : update largest w/ right extent
 - __try_update_largest_extent : update largest w/ left extent

Thanks,

> the case where the largest extent is not in memory, avoiding
> inconsistency between the largest extent and the extent tree.
> 
> This patch changes the semantics of __drop_largest_extent (renamed to
> __punch_largest_extent): instead of discarding the entire largest
> extent when any overlap is detected, keep the larger remaining portion
> (left or right) after the punch. This preserves extent cache coverage
> for truncate and overwrite operations that only partially overlap the
> largest extent.
> 
> Signed-off-by: Yongpeng Yang <[email protected]>
> ---
>  fs/f2fs/extent_cache.c | 31 ++++++++++++++++++++++++-------
>  1 file changed, 24 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
> index f8d94db60dc6..82d84c4e98b2 100644
> --- a/fs/f2fs/extent_cache.c
> +++ b/fs/f2fs/extent_cache.c
> @@ -397,14 +397,31 @@ static unsigned int __free_extent_tree(struct 
> f2fs_sb_info *sbi,
>       return count;
>  }
>  
> -static void __drop_largest_extent(struct extent_tree *et,
> +static void __punch_largest_extent(struct extent_tree *et,
>                                       pgoff_t fofs, unsigned int len)
>  {
> -     if (fofs < (pgoff_t)et->largest.fofs + et->largest.len &&
> -                     fofs + len > et->largest.fofs) {
> -             et->largest.len = 0;
> -             et->largest_updated = true;
> +     unsigned int largest_end, punch_end;
> +     unsigned int left_len, right_len;
> +
> +     if (fofs >= (pgoff_t)et->largest.fofs + et->largest.len ||
> +                     fofs + len <= et->largest.fofs)
> +             return;
> +
> +     /* Punch [fofs, fofs + len) from largest extent. */
> +     largest_end = et->largest.fofs + et->largest.len;
> +     punch_end = fofs + len;
> +
> +     left_len = fofs > et->largest.fofs ? fofs - et->largest.fofs : 0;
> +     right_len = largest_end > punch_end ? largest_end - punch_end : 0;
> +
> +     if (left_len >= right_len) {
> +             et->largest.len = left_len;
> +     } else {
> +             et->largest.blk += punch_end - et->largest.fofs;
> +             et->largest.fofs = punch_end;
> +             et->largest.len = right_len;
>       }
> +     et->largest_updated = true;
>  }
>  
>  void f2fs_init_read_extent_tree(struct inode *inode, struct folio *ifolio)
> @@ -680,10 +697,10 @@ static void __update_extent_tree_range(struct inode 
> *inode,
>               dei.len = 0;
>  
>               /*
> -              * drop largest extent before lookup, in case it's already
> +              * punch largest extent before lookup, in case it's already
>                * been shrunk from extent tree
>                */
> -             __drop_largest_extent(et, fofs, len);
> +             __punch_largest_extent(et, fofs, len);
>       }
>  
>       if (et->largest.len != 0 &&



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to