Re: [PATCH 03/15] md: use folio for bb_folio
From: Li Nan
Date: Tue Jan 20 2026 - 06:49:21 EST
在 2026/1/19 11:03, Xiao Ni 写道:
On Wed, Dec 17, 2025 at 8:11 PM <linan666@xxxxxxxxxxxxxxx> wrote:
From: Li Nan <linan122@xxxxxxxxxx>
Convert bio_page to bio_folio and use it throughout.
Signed-off-by: Li Nan <linan122@xxxxxxxxxx>
---
drivers/md/md.h | 3 ++-
drivers/md/md.c | 25 +++++++++++++------------
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 410f8a6b75e7..aa6d9df50fd0 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -144,7 +144,8 @@ struct md_rdev {
struct block_device *bdev; /* block device handle */
struct file *bdev_file; /* Handle from open for bdev */
- struct page *sb_page, *bb_page;
+ struct page *sb_page;
+ struct folio *bb_folio;
int sb_loaded;
__u64 sb_events;
sector_t data_offset; /* start of data in array */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9dfd6f8da5b8..0732bbcdb95d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1073,9 +1073,9 @@ void md_rdev_clear(struct md_rdev *rdev)
rdev->sb_start = 0;
rdev->sectors = 0;
}
- if (rdev->bb_page) {
- put_page(rdev->bb_page);
- rdev->bb_page = NULL;
+ if (rdev->bb_folio) {
+ folio_put(rdev->bb_folio);
+ rdev->bb_folio = NULL;
}
badblocks_exit(&rdev->badblocks);
}
@@ -1909,9 +1909,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
rdev->desc_nr = le32_to_cpu(sb->dev_number);
- if (!rdev->bb_page) {
- rdev->bb_page = alloc_page(GFP_KERNEL);
- if (!rdev->bb_page)
+ if (!rdev->bb_folio) {
+ rdev->bb_folio = folio_alloc(GFP_KERNEL, 0);
+
+ if (!rdev->bb_folio)
return -ENOMEM;
}
if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BAD_BLOCKS) &&
@@ -1930,10 +1931,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
if (offset == 0)
return -EINVAL;
bb_sector = (long long)offset;
- if (!sync_page_io(rdev, bb_sector, sectors << 9,
- rdev->bb_page, REQ_OP_READ, true))
+ if (!sync_folio_io(rdev, bb_sector, sectors << 9, 0,
+ rdev->bb_folio, REQ_OP_READ, true))
return -EIO;
- bbp = (__le64 *)page_address(rdev->bb_page);
+ bbp = (__le64 *)folio_address(rdev->bb_folio);
rdev->badblocks.shift = sb->bblog_shift;
for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
u64 bb = le64_to_cpu(*bbp);
@@ -2300,7 +2301,7 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
md_error(mddev, rdev);
else {
struct badblocks *bb = &rdev->badblocks;
- __le64 *bbp = (__le64 *)page_address(rdev->bb_page);
+ __le64 *bbp = (__le64 *)folio_address(rdev->bb_folio);
u64 *p = bb->page;
sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS);
if (bb->changed) {
@@ -2953,7 +2954,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
md_write_metadata(mddev, rdev,
rdev->badblocks.sector,
rdev->badblocks.size << 9,
- rdev->bb_page, 0);
+ folio_page(rdev->bb_folio, 0), 0);
rdev->badblocks.size = 0;
}
@@ -3809,7 +3810,7 @@ int md_rdev_init(struct md_rdev *rdev)
rdev->sb_events = 0;
rdev->last_read_error = 0;
rdev->sb_loaded = 0;
- rdev->bb_page = NULL;
+ rdev->bb_folio = NULL;
atomic_set(&rdev->nr_pending, 0);
atomic_set(&rdev->read_errors, 0);
atomic_set(&rdev->corrected_errors, 0);
--
2.39.2
Hi Nan
Bad block page is only one single page. I don't think it's necessary
to use folio here. And it uses folio_page to get the page again. Or do
you plan to replace all page apis to folio apis? Looking through all
patches, sync_page_io is not removed. In patch02, it says sync_page_io
will be removed. So maybe it's better to switch bb_page to bb_folio in
your second patch set? And this patch set only focuses on replacing
sync pages with folio. It's my 2 cents point. If you think it's better
to change the bad block page here, I'm still ok.
Best Regards
Xiao
Hi Xiao,
Thanks for your review. Move it to next patch set is fine. I will delete
this patch in v2.
--
Thanks,
Nan