]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
md/raid1: fix the comparing region of interval tree
authorXiao Ni <xni@redhat.com>
Thu, 5 Mar 2026 01:18:33 +0000 (09:18 +0800)
committerYu Kuai <yukuai@fnnas.com>
Sun, 22 Mar 2026 18:15:10 +0000 (02:15 +0800)
Interval tree uses [start, end] as a region which stores in the tree.
In raid1, it uses the wrong end value. For example:
bio(A,B) is too big and needs to be split to bio1(A,C-1), bio2(C,B).
The region of bio1 is [A,C] and the region of bio2 is [C,B]. So bio1 and
bio2 overlap which is not right.

Fix this problem by using right end value of the region.

Fixes: d0d2d8ba0494 ("md/raid1: introduce wait_for_serialization")
Signed-off-by: Xiao Ni <xni@redhat.com>
Link: https://lore.kernel.org/linux-raid/20260305011839.5118-2-xni@redhat.com/
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
drivers/md/raid1.c

index cda6af0712b9296fc92224d0fd1682d74ea6fd19..16f671ab12c00d0d873faf1a5b5469c3fcb572f2 100644 (file)
@@ -62,7 +62,7 @@ static int check_and_add_serial(struct md_rdev *rdev, struct r1bio *r1_bio,
        unsigned long flags;
        int ret = 0;
        sector_t lo = r1_bio->sector;
-       sector_t hi = lo + r1_bio->sectors;
+       sector_t hi = lo + r1_bio->sectors - 1;
        struct serial_in_rdev *serial = &rdev->serial[idx];
 
        spin_lock_irqsave(&serial->serial_lock, flags);
@@ -452,7 +452,7 @@ static void raid1_end_write_request(struct bio *bio)
        int mirror = find_bio_disk(r1_bio, bio);
        struct md_rdev *rdev = conf->mirrors[mirror].rdev;
        sector_t lo = r1_bio->sector;
-       sector_t hi = r1_bio->sector + r1_bio->sectors;
+       sector_t hi = r1_bio->sector + r1_bio->sectors - 1;
        bool ignore_error = !raid1_should_handle_error(bio) ||
                (bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);