mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
md/raid10: consistently fail atomic writes that require splitting
RAID10 currently handles one badblock path explicitly by failing atomic
writes with EIO. However, another badblock path can also reduce the
writable range and force the bio through bio_submit_split_bioset(),
which implicitly completes the bio with EINVAL.
Fix this by handling atomic writes in the common split check. If RAID10
determines that an atomic write would require splitting, complete the
bio with EIO.
Fixes: a1d9b4fd42 ("md/raid10: Atomic write support")
Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com>
Reviewed-by: Yu Kuai <yukuai@fygo.io>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://patch.msgid.link/20260710101521.1714-4-abd.masalkhi@gmail.com
Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
committed by
Yu Kuai
parent
86d801e895
commit
3409bf2f96
@@ -1333,6 +1333,7 @@ static bool raid10_write_request(struct mddev *mddev, struct bio *bio,
|
||||
int i, k;
|
||||
sector_t sectors;
|
||||
int max_sectors;
|
||||
bool atomic = bio->bi_opf & REQ_ATOMIC;
|
||||
|
||||
if ((mddev_is_clustered(mddev) &&
|
||||
mddev->cluster_ops->area_resyncing(mddev, WRITE,
|
||||
@@ -1420,16 +1421,6 @@ static bool raid10_write_request(struct mddev *mddev, struct bio *bio,
|
||||
if (is_bad) {
|
||||
int good_sectors;
|
||||
|
||||
/*
|
||||
* We cannot atomically write this, so just
|
||||
* error in that case. It could be possible to
|
||||
* atomically write other mirrors, but the
|
||||
* complexity of supporting that is not worth
|
||||
* the benefit.
|
||||
*/
|
||||
if (bio->bi_opf & REQ_ATOMIC)
|
||||
goto err_handle;
|
||||
|
||||
good_sectors = first_bad - dev_sector;
|
||||
if (good_sectors < max_sectors)
|
||||
max_sectors = good_sectors;
|
||||
@@ -1449,6 +1440,9 @@ static bool raid10_write_request(struct mddev *mddev, struct bio *bio,
|
||||
r10_bio->sectors = max_sectors;
|
||||
|
||||
if (r10_bio->sectors < bio_sectors(bio)) {
|
||||
if (atomic)
|
||||
goto err_handle;
|
||||
|
||||
allow_barrier(conf);
|
||||
bio = bio_submit_split_bioset(bio, r10_bio->sectors,
|
||||
&conf->bio_split);
|
||||
|
||||
Reference in New Issue
Block a user