Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md/raid1: Atomic write support

Set BLK_FEAT_ATOMIC_WRITES_STACKED to enable atomic writes.

For an attempt to atomic write to a region which has bad blocks, error
the write as we just cannot do this. It is unlikely to find devices which
support atomic writes and bad blocks.

Reviewed-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20241118105018.1870052-5-john.g.garry@oracle.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

John Garry and committed by
Jens Axboe
f2a38abf fa6fec82

+18 -2
+18 -2
drivers/md/raid1.c
··· 1571 1571 continue; 1572 1572 } 1573 1573 if (is_bad) { 1574 - int good_sectors = first_bad - r1_bio->sector; 1574 + int good_sectors; 1575 + 1576 + /* 1577 + * We cannot atomically write this, so just 1578 + * error in that case. It could be possible to 1579 + * atomically write other mirrors, but the 1580 + * complexity of supporting that is not worth 1581 + * the benefit. 1582 + */ 1583 + if (bio->bi_opf & REQ_ATOMIC) { 1584 + error = -EIO; 1585 + goto err_handle; 1586 + } 1587 + 1588 + good_sectors = first_bad - r1_bio->sector; 1575 1589 if (good_sectors < max_sectors) 1576 1590 max_sectors = good_sectors; 1577 1591 } ··· 1671 1657 1672 1658 mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset); 1673 1659 mbio->bi_end_io = raid1_end_write_request; 1674 - mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA)); 1660 + mbio->bi_opf = bio_op(bio) | 1661 + (bio->bi_opf & (REQ_SYNC | REQ_FUA | REQ_ATOMIC)); 1675 1662 if (test_bit(FailFast, &rdev->flags) && 1676 1663 !test_bit(WriteMostly, &rdev->flags) && 1677 1664 conf->raid_disks - mddev->degraded > 1) ··· 3239 3224 3240 3225 md_init_stacking_limits(&lim); 3241 3226 lim.max_write_zeroes_sectors = 0; 3227 + lim.features |= BLK_FEAT_ATOMIC_WRITES_STACKED; 3242 3228 err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY); 3243 3229 if (err) { 3244 3230 queue_limits_cancel_update(mddev->gendisk->queue);