diff mbox series

[2/3] btrfs: use folio_contains() for EOF detection

Message ID 6a71b4597a65114b646032648129558fe6bef38d.1743731232.git.wqu@suse.com (mailing list archive)
State New
Headers show
Series btrfs: fsstress hang fix for large data folios | expand

Commit Message

Qu Wenruo April 4, 2025, 1:47 a.m. UTC
Currently we use the following pattern to detect if the folio contains
the end of a file:

	if (folio->index == end_index)
		folio_zero_range();

But that only works if the folio is page sized.

For the following case, it will not work and leave the range beyond EOF
uninitialized:

  The page size is 4K, and the fs block size is also 4K.

	16K        20K       24K
        |          |     |   |
	                 |
                         EOF at 22K

And we have a large folio sized 8K at file offset 16K.

In that case, the old "folio->index == end_index" will not work, thus
we the range [22K, 24K) will not be zeroed out.

Fix the following call sites which use the above pattern:

- add_ra_bio_pages()

- extent_writepage()

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/compression.c | 2 +-
 fs/btrfs/extent_io.c   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

Comments

Filipe Manana April 4, 2025, 4:09 p.m. UTC | #1
On Fri, Apr 4, 2025 at 2:48 AM Qu Wenruo <wqu@suse.com> wrote:
>
> Currently we use the following pattern to detect if the folio contains
> the end of a file:
>
>         if (folio->index == end_index)
>                 folio_zero_range();
>
> But that only works if the folio is page sized.
>
> For the following case, it will not work and leave the range beyond EOF
> uninitialized:
>
>   The page size is 4K, and the fs block size is also 4K.
>
>         16K        20K       24K
>         |          |     |   |
>                          |
>                          EOF at 22K
>
> And we have a large folio sized 8K at file offset 16K.
>
> In that case, the old "folio->index == end_index" will not work, thus
> we the range [22K, 24K) will not be zeroed out.

thus we the range -> thus the range

>
> Fix the following call sites which use the above pattern:
>
> - add_ra_bio_pages()
>
> - extent_writepage()
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>

Reviewed-by: Filipe Manana <fdmanana@suse.com>

Otherwise it looks good, thanks.


> ---
>  fs/btrfs/compression.c | 2 +-
>  fs/btrfs/extent_io.c   | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
> index cb954f9bc332..7aa63681f92a 100644
> --- a/fs/btrfs/compression.c
> +++ b/fs/btrfs/compression.c
> @@ -523,7 +523,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
>                 free_extent_map(em);
>                 unlock_extent(tree, cur, page_end, NULL);
>
> -               if (folio->index == end_index) {
> +               if (folio_contains(folio, end_index)) {
>                         size_t zero_offset = offset_in_folio(folio, isize);
>
>                         if (zero_offset) {
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index 013268f70621..f0d51f6ed951 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -221,7 +221,7 @@ static void __process_folios_contig(struct address_space *mapping,
>  }
>
>  static noinline void unlock_delalloc_folio(const struct inode *inode,
> -                                          const struct folio *locked_folio,
> +                                          struct folio *locked_folio,
>                                            u64 start, u64 end)
>  {
>         ASSERT(locked_folio);
> @@ -231,7 +231,7 @@ static noinline void unlock_delalloc_folio(const struct inode *inode,
>  }
>
>  static noinline int lock_delalloc_folios(struct inode *inode,
> -                                        const struct folio *locked_folio,
> +                                        struct folio *locked_folio,
>                                          u64 start, u64 end)
>  {
>         struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
> @@ -1711,7 +1711,7 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
>                 return 0;
>         }
>
> -       if (folio->index == end_index)
> +       if (folio_contains(folio, end_index))
>                 folio_zero_range(folio, pg_offset, folio_size(folio) - pg_offset);
>
>         /*
> --
> 2.49.0
>
>
diff mbox series

Patch

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index cb954f9bc332..7aa63681f92a 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -523,7 +523,7 @@  static noinline int add_ra_bio_pages(struct inode *inode,
 		free_extent_map(em);
 		unlock_extent(tree, cur, page_end, NULL);
 
-		if (folio->index == end_index) {
+		if (folio_contains(folio, end_index)) {
 			size_t zero_offset = offset_in_folio(folio, isize);
 
 			if (zero_offset) {
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 013268f70621..f0d51f6ed951 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -221,7 +221,7 @@  static void __process_folios_contig(struct address_space *mapping,
 }
 
 static noinline void unlock_delalloc_folio(const struct inode *inode,
-					   const struct folio *locked_folio,
+					   struct folio *locked_folio,
 					   u64 start, u64 end)
 {
 	ASSERT(locked_folio);
@@ -231,7 +231,7 @@  static noinline void unlock_delalloc_folio(const struct inode *inode,
 }
 
 static noinline int lock_delalloc_folios(struct inode *inode,
-					 const struct folio *locked_folio,
+					 struct folio *locked_folio,
 					 u64 start, u64 end)
 {
 	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
@@ -1711,7 +1711,7 @@  static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
 		return 0;
 	}
 
-	if (folio->index == end_index)
+	if (folio_contains(folio, end_index))
 		folio_zero_range(folio, pg_offset, folio_size(folio) - pg_offset);
 
 	/*