mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 21:54:06 +08:00
btrfs: provide btrfs_page_clamp_*() helpers
In the coming subpage RW supports, there are a lot of page status update calls which need to be converted to subpage compatible version, which needs @start and @len. Some call sites already have such @start/@len and are already in page range, like various endio functions. But there are also call sites which need to clamp the range for subpage case, like btrfs_dirty_pagse() and __process_contig_pages(). Here we introduce new helpers, btrfs_page_clamp_*(), to do and only do the clamp for subpage version. Although in theory all existing btrfs_page_*() calls can be converted to use btrfs_page_clamp_*() directly, but that would make us to do unnecessary clamp operations. Tested-by: Ritesh Harjani <riteshh@linux.ibm.com> # [ppc64] Tested-by: Anand Jain <anand.jain@oracle.com> # [aarch64] Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ed8f13bf4a
commit
60e2d25500
@ -354,6 +354,16 @@ void btrfs_subpage_clear_writeback(const struct btrfs_fs_info *fs_info,
|
|||||||
spin_unlock_irqrestore(&subpage->lock, flags);
|
spin_unlock_irqrestore(&subpage->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btrfs_subpage_clamp_range(struct page *page, u64 *start, u32 *len)
|
||||||
|
{
|
||||||
|
u64 orig_start = *start;
|
||||||
|
u32 orig_len = *len;
|
||||||
|
|
||||||
|
*start = max_t(u64, page_offset(page), orig_start);
|
||||||
|
*len = min_t(u64, page_offset(page) + PAGE_SIZE,
|
||||||
|
orig_start + orig_len) - *start;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unlike set/clear which is dependent on each page status, for test all bits
|
* Unlike set/clear which is dependent on each page status, for test all bits
|
||||||
* are tested in the same way.
|
* are tested in the same way.
|
||||||
@ -408,6 +418,34 @@ bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \
|
|||||||
if (unlikely(!fs_info) || fs_info->sectorsize == PAGE_SIZE) \
|
if (unlikely(!fs_info) || fs_info->sectorsize == PAGE_SIZE) \
|
||||||
return test_page_func(page); \
|
return test_page_func(page); \
|
||||||
return btrfs_subpage_test_##name(fs_info, page, start, len); \
|
return btrfs_subpage_test_##name(fs_info, page, start, len); \
|
||||||
|
} \
|
||||||
|
void btrfs_page_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len) \
|
||||||
|
{ \
|
||||||
|
if (unlikely(!fs_info) || fs_info->sectorsize == PAGE_SIZE) { \
|
||||||
|
set_page_func(page); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
btrfs_subpage_clamp_range(page, &start, &len); \
|
||||||
|
btrfs_subpage_set_##name(fs_info, page, start, len); \
|
||||||
|
} \
|
||||||
|
void btrfs_page_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len) \
|
||||||
|
{ \
|
||||||
|
if (unlikely(!fs_info) || fs_info->sectorsize == PAGE_SIZE) { \
|
||||||
|
clear_page_func(page); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
btrfs_subpage_clamp_range(page, &start, &len); \
|
||||||
|
btrfs_subpage_clear_##name(fs_info, page, start, len); \
|
||||||
|
} \
|
||||||
|
bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len) \
|
||||||
|
{ \
|
||||||
|
if (unlikely(!fs_info) || fs_info->sectorsize == PAGE_SIZE) \
|
||||||
|
return test_page_func(page); \
|
||||||
|
btrfs_subpage_clamp_range(page, &start, &len); \
|
||||||
|
return btrfs_subpage_test_##name(fs_info, page, start, len); \
|
||||||
}
|
}
|
||||||
IMPLEMENT_BTRFS_PAGE_OPS(uptodate, SetPageUptodate, ClearPageUptodate,
|
IMPLEMENT_BTRFS_PAGE_OPS(uptodate, SetPageUptodate, ClearPageUptodate,
|
||||||
PageUptodate);
|
PageUptodate);
|
||||||
|
@ -72,6 +72,10 @@ void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info,
|
|||||||
* btrfs_page_*() are for call sites where the page can either be subpage
|
* btrfs_page_*() are for call sites where the page can either be subpage
|
||||||
* specific or regular page. The function will handle both cases.
|
* specific or regular page. The function will handle both cases.
|
||||||
* But the range still needs to be inside the page.
|
* But the range still needs to be inside the page.
|
||||||
|
*
|
||||||
|
* btrfs_page_clamp_*() are similar to btrfs_page_*(), except the range doesn't
|
||||||
|
* need to be inside the page. Those functions will truncate the range
|
||||||
|
* automatically.
|
||||||
*/
|
*/
|
||||||
#define DECLARE_BTRFS_SUBPAGE_OPS(name) \
|
#define DECLARE_BTRFS_SUBPAGE_OPS(name) \
|
||||||
void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \
|
void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
@ -85,6 +89,12 @@ void btrfs_page_set_##name(const struct btrfs_fs_info *fs_info, \
|
|||||||
void btrfs_page_clear_##name(const struct btrfs_fs_info *fs_info, \
|
void btrfs_page_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
struct page *page, u64 start, u32 len); \
|
struct page *page, u64 start, u32 len); \
|
||||||
bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \
|
bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len); \
|
||||||
|
void btrfs_page_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len); \
|
||||||
|
void btrfs_page_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
|
struct page *page, u64 start, u32 len); \
|
||||||
|
bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||||
struct page *page, u64 start, u32 len);
|
struct page *page, u64 start, u32 len);
|
||||||
|
|
||||||
DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
|
DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
|
||||||
|
Loading…
Reference in New Issue
Block a user