]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
md/raid1: Atomic write support
authorJohn Garry <john.g.garry@oracle.com>
Mon, 18 Nov 2024 10:50:17 +0000 (10:50 +0000)
committerJens Axboe <axboe@kernel.dk>
Tue, 19 Nov 2024 17:30:02 +0000 (10:30 -0700)
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>
drivers/md/raid1.c

index a5adf08ee174199531575b9deb9f34577bbb72bc..519c56f0ee3d40e97cfd4343e43e81610bfeeb3c 100644 (file)
@@ -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);