mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
md/raid1: restrict atomic write limits and handle runtime constraints
Restrict the RAID1 atomic write limits by setting chunk_sectors to BARRIER_UNIT_SECTOR_SIZE so that atomic writes never straddle a barrier unit. A bio that passes block-layer validation may still become unserviceable within RAID1 due to bad blocks or write-behind constraints. In the former case, complete the bio with EIO. In the latter case, disable write-behind rather than failing the bio with EIO. Fixes:f2a38abf5f("md/raid1: Atomic write support") Fixes:a4c55c9026("md/raid1: simplify raid1_write_request() error handling") Reviewed-by: John Garry <john.g.garry@oracle.com> Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Reviewed-by: Yu Kuai <yukuai@fygo.io> Link: https://patch.msgid.link/20260710101521.1714-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
parent
c7d34d17ea
commit
86d801e895
|
|
@ -1485,6 +1485,7 @@ static bool raid1_write_request(struct mddev *mddev, struct bio *bio,
|
|||
unsigned long flags;
|
||||
int first_clone;
|
||||
bool write_behind = false;
|
||||
bool atomic = bio->bi_opf & REQ_ATOMIC;
|
||||
bool is_discard = op_is_discard(bio->bi_opf);
|
||||
sector_t sector = bio->bi_iter.bi_sector;
|
||||
|
||||
|
|
@ -1531,6 +1532,8 @@ static bool raid1_write_request(struct mddev *mddev, struct bio *bio,
|
|||
*/
|
||||
if (!is_discard && rdev && test_bit(WriteMostly, &rdev->flags))
|
||||
write_behind = true;
|
||||
if (atomic && max_sectors > BIO_MAX_VECS * (PAGE_SIZE >> 9))
|
||||
write_behind = false;
|
||||
|
||||
r1_bio->bios[i] = NULL;
|
||||
if (!rdev || test_bit(Faulty, &rdev->flags))
|
||||
|
|
@ -1556,19 +1559,6 @@ static bool raid1_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) {
|
||||
bio->bi_status = BLK_STS_NOTSUPP;
|
||||
bio_endio(bio);
|
||||
goto err_dec_pending;
|
||||
}
|
||||
|
||||
good_sectors = first_bad - sector;
|
||||
if (good_sectors < max_sectors)
|
||||
max_sectors = good_sectors;
|
||||
|
|
@ -1589,6 +1579,11 @@ static bool raid1_write_request(struct mddev *mddev, struct bio *bio,
|
|||
max_sectors = min_t(int, max_sectors,
|
||||
BIO_MAX_VECS * (PAGE_SIZE >> 9));
|
||||
if (max_sectors < bio_sectors(bio)) {
|
||||
if (atomic) {
|
||||
bio_io_error(bio);
|
||||
goto err_dec_pending;
|
||||
}
|
||||
|
||||
bio = bio_submit_split_bioset(bio, max_sectors,
|
||||
&conf->bio_split);
|
||||
if (!bio)
|
||||
|
|
@ -3177,6 +3172,7 @@ static int raid1_set_limits(struct mddev *mddev)
|
|||
md_init_stacking_limits(&lim);
|
||||
lim.max_write_zeroes_sectors = 0;
|
||||
lim.max_hw_wzeroes_unmap_sectors = 0;
|
||||
lim.chunk_sectors = BARRIER_UNIT_SECTOR_SIZE;
|
||||
lim.logical_block_size = mddev->logical_block_size;
|
||||
lim.features |= BLK_FEAT_ATOMIC_WRITES;
|
||||
lim.features |= BLK_FEAT_PCI_P2PDMA;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user