btrfs: pass a physical address to btrfs_repair_io_failure()
authorChristoph Hellwig <hch@lst.de>
Wed, 9 Apr 2025 11:10:37 +0000 (13:10 +0200)
committerDavid Sterba <dsterba@suse.com>
Thu, 15 May 2025 12:30:46 +0000 (14:30 +0200)
Using physical address has the following advantages:

- All involved callers only need a single pointer
  Instead of the old @folio + @offset pair.

- No complex poking into the bio_vec structure
  As a bio_vec can be single or multiple paged, grabbing the real page
  can be quite complex if the bio_vec is a multi-page one.

  Instead bvec_phys() will always give a single physical address, and it
  cab be easily converted to a page.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/bio.c
fs/btrfs/bio.h
fs/btrfs/disk-io.c

index f602dda99af02970fa405ffa84e7c6f5856d88b4..a3ee9a976f6fa5d0af475e2de04f9c2efbdcfd78 100644 (file)
@@ -192,7 +192,7 @@ static void btrfs_end_repair_bio(struct btrfs_bio *repair_bbio,
                btrfs_repair_io_failure(fs_info, btrfs_ino(inode),
                                  repair_bbio->file_offset, fs_info->sectorsize,
                                  repair_bbio->saved_iter.bi_sector << SECTOR_SHIFT,
-                                 page_folio(bv->bv_page), bv->bv_offset, mirror);
+                                 bvec_phys(bv), mirror);
        } while (mirror != fbio->bbio->mirror_num);
 
 done:
@@ -803,8 +803,7 @@ void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num)
  * freeing the bio.
  */
 int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
-                           u64 length, u64 logical, struct folio *folio,
-                           unsigned int folio_offset, int mirror_num)
+                           u64 length, u64 logical, phys_addr_t paddr, int mirror_num)
 {
        struct btrfs_io_stripe smap = { 0 };
        struct bio_vec bvec;
@@ -835,8 +834,7 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
 
        bio_init(&bio, smap.dev->bdev, &bvec, 1, REQ_OP_WRITE | REQ_SYNC);
        bio.bi_iter.bi_sector = smap.physical >> SECTOR_SHIFT;
-       ret = bio_add_folio(&bio, folio, length, folio_offset);
-       ASSERT(ret);
+       __bio_add_page(&bio, phys_to_page(paddr), length, offset_in_page(paddr));
        ret = submit_bio_wait(&bio);
        if (ret) {
                /* try to remap that extent elsewhere? */
index e2fe16074ad6558cd7e604cd0aab0ac0fae4a68d..dc2eb43b70970b110c47697f462b81013de5beca 100644 (file)
@@ -110,7 +110,6 @@ void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status);
 void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num);
 void btrfs_submit_repair_write(struct btrfs_bio *bbio, int mirror_num, bool dev_replace);
 int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
-                           u64 length, u64 logical, struct folio *folio,
-                           unsigned int folio_offset, int mirror_num);
+                           u64 length, u64 logical, phys_addr_t paddr, int mirror_num);
 
 #endif
index 59da809b7d57ab6138cd3babfac1b2beb1b1d5bd..280bc0ee60465f0e03bd5b80f965aac4b9c8450a 100644 (file)
@@ -193,10 +193,11 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
                u64 end = min_t(u64, eb->start + eb->len,
                                folio_pos(folio) + eb->folio_size);
                u32 len = end - start;
+               phys_addr_t paddr = PFN_PHYS(folio_pfn(folio)) +
+                                   offset_in_folio(folio, start);
 
-               ret = btrfs_repair_io_failure(fs_info, 0, start, len,
-                                             start, folio, offset_in_folio(folio, start),
-                                             mirror_num);
+               ret = btrfs_repair_io_failure(fs_info, 0, start, len, start,
+                                             paddr, mirror_num);
                if (ret)
                        break;
        }