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>
This commit is contained in:
1 parent
b2a9f217ad
commit
115421e29b
7 files changed
+4
-61
No files matched your search
@@ -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);
|
||||
|
||||
+1
-11
@@ -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);
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
+2
-37
@@ -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,
|
||||
|
||||
+1
-4
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user