btrfs: migrate to use folio private instead of page private
As a cleanup and preparation for future folio migration, this patch would replace all page->private to folio version. This includes: - PagePrivate() -> folio_test_private() - page->private -> folio_get_private() - attach_page_private() -> folio_attach_private() - detach_page_private() -> folio_detach_private() Since we're here, also remove the forced cast on page->private, since it's (void *) already, we don't really need to do the cast. For now even if we missed some call sites, it won't cause any problem yet, as we're only using order 0 folio (single page), thus all those folio/page flags should be synced. But for the future conversion to utilize higher order folio, the page <-> folio flag sync is no longer guaranteed, thus we have to migrate to utilize folio flags. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> 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
4cea422a77
commit
cfbf07e278
@ -562,11 +562,13 @@ update:
|
||||
|
||||
static void begin_page_read(struct btrfs_fs_info *fs_info, struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
ASSERT(PageLocked(page));
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return;
|
||||
|
||||
ASSERT(PagePrivate(page));
|
||||
ASSERT(folio_test_private(folio));
|
||||
btrfs_subpage_start_reader(fs_info, page, page_offset(page), PAGE_SIZE);
|
||||
}
|
||||
|
||||
@ -865,6 +867,7 @@ static int attach_extent_buffer_page(struct extent_buffer *eb,
|
||||
struct page *page,
|
||||
struct btrfs_subpage *prealloc)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
int ret = 0;
|
||||
|
||||
@ -878,22 +881,22 @@ static int attach_extent_buffer_page(struct extent_buffer *eb,
|
||||
lockdep_assert_held(&page->mapping->private_lock);
|
||||
|
||||
if (fs_info->nodesize >= PAGE_SIZE) {
|
||||
if (!PagePrivate(page))
|
||||
attach_page_private(page, eb);
|
||||
if (!folio_test_private(folio))
|
||||
folio_attach_private(folio, eb);
|
||||
else
|
||||
WARN_ON(page->private != (unsigned long)eb);
|
||||
WARN_ON(folio_get_private(folio) != eb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Already mapped, just free prealloc */
|
||||
if (PagePrivate(page)) {
|
||||
if (folio_test_private(folio)) {
|
||||
btrfs_free_subpage(prealloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (prealloc)
|
||||
/* Has preallocated memory for subpage */
|
||||
attach_page_private(page, prealloc);
|
||||
folio_attach_private(folio, prealloc);
|
||||
else
|
||||
/* Do new allocation to attach subpage */
|
||||
ret = btrfs_attach_subpage(fs_info, page,
|
||||
@ -903,11 +906,12 @@ static int attach_extent_buffer_page(struct extent_buffer *eb,
|
||||
|
||||
int set_page_extent_mapped(struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_fs_info *fs_info;
|
||||
|
||||
ASSERT(page->mapping);
|
||||
|
||||
if (PagePrivate(page))
|
||||
if (folio_test_private(folio))
|
||||
return 0;
|
||||
|
||||
fs_info = btrfs_sb(page->mapping->host->i_sb);
|
||||
@ -915,24 +919,25 @@ int set_page_extent_mapped(struct page *page)
|
||||
if (btrfs_is_subpage(fs_info, page))
|
||||
return btrfs_attach_subpage(fs_info, page, BTRFS_SUBPAGE_DATA);
|
||||
|
||||
attach_page_private(page, (void *)EXTENT_PAGE_PRIVATE);
|
||||
folio_attach_private(folio, (void *)EXTENT_FOLIO_PRIVATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear_page_extent_mapped(struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_fs_info *fs_info;
|
||||
|
||||
ASSERT(page->mapping);
|
||||
|
||||
if (!PagePrivate(page))
|
||||
if (!folio_test_private(folio))
|
||||
return;
|
||||
|
||||
fs_info = btrfs_sb(page->mapping->host->i_sb);
|
||||
if (btrfs_is_subpage(fs_info, page))
|
||||
return btrfs_detach_subpage(fs_info, page);
|
||||
|
||||
detach_page_private(page);
|
||||
folio_detach_private(folio);
|
||||
}
|
||||
|
||||
static struct extent_map *
|
||||
@ -1240,7 +1245,8 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
|
||||
static void find_next_dirty_byte(struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 *start, u64 *end)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
struct btrfs_subpage_info *spi = fs_info->subpage_info;
|
||||
u64 orig_start = *start;
|
||||
/* Declare as unsigned long so we can use bitmap ops */
|
||||
@ -1725,6 +1731,7 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb,
|
||||
static int submit_eb_subpage(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb);
|
||||
struct folio *folio = page_folio(page);
|
||||
int submitted = 0;
|
||||
u64 page_start = page_offset(page);
|
||||
int bit_start = 0;
|
||||
@ -1732,7 +1739,7 @@ static int submit_eb_subpage(struct page *page, struct writeback_control *wbc)
|
||||
|
||||
/* Lock and write each dirty extent buffers in the range */
|
||||
while (bit_start < fs_info->subpage_info->bitmap_nr_bits) {
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
struct extent_buffer *eb;
|
||||
unsigned long flags;
|
||||
u64 start;
|
||||
@ -1742,7 +1749,7 @@ static int submit_eb_subpage(struct page *page, struct writeback_control *wbc)
|
||||
* in the meantime.
|
||||
*/
|
||||
spin_lock(&page->mapping->private_lock);
|
||||
if (!PagePrivate(page)) {
|
||||
if (!folio_test_private(folio)) {
|
||||
spin_unlock(&page->mapping->private_lock);
|
||||
break;
|
||||
}
|
||||
@ -1807,22 +1814,23 @@ static int submit_eb_page(struct page *page, struct btrfs_eb_write_context *ctx)
|
||||
{
|
||||
struct writeback_control *wbc = ctx->wbc;
|
||||
struct address_space *mapping = page->mapping;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct extent_buffer *eb;
|
||||
int ret;
|
||||
|
||||
if (!PagePrivate(page))
|
||||
if (!folio_test_private(folio))
|
||||
return 0;
|
||||
|
||||
if (btrfs_sb(page->mapping->host->i_sb)->nodesize < PAGE_SIZE)
|
||||
return submit_eb_subpage(page, wbc);
|
||||
|
||||
spin_lock(&mapping->private_lock);
|
||||
if (!PagePrivate(page)) {
|
||||
if (!folio_test_private(folio)) {
|
||||
spin_unlock(&mapping->private_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
eb = (struct extent_buffer *)page->private;
|
||||
eb = folio_get_private(folio);
|
||||
|
||||
/*
|
||||
* Shouldn't happen and normally this would be a BUG_ON but no point
|
||||
@ -3060,12 +3068,13 @@ static int extent_buffer_under_io(const struct extent_buffer *eb)
|
||||
|
||||
static bool page_range_has_eb(struct btrfs_fs_info *fs_info, struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
lockdep_assert_held(&page->mapping->private_lock);
|
||||
|
||||
if (PagePrivate(page)) {
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
if (folio_test_private(folio)) {
|
||||
subpage = folio_get_private(folio);
|
||||
if (atomic_read(&subpage->eb_refs))
|
||||
return true;
|
||||
/*
|
||||
@ -3082,15 +3091,16 @@ static void detach_extent_buffer_page(struct extent_buffer *eb, struct page *pag
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
const bool mapped = !test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags);
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
/*
|
||||
* For mapped eb, we're going to change the page private, which should
|
||||
* For mapped eb, we're going to change the folio private, which should
|
||||
* be done under the private_lock.
|
||||
*/
|
||||
if (mapped)
|
||||
spin_lock(&page->mapping->private_lock);
|
||||
|
||||
if (!PagePrivate(page)) {
|
||||
if (!folio_test_private(folio)) {
|
||||
if (mapped)
|
||||
spin_unlock(&page->mapping->private_lock);
|
||||
return;
|
||||
@ -3101,19 +3111,15 @@ static void detach_extent_buffer_page(struct extent_buffer *eb, struct page *pag
|
||||
* We do this since we'll remove the pages after we've
|
||||
* removed the eb from the radix tree, so we could race
|
||||
* and have this page now attached to the new eb. So
|
||||
* only clear page_private if it's still connected to
|
||||
* only clear folio if it's still connected to
|
||||
* this eb.
|
||||
*/
|
||||
if (PagePrivate(page) &&
|
||||
page->private == (unsigned long)eb) {
|
||||
if (folio_test_private(folio) && folio_get_private(folio) == eb) {
|
||||
BUG_ON(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
|
||||
BUG_ON(PageDirty(page));
|
||||
BUG_ON(PageWriteback(page));
|
||||
/*
|
||||
* We need to make sure we haven't be attached
|
||||
* to a new eb.
|
||||
*/
|
||||
detach_page_private(page);
|
||||
/* We need to make sure we haven't be attached to a new eb. */
|
||||
folio_detach_private(folio);
|
||||
}
|
||||
if (mapped)
|
||||
spin_unlock(&page->mapping->private_lock);
|
||||
@ -3121,9 +3127,9 @@ static void detach_extent_buffer_page(struct extent_buffer *eb, struct page *pag
|
||||
}
|
||||
|
||||
/*
|
||||
* For subpage, we can have dummy eb with page private. In this case,
|
||||
* we can directly detach the private as such page is only attached to
|
||||
* one dummy eb, no sharing.
|
||||
* For subpage, we can have dummy eb with folio private attached. In
|
||||
* this case, we can directly detach the private as such folio is only
|
||||
* attached to one dummy eb, no sharing.
|
||||
*/
|
||||
if (!mapped) {
|
||||
btrfs_detach_subpage(fs_info, page);
|
||||
@ -3133,7 +3139,7 @@ static void detach_extent_buffer_page(struct extent_buffer *eb, struct page *pag
|
||||
btrfs_page_dec_eb_refs(fs_info, page);
|
||||
|
||||
/*
|
||||
* We can only detach the page private if there are no other ebs in the
|
||||
* We can only detach the folio private if there are no other ebs in the
|
||||
* page range and no unfinished IO.
|
||||
*/
|
||||
if (!page_range_has_eb(fs_info, page))
|
||||
@ -3410,6 +3416,7 @@ free_eb:
|
||||
static struct extent_buffer *grab_extent_buffer(
|
||||
struct btrfs_fs_info *fs_info, struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct extent_buffer *exists;
|
||||
|
||||
/*
|
||||
@ -3421,21 +3428,21 @@ static struct extent_buffer *grab_extent_buffer(
|
||||
return NULL;
|
||||
|
||||
/* Page not yet attached to an extent buffer */
|
||||
if (!PagePrivate(page))
|
||||
if (!folio_test_private(folio))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* We could have already allocated an eb for this page and attached one
|
||||
* so lets see if we can get a ref on the existing eb, and if we can we
|
||||
* know it's good and we can just return that one, else we know we can
|
||||
* just overwrite page->private.
|
||||
* just overwrite folio private.
|
||||
*/
|
||||
exists = (struct extent_buffer *)page->private;
|
||||
exists = folio_get_private(folio);
|
||||
if (atomic_inc_not_zero(&exists->refs))
|
||||
return exists;
|
||||
|
||||
WARN_ON(PageDirty(page));
|
||||
detach_page_private(page);
|
||||
folio_detach_private(folio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -3519,7 +3526,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
num_pages = num_extent_pages(eb);
|
||||
|
||||
/*
|
||||
* Preallocate page->private for subpage case, so that we won't
|
||||
* Preallocate folio private for subpage case, so that we won't
|
||||
* allocate memory with private_lock nor page lock hold.
|
||||
*
|
||||
* The memory will be freed by attach_extent_buffer_page() or freed
|
||||
@ -3556,7 +3563,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
ASSERT(!ret);
|
||||
/*
|
||||
* To inform we have extra eb under allocation, so that
|
||||
* detach_extent_buffer_page() won't release the page private
|
||||
* detach_extent_buffer_page() won't release the folio private
|
||||
* when the eb hasn't yet been inserted into radix tree.
|
||||
*
|
||||
* The ref will be decreased when the eb released the page, in
|
||||
@ -4520,7 +4527,7 @@ static int try_release_subpage_extent_buffer(struct page *page)
|
||||
struct extent_buffer *eb = NULL;
|
||||
|
||||
/*
|
||||
* Unlike try_release_extent_buffer() which uses page->private
|
||||
* Unlike try_release_extent_buffer() which uses folio private
|
||||
* to grab buffer, for subpage case we rely on radix tree, thus
|
||||
* we need to ensure radix tree consistency.
|
||||
*
|
||||
@ -4560,17 +4567,17 @@ static int try_release_subpage_extent_buffer(struct page *page)
|
||||
|
||||
/*
|
||||
* Here we don't care about the return value, we will always
|
||||
* check the page private at the end. And
|
||||
* check the folio private at the end. And
|
||||
* release_extent_buffer() will release the refs_lock.
|
||||
*/
|
||||
release_extent_buffer(eb);
|
||||
}
|
||||
/*
|
||||
* Finally to check if we have cleared page private, as if we have
|
||||
* released all ebs in the page, the page private should be cleared now.
|
||||
* Finally to check if we have cleared folio private, as if we have
|
||||
* released all ebs in the page, the folio private should be cleared now.
|
||||
*/
|
||||
spin_lock(&page->mapping->private_lock);
|
||||
if (!PagePrivate(page))
|
||||
if (!folio_test_private(page_folio(page)))
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
@ -4581,22 +4588,23 @@ static int try_release_subpage_extent_buffer(struct page *page)
|
||||
|
||||
int try_release_extent_buffer(struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct extent_buffer *eb;
|
||||
|
||||
if (btrfs_sb(page->mapping->host->i_sb)->nodesize < PAGE_SIZE)
|
||||
return try_release_subpage_extent_buffer(page);
|
||||
|
||||
/*
|
||||
* We need to make sure nobody is changing page->private, as we rely on
|
||||
* page->private as the pointer to extent buffer.
|
||||
* We need to make sure nobody is changing folio private, as we rely on
|
||||
* folio private as the pointer to extent buffer.
|
||||
*/
|
||||
spin_lock(&page->mapping->private_lock);
|
||||
if (!PagePrivate(page)) {
|
||||
if (!folio_test_private(folio)) {
|
||||
spin_unlock(&page->mapping->private_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
eb = (struct extent_buffer *)page->private;
|
||||
eb = folio_get_private(folio);
|
||||
BUG_ON(!eb);
|
||||
|
||||
/*
|
||||
|
@ -43,10 +43,10 @@ enum {
|
||||
};
|
||||
|
||||
/*
|
||||
* page->private values. Every page that is controlled by the extent
|
||||
* map has page->private set to one.
|
||||
* Folio private values. Every page that is controlled by the extent map has
|
||||
* folio private set to this value.
|
||||
*/
|
||||
#define EXTENT_PAGE_PRIVATE 1
|
||||
#define EXTENT_FOLIO_PRIVATE 1
|
||||
|
||||
/*
|
||||
* The extent buffer bitmap operations are done with byte granularity instead of
|
||||
|
@ -869,9 +869,9 @@ static int prepare_uptodate_page(struct inode *inode,
|
||||
* released.
|
||||
*
|
||||
* The private flag check is essential for subpage as we need
|
||||
* to store extra bitmap using page->private.
|
||||
* to store extra bitmap using folio private.
|
||||
*/
|
||||
if (page->mapping != inode->i_mapping || !PagePrivate(page)) {
|
||||
if (page->mapping != inode->i_mapping || !folio_test_private(folio)) {
|
||||
unlock_page(page);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
@ -4725,7 +4725,7 @@ again:
|
||||
/*
|
||||
* We unlock the page after the io is completed and then re-lock it
|
||||
* above. release_folio() could have come in between that and cleared
|
||||
* PagePrivate(), but left the page in the mapping. Set the page mapped
|
||||
* folio private, but left the page in the mapping. Set the page mapped
|
||||
* here to make sure it's properly set for the subpage stuff.
|
||||
*/
|
||||
ret = set_page_extent_mapped(page);
|
||||
@ -7851,13 +7851,14 @@ static void btrfs_readahead(struct readahead_control *rac)
|
||||
static void wait_subpage_spinlock(struct page *page)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb);
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return;
|
||||
|
||||
ASSERT(PagePrivate(page) && page->private);
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
subpage = folio_get_private(folio);
|
||||
|
||||
/*
|
||||
* This may look insane as we just acquire the spinlock and release it,
|
||||
|
@ -118,6 +118,7 @@ void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sector
|
||||
int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, enum btrfs_subpage_type type)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
/*
|
||||
@ -127,28 +128,29 @@ int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
|
||||
if (page->mapping)
|
||||
ASSERT(PageLocked(page));
|
||||
|
||||
/* Either not subpage, or the page already has private attached */
|
||||
if (!btrfs_is_subpage(fs_info, page) || PagePrivate(page))
|
||||
/* Either not subpage, or the folio already has private attached. */
|
||||
if (!btrfs_is_subpage(fs_info, page) || folio_test_private(folio))
|
||||
return 0;
|
||||
|
||||
subpage = btrfs_alloc_subpage(fs_info, type);
|
||||
if (IS_ERR(subpage))
|
||||
return PTR_ERR(subpage);
|
||||
|
||||
attach_page_private(page, subpage);
|
||||
folio_attach_private(folio, subpage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
/* Either not subpage, or already detached */
|
||||
if (!btrfs_is_subpage(fs_info, page) || !PagePrivate(page))
|
||||
/* Either not subpage, or the folio already has private attached. */
|
||||
if (!btrfs_is_subpage(fs_info, page) || !folio_test_private(folio))
|
||||
return;
|
||||
|
||||
subpage = detach_page_private(page);
|
||||
subpage = folio_detach_private(folio);
|
||||
ASSERT(subpage);
|
||||
btrfs_free_subpage(subpage);
|
||||
}
|
||||
@ -188,36 +190,38 @@ void btrfs_free_subpage(struct btrfs_subpage *subpage)
|
||||
* This is important for eb allocation, to prevent race with last eb freeing
|
||||
* of the same page.
|
||||
* With the eb_refs increased before the eb inserted into radix tree,
|
||||
* detach_extent_buffer_page() won't detach the page private while we're still
|
||||
* detach_extent_buffer_page() won't detach the folio private while we're still
|
||||
* allocating the extent buffer.
|
||||
*/
|
||||
void btrfs_page_inc_eb_refs(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return;
|
||||
|
||||
ASSERT(PagePrivate(page) && page->mapping);
|
||||
ASSERT(folio_test_private(folio) && page->mapping);
|
||||
lockdep_assert_held(&page->mapping->private_lock);
|
||||
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
subpage = folio_get_private(folio);
|
||||
atomic_inc(&subpage->eb_refs);
|
||||
}
|
||||
|
||||
void btrfs_page_dec_eb_refs(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return;
|
||||
|
||||
ASSERT(PagePrivate(page) && page->mapping);
|
||||
ASSERT(folio_test_private(folio) && page->mapping);
|
||||
lockdep_assert_held(&page->mapping->private_lock);
|
||||
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
subpage = folio_get_private(folio);
|
||||
ASSERT(atomic_read(&subpage->eb_refs));
|
||||
atomic_dec(&subpage->eb_refs);
|
||||
}
|
||||
@ -225,8 +229,10 @@ void btrfs_page_dec_eb_refs(const struct btrfs_fs_info *fs_info,
|
||||
static void btrfs_subpage_assert(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
/* Basic checks */
|
||||
ASSERT(PagePrivate(page) && page->private);
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
|
||||
IS_ALIGNED(len, fs_info->sectorsize));
|
||||
/*
|
||||
@ -241,7 +247,8 @@ static void btrfs_subpage_assert(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
const int nbits = len >> fs_info->sectorsize_bits;
|
||||
|
||||
btrfs_subpage_assert(fs_info, page, start, len);
|
||||
@ -252,7 +259,8 @@ void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
const int nbits = len >> fs_info->sectorsize_bits;
|
||||
bool is_data;
|
||||
bool last;
|
||||
@ -294,7 +302,8 @@ static void btrfs_subpage_clamp_range(struct page *page, u64 *start, u32 *len)
|
||||
void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
const int nbits = (len >> fs_info->sectorsize_bits);
|
||||
int ret;
|
||||
|
||||
@ -308,7 +317,8 @@ void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info,
|
||||
bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
const int nbits = (len >> fs_info->sectorsize_bits);
|
||||
|
||||
btrfs_subpage_assert(fs_info, page, start, len);
|
||||
@ -340,12 +350,14 @@ bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
|
||||
int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
if (unlikely(!fs_info) || !btrfs_is_subpage(fs_info, page)) {
|
||||
lock_page(page);
|
||||
return 0;
|
||||
}
|
||||
lock_page(page);
|
||||
if (!PagePrivate(page) || !page->private) {
|
||||
if (!folio_test_private(folio) || !folio_get_private(folio)) {
|
||||
unlock_page(page);
|
||||
return -EAGAIN;
|
||||
}
|
||||
@ -387,7 +399,8 @@ void btrfs_page_end_writer_lock(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_set_uptodate(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
uptodate, start, len);
|
||||
unsigned long flags;
|
||||
@ -402,7 +415,8 @@ void btrfs_subpage_set_uptodate(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_clear_uptodate(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
uptodate, start, len);
|
||||
unsigned long flags;
|
||||
@ -416,7 +430,8 @@ void btrfs_subpage_clear_uptodate(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_set_dirty(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
dirty, start, len);
|
||||
unsigned long flags;
|
||||
@ -440,7 +455,8 @@ void btrfs_subpage_set_dirty(const struct btrfs_fs_info *fs_info,
|
||||
bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
dirty, start, len);
|
||||
unsigned long flags;
|
||||
@ -467,7 +483,8 @@ void btrfs_subpage_clear_dirty(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_set_writeback(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
writeback, start, len);
|
||||
unsigned long flags;
|
||||
@ -481,7 +498,8 @@ void btrfs_subpage_set_writeback(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_clear_writeback(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
writeback, start, len);
|
||||
unsigned long flags;
|
||||
@ -498,7 +516,8 @@ void btrfs_subpage_clear_writeback(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_set_ordered(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
ordered, start, len);
|
||||
unsigned long flags;
|
||||
@ -512,7 +531,8 @@ void btrfs_subpage_set_ordered(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_clear_ordered(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
ordered, start, len);
|
||||
unsigned long flags;
|
||||
@ -527,7 +547,8 @@ void btrfs_subpage_clear_ordered(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_set_checked(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
checked, start, len);
|
||||
unsigned long flags;
|
||||
@ -542,7 +563,8 @@ void btrfs_subpage_set_checked(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_subpage_clear_checked(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
|
||||
checked, start, len);
|
||||
unsigned long flags;
|
||||
@ -561,7 +583,8 @@ void btrfs_subpage_clear_checked(const struct btrfs_fs_info *fs_info,
|
||||
bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \
|
||||
struct page *page, u64 start, u32 len) \
|
||||
{ \
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private; \
|
||||
struct folio *folio = page_folio(page); \
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio); \
|
||||
unsigned int start_bit = subpage_calc_start_bit(fs_info, page, \
|
||||
name, start, len); \
|
||||
unsigned long flags; \
|
||||
@ -656,7 +679,8 @@ IMPLEMENT_BTRFS_PAGE_OPS(checked, SetPageChecked, ClearPageChecked, PageChecked)
|
||||
void btrfs_page_assert_not_dirty(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page)
|
||||
{
|
||||
struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage = folio_get_private(folio);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_BTRFS_ASSERT))
|
||||
return;
|
||||
@ -665,7 +689,7 @@ void btrfs_page_assert_not_dirty(const struct btrfs_fs_info *fs_info,
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return;
|
||||
|
||||
ASSERT(PagePrivate(page) && page->private);
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
ASSERT(subpage_test_bitmap_all_zero(fs_info, subpage, dirty));
|
||||
}
|
||||
|
||||
@ -687,6 +711,7 @@ void btrfs_page_assert_not_dirty(const struct btrfs_fs_info *fs_info,
|
||||
void btrfs_page_unlock_writer(struct btrfs_fs_info *fs_info, struct page *page,
|
||||
u64 start, u32 len)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
|
||||
ASSERT(PageLocked(page));
|
||||
@ -694,8 +719,8 @@ void btrfs_page_unlock_writer(struct btrfs_fs_info *fs_info, struct page *page,
|
||||
if (!btrfs_is_subpage(fs_info, page))
|
||||
return unlock_page(page);
|
||||
|
||||
ASSERT(PagePrivate(page) && page->private);
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
subpage = folio_get_private(folio);
|
||||
|
||||
/*
|
||||
* For subpage case, there are two types of locked page. With or
|
||||
@ -720,6 +745,7 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
||||
struct page *page, u64 start, u32 len)
|
||||
{
|
||||
struct btrfs_subpage_info *subpage_info = fs_info->subpage_info;
|
||||
struct folio *folio = page_folio(page);
|
||||
struct btrfs_subpage *subpage;
|
||||
unsigned long uptodate_bitmap;
|
||||
unsigned long error_bitmap;
|
||||
@ -729,9 +755,9 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
|
||||
unsigned long checked_bitmap;
|
||||
unsigned long flags;
|
||||
|
||||
ASSERT(PagePrivate(page) && page->private);
|
||||
ASSERT(folio_test_private(folio) && folio_get_private(folio));
|
||||
ASSERT(subpage_info);
|
||||
subpage = (struct btrfs_subpage *)page->private;
|
||||
subpage = folio_get_private(folio);
|
||||
|
||||
spin_lock_irqsave(&subpage->lock, flags);
|
||||
GET_SUBPAGE_BITMAP(subpage, subpage_info, uptodate, &uptodate_bitmap);
|
||||
|
Loading…
Reference in New Issue
Block a user