md/raid1: factor out helpers to add rdev to conf
authorYu Kuai <yukuai3@huawei.com>
Thu, 29 Feb 2024 09:57:05 +0000 (17:57 +0800)
committerSong Liu <song@kernel.org>
Fri, 1 Mar 2024 06:49:45 +0000 (22:49 -0800)
There are no functional changes, just make code cleaner and prepare to
record disk non-rotational information while adding and removing rdev to
conf

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20240229095714.926789-3-yukuai1@huaweicloud.com
drivers/md/raid1.c

index a145fe48b9cef5dbcbdff377779b584b1744c955..6ec9998f62573cab618ffab25eede66a68cc1bed 100644 (file)
@@ -1757,6 +1757,44 @@ static int raid1_spare_active(struct mddev *mddev)
        return count;
 }
 
+static bool raid1_add_conf(struct r1conf *conf, struct md_rdev *rdev, int disk,
+                          bool replacement)
+{
+       struct raid1_info *info = conf->mirrors + disk;
+
+       if (replacement)
+               info += conf->raid_disks;
+
+       if (info->rdev)
+               return false;
+
+       rdev->raid_disk = disk;
+       info->head_position = 0;
+       info->seq_start = MaxSector;
+       WRITE_ONCE(info->rdev, rdev);
+
+       return true;
+}
+
+static bool raid1_remove_conf(struct r1conf *conf, int disk)
+{
+       struct raid1_info *info = conf->mirrors + disk;
+       struct md_rdev *rdev = info->rdev;
+
+       if (!rdev || test_bit(In_sync, &rdev->flags) ||
+           atomic_read(&rdev->nr_pending))
+               return false;
+
+       /* Only remove non-faulty devices if recovery is not possible. */
+       if (!test_bit(Faulty, &rdev->flags) &&
+           rdev->mddev->recovery_disabled != conf->recovery_disabled &&
+           rdev->mddev->degraded < conf->raid_disks)
+               return false;
+
+       WRITE_ONCE(info->rdev, NULL);
+       return true;
+}
+
 static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
 {
        struct r1conf *conf = mddev->private;
@@ -1792,15 +1830,13 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
                                disk_stack_limits(mddev->gendisk, rdev->bdev,
                                                  rdev->data_offset << 9);
 
-                       p->head_position = 0;
-                       rdev->raid_disk = mirror;
+                       raid1_add_conf(conf, rdev, mirror, false);
                        err = 0;
                        /* As all devices are equivalent, we don't need a full recovery
                         * if this was recently any drive of the array
                         */
                        if (rdev->saved_raid_disk < 0)
                                conf->fullsync = 1;
-                       WRITE_ONCE(p->rdev, rdev);
                        break;
                }
                if (test_bit(WantReplacement, &p->rdev->flags) &&
@@ -1810,13 +1846,11 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
 
        if (err && repl_slot >= 0) {
                /* Add this device as a replacement */
-               p = conf->mirrors + repl_slot;
                clear_bit(In_sync, &rdev->flags);
                set_bit(Replacement, &rdev->flags);
-               rdev->raid_disk = repl_slot;
+               raid1_add_conf(conf, rdev, repl_slot, true);
                err = 0;
                conf->fullsync = 1;
-               WRITE_ONCE(p[conf->raid_disks].rdev, rdev);
        }
 
        print_conf(conf);
@@ -1833,27 +1867,20 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
        if (unlikely(number >= conf->raid_disks))
                goto abort;
 
-       if (rdev != p->rdev)
-               p = conf->mirrors + conf->raid_disks + number;
+       if (rdev != p->rdev) {
+               number += conf->raid_disks;
+               p = conf->mirrors + number;
+       }
 
        print_conf(conf);
        if (rdev == p->rdev) {
-               if (test_bit(In_sync, &rdev->flags) ||
-                   atomic_read(&rdev->nr_pending)) {
-                       err = -EBUSY;
-                       goto abort;
-               }
-               /* Only remove non-faulty devices if recovery
-                * is not possible.
-                */
-               if (!test_bit(Faulty, &rdev->flags) &&
-                   mddev->recovery_disabled != conf->recovery_disabled &&
-                   mddev->degraded < conf->raid_disks) {
+               if (!raid1_remove_conf(conf, number)) {
                        err = -EBUSY;
                        goto abort;
                }
-               WRITE_ONCE(p->rdev, NULL);
-               if (conf->mirrors[conf->raid_disks + number].rdev) {
+
+               if (number < conf->raid_disks &&
+                   conf->mirrors[conf->raid_disks + number].rdev) {
                        /* We just removed a device that is being replaced.
                         * Move down the replacement.  We drain all IO before
                         * doing this to avoid confusion.
@@ -2994,23 +3021,17 @@ static struct r1conf *setup_conf(struct mddev *mddev)
 
        err = -EINVAL;
        spin_lock_init(&conf->device_lock);
+       conf->raid_disks = mddev->raid_disks;
        rdev_for_each(rdev, mddev) {
                int disk_idx = rdev->raid_disk;
-               if (disk_idx >= mddev->raid_disks
-                   || disk_idx < 0)
+
+               if (disk_idx >= conf->raid_disks || disk_idx < 0)
                        continue;
-               if (test_bit(Replacement, &rdev->flags))
-                       disk = conf->mirrors + mddev->raid_disks + disk_idx;
-               else
-                       disk = conf->mirrors + disk_idx;
 
-               if (disk->rdev)
+               if (!raid1_add_conf(conf, rdev, disk_idx,
+                                   test_bit(Replacement, &rdev->flags)))
                        goto abort;
-               disk->rdev = rdev;
-               disk->head_position = 0;
-               disk->seq_start = MaxSector;
        }
-       conf->raid_disks = mddev->raid_disks;
        conf->mddev = mddev;
        INIT_LIST_HEAD(&conf->retry_list);
        INIT_LIST_HEAD(&conf->bio_end_io_list);