]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
imsm: validate multiple ppls during assemble
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index e47f5e483cdd9423a9e8dc899270985778958f81..bf5c8c5db282d1d9a9f027d3524bea45597e8742 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -78,7 +78,7 @@ int sysfs_open(char *devnm, char *devname, char *attr)
        return fd;
 }
 
-void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
+void sysfs_init_dev(struct mdinfo *mdi, dev_t devid)
 {
        snprintf(mdi->sys_name,
                 sizeof(mdi->sys_name), "dev-%s", devid2kname(devid));
@@ -162,18 +162,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
                        goto abort;
                sra->array.layout = strtoul(buf, NULL, 0);
        }
-       if (options & GET_DISKS) {
+       if (options & (GET_DISKS|GET_STATE)) {
                strcpy(base, "raid_disks");
                if (load_sys(fname, buf, sizeof(buf)))
                        goto abort;
                sra->array.raid_disks = strtoul(buf, NULL, 0);
        }
-       if (options & GET_DEGRADED) {
-               strcpy(base, "degraded");
-               if (load_sys(fname, buf, sizeof(buf)))
-                       goto abort;
-               sra->array.failed_disks = strtoul(buf, NULL, 0);
-       }
        if (options & GET_COMPONENT) {
                strcpy(base, "component_size");
                if (load_sys(fname, buf, sizeof(buf)))
@@ -359,10 +353,9 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
                        strcpy(dbase, "state");
                        if (load_sys(fname, buf, sizeof(buf)))
                                goto abort;
-                       if (strstr(buf, "faulty")) {
+                       if (strstr(buf, "faulty"))
                                dev->disk.state |= (1<<MD_DISK_FAULTY);
-                               sra->array.failed_disks++;
-                       } else {
+                       else {
                                sra->array.working_disks++;
                                if (strstr(buf, "in_sync")) {
                                        dev->disk.state |= (1<<MD_DISK_SYNC);
@@ -379,6 +372,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
                        dev->errors = strtoul(buf, NULL, 0);
                }
        }
+
+       if ((options & GET_STATE) && sra->array.raid_disks)
+               sra->array.failed_disks = sra->array.raid_disks -
+                       sra->array.active_disks - sra->array.spare_disks;
+
        closedir(dir);
        return sra;
 
@@ -711,8 +709,8 @@ int sysfs_set_array(struct mdinfo *info, int vers)
                if (sysfs_set_str(info, NULL, "consistency_policy",
                                  map_num(consistency_policies,
                                          info->consistency_policy))) {
-                       pr_err("This kernel does not support PPL\n");
-                       return 1;
+                       pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n");
+                       info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
                }
        }
 
@@ -747,7 +745,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
        rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
        rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
        if (sra->array.level != LEVEL_CONTAINER) {
-               if (sd->consistency_policy == CONSISTENCY_POLICY_PPL) {
+               if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) {
                        rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector);
                        rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size);
                }