Commit f2a38abf authored by John Garry's avatar John Garry Committed by Jens Axboe
Browse files

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: default avatarYu Kuai <yukuai3@huawei.com>
Signed-off-by: default avatarJohn Garry <john.g.garry@oracle.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20241118105018.1870052-5-john.g.garry@oracle.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent fa6fec82
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -1571,7 +1571,21 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
				continue;
			}
			if (is_bad) {
				int good_sectors = first_bad - r1_bio->sector;
				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) {
					error = -EIO;
					goto err_handle;
				}

				good_sectors = first_bad - r1_bio->sector;
				if (good_sectors < max_sectors)
					max_sectors = good_sectors;
			}
@@ -1657,7 +1671,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,

		mbio->bi_iter.bi_sector	= (r1_bio->sector + rdev->data_offset);
		mbio->bi_end_io	= raid1_end_write_request;
		mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
		mbio->bi_opf = bio_op(bio) |
			(bio->bi_opf & (REQ_SYNC | REQ_FUA | REQ_ATOMIC));
		if (test_bit(FailFast, &rdev->flags) &&
		    !test_bit(WriteMostly, &rdev->flags) &&
		    conf->raid_disks - mddev->degraded > 1)
@@ -3224,6 +3239,7 @@ static int raid1_set_limits(struct mddev *mddev)

	md_init_stacking_limits(&lim);
	lim.max_write_zeroes_sectors = 0;
	lim.features |= BLK_FEAT_ATOMIC_WRITES_STACKED;
	err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY);
	if (err) {
		queue_limits_cancel_update(mddev->gendisk->queue);