aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
authorQu Wenruo <wqu@suse.com>2026-04-14 13:05:27 +0930
committerDavid Sterba <dsterba@suse.com>2026-05-24 03:01:00 +0200
commit5ee40ef3b72f95e1707a0fa032e94c24ab3df4e8 (patch)
treeefd689e80c17dfded781dde60e2b6e6fc53ea90f /fs
parentc6abccf6a159eac0ae1e0c51bcc2041cfb89ad3b (diff)
downloadlinux-next-history-5ee40ef3b72f95e1707a0fa032e94c24ab3df4e8.tar.gz
btrfs: remove folio checked subpage bitmap tracking
The folio checked flag is only utilized by the COW fixup mechanism inside btrfs. Since the COW fixup is already removed from non-experimental builds, there is no need to keep the checked subpage bitmap. This will saves us some space for large folios, for example for a single 256K sized large folio on 4K page sized systems: Old bitmap size = 6 * (256K / 4K / 8) = 48 bytes New bitmap size = 5 * (256K / 4K / 8) = 40 bytes This will be more obvious when we're going to support huge folios (order = 9). Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/defrag.c1
-rw-r--r--fs/btrfs/file.c12
-rw-r--r--fs/btrfs/free-space-cache.c4
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/reflink.c1
-rw-r--r--fs/btrfs/subpage.c39
-rw-r--r--fs/btrfs/subpage.h5
7 files changed, 4 insertions, 61 deletions
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index 7e2db5d3a4d4c..af40ad62009a4 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -1179,7 +1179,6 @@ static int defrag_one_locked_target(struct btrfs_inode *inode,
if (start >= folio_next_pos(folio) ||
start + len <= folio_pos(folio))
continue;
- btrfs_folio_clamp_clear_checked(fs_info, folio, start, len);
btrfs_folio_clamp_set_dirty(fs_info, folio, start, len);
}
btrfs_delalloc_release_extents(inode, len);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 8c171ed07008b..2c1862ee99984 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -49,14 +49,6 @@ static void btrfs_drop_folio(struct btrfs_fs_info *fs_info, struct folio *folio,
u64 block_len = round_up(pos + copied, fs_info->sectorsize) - block_start;
ASSERT(block_len <= U32_MAX);
- /*
- * Folio checked is some magic around finding folios that have been
- * modified without going through btrfs_dirty_folio(). Clear it here.
- * There should be no need to mark the pages accessed as
- * prepare_one_folio() should have marked them accessed in
- * prepare_one_folio() via find_or_create_page()
- */
- btrfs_folio_clamp_clear_checked(fs_info, folio, block_start, block_len);
folio_unlock(folio);
folio_put(folio);
}
@@ -65,7 +57,7 @@ static void btrfs_drop_folio(struct btrfs_fs_info *fs_info, struct folio *folio,
* After copy_folio_from_iter_atomic(), update the following things for delalloc:
* - Mark newly dirtied folio as DELALLOC in the io tree.
* Used to advise which range is to be written back.
- * - Mark modified folio as Uptodate/Dirty and not needing COW fixup
+ * - Mark modified folio as Uptodate/Dirty
* - Update inode size for past EOF write
*/
int btrfs_dirty_folio(struct btrfs_inode *inode, struct folio *folio, loff_t pos,
@@ -107,7 +99,6 @@ int btrfs_dirty_folio(struct btrfs_inode *inode, struct folio *folio, loff_t pos
return ret;
btrfs_folio_clamp_set_uptodate(fs_info, folio, start_pos, num_bytes);
- btrfs_folio_clamp_clear_checked(fs_info, folio, start_pos, num_bytes);
btrfs_folio_clamp_set_dirty(fs_info, folio, start_pos, num_bytes);
/*
@@ -1992,7 +1983,6 @@ again:
if (zero_start != fsize)
folio_zero_range(folio, zero_start, folio_size(folio) - zero_start);
- btrfs_folio_clear_checked(fs_info, folio, page_start, fsize);
btrfs_folio_set_dirty(fs_info, folio, page_start, end + 1 - page_start);
btrfs_folio_set_uptodate(fs_info, folio, page_start, end + 1 - page_start);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index ab22e4f9ffdde..07567fd456347 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -433,10 +433,6 @@ static void io_ctl_drop_pages(struct btrfs_io_ctl *io_ctl)
for (i = 0; i < io_ctl->num_pages; i++) {
if (io_ctl->pages[i]) {
- btrfs_folio_clear_checked(io_ctl->fs_info,
- page_folio(io_ctl->pages[i]),
- page_offset(io_ctl->pages[i]),
- PAGE_SIZE);
unlock_page(io_ctl->pages[i]);
put_page(io_ctl->pages[i]);
}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f705445020005..7557b571a5d9a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5009,8 +5009,6 @@ again:
folio_zero_range(folio, zero_start - folio_pos(folio),
zero_end - zero_start + 1);
- btrfs_folio_clear_checked(fs_info, folio, block_start,
- block_end + 1 - block_start);
btrfs_folio_set_dirty(fs_info, folio, block_start,
block_end + 1 - block_start);
@@ -7627,7 +7625,6 @@ next:
* did something wrong.
*/
ASSERT(!folio_test_ordered(folio));
- btrfs_folio_clear_checked(fs_info, folio, folio_pos(folio), folio_size(folio));
if (!inode_evicting)
__btrfs_release_folio(folio, GFP_NOFS);
clear_folio_extent_mapped(folio);
diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
index 49865a4637809..14742abe0f92b 100644
--- a/fs/btrfs/reflink.c
+++ b/fs/btrfs/reflink.c
@@ -141,7 +141,6 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
folio_zero_range(folio, datal, block_size - datal);
btrfs_folio_set_uptodate(fs_info, folio, file_offset, block_size);
- btrfs_folio_clear_checked(fs_info, folio, file_offset, block_size);
btrfs_folio_set_dirty(fs_info, folio, file_offset, block_size);
out_unlock:
if (!IS_ERR(folio)) {
diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c
index f82e71f5d88b6..8a09f34ea31ec 100644
--- a/fs/btrfs/subpage.c
+++ b/fs/btrfs/subpage.c
@@ -508,35 +508,6 @@ void btrfs_subpage_clear_ordered(const struct btrfs_fs_info *fs_info,
spin_unlock_irqrestore(&bfs->lock, flags);
}
-void btrfs_subpage_set_checked(const struct btrfs_fs_info *fs_info,
- struct folio *folio, u64 start, u32 len)
-{
- struct btrfs_folio_state *bfs = folio_get_private(folio);
- unsigned int start_bit = subpage_calc_start_bit(fs_info, folio,
- checked, start, len);
- unsigned long flags;
-
- spin_lock_irqsave(&bfs->lock, flags);
- bitmap_set(bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
- if (subpage_test_bitmap_all_set(fs_info, folio, checked))
- folio_set_checked(folio);
- spin_unlock_irqrestore(&bfs->lock, flags);
-}
-
-void btrfs_subpage_clear_checked(const struct btrfs_fs_info *fs_info,
- struct folio *folio, u64 start, u32 len)
-{
- struct btrfs_folio_state *bfs = folio_get_private(folio);
- unsigned int start_bit = subpage_calc_start_bit(fs_info, folio,
- checked, start, len);
- unsigned long flags;
-
- spin_lock_irqsave(&bfs->lock, flags);
- bitmap_clear(bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
- folio_clear_checked(folio);
- spin_unlock_irqrestore(&bfs->lock, flags);
-}
-
/*
* Unlike set/clear which is dependent on each page status, for test all bits
* are tested in the same way.
@@ -561,7 +532,6 @@ IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(uptodate);
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(dirty);
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(writeback);
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(ordered);
-IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(checked);
/*
* Note that, in selftests (extent-io-tests), we can have empty fs_info passed
@@ -659,8 +629,6 @@ IMPLEMENT_BTRFS_PAGE_OPS(writeback, folio_start_writeback, folio_end_writeback,
folio_test_writeback);
IMPLEMENT_BTRFS_PAGE_OPS(ordered, folio_set_ordered, folio_clear_ordered,
folio_test_ordered);
-IMPLEMENT_BTRFS_PAGE_OPS(checked, folio_set_checked, folio_clear_checked,
- folio_test_checked);
#define GET_SUBPAGE_BITMAP(fs_info, folio, name, dst) \
{ \
@@ -782,7 +750,6 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
unsigned long dirty_bitmap;
unsigned long writeback_bitmap;
unsigned long ordered_bitmap;
- unsigned long checked_bitmap;
unsigned long locked_bitmap;
unsigned long flags;
@@ -795,20 +762,18 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
GET_SUBPAGE_BITMAP(fs_info, folio, dirty, &dirty_bitmap);
GET_SUBPAGE_BITMAP(fs_info, folio, writeback, &writeback_bitmap);
GET_SUBPAGE_BITMAP(fs_info, folio, ordered, &ordered_bitmap);
- GET_SUBPAGE_BITMAP(fs_info, folio, checked, &checked_bitmap);
GET_SUBPAGE_BITMAP(fs_info, folio, locked, &locked_bitmap);
spin_unlock_irqrestore(&bfs->lock, flags);
dump_page(folio_page(folio, 0), "btrfs folio state dump");
btrfs_warn(fs_info,
-"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl locked=%*pbl writeback=%*pbl ordered=%*pbl checked=%*pbl",
+"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl locked=%*pbl writeback=%*pbl ordered=%*pbl",
start, len, folio_pos(folio),
blocks_per_folio, &uptodate_bitmap,
blocks_per_folio, &dirty_bitmap,
blocks_per_folio, &locked_bitmap,
blocks_per_folio, &writeback_bitmap,
- blocks_per_folio, &ordered_bitmap,
- blocks_per_folio, &checked_bitmap);
+ blocks_per_folio, &ordered_bitmap);
}
void btrfs_get_subpage_dirty_bitmap(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/subpage.h b/fs/btrfs/subpage.h
index d81a0ade559fd..fdea0b605bfc7 100644
--- a/fs/btrfs/subpage.h
+++ b/fs/btrfs/subpage.h
@@ -41,11 +41,9 @@ enum {
btrfs_bitmap_nr_writeback,
/*
- * The ordered and checked flags are for COW fixup, already marked
- * deprecated, and will be removed eventually.
+ * The ordered flags shows if the range has an ordered extent.
*/
btrfs_bitmap_nr_ordered,
- btrfs_bitmap_nr_checked,
/*
* The locked bit is for async delalloc range (compression), currently
@@ -182,7 +180,6 @@ DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
DECLARE_BTRFS_SUBPAGE_OPS(dirty);
DECLARE_BTRFS_SUBPAGE_OPS(writeback);
DECLARE_BTRFS_SUBPAGE_OPS(ordered);
-DECLARE_BTRFS_SUBPAGE_OPS(checked);
/*
* Helper for error cleanup, where a folio will have its dirty flag cleared,