mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 02:59:19 -04:00
btrfs: use metadata specific helpers to simplify extent buffer helpers
The following functions are doing metadata specific checks: - set_extent_buffer_uptodate() - clear_extent_buffer_uptodate() The reason why we do not use btrfs_folio_*() helpers for those helpers is, btrfs_is_subpage() cannot handle dummy extent buffer if nodesize >= PAGE_SIZE but block size < PAGE_SIZE. In that case, we do not need to attach extra bitmaps to the extent buffer folio. But since dummy extent buffer folios are not attached to btree inode, btrfs_is_subpage() will return true, causing problems. And the following are using btrfs_folio_*() helpers for metadata, but in theory we should use metadata specific checks: - set_extent_buffer_dirty() This is not causing problems because a dummy extent buffer should never be marked dirty. To make code simpler, introduce btrfs_meta_folio_*() helpers, to do the metadata specific handling, so that we do not to open-code such checks in above involved functions. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
@@ -3442,8 +3442,8 @@ void set_extent_buffer_dirty(struct extent_buffer *eb)
|
||||
if (subpage)
|
||||
folio_lock(eb->folios[0]);
|
||||
for (int i = 0; i < num_folios; i++)
|
||||
btrfs_folio_set_dirty(eb->fs_info, eb->folios[i],
|
||||
eb->start, eb->len);
|
||||
btrfs_meta_folio_set_dirty(eb->fs_info, eb->folios[i],
|
||||
eb->start, eb->len);
|
||||
if (subpage)
|
||||
folio_unlock(eb->folios[0]);
|
||||
percpu_counter_add_batch(&eb->fs_info->dirty_metadata_bytes,
|
||||
@@ -3468,15 +3468,7 @@ void clear_extent_buffer_uptodate(struct extent_buffer *eb)
|
||||
if (!folio)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This is special handling for metadata subpage, as regular
|
||||
* btrfs_is_subpage() can not handle cloned/dummy metadata.
|
||||
*/
|
||||
if (!btrfs_meta_is_subpage(fs_info))
|
||||
folio_clear_uptodate(folio);
|
||||
else
|
||||
btrfs_subpage_clear_uptodate(fs_info, folio,
|
||||
eb->start, eb->len);
|
||||
btrfs_meta_folio_clear_uptodate(fs_info, folio, eb->start, eb->len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3489,15 +3481,7 @@ void set_extent_buffer_uptodate(struct extent_buffer *eb)
|
||||
for (int i = 0; i < num_folios; i++) {
|
||||
struct folio *folio = eb->folios[i];
|
||||
|
||||
/*
|
||||
* This is special handling for metadata subpage, as regular
|
||||
* btrfs_is_subpage() can not handle cloned/dummy metadata.
|
||||
*/
|
||||
if (!btrfs_meta_is_subpage(fs_info))
|
||||
folio_mark_uptodate(folio);
|
||||
else
|
||||
btrfs_subpage_set_uptodate(fs_info, folio,
|
||||
eb->start, eb->len);
|
||||
btrfs_meta_folio_set_uptodate(fs_info, folio, eb->start, eb->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -651,6 +651,31 @@ bool btrfs_folio_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||
return folio_test_func(folio); \
|
||||
btrfs_subpage_clamp_range(folio, &start, &len); \
|
||||
return btrfs_subpage_test_##name(fs_info, folio, start, len); \
|
||||
} \
|
||||
void btrfs_meta_folio_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len) \
|
||||
{ \
|
||||
if (!btrfs_meta_is_subpage(fs_info)) { \
|
||||
folio_set_func(folio); \
|
||||
return; \
|
||||
} \
|
||||
btrfs_subpage_set_##name(fs_info, folio, start, len); \
|
||||
} \
|
||||
void btrfs_meta_folio_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len) \
|
||||
{ \
|
||||
if (!btrfs_meta_is_subpage(fs_info)) { \
|
||||
folio_clear_func(folio); \
|
||||
return; \
|
||||
} \
|
||||
btrfs_subpage_clear_##name(fs_info, folio, start, len); \
|
||||
} \
|
||||
bool btrfs_meta_folio_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len) \
|
||||
{ \
|
||||
if (!btrfs_meta_is_subpage(fs_info)) \
|
||||
return folio_test_func(folio); \
|
||||
return btrfs_subpage_test_##name(fs_info, folio, start, len); \
|
||||
}
|
||||
IMPLEMENT_BTRFS_PAGE_OPS(uptodate, folio_mark_uptodate, folio_clear_uptodate,
|
||||
folio_test_uptodate);
|
||||
|
||||
@@ -128,6 +128,13 @@ void btrfs_folio_end_lock_bitmap(const struct btrfs_fs_info *fs_info,
|
||||
* btrfs_folio_clamp_*() are similar to btrfs_folio_*(), except the range doesn't
|
||||
* need to be inside the page. Those functions will truncate the range
|
||||
* automatically.
|
||||
*
|
||||
* Both btrfs_folio_*() and btrfs_folio_clamp_*() are for data folios.
|
||||
*
|
||||
* For metadata, one should use btrfs_meta_folio_*() helpers instead, and there
|
||||
* is no clamp version for metadata helpers, as we either go subpage
|
||||
* (nodesize < PAGE_SIZE) or go regular folio helpers (nodesize >= PAGE_SIZE,
|
||||
* and our folio is never larger than nodesize).
|
||||
*/
|
||||
#define DECLARE_BTRFS_SUBPAGE_OPS(name) \
|
||||
void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||
@@ -147,7 +154,13 @@ void btrfs_folio_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||
void btrfs_folio_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len); \
|
||||
bool btrfs_folio_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len);
|
||||
struct folio *folio, u64 start, u32 len); \
|
||||
void btrfs_meta_folio_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len); \
|
||||
void btrfs_meta_folio_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len); \
|
||||
bool btrfs_meta_folio_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct folio *folio, u64 start, u32 len); \
|
||||
|
||||
DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
|
||||
DECLARE_BTRFS_SUBPAGE_OPS(dirty);
|
||||
|
||||
Reference in New Issue
Block a user