From: Li Nan <linan122@huawei.com>
Convert bio_page to bio_folio and use it throughout.
Signed-off-by: Li Nan <linan122@huawei.com>
---
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
On Wed, Dec 17, 2025 at 8:11 PM <linan666@huaweicloud.com> wrote:
>
> From: Li Nan <linan122@huawei.com>
>
> Convert bio_page to bio_folio and use it throughout.
>
> Signed-off-by: Li Nan <linan122@huawei.com>
> ---
> 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
在 2026/1/19 11:03, Xiao Ni 写道:
> On Wed, Dec 17, 2025 at 8:11 PM <linan666@huaweicloud.com> wrote:
>>
>> From: Li Nan <linan122@huawei.com>
>>
>> Convert bio_page to bio_folio and use it throughout.
>>
>> Signed-off-by: Li Nan <linan122@huawei.com>
>> ---
>> 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
© 2016 - 2026 Red Hat, Inc.