* [PATCH v4 0/5] RAID 0/1/10 atomic write support
@ 2024-11-12 12:42 John Garry
2024-11-12 12:42 ` [PATCH v4 1/5] block: Add extra checks in blk_validate_atomic_write_limits() John Garry
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
This series introduces atomic write support for software RAID 0/1/10.
The main changes are to ensure that we can calculate the stacked device
request_queue limits appropriately for atomic writes. Fundamentally, if
some bottom does not support atomic writes, then atomic writes are not
supported for the top device. Furthermore, the atomic writes limits are
the lowest common supported limits from all bottom devices.
Flag BLK_FEAT_ATOMIC_WRITES_STACKED is introduced to enable atomic writes
for stacked devices selectively. This ensures that we can analyze and test
atomic writes support per individual md/dm personality (prior to
enabling).
Based on 0b4ace9da58d (for-6.13/block) nvme-multipath: don't bother
clearing max_hw_zone_append_sectors
Differences to v3:
- Add RB tags from Christoph and Kuai (thanks!)
- Rebase
Differences to v2:
- Refactor blk_stack_atomic_writes_limits() (Christoph)
- Relocate RAID 1/10 BB check (Kuai)
- Add RB tag from Christoph (Thanks!)
- Set REQ_ATOMIC for RAID 1/10
John Garry (5):
block: Add extra checks in blk_validate_atomic_write_limits()
block: Support atomic writes limits for stacked devices
md/raid0: Atomic write support
md/raid1: Atomic write support
md/raid10: Atomic write support
block/blk-settings.c | 132 +++++++++++++++++++++++++++++++++++++++++
drivers/md/raid0.c | 1 +
drivers/md/raid1.c | 14 ++++-
drivers/md/raid10.c | 14 ++++-
include/linux/blkdev.h | 4 ++
5 files changed, 161 insertions(+), 4 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 1/5] block: Add extra checks in blk_validate_atomic_write_limits()
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
@ 2024-11-12 12:42 ` John Garry
2024-11-12 12:42 ` [PATCH v4 2/5] block: Support atomic writes limits for stacked devices John Garry
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
It is so far expected that the limits passed are valid.
In future atomic writes will be supported for stacked block devices, and
calculating the limits there will be complicated, so add extra sanity
checks to ensure that the values are always valid.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
block/blk-settings.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 7d6b296997c2..44e1148986b3 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -178,9 +178,26 @@ static void blk_validate_atomic_write_limits(struct queue_limits *lim)
if (!lim->atomic_write_hw_max)
goto unsupported;
+ if (WARN_ON_ONCE(!is_power_of_2(lim->atomic_write_hw_unit_min)))
+ goto unsupported;
+
+ if (WARN_ON_ONCE(!is_power_of_2(lim->atomic_write_hw_unit_max)))
+ goto unsupported;
+
+ if (WARN_ON_ONCE(lim->atomic_write_hw_unit_min >
+ lim->atomic_write_hw_unit_max))
+ goto unsupported;
+
+ if (WARN_ON_ONCE(lim->atomic_write_hw_unit_max >
+ lim->atomic_write_hw_max))
+ goto unsupported;
+
boundary_sectors = lim->atomic_write_hw_boundary >> SECTOR_SHIFT;
if (boundary_sectors) {
+ if (WARN_ON_ONCE(lim->atomic_write_hw_max >
+ lim->atomic_write_hw_boundary))
+ goto unsupported;
/*
* A feature of boundary support is that it disallows bios to
* be merged which would result in a merged request which
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 2/5] block: Support atomic writes limits for stacked devices
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
2024-11-12 12:42 ` [PATCH v4 1/5] block: Add extra checks in blk_validate_atomic_write_limits() John Garry
@ 2024-11-12 12:42 ` John Garry
2024-11-12 12:42 ` [PATCH v4 3/5] md/raid0: Atomic write support John Garry
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
Allow stacked devices to support atomic writes by aggregating the minimum
capability of all bottom devices.
Flag BLK_FEAT_ATOMIC_WRITES_STACKED is set for stacked devices which
have been enabled to support atomic writes.
Some things to note on the implementation:
- For simplicity, all bottom devices must have same atomic write boundary
value (if any)
- The atomic write boundary must be a power-of-2 already, but this
restriction could be relaxed. Furthermore, it is now required that the
chunk sectors for a top device must be aligned with this boundary.
- If a bottom device atomic write unit min/max are not aligned with the
top device chunk sectors, the top device atomic write unit min/max are
reduced to a value which works for the chunk sectors.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
block/blk-settings.c | 115 +++++++++++++++++++++++++++++++++++++++++
include/linux/blkdev.h | 4 ++
2 files changed, 119 insertions(+)
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 44e1148986b3..e087e5d886ce 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -495,6 +495,119 @@ static unsigned int blk_round_down_sectors(unsigned int sectors, unsigned int lb
return sectors;
}
+/* Check if second and later bottom devices are compliant */
+static bool blk_stack_atomic_writes_tail(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ /* We're not going to support different boundary sizes.. yet */
+ if (t->atomic_write_hw_boundary != b->atomic_write_hw_boundary)
+ return false;
+
+ /* Can't support this */
+ if (t->atomic_write_hw_unit_min > b->atomic_write_hw_unit_max)
+ return false;
+
+ /* Or this */
+ if (t->atomic_write_hw_unit_max < b->atomic_write_hw_unit_min)
+ return false;
+
+ t->atomic_write_hw_max = min(t->atomic_write_hw_max,
+ b->atomic_write_hw_max);
+ t->atomic_write_hw_unit_min = max(t->atomic_write_hw_unit_min,
+ b->atomic_write_hw_unit_min);
+ t->atomic_write_hw_unit_max = min(t->atomic_write_hw_unit_max,
+ b->atomic_write_hw_unit_max);
+ return true;
+}
+
+/* Check for valid boundary of first bottom device */
+static bool blk_stack_atomic_writes_boundary_head(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ /*
+ * Ensure atomic write boundary is aligned with chunk sectors. Stacked
+ * devices store chunk sectors in t->io_min.
+ */
+ if (b->atomic_write_hw_boundary > t->io_min &&
+ b->atomic_write_hw_boundary % t->io_min)
+ return false;
+ if (t->io_min > b->atomic_write_hw_boundary &&
+ t->io_min % b->atomic_write_hw_boundary)
+ return false;
+
+ t->atomic_write_hw_boundary = b->atomic_write_hw_boundary;
+ return true;
+}
+
+
+/* Check stacking of first bottom device */
+static bool blk_stack_atomic_writes_head(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ if (b->atomic_write_hw_boundary &&
+ !blk_stack_atomic_writes_boundary_head(t, b))
+ return false;
+
+ if (t->io_min <= SECTOR_SIZE) {
+ /* No chunk sectors, so use bottom device values directly */
+ t->atomic_write_hw_unit_max = b->atomic_write_hw_unit_max;
+ t->atomic_write_hw_unit_min = b->atomic_write_hw_unit_min;
+ t->atomic_write_hw_max = b->atomic_write_hw_max;
+ return true;
+ }
+
+ /*
+ * Find values for limits which work for chunk size.
+ * b->atomic_write_hw_unit_{min, max} may not be aligned with chunk
+ * size (t->io_min), as chunk size is not restricted to a power-of-2.
+ * So we need to find highest power-of-2 which works for the chunk
+ * size.
+ * As an example scenario, we could have b->unit_max = 16K and
+ * t->io_min = 24K. For this case, reduce t->unit_max to a value
+ * aligned with both limits, i.e. 8K in this example.
+ */
+ t->atomic_write_hw_unit_max = b->atomic_write_hw_unit_max;
+ while (t->io_min % t->atomic_write_hw_unit_max)
+ t->atomic_write_hw_unit_max /= 2;
+
+ t->atomic_write_hw_unit_min = min(b->atomic_write_hw_unit_min,
+ t->atomic_write_hw_unit_max);
+ t->atomic_write_hw_max = min(b->atomic_write_hw_max, t->io_min);
+
+ return true;
+}
+
+static void blk_stack_atomic_writes_limits(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ if (!(t->features & BLK_FEAT_ATOMIC_WRITES_STACKED))
+ goto unsupported;
+
+ if (!b->atomic_write_unit_min)
+ goto unsupported;
+
+ /*
+ * If atomic_write_hw_max is set, we have already stacked 1x bottom
+ * device, so check for compliance.
+ */
+ if (t->atomic_write_hw_max) {
+ if (!blk_stack_atomic_writes_tail(t, b))
+ goto unsupported;
+ return;
+ }
+
+ if (!blk_stack_atomic_writes_head(t, b))
+ goto unsupported;
+ return;
+
+unsupported:
+ t->atomic_write_hw_max = 0;
+ t->atomic_write_hw_unit_max = 0;
+ t->atomic_write_hw_unit_min = 0;
+ t->atomic_write_hw_boundary = 0;
+ t->features &= ~BLK_FEAT_ATOMIC_WRITES_STACKED;
+}
+
/**
* blk_stack_limits - adjust queue_limits for stacked devices
* @t: the stacking driver limits (top device)
@@ -655,6 +768,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
t->zone_write_granularity = 0;
t->max_zone_append_sectors = 0;
}
+ blk_stack_atomic_writes_limits(t, b);
+
return ret;
}
EXPORT_SYMBOL(blk_stack_limits);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 65f37ae70712..b9e5b00cd825 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -333,6 +333,10 @@ typedef unsigned int __bitwise blk_features_t;
#define BLK_FEAT_RAID_PARTIAL_STRIPES_EXPENSIVE \
((__force blk_features_t)(1u << 15))
+/* stacked device can/does support atomic writes */
+#define BLK_FEAT_ATOMIC_WRITES_STACKED \
+ ((__force blk_features_t)(1u << 16))
+
/*
* Flags automatically inherited when stacking limits.
*/
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 3/5] md/raid0: Atomic write support
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
2024-11-12 12:42 ` [PATCH v4 1/5] block: Add extra checks in blk_validate_atomic_write_limits() John Garry
2024-11-12 12:42 ` [PATCH v4 2/5] block: Support atomic writes limits for stacked devices John Garry
@ 2024-11-12 12:42 ` John Garry
2024-11-12 12:42 ` [PATCH v4 4/5] md/raid1: " John Garry
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
Set BLK_FEAT_ATOMIC_WRITES_STACKED to enable atomic writes. All other
stacked device request queue limits should automatically be set properly.
With regards to atomic write max bytes limit, this will be set at
hw_max_sectors and this is limited by the stripe width, which we want.
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
drivers/md/raid0.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index baaf5f8b80ae..7049ec7fb8eb 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -384,6 +384,7 @@ static int raid0_set_limits(struct mddev *mddev)
lim.max_write_zeroes_sectors = mddev->chunk_sectors;
lim.io_min = mddev->chunk_sectors << 9;
lim.io_opt = lim.io_min * mddev->raid_disks;
+ 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);
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 4/5] md/raid1: Atomic write support
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
` (2 preceding siblings ...)
2024-11-12 12:42 ` [PATCH v4 3/5] md/raid0: Atomic write support John Garry
@ 2024-11-12 12:42 ` John Garry
2024-11-16 3:51 ` Yu Kuai
2024-11-12 12:42 ` [PATCH v4 5/5] md/raid10: " John Garry
2024-11-14 8:22 ` [PATCH v4 0/5] RAID 0/1/10 atomic " John Garry
5 siblings, 1 reply; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
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.
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
drivers/md/raid1.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index a5adf08ee174..cd44b4bebf49 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1571,7 +1571,15 @@ 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;
+
+ if (bio->bi_opf & REQ_ATOMIC) {
+ /* We just cannot atomically write this ... */
+ error = -EFAULT;
+ goto err_handle;
+ }
+
+ good_sectors = first_bad - r1_bio->sector;
if (good_sectors < max_sectors)
max_sectors = good_sectors;
}
@@ -1657,7 +1665,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 +3233,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);
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 5/5] md/raid10: Atomic write support
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
` (3 preceding siblings ...)
2024-11-12 12:42 ` [PATCH v4 4/5] md/raid1: " John Garry
@ 2024-11-12 12:42 ` John Garry
2024-11-15 18:19 ` Song Liu
2024-11-14 8:22 ` [PATCH v4 0/5] RAID 0/1/10 atomic " John Garry
5 siblings, 1 reply; 11+ messages in thread
From: John Garry @ 2024-11-12 12:42 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, John Garry
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.
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
drivers/md/raid10.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 8c7f5daa073a..a3936a67e1e8 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1255,6 +1255,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
const enum req_op op = bio_op(bio);
const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
+ const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC;
unsigned long flags;
struct r10conf *conf = mddev->private;
struct md_rdev *rdev;
@@ -1273,7 +1274,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
choose_data_offset(r10_bio, rdev));
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_opf = op | do_sync | do_fua;
+ mbio->bi_opf = op | do_sync | do_fua | do_atomic;
if (!replacement && test_bit(FailFast,
&conf->mirrors[devnum].rdev->flags)
&& enough(conf, devnum))
@@ -1468,7 +1469,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
continue;
}
if (is_bad) {
- int good_sectors = first_bad - dev_sector;
+ int good_sectors;
+
+ if (bio->bi_opf & REQ_ATOMIC) {
+ /* We just cannot atomically write this ... */
+ error = -EFAULT;
+ goto err_handle;
+ }
+
+ good_sectors = first_bad - dev_sector;
if (good_sectors < max_sectors)
max_sectors = good_sectors;
}
@@ -4025,6 +4034,7 @@ static int raid10_set_queue_limits(struct mddev *mddev)
lim.max_write_zeroes_sectors = 0;
lim.io_min = mddev->chunk_sectors << 9;
lim.io_opt = lim.io_min * raid10_nr_stripes(conf);
+ 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);
--
2.31.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/5] RAID 0/1/10 atomic write support
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
` (4 preceding siblings ...)
2024-11-12 12:42 ` [PATCH v4 5/5] md/raid10: " John Garry
@ 2024-11-14 8:22 ` John Garry
5 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2024-11-14 8:22 UTC (permalink / raw)
To: axboe, song, yukuai3, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen
On 12/11/2024 12:42, John Garry wrote:
Hi Song, Kuai,
Can you check the remaining 2x patches in this series when you get a chance?
I was hoping that I could get this queued for 6.13 via the block tree.
Thanks,
John
Ps. I do appreciate that I am pinging on this quite early, but those
patches mentioned have not changed since the last revision.
> This series introduces atomic write support for software RAID 0/1/10.
>
> The main changes are to ensure that we can calculate the stacked device
> request_queue limits appropriately for atomic writes. Fundamentally, if
> some bottom does not support atomic writes, then atomic writes are not
> supported for the top device. Furthermore, the atomic writes limits are
> the lowest common supported limits from all bottom devices.
>
> Flag BLK_FEAT_ATOMIC_WRITES_STACKED is introduced to enable atomic writes
> for stacked devices selectively. This ensures that we can analyze and test
> atomic writes support per individual md/dm personality (prior to
> enabling).
>
> Based on 0b4ace9da58d (for-6.13/block) nvme-multipath: don't bother
> clearing max_hw_zone_append_sectors
>
> Differences to v3:
> - Add RB tags from Christoph and Kuai (thanks!)
> - Rebase
>
> Differences to v2:
> - Refactor blk_stack_atomic_writes_limits() (Christoph)
> - Relocate RAID 1/10 BB check (Kuai)
> - Add RB tag from Christoph (Thanks!)
> - Set REQ_ATOMIC for RAID 1/10
>
> John Garry (5):
> block: Add extra checks in blk_validate_atomic_write_limits()
> block: Support atomic writes limits for stacked devices
> md/raid0: Atomic write support
> md/raid1: Atomic write support
> md/raid10: Atomic write support
>
> block/blk-settings.c | 132 +++++++++++++++++++++++++++++++++++++++++
> drivers/md/raid0.c | 1 +
> drivers/md/raid1.c | 14 ++++-
> drivers/md/raid10.c | 14 ++++-
> include/linux/blkdev.h | 4 ++
> 5 files changed, 161 insertions(+), 4 deletions(-)
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 5/5] md/raid10: Atomic write support
2024-11-12 12:42 ` [PATCH v4 5/5] md/raid10: " John Garry
@ 2024-11-15 18:19 ` Song Liu
2024-11-16 3:50 ` Yu Kuai
0 siblings, 1 reply; 11+ messages in thread
From: Song Liu @ 2024-11-15 18:19 UTC (permalink / raw)
To: John Garry
Cc: axboe, yukuai3, hch, linux-block, linux-kernel, linux-raid,
martin.petersen
On Tue, Nov 12, 2024 at 4:43 AM John Garry <john.g.garry@oracle.com> wrote:
>
> 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.
>
> Signed-off-by: John Garry <john.g.garry@oracle.com>
> ---
> drivers/md/raid10.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
> index 8c7f5daa073a..a3936a67e1e8 100644
> --- a/drivers/md/raid10.c
> +++ b/drivers/md/raid10.c
> @@ -1255,6 +1255,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
> const enum req_op op = bio_op(bio);
> const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
> const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
> + const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC;
> unsigned long flags;
> struct r10conf *conf = mddev->private;
> struct md_rdev *rdev;
> @@ -1273,7 +1274,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
> mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
> choose_data_offset(r10_bio, rdev));
> mbio->bi_end_io = raid10_end_write_request;
> - mbio->bi_opf = op | do_sync | do_fua;
> + mbio->bi_opf = op | do_sync | do_fua | do_atomic;
> if (!replacement && test_bit(FailFast,
> &conf->mirrors[devnum].rdev->flags)
> && enough(conf, devnum))
> @@ -1468,7 +1469,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
> continue;
> }
> if (is_bad) {
> - int good_sectors = first_bad - dev_sector;
> + int good_sectors;
> +
> + if (bio->bi_opf & REQ_ATOMIC) {
> + /* We just cannot atomically write this ... */
> + error = -EFAULT;
Is EFAULT the right error code here? I think we should return something
covered by blk_errors?
Other than this, 4/5 and 5/5 look good to me.
Thanks,
Song
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 5/5] md/raid10: Atomic write support
2024-11-15 18:19 ` Song Liu
@ 2024-11-16 3:50 ` Yu Kuai
2024-11-17 18:32 ` John Garry
0 siblings, 1 reply; 11+ messages in thread
From: Yu Kuai @ 2024-11-16 3:50 UTC (permalink / raw)
To: Song Liu, John Garry
Cc: axboe, hch, linux-block, linux-kernel, linux-raid,
martin.petersen, yukuai (C)
Hi,
在 2024/11/16 2:19, Song Liu 写道:
> On Tue, Nov 12, 2024 at 4:43 AM John Garry <john.g.garry@oracle.com> wrote:
>>
>> 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.
>>
>> Signed-off-by: John Garry <john.g.garry@oracle.com>
>> ---
>> drivers/md/raid10.c | 14 ++++++++++++--
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
One nit below:
>> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
>> index 8c7f5daa073a..a3936a67e1e8 100644
>> --- a/drivers/md/raid10.c
>> +++ b/drivers/md/raid10.c
>> @@ -1255,6 +1255,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
>> const enum req_op op = bio_op(bio);
>> const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
>> const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
>> + const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC;
>> unsigned long flags;
>> struct r10conf *conf = mddev->private;
>> struct md_rdev *rdev;
>> @@ -1273,7 +1274,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
>> mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
>> choose_data_offset(r10_bio, rdev));
>> mbio->bi_end_io = raid10_end_write_request;
>> - mbio->bi_opf = op | do_sync | do_fua;
>> + mbio->bi_opf = op | do_sync | do_fua | do_atomic;
>> if (!replacement && test_bit(FailFast,
>> &conf->mirrors[devnum].rdev->flags)
>> && enough(conf, devnum))
>> @@ -1468,7 +1469,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
>> continue;
>> }
>> if (is_bad) {
>> - int good_sectors = first_bad - dev_sector;
>> + int good_sectors;
>> +
>> + if (bio->bi_opf & REQ_ATOMIC) {
>> + /* We just cannot atomically write this ... */
Maybe mention that we can if there is at least one disk without any BB,
it's just benefit does not worth the complexity. And return the special
error code to let user retry without atomic write.
>> + error = -EFAULT;
>
> Is EFAULT the right error code here? I think we should return something
> covered by blk_errors?
The error code is passed to bio by:
bio->bi_status = errno_to_blk_status(error);
So, this is fine.
>
> Other than this, 4/5 and 5/5 look good to me.
>
> Thanks,
> Song
>
> .
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/5] md/raid1: Atomic write support
2024-11-12 12:42 ` [PATCH v4 4/5] md/raid1: " John Garry
@ 2024-11-16 3:51 ` Yu Kuai
0 siblings, 0 replies; 11+ messages in thread
From: Yu Kuai @ 2024-11-16 3:51 UTC (permalink / raw)
To: John Garry, axboe, song, hch
Cc: linux-block, linux-kernel, linux-raid, martin.petersen, yukuai (C)
在 2024/11/12 20:42, John Garry 写道:
> 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.
>
> Signed-off-by: John Garry <john.g.garry@oracle.com>
> ---
> drivers/md/raid1.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
I review the patch 5 first, it's the same, so.
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index a5adf08ee174..cd44b4bebf49 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -1571,7 +1571,15 @@ 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;
> +
> + if (bio->bi_opf & REQ_ATOMIC) {
> + /* We just cannot atomically write this ... */
> + error = -EFAULT;
> + goto err_handle;
> + }
> +
> + good_sectors = first_bad - r1_bio->sector;
> if (good_sectors < max_sectors)
> max_sectors = good_sectors;
> }
> @@ -1657,7 +1665,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 +3233,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);
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 5/5] md/raid10: Atomic write support
2024-11-16 3:50 ` Yu Kuai
@ 2024-11-17 18:32 ` John Garry
0 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2024-11-17 18:32 UTC (permalink / raw)
To: Yu Kuai, Song Liu
Cc: axboe, hch, linux-block, linux-kernel, linux-raid,
martin.petersen, yukuai (C)
On 16/11/2024 03:50, Yu Kuai wrote:
> Hi,
>
> 在 2024/11/16 2:19, Song Liu 写道:
>> On Tue, Nov 12, 2024 at 4:43 AM John Garry <john.g.garry@oracle.com>
>> wrote:
>>>
>>> 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.
>>>
>>> Signed-off-by: John Garry <john.g.garry@oracle.com>
>>> ---
>>> drivers/md/raid10.c | 14 ++++++++++++--
>>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>>
>
> Reviewed-by: Yu Kuai <yukuai3@huawei.com>
>
> One nit below:
>>> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
>>> index 8c7f5daa073a..a3936a67e1e8 100644
>>> --- a/drivers/md/raid10.c
>>> +++ b/drivers/md/raid10.c
>>> @@ -1255,6 +1255,7 @@ static void raid10_write_one_disk(struct mddev
>>> *mddev, struct r10bio *r10_bio,
>>> const enum req_op op = bio_op(bio);
>>> const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
>>> const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
>>> + const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC;
>>> unsigned long flags;
>>> struct r10conf *conf = mddev->private;
>>> struct md_rdev *rdev;
>>> @@ -1273,7 +1274,7 @@ static void raid10_write_one_disk(struct mddev
>>> *mddev, struct r10bio *r10_bio,
>>> mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
>>> choose_data_offset(r10_bio, rdev));
>>> mbio->bi_end_io = raid10_end_write_request;
>>> - mbio->bi_opf = op | do_sync | do_fua;
>>> + mbio->bi_opf = op | do_sync | do_fua | do_atomic;
>>> if (!replacement && test_bit(FailFast,
>>> &conf->mirrors[devnum].rdev-
>>> >flags)
>>> && enough(conf, devnum))
>>> @@ -1468,7 +1469,15 @@ static void raid10_write_request(struct mddev
>>> *mddev, struct bio *bio,
>>> continue;
>>> }
>>> if (is_bad) {
>>> - int good_sectors = first_bad -
>>> dev_sector;
>>> + int good_sectors;
>>> +
>>> + if (bio->bi_opf & REQ_ATOMIC) {
>>> + /* We just cannot atomically
>>> write this ... */
>
> Maybe mention that we can if there is at least one disk without any BB,
> it's just benefit does not worth the complexity. And return the special
> error code to let user retry without atomic write.
ok
>
>>> + error = -EFAULT;
>>
>> Is EFAULT the right error code here? I think we should return something
>> covered by blk_errors?
sure, so maybe explicitly use BLK_STS_IOERR / EIO, which is what we
generally use in raid drivers when we cannot read/write - ok?
>
> The error code is passed to bio by:
>
> bio->bi_status = errno_to_blk_status(error);
>
> So, this is fine.
>>
>> Other than this, 4/5 and 5/5 look good to me.
>>
Thanks,
John
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-11-17 18:32 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-11-12 12:42 [PATCH v4 0/5] RAID 0/1/10 atomic write support John Garry
2024-11-12 12:42 ` [PATCH v4 1/5] block: Add extra checks in blk_validate_atomic_write_limits() John Garry
2024-11-12 12:42 ` [PATCH v4 2/5] block: Support atomic writes limits for stacked devices John Garry
2024-11-12 12:42 ` [PATCH v4 3/5] md/raid0: Atomic write support John Garry
2024-11-12 12:42 ` [PATCH v4 4/5] md/raid1: " John Garry
2024-11-16 3:51 ` Yu Kuai
2024-11-12 12:42 ` [PATCH v4 5/5] md/raid10: " John Garry
2024-11-15 18:19 ` Song Liu
2024-11-16 3:50 ` Yu Kuai
2024-11-17 18:32 ` John Garry
2024-11-14 8:22 ` [PATCH v4 0/5] RAID 0/1/10 atomic " John Garry
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®