diff options
author | Qu Wenruo <wqu@suse.com> | 2025-01-29 14:29:30 +1030 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2025-03-18 20:35:42 +0100 |
commit | fcc384be06aa28d246ace6ca38c8d2b8eb4bf5a4 (patch) | |
tree | f23222e3d58ab395f0df1323922236cb6a404bd0 | |
parent | 67ebd7a1f155189d0dc5d7bf6b29e1814a7be2a0 (diff) |
btrfs: require strict data/metadata split for subpage checks
Since we have btrfs_meta_is_subpage(), we should make btrfs_is_subpage()
to be data inode specific.
This change involves:
- Simplify btrfs_is_subpage()
Now we only need to do a very simple sectorsize check against
PAGE_SIZE.
And since the function is pretty simple now, just make it an inline
function.
- Add an extra ASSERT() to make sure btrfs_is_subpage() is only called
on data inode mapping
- Migrate btree_csum_one_bio() to use btrfs_meta_folio_*() helpers
- Migrate alloc_extent_buffer() to use btrfs_meta_folio_*() helpers
- Migrate end_bbio_meta_write() to use btrfs_meta_folio_*() helpers
Or we will trigger the ASSERT() due to calling btrfs_folio_*() on
metadata folios.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/disk-io.c | 4 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 10 | ||||
-rw-r--r-- | fs/btrfs/subpage.c | 24 | ||||
-rw-r--r-- | fs/btrfs/subpage.h | 11 |
4 files changed, 15 insertions, 34 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d55e282828095..8c31ba1b061ec 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -284,8 +284,8 @@ blk_status_t btree_csum_one_bio(struct btrfs_bio *bbio) if (WARN_ON_ONCE(found_start != eb->start)) return BLK_STS_IOERR; - if (WARN_ON(!btrfs_folio_test_uptodate(fs_info, eb->folios[0], - eb->start, eb->len))) + if (WARN_ON(!btrfs_meta_folio_test_uptodate(fs_info, eb->folios[0], + eb->start, eb->len))) return BLK_STS_IOERR; ASSERT(memcmp_extent_buffer(eb, fs_info->fs_devices->metadata_uuid, diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 1deff394ead3f..580bdb0379742 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1732,18 +1732,14 @@ static void end_bbio_meta_write(struct btrfs_bio *bbio) struct extent_buffer *eb = bbio->private; struct btrfs_fs_info *fs_info = eb->fs_info; struct folio_iter fi; - u32 bio_offset = 0; if (bbio->bio.bi_status != BLK_STS_OK) set_btree_ioerr(eb); bio_for_each_folio_all(fi, &bbio->bio) { - u64 start = eb->start + bio_offset; struct folio *folio = fi.folio; - u32 len = fi.length; - btrfs_folio_clear_writeback(fs_info, folio, start, len); - bio_offset += len; + btrfs_meta_folio_clear_writeback(fs_info, folio, eb->start, eb->len); } clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); @@ -3136,7 +3132,7 @@ reallocate: * and free the allocated page. */ folio = eb->folios[i]; - WARN_ON(btrfs_folio_test_dirty(fs_info, folio, eb->start, eb->len)); + WARN_ON(btrfs_meta_folio_test_dirty(fs_info, folio, eb->start, eb->len)); /* * Check if the current page is physically contiguous with previous eb @@ -3147,7 +3143,7 @@ reallocate: if (i && folio_page(eb->folios[i - 1], 0) + 1 != folio_page(folio, 0)) page_contig = false; - if (!btrfs_folio_test_uptodate(fs_info, folio, eb->start, eb->len)) + if (!btrfs_meta_folio_test_uptodate(fs_info, folio, eb->start, eb->len)) uptodate = 0; /* diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c index f02346aff827f..a8a6e105e5f6c 100644 --- a/fs/btrfs/subpage.c +++ b/fs/btrfs/subpage.c @@ -64,30 +64,6 @@ * This means a slightly higher tree locking latency. */ -#if PAGE_SIZE > SZ_4K -bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping) -{ - if (fs_info->sectorsize >= PAGE_SIZE) - return false; - - /* - * Only data pages (either through DIO or compression) can have no - * mapping. And if mapping->host is data inode, it's subpage. - * As we have ruled our sectorsize >= PAGE_SIZE case already. - */ - if (!mapping || !mapping->host || is_data_inode(BTRFS_I(mapping->host))) - return true; - - /* - * Now the only remaining case is metadata, which we only go subpage - * routine if nodesize < PAGE_SIZE. - */ - if (fs_info->nodesize < PAGE_SIZE) - return true; - return false; -} -#endif - int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, struct folio *folio, enum btrfs_subpage_type type) { diff --git a/fs/btrfs/subpage.h b/fs/btrfs/subpage.h index 6a2dd208eeae8..e10a1d308f32e 100644 --- a/fs/btrfs/subpage.h +++ b/fs/btrfs/subpage.h @@ -6,6 +6,7 @@ #include <linux/spinlock.h> #include <linux/atomic.h> #include <linux/sizes.h> +#include "btrfs_inode.h" #include "fs.h" struct address_space; @@ -83,7 +84,13 @@ static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info) { return fs_info->nodesize < PAGE_SIZE; } -bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping); +static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, + struct address_space *mapping) +{ + if (mapping && mapping->host) + ASSERT(is_data_inode(BTRFS_I(mapping->host))); + return fs_info->sectorsize < PAGE_SIZE; +} #else static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info) { @@ -92,6 +99,8 @@ static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info) static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping) { + if (mapping && mapping->host) + ASSERT(is_data_inode(BTRFS_I(mapping->host))); return false; } #endif |