mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
btrfs: use folios for reading super blocks from the block device
btrfs_read_disk_super() and the zoned super block log comparison go through read_cache_page_gfp() and page_address(), and btrfs_release_disk_super() recovers the page with virt_to_page(). Use mapping_read_folio_gfp(), folio_address(), and virt_to_folio() instead. This removes the last callers of read_cache_page_gfp() and put_page() in btrfs. Compute the super block address with offset_in_folio() as write_dev_supers() does, rather than assuming it is at the start of the page. Assisted-by: Claude:claude-fable-5-1 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Tal Zussman <tz2294@columbia.edu> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
dcfc00dc02
commit
cf7ded644e
|
|
@ -1358,16 +1358,14 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
|
|||
|
||||
void btrfs_release_disk_super(struct btrfs_super_block *super)
|
||||
{
|
||||
struct page *page = virt_to_page(super);
|
||||
|
||||
put_page(page);
|
||||
folio_put(virt_to_folio(super));
|
||||
}
|
||||
|
||||
struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
|
||||
int copy_num, bool drop_cache)
|
||||
{
|
||||
struct btrfs_super_block *super;
|
||||
struct page *page;
|
||||
struct folio *folio;
|
||||
u64 bytenr, bytenr_orig;
|
||||
struct address_space *mapping = bdev->bd_mapping;
|
||||
int ret;
|
||||
|
|
@ -1388,7 +1386,7 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
|
|||
ASSERT(copy_num == 0);
|
||||
|
||||
/*
|
||||
* Drop the page of the primary superblock, so later read will
|
||||
* Drop the folio of the primary superblock, so later read will
|
||||
* always read from the device.
|
||||
*/
|
||||
invalidate_inode_pages2_range(mapping, bytenr >> PAGE_SHIFT,
|
||||
|
|
@ -1396,12 +1394,12 @@ struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
|
|||
}
|
||||
|
||||
filemap_invalidate_lock_shared(mapping);
|
||||
page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
|
||||
folio = mapping_read_folio_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
|
||||
filemap_invalidate_unlock_shared(mapping);
|
||||
if (IS_ERR(page))
|
||||
return ERR_CAST(page);
|
||||
if (IS_ERR(folio))
|
||||
return ERR_CAST(folio);
|
||||
|
||||
super = page_address(page);
|
||||
super = folio_address(folio) + offset_in_folio(folio, bytenr);
|
||||
if (btrfs_super_magic(super) != BTRFS_MAGIC ||
|
||||
btrfs_super_bytenr(super) != bytenr_orig) {
|
||||
btrfs_release_disk_super(super);
|
||||
|
|
|
|||
|
|
@ -123,24 +123,24 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
|
|||
} else if (full[0] && full[1]) {
|
||||
/* Compare two super blocks */
|
||||
struct address_space *mapping = bdev->bd_mapping;
|
||||
struct page *page[BTRFS_NR_SB_LOG_ZONES];
|
||||
struct btrfs_super_block *super[BTRFS_NR_SB_LOG_ZONES];
|
||||
|
||||
for (int i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
|
||||
u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
|
||||
u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
|
||||
BTRFS_SUPER_INFO_SIZE;
|
||||
struct folio *folio;
|
||||
|
||||
filemap_invalidate_lock_shared(mapping);
|
||||
page[i] = read_cache_page_gfp(mapping,
|
||||
bytenr >> PAGE_SHIFT, GFP_NOFS);
|
||||
folio = mapping_read_folio_gfp(mapping, bytenr >> PAGE_SHIFT,
|
||||
GFP_NOFS);
|
||||
filemap_invalidate_unlock_shared(mapping);
|
||||
if (IS_ERR(page[i])) {
|
||||
if (IS_ERR(folio)) {
|
||||
if (i == 1)
|
||||
btrfs_release_disk_super(super[0]);
|
||||
return PTR_ERR(page[i]);
|
||||
return PTR_ERR(folio);
|
||||
}
|
||||
super[i] = page_address(page[i]);
|
||||
super[i] = folio_address(folio) + offset_in_folio(folio, bytenr);
|
||||
}
|
||||
|
||||
if (btrfs_super_generation(super[0]) >
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user