From: Li Nan <linan122@huawei.com>
narrow_write_error() currently returns true when setting badblocks fails.
Instead, return actual status of all retried writes, succeeding only when
all retried writes complete successfully. This gives upper layers accurate
information about write outcomes.
When setting badblocks fails, mark the device as faulty and return at once.
No need to continue processing remaining sections in such cases.
Signed-off-by: Li Nan <linan122@huawei.com>
---
drivers/md/raid1.c | 17 +++++++++--------
drivers/md/raid10.c | 15 +++++++++------
2 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e65d104cb9c5..090fe8f71224 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2541,11 +2541,15 @@ static bool narrow_write_error(struct r1bio *r1_bio, int i)
bio_trim(wbio, sector - r1_bio->sector, sectors);
wbio->bi_iter.bi_sector += rdev->data_offset;
- if (submit_bio_wait(wbio) < 0)
+ if (submit_bio_wait(wbio)) {
/* failure! */
- ok = rdev_set_badblocks(rdev, sector,
- sectors, 0)
- && ok;
+ ok = false;
+ if (!rdev_set_badblocks(rdev, sector, sectors, 0)) {
+ md_error(mddev, rdev);
+ bio_put(wbio);
+ break;
+ }
+ }
bio_put(wbio);
sect_to_write -= sectors;
@@ -2596,10 +2600,7 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
* errors.
*/
fail = true;
- if (!narrow_write_error(r1_bio, m))
- md_error(conf->mddev,
- conf->mirrors[m].rdev);
- /* an I/O failed, we can't clear the bitmap */
+ narrow_write_error(r1_bio, m);
rdev_dec_pending(conf->mirrors[m].rdev,
conf->mddev);
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 231177cee928..9c43c380d7e8 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2820,11 +2820,15 @@ static bool narrow_write_error(struct r10bio *r10_bio, int i)
choose_data_offset(r10_bio, rdev);
wbio->bi_opf = REQ_OP_WRITE;
- if (submit_bio_wait(wbio) < 0)
+ if (submit_bio_wait(wbio)) {
/* Failure! */
- ok = rdev_set_badblocks(rdev, wsector,
- sectors, 0)
- && ok;
+ ok = false;
+ if (!rdev_set_badblocks(rdev, wsector, sectors, 0)) {
+ md_error(mddev, rdev);
+ bio_put(wbio);
+ break;
+ }
+ }
bio_put(wbio);
sect_to_write -= sectors;
@@ -2936,8 +2940,7 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
rdev_dec_pending(rdev, conf->mddev);
} else if (bio != NULL && bio->bi_status) {
fail = true;
- if (!narrow_write_error(r10_bio, m))
- md_error(conf->mddev, rdev);
+ narrow_write_error(r10_bio, m);
rdev_dec_pending(rdev, conf->mddev);
}
bio = r10_bio->devs[m].repl_bio;
--
2.39.2
Hi,
在 2025/11/6 19:59, linan666@huaweicloud.com 写道:
> From: Li Nan <linan122@huawei.com>
>
> narrow_write_error() currently returns true when setting badblocks fails.
> Instead, return actual status of all retried writes, succeeding only when
> all retried writes complete successfully. This gives upper layers accurate
> information about write outcomes.
>
> When setting badblocks fails, mark the device as faulty and return at once.
> No need to continue processing remaining sections in such cases.
>
> Signed-off-by: Li Nan <linan122@huawei.com>
> ---
> drivers/md/raid1.c | 17 +++++++++--------
> drivers/md/raid10.c | 15 +++++++++------
> 2 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index e65d104cb9c5..090fe8f71224 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -2541,11 +2541,15 @@ static bool narrow_write_error(struct r1bio *r1_bio, int i)
> bio_trim(wbio, sector - r1_bio->sector, sectors);
> wbio->bi_iter.bi_sector += rdev->data_offset;
>
> - if (submit_bio_wait(wbio) < 0)
> + if (submit_bio_wait(wbio)) {
> /* failure! */
> - ok = rdev_set_badblocks(rdev, sector,
> - sectors, 0)
> - && ok;
> + ok = false;
> + if (!rdev_set_badblocks(rdev, sector, sectors, 0)) {
> + md_error(mddev, rdev);
> + bio_put(wbio);
> + break;
> + }
> + }
>
> bio_put(wbio);
> sect_to_write -= sectors;
> @@ -2596,10 +2600,7 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
> * errors.
> */
> fail = true;
> - if (!narrow_write_error(r1_bio, m))
> - md_error(conf->mddev,
> - conf->mirrors[m].rdev);
> - /* an I/O failed, we can't clear the bitmap */
> + narrow_write_error(r1_bio, m);
Now that return value is not used, you can make this helper void.
Thanks,
Kuai
> rdev_dec_pending(conf->mirrors[m].rdev,
> conf->mddev);
> }
> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
> index 231177cee928..9c43c380d7e8 100644
> --- a/drivers/md/raid10.c
> +++ b/drivers/md/raid10.c
> @@ -2820,11 +2820,15 @@ static bool narrow_write_error(struct r10bio *r10_bio, int i)
> choose_data_offset(r10_bio, rdev);
> wbio->bi_opf = REQ_OP_WRITE;
>
> - if (submit_bio_wait(wbio) < 0)
> + if (submit_bio_wait(wbio)) {
> /* Failure! */
> - ok = rdev_set_badblocks(rdev, wsector,
> - sectors, 0)
> - && ok;
> + ok = false;
> + if (!rdev_set_badblocks(rdev, wsector, sectors, 0)) {
> + md_error(mddev, rdev);
> + bio_put(wbio);
> + break;
> + }
> + }
>
> bio_put(wbio);
> sect_to_write -= sectors;
> @@ -2936,8 +2940,7 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
> rdev_dec_pending(rdev, conf->mddev);
> } else if (bio != NULL && bio->bi_status) {
> fail = true;
> - if (!narrow_write_error(r10_bio, m))
> - md_error(conf->mddev, rdev);
> + narrow_write_error(r10_bio, m);
> rdev_dec_pending(rdev, conf->mddev);
> }
> bio = r10_bio->devs[m].repl_bio;
在 2025/11/8 18:07, Yu Kuai 写道:
> Hi,
>
> 在 2025/11/6 19:59, linan666@huaweicloud.com 写道:
>> From: Li Nan <linan122@huawei.com>
>>
>> narrow_write_error() currently returns true when setting badblocks fails.
>> Instead, return actual status of all retried writes, succeeding only when
>> all retried writes complete successfully. This gives upper layers accurate
>> information about write outcomes.
>>
>> When setting badblocks fails, mark the device as faulty and return at once.
>> No need to continue processing remaining sections in such cases.
>>
>> Signed-off-by: Li Nan <linan122@huawei.com>
>> ---
>> drivers/md/raid1.c | 17 +++++++++--------
>> drivers/md/raid10.c | 15 +++++++++------
>> 2 files changed, 18 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
>> index e65d104cb9c5..090fe8f71224 100644
>> --- a/drivers/md/raid1.c
>> +++ b/drivers/md/raid1.c
>> @@ -2541,11 +2541,15 @@ static bool narrow_write_error(struct r1bio *r1_bio, int i)
>> bio_trim(wbio, sector - r1_bio->sector, sectors);
>> wbio->bi_iter.bi_sector += rdev->data_offset;
>>
>> - if (submit_bio_wait(wbio) < 0)
>> + if (submit_bio_wait(wbio)) {
>> /* failure! */
>> - ok = rdev_set_badblocks(rdev, sector,
>> - sectors, 0)
>> - && ok;
>> + ok = false;
>> + if (!rdev_set_badblocks(rdev, sector, sectors, 0)) {
>> + md_error(mddev, rdev);
>> + bio_put(wbio);
>> + break;
>> + }
>> + }
>>
>> bio_put(wbio);
>> sect_to_write -= sectors;
>> @@ -2596,10 +2600,7 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
>> * errors.
>> */
>> fail = true;
>> - if (!narrow_write_error(r1_bio, m))
>> - md_error(conf->mddev,
>> - conf->mirrors[m].rdev);
>> - /* an I/O failed, we can't clear the bitmap */
>> + narrow_write_error(r1_bio, m);
>
> Now that return value is not used, you can make this helper void.
>
> Thanks,
> Kuai
>
Hi, Kuai
In v1, I changed return type of narrow_write_error() to void.
But a better return value will help Akagi's fix:
https://lore.kernel.org/all/8136b746-50c9-51eb-483b-f2661e86d3eb@huaweicloud.com/
--
Thanks,
Nan
Hi,
在 2025/11/10 19:56, Li Nan 写道:
>
>
> 在 2025/11/8 18:07, Yu Kuai 写道:
>> Hi,
>>
>> 在 2025/11/6 19:59, linan666@huaweicloud.com 写道:
>>> From: Li Nan <linan122@huawei.com>
>>>
>>> narrow_write_error() currently returns true when setting badblocks
>>> fails.
>>> Instead, return actual status of all retried writes, succeeding only
>>> when
>>> all retried writes complete successfully. This gives upper layers
>>> accurate
>>> information about write outcomes.
>>>
>>> When setting badblocks fails, mark the device as faulty and return
>>> at once.
>>> No need to continue processing remaining sections in such cases.
>>>
>>> Signed-off-by: Li Nan <linan122@huawei.com>
>>> ---
>>> drivers/md/raid1.c | 17 +++++++++--------
>>> drivers/md/raid10.c | 15 +++++++++------
>>> 2 files changed, 18 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
>>> index e65d104cb9c5..090fe8f71224 100644
>>> --- a/drivers/md/raid1.c
>>> +++ b/drivers/md/raid1.c
>>> @@ -2541,11 +2541,15 @@ static bool narrow_write_error(struct r1bio
>>> *r1_bio, int i)
>>> bio_trim(wbio, sector - r1_bio->sector, sectors);
>>> wbio->bi_iter.bi_sector += rdev->data_offset;
>>> - if (submit_bio_wait(wbio) < 0)
>>> + if (submit_bio_wait(wbio)) {
>>> /* failure! */
>>> - ok = rdev_set_badblocks(rdev, sector,
>>> - sectors, 0)
>>> - && ok;
>>> + ok = false;
>>> + if (!rdev_set_badblocks(rdev, sector, sectors, 0)) {
>>> + md_error(mddev, rdev);
>>> + bio_put(wbio);
>>> + break;
>>> + }
>>> + }
>>> bio_put(wbio);
>>> sect_to_write -= sectors;
>>> @@ -2596,10 +2600,7 @@ static void handle_write_finished(struct
>>> r1conf *conf, struct r1bio *r1_bio)
>>> * errors.
>>> */
>>> fail = true;
>>> - if (!narrow_write_error(r1_bio, m))
>>> - md_error(conf->mddev,
>>> - conf->mirrors[m].rdev);
>>> - /* an I/O failed, we can't clear the bitmap */
>>> + narrow_write_error(r1_bio, m);
>>
>> Now that return value is not used, you can make this helper void.
>>
>> Thanks,
>> Kuai
>>
>
> Hi, Kuai
>
> In v1, I changed return type of narrow_write_error() to void.
> But a better return value will help Akagi's fix:
> https://lore.kernel.org/all/8136b746-50c9-51eb-483b-f2661e86d3eb@huaweicloud.com/
>
>
Please change to void now, people who want to use the return value later can
change return type
--
Thanks,
Kuai
© 2016 - 2025 Red Hat, Inc.