mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
btrfs: require strict data/metadata split for subpage checks
Since we have btrfs_meta_is_subpage(), we should make btrfs_is_subpage() to be data inode specific. This change involves: - Simplify btrfs_is_subpage() Now we only need to do a very simple sectorsize check against PAGE_SIZE. And since the function is pretty simple now, just make it an inline function. - Add an extra ASSERT() to make sure btrfs_is_subpage() is only called on data inode mapping - Migrate btree_csum_one_bio() to use btrfs_meta_folio_*() helpers - Migrate alloc_extent_buffer() to use btrfs_meta_folio_*() helpers - Migrate end_bbio_meta_write() to use btrfs_meta_folio_*() helpers Or we will trigger the ASSERT() due to calling btrfs_folio_*() on metadata folios. 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:
parent
67ebd7a1f1
commit
fcc384be06
4 changed files with 15 additions and 34 deletions
|
@ -284,8 +284,8 @@ blk_status_t btree_csum_one_bio(struct btrfs_bio *bbio)
|
|||
|
||||
if (WARN_ON_ONCE(found_start != eb->start))
|
||||
return BLK_STS_IOERR;
|
||||
if (WARN_ON(!btrfs_folio_test_uptodate(fs_info, eb->folios[0],
|
||||
eb->start, eb->len)))
|
||||
if (WARN_ON(!btrfs_meta_folio_test_uptodate(fs_info, eb->folios[0],
|
||||
eb->start, eb->len)))
|
||||
return BLK_STS_IOERR;
|
||||
|
||||
ASSERT(memcmp_extent_buffer(eb, fs_info->fs_devices->metadata_uuid,
|
||||
|
|
|
@ -1732,18 +1732,14 @@ static void end_bbio_meta_write(struct btrfs_bio *bbio)
|
|||
struct extent_buffer *eb = bbio->private;
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
struct folio_iter fi;
|
||||
u32 bio_offset = 0;
|
||||
|
||||
if (bbio->bio.bi_status != BLK_STS_OK)
|
||||
set_btree_ioerr(eb);
|
||||
|
||||
bio_for_each_folio_all(fi, &bbio->bio) {
|
||||
u64 start = eb->start + bio_offset;
|
||||
struct folio *folio = fi.folio;
|
||||
u32 len = fi.length;
|
||||
|
||||
btrfs_folio_clear_writeback(fs_info, folio, start, len);
|
||||
bio_offset += len;
|
||||
btrfs_meta_folio_clear_writeback(fs_info, folio, eb->start, eb->len);
|
||||
}
|
||||
|
||||
clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
|
||||
|
@ -3136,7 +3132,7 @@ reallocate:
|
|||
* and free the allocated page.
|
||||
*/
|
||||
folio = eb->folios[i];
|
||||
WARN_ON(btrfs_folio_test_dirty(fs_info, folio, eb->start, eb->len));
|
||||
WARN_ON(btrfs_meta_folio_test_dirty(fs_info, folio, eb->start, eb->len));
|
||||
|
||||
/*
|
||||
* Check if the current page is physically contiguous with previous eb
|
||||
|
@ -3147,7 +3143,7 @@ reallocate:
|
|||
if (i && folio_page(eb->folios[i - 1], 0) + 1 != folio_page(folio, 0))
|
||||
page_contig = false;
|
||||
|
||||
if (!btrfs_folio_test_uptodate(fs_info, folio, eb->start, eb->len))
|
||||
if (!btrfs_meta_folio_test_uptodate(fs_info, folio, eb->start, eb->len))
|
||||
uptodate = 0;
|
||||
|
||||
/*
|
||||
|
|
|
@ -64,30 +64,6 @@
|
|||
* This means a slightly higher tree locking latency.
|
||||
*/
|
||||
|
||||
#if PAGE_SIZE > SZ_4K
|
||||
bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping)
|
||||
{
|
||||
if (fs_info->sectorsize >= PAGE_SIZE)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Only data pages (either through DIO or compression) can have no
|
||||
* mapping. And if mapping->host is data inode, it's subpage.
|
||||
* As we have ruled our sectorsize >= PAGE_SIZE case already.
|
||||
*/
|
||||
if (!mapping || !mapping->host || is_data_inode(BTRFS_I(mapping->host)))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Now the only remaining case is metadata, which we only go subpage
|
||||
* routine if nodesize < PAGE_SIZE.
|
||||
*/
|
||||
if (fs_info->nodesize < PAGE_SIZE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
|
||||
struct folio *folio, enum btrfs_subpage_type type)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/sizes.h>
|
||||
#include "btrfs_inode.h"
|
||||
#include "fs.h"
|
||||
|
||||
struct address_space;
|
||||
|
@ -83,7 +84,13 @@ static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info)
|
|||
{
|
||||
return fs_info->nodesize < PAGE_SIZE;
|
||||
}
|
||||
bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping);
|
||||
static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
|
||||
struct address_space *mapping)
|
||||
{
|
||||
if (mapping && mapping->host)
|
||||
ASSERT(is_data_inode(BTRFS_I(mapping->host)));
|
||||
return fs_info->sectorsize < PAGE_SIZE;
|
||||
}
|
||||
#else
|
||||
static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
|
@ -92,6 +99,8 @@ static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info)
|
|||
static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
|
||||
struct address_space *mapping)
|
||||
{
|
||||
if (mapping && mapping->host)
|
||||
ASSERT(is_data_inode(BTRFS_I(mapping->host)));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue