]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: use metadata specific helpers to simplify extent buffer helpers
authorQu Wenruo <wqu@suse.com>
Wed, 29 Jan 2025 02:57:39 +0000 (13:27 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 18 Mar 2025 19:35:41 +0000 (20:35 +0100)
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>
fs/btrfs/extent_io.c
fs/btrfs/subpage.c
fs/btrfs/subpage.h

index 089fb6cecbba5115cd024e2d7f733ec0ecc74ca3..dbf4fb1fc2d194ff4f2a2a88c93c4773dd3b632f 100644 (file)
@@ -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);
        }
 }
 
index 073eca132292f5f211d70a0477324c0455c9be3e..3b5cde51ba549e3322a55ab798e0b83580a8d473 100644 (file)
@@ -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);
index 4de61ee938592bcb1695fc66054909859baee16f..ee118bb2c22f10b1980aa84898ef9e09f803bf54 100644 (file)
@@ -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);