mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02:00
btrfs: remove folio ordered flag and subpage bitmap
Btrfs has an internal flag/subpage bitmap called ordered, which is to indicate that a block has corresponding ordered extent covering it. However this requires extra synchronization between the inode ordered tree, and the folio flag/subpage bitmap, not to mention we need to maintain the extra folio flag with subpage bitmap. As a step to align btrfs_folio_state more closely to iomap_folio_state, remove the btrfs specific ordered flag/bitmap. This will also save us 64 bytes for the bitmap of a huge folio. Since we're here, also update the ASCII graph of the bitmap, as there are only 3 sub-bitmaps now, show all sub-bitmaps directly. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
aea704836e
commit
4927b14187
|
|
@ -250,8 +250,6 @@ static void process_one_folio(struct btrfs_fs_info *fs_info,
|
|||
ASSERT(end + 1 - start != 0 && end + 1 - start < U32_MAX);
|
||||
len = end + 1 - start;
|
||||
|
||||
if (page_ops & PAGE_SET_ORDERED)
|
||||
btrfs_folio_clamp_set_ordered(fs_info, folio, start, len);
|
||||
if (page_ops & PAGE_START_WRITEBACK) {
|
||||
btrfs_folio_clamp_clear_dirty(fs_info, folio, start, len);
|
||||
btrfs_folio_clamp_set_writeback(fs_info, folio, start, len);
|
||||
|
|
@ -530,7 +528,6 @@ static void end_bbio_data_write(struct btrfs_bio *bbio)
|
|||
u32 len = fi.length;
|
||||
|
||||
bio_size += len;
|
||||
btrfs_folio_clear_ordered(fs_info, folio, start, len);
|
||||
btrfs_folio_clear_writeback(fs_info, folio, start, len);
|
||||
}
|
||||
|
||||
|
|
@ -1629,7 +1626,6 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
|
|||
u64 start = page_start + (start_bit << fs_info->sectorsize_bits);
|
||||
u32 len = (end_bit - start_bit) << fs_info->sectorsize_bits;
|
||||
|
||||
btrfs_folio_clear_ordered(fs_info, folio, start, len);
|
||||
btrfs_mark_ordered_io_finished(inode, start, len, false);
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -1707,7 +1703,6 @@ static int submit_one_sector(struct btrfs_inode *inode,
|
|||
* ordered extent.
|
||||
*/
|
||||
btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
|
||||
btrfs_folio_clear_ordered(fs_info, folio, filepos, sectorsize);
|
||||
btrfs_folio_set_writeback(fs_info, folio, filepos, sectorsize);
|
||||
btrfs_folio_clear_writeback(fs_info, folio, filepos, sectorsize);
|
||||
|
||||
|
|
@ -1756,7 +1751,6 @@ static int submit_one_sector(struct btrfs_inode *inode,
|
|||
sectorsize, filepos - folio_pos(folio), 0);
|
||||
if (unlikely(queued < sectorsize)) {
|
||||
btrfs_folio_clear_writeback(fs_info, folio, filepos, sectorsize);
|
||||
btrfs_folio_clear_ordered(fs_info, folio, filepos, sectorsize);
|
||||
btrfs_mark_ordered_io_finished(inode, filepos, fs_info->sectorsize,
|
||||
false);
|
||||
return -EUCLEAN;
|
||||
|
|
@ -1821,7 +1815,6 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
|
|||
spin_unlock(&inode->ordered_tree_lock);
|
||||
btrfs_put_ordered_extent(ordered);
|
||||
|
||||
btrfs_folio_clear_ordered(fs_info, folio, cur, fs_info->sectorsize);
|
||||
btrfs_mark_ordered_io_finished(inode, cur, fs_info->sectorsize, true);
|
||||
/*
|
||||
* This range is beyond i_size, thus we don't need to
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ enum {
|
|||
/* Page starts writeback, clear dirty bit and set writeback bit */
|
||||
ENUM_BIT(PAGE_START_WRITEBACK),
|
||||
ENUM_BIT(PAGE_END_WRITEBACK),
|
||||
ENUM_BIT(PAGE_SET_ORDERED),
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1198,14 +1198,6 @@ static inline void btrfs_force_shutdown(struct btrfs_fs_info *fs_info)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We use folio flag owner_2 to indicate there is an ordered extent with
|
||||
* unfinished IO.
|
||||
*/
|
||||
#define folio_test_ordered(folio) folio_test_owner_2(folio)
|
||||
#define folio_set_ordered(folio) folio_set_owner_2(folio)
|
||||
#define folio_clear_ordered(folio) folio_clear_owner_2(folio)
|
||||
|
||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
||||
|
||||
#define EXPORT_FOR_TESTS
|
||||
|
|
|
|||
|
|
@ -401,28 +401,6 @@ void btrfs_inode_unlock(struct btrfs_inode *inode, unsigned int ilock_flags)
|
|||
static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,
|
||||
u64 offset, u64 bytes)
|
||||
{
|
||||
pgoff_t index = offset >> PAGE_SHIFT;
|
||||
const pgoff_t end_index = (offset + bytes - 1) >> PAGE_SHIFT;
|
||||
struct folio *folio;
|
||||
|
||||
while (index <= end_index) {
|
||||
folio = filemap_get_folio(inode->vfs_inode.i_mapping, index);
|
||||
if (IS_ERR(folio)) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
index = folio_next_index(folio);
|
||||
/*
|
||||
* Here we just clear all Ordered bits for every page in the
|
||||
* range, then btrfs_mark_ordered_io_finished() will handle
|
||||
* the ordered extent accounting for the range.
|
||||
*/
|
||||
btrfs_folio_clamp_clear_ordered(inode->root->fs_info, folio,
|
||||
offset, bytes);
|
||||
folio_put(folio);
|
||||
}
|
||||
|
||||
return btrfs_mark_ordered_io_finished(inode, offset, bytes, false);
|
||||
}
|
||||
|
||||
|
|
@ -1406,7 +1384,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
|
|||
* setup for writepage.
|
||||
*/
|
||||
page_ops = ((flags & COW_FILE_RANGE_KEEP_LOCKED) ? 0 : PAGE_UNLOCK);
|
||||
page_ops |= PAGE_SET_ORDERED;
|
||||
|
||||
/*
|
||||
* Relocation relies on the relocated extents to have exactly the same
|
||||
|
|
@ -1972,8 +1949,7 @@ static int nocow_one_range(struct btrfs_inode *inode, struct folio *locked_folio
|
|||
goto error;
|
||||
extent_clear_unlock_delalloc(inode, file_pos, end, locked_folio, cached,
|
||||
EXTENT_LOCKED | EXTENT_DELALLOC |
|
||||
EXTENT_CLEAR_DATA_RESV,
|
||||
PAGE_SET_ORDERED);
|
||||
EXTENT_CLEAR_DATA_RESV, 0);
|
||||
return ret;
|
||||
|
||||
error:
|
||||
|
|
@ -7600,10 +7576,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
|
|||
* The range is dirty meaning it has not been submitted.
|
||||
* Here we need to truncate the OE range as the range will never
|
||||
* be submitted.
|
||||
*/
|
||||
btrfs_folio_clear_ordered(fs_info, folio, cur, range_len);
|
||||
|
||||
/*
|
||||
*
|
||||
* IO on this page will never be started, so we need to account
|
||||
* for any ordered extents now. Don't clear EXTENT_DELALLOC_NEW
|
||||
* here, must leave that up for the ordered extent completion.
|
||||
|
|
|
|||
|
|
@ -465,35 +465,6 @@ void btrfs_subpage_clear_writeback(const struct btrfs_fs_info *fs_info,
|
|||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
}
|
||||
|
||||
void btrfs_subpage_set_ordered(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,
|
||||
ordered, start, len);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfs->lock, flags);
|
||||
bitmap_set(bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
|
||||
folio_set_ordered(folio);
|
||||
spin_unlock_irqrestore(&bfs->lock, flags);
|
||||
}
|
||||
|
||||
void btrfs_subpage_clear_ordered(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,
|
||||
ordered, start, len);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfs->lock, flags);
|
||||
bitmap_clear(bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
|
||||
if (subpage_test_bitmap_all_zero(fs_info, folio, ordered))
|
||||
folio_clear_ordered(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.
|
||||
|
|
@ -517,7 +488,6 @@ bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \
|
|||
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(uptodate);
|
||||
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(dirty);
|
||||
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(writeback);
|
||||
IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(ordered);
|
||||
|
||||
/*
|
||||
* Note that, in selftests (extent-io-tests), we can have empty fs_info passed
|
||||
|
|
@ -613,8 +583,6 @@ IMPLEMENT_BTRFS_PAGE_OPS(dirty, folio_mark_dirty, folio_clear_dirty_for_io,
|
|||
folio_test_dirty);
|
||||
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);
|
||||
|
||||
#define GET_SUBPAGE_BITMAP(fs_info, folio, name, dst) \
|
||||
{ \
|
||||
|
|
@ -727,7 +695,6 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
unsigned long uptodate_bitmap;
|
||||
unsigned long dirty_bitmap;
|
||||
unsigned long writeback_bitmap;
|
||||
unsigned long ordered_bitmap;
|
||||
unsigned long flags;
|
||||
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
|
|
@ -738,17 +705,15 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
|||
GET_SUBPAGE_BITMAP(fs_info, folio, uptodate, &uptodate_bitmap);
|
||||
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);
|
||||
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 writeback=%*pbl ordered=%*pbl",
|
||||
"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl writeback=%*pbl",
|
||||
start, len, folio_pos(folio),
|
||||
blocks_per_folio, &uptodate_bitmap,
|
||||
blocks_per_folio, &dirty_bitmap,
|
||||
blocks_per_folio, &writeback_bitmap,
|
||||
blocks_per_folio, &ordered_bitmap);
|
||||
blocks_per_folio, &writeback_bitmap);
|
||||
}
|
||||
|
||||
void btrfs_get_subpage_dirty_bitmap(struct btrfs_fs_info *fs_info,
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@ struct folio;
|
|||
/*
|
||||
* Extra info for subpage bitmap.
|
||||
*
|
||||
* For subpage we pack all uptodate/dirty/writeback/ordered bitmaps into
|
||||
* For subpage we pack all uptodate/dirty/writeback bitmaps into
|
||||
* one larger bitmap.
|
||||
*
|
||||
* This structure records how they are organized in the bitmap:
|
||||
*
|
||||
* /- uptodate /- dirty /- ordered
|
||||
* /- uptodate /- dirty /- writeback
|
||||
* | | |
|
||||
* v v v
|
||||
* |u|u|u|u|........|u|u|d|d|.......|d|d|o|o|.......|o|o|
|
||||
* |u|u|u|u|........|u|u|d|d|.......|d|d|w|w|.......|w|w|
|
||||
* |< sectors_per_page >|
|
||||
*
|
||||
* Unlike regular macro-like enums, here we do not go upper-case names, as
|
||||
|
|
@ -40,11 +40,6 @@ enum {
|
|||
*/
|
||||
btrfs_bitmap_nr_writeback,
|
||||
|
||||
/*
|
||||
* The ordered flags shows if the range has an ordered extent.
|
||||
*/
|
||||
btrfs_bitmap_nr_ordered,
|
||||
|
||||
btrfs_bitmap_nr_max
|
||||
};
|
||||
|
||||
|
|
@ -169,7 +164,6 @@ bool btrfs_meta_folio_test_##name(struct folio *folio, const struct extent_buffe
|
|||
DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
|
||||
DECLARE_BTRFS_SUBPAGE_OPS(dirty);
|
||||
DECLARE_BTRFS_SUBPAGE_OPS(writeback);
|
||||
DECLARE_BTRFS_SUBPAGE_OPS(ordered);
|
||||
|
||||
/*
|
||||
* Helper for error cleanup, where a folio will have its dirty flag cleared,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user