]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Manage_subdevs(): Use a dev_t
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
old mode 100755 (executable)
new mode 100644 (file)
index f4bd301..534ba80
--- a/Grow.c
+++ b/Grow.c
@@ -109,7 +109,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
         */
        struct mdinfo info;
 
-       struct stat stb;
+       dev_t rdev;
        int nfd, fd2;
        int d, nd;
        struct supertype *st = NULL;
@@ -145,9 +145,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                free(st);
                return 1;
        }
-       fstat(nfd, &stb);
-       if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-               pr_err("%s is not a block device!\n", newdev);
+       if (!fstat_is_blkdev(nfd, newdev, &rdev)) {
                close(nfd);
                free(st);
                return 1;
@@ -198,8 +196,8 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
         */
 
        info.disk.number = d;
-       info.disk.major = major(stb.st_rdev);
-       info.disk.minor = minor(stb.st_rdev);
+       info.disk.major = major(rdev);
+       info.disk.minor = minor(rdev);
        info.disk.raid_disk = d;
        info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
        st->ss->update_super(st, &info, "linear-grow-new", newdev,
@@ -532,6 +530,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
        char *subarray = NULL;
        int ret = 0;
        char container_dev[PATH_MAX];
+       char buf[20];
 
        if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
            s->consistency_policy != CONSISTENCY_POLICY_PPL) {
@@ -579,6 +578,17 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
                goto free_info;
        }
 
+       if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
+               if (sysfs_get_str(sra, NULL, "sync_action", buf, 20) <= 0) {
+                       ret = 1;
+                       goto free_info;
+               } else if (strcmp(buf, "reshape\n") == 0) {
+                       pr_err("PPL cannot be enabled when reshape is in progress\n");
+                       ret = 1;
+                       goto free_info;
+               }
+       }
+
        if (subarray) {
                char *update;
 
@@ -815,8 +825,8 @@ static void unfreeze(struct supertype *st)
                char buf[20];
 
                if (sra &&
-                   sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0
-                   && strcmp(buf, "frozen\n") == 0)
+                   sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0 &&
+                   strcmp(buf, "frozen\n") == 0)
                        sysfs_set_str(sra, NULL, "sync_action", "idle");
                sysfs_free(sra);
        }
@@ -1405,8 +1415,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
                        if (info->new_layout == UnSet) {
                                int copies = 1 + (info->delta_disks
                                                  / info->array.raid_disks);
-                               if (info->array.raid_disks * (copies-1)
-                                   != info->delta_disks)
+                               if (info->array.raid_disks * (copies-1) !=
+                                   info->delta_disks)
                                        return "Impossible number of devices for RAID0->RAID10";
                                info->new_layout = 0x100 + copies;
                        }
@@ -1882,6 +1892,13 @@ int Grow_reshape(char *devname, int fd,
                                        free(subarray);
                                        return 1;
                                }
+                               if (content->consistency_policy ==
+                                   CONSISTENCY_POLICY_PPL) {
+                                       pr_err("Operation not supported when ppl consistency policy is enabled\n");
+                                       sysfs_free(cc);
+                                       free(subarray);
+                                       return 1;
+                               }
                        }
                        sysfs_free(cc);
                }
@@ -1979,6 +1996,8 @@ int Grow_reshape(char *devname, int fd,
                 */
                min_csize = 0;
                for (mdi = sra->devs; mdi; mdi = mdi->next) {
+                       sysfs_set_num(sra, mdi, "size", s->size == MAX_SIZE ? 0
+                                     : s->size);
                        if (array.not_persistent == 0 &&
                            array.major_version == 0 &&
                            get_linux_version() < 3001000) {
@@ -2904,8 +2923,8 @@ static int impose_level(int fd, int level, char *devname, int verbose)
                        if (disk.major == 0 && disk.minor == 0)
                                continue;
                        found++;
-                       if ((disk.state & (1 << MD_DISK_ACTIVE))
-                           && disk.raid_disk < data_disks)
+                       if ((disk.state & (1 << MD_DISK_ACTIVE)) &&
+                           disk.raid_disk < data_disks)
                                /* keep this */
                                continue;
                        ioctl(fd, HOT_REMOVE_DISK,
@@ -2923,8 +2942,8 @@ static int impose_level(int fd, int level, char *devname, int verbose)
                        if (disk.major == 0 && disk.minor == 0)
                                continue;
                        found++;
-                       if ((disk.state & (1 << MD_DISK_ACTIVE))
-                           && disk.raid_disk < data_disks)
+                       if ((disk.state & (1 << MD_DISK_ACTIVE)) &&
+                           disk.raid_disk < data_disks)
                                /* keep this */
                                continue;
                        ioctl(fd, SET_DISK_FAULTY,
@@ -3069,8 +3088,8 @@ static int reshape_array(char *container, int fd, char *devname,
        if (restart &&
            (reshape.level != info->array.level ||
             reshape.before.layout != info->array.layout ||
-            reshape.before.data_disks + reshape.parity
-            != info->array.raid_disks - max(0, info->delta_disks))) {
+            reshape.before.data_disks + reshape.parity !=
+            info->array.raid_disks - max(0, info->delta_disks))) {
                pr_err("reshape info is not in native format - cannot continue.\n");
                goto release;
        }
@@ -3183,7 +3202,7 @@ static int reshape_array(char *container, int fd, char *devname,
 
                if (info2) {
                        if (sysfs_init(info2, fd, st->devnm)) {
-                               pr_err("unable to initialize sysfs for %s",
+                               pr_err("unable to initialize sysfs for %s\n",
                                       st->devnm);
                                free(info2);
                                goto release;
@@ -3599,9 +3618,8 @@ started:
        }
 
        if (!st->ss->external &&
-           !(reshape.before.data_disks != reshape.after.data_disks
-             && info->custom_array_size) &&
-           info->new_level == reshape.level &&
+           !(reshape.before.data_disks != reshape.after.data_disks &&
+             info->custom_array_size) && info->new_level == reshape.level &&
            !forked) {
                /* no need to wait for the reshape to finish as
                 * there is nothing more to do.
@@ -3998,8 +4016,8 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
         * a backup.
         */
        if (advancing) {
-               if ((need_backup > info->reshape_progress
-                    || info->array.major_version < 0) &&
+               if ((need_backup > info->reshape_progress ||
+                    info->array.major_version < 0) &&
                    *suspend_point < info->reshape_progress + target) {
                        if (need_backup < *suspend_point + 2 * target)
                                *suspend_point = need_backup;
@@ -4094,14 +4112,14 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
                 * before setting 'sync_action' to 'idle'.
                 * So we need these extra tests.
                 */
-               if (completed == 0 && advancing
-                   && strncmp(action, "idle", 4) == 0
-                   && info->reshape_progress > 0)
+               if (completed == 0 && advancing &&
+                   strncmp(action, "idle", 4) == 0 &&
+                   info->reshape_progress > 0)
                        break;
-               if (completed == 0 && !advancing
-                   && strncmp(action, "idle", 4) == 0
-                   && info->reshape_progress < (info->component_size
-                                                * reshape->after.data_disks))
+               if (completed == 0 && !advancing &&
+                   strncmp(action, "idle", 4) == 0 &&
+                   info->reshape_progress < (info->component_size
+                                             * reshape->after.data_disks))
                        break;
                sysfs_wait(fd, NULL);
                if (sysfs_fd_get_ll(fd, &completed) < 0)
@@ -4152,8 +4170,9 @@ check_progress:
         * it was just a device failure that leaves us degraded but
         * functioning.
         */
-       if (sysfs_get_str(info, NULL, "reshape_position", buf, sizeof(buf)) < 0
-           || strncmp(buf, "none", 4) != 0) {
+       if (sysfs_get_str(info, NULL, "reshape_position", buf,
+                         sizeof(buf)) < 0 ||
+           strncmp(buf, "none", 4) != 0) {
                /* The abort might only be temporary.  Wait up to 10
                 * seconds for fd to contain a valid number again.
                 */
@@ -4185,9 +4204,10 @@ check_progress:
                /* Maybe racing with array shutdown - check state */
                if (fd >= 0)
                        close(fd);
-               if (sysfs_get_str(info, NULL, "array_state", buf, sizeof(buf)) < 0
-                   || strncmp(buf, "inactive", 8) == 0
-                   || strncmp(buf, "clear",5) == 0)
+               if (sysfs_get_str(info, NULL, "array_state", buf,
+                                 sizeof(buf)) < 0 ||
+                   strncmp(buf, "inactive", 8) == 0 ||
+                   strncmp(buf, "clear",5) == 0)
                        return -2; /* abort */
                return -1; /* complete */
        }
@@ -4282,8 +4302,9 @@ static int grow_backup(struct mdinfo *sra,
                                                ((char*)&bsb.sb_csum2)-((char*)&bsb));
 
                rv = -1;
-               if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0)
-                   != destoffsets[i] - 4096)
+               if ((unsigned long long)lseek64(destfd[i],
+                                               destoffsets[i] - 4096, 0) !=
+                   destoffsets[i] - 4096)
                        break;
                if (write(destfd[i], &bsb, 512) != 512)
                        break;
@@ -4789,8 +4810,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                                /* reshape_progress is increasing */
                                if ((__le64_to_cpu(bsb.arraystart)
                                     + __le64_to_cpu(bsb.length)
-                                    < info->reshape_progress)
-                                   &&
+                                    < info->reshape_progress) &&
                                    (__le64_to_cpu(bsb.arraystart2)
                                     + __le64_to_cpu(bsb.length2)
                                     < info->reshape_progress))
@@ -5126,7 +5146,7 @@ int Grow_continue_command(char *devname, int fd,
                }
 
                if (sysfs_init(content, fd2, mdstat->devnm)) {
-                       pr_err("Unable to initialize sysfs for %s, Grow cannot continue",
+                       pr_err("Unable to initialize sysfs for %s, Grow cannot continue.\n",
                               mdstat->devnm);
                        ret_val = 1;
                        close(fd2);