]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
sysfs: Use the presence of /sys/block/<dev>/md as indicator of valid device
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 84c7348526c995929a2d7f07b68ee801d3363529..93ec3de826c1c491c9f92a6255667683b025c66d 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -86,15 +86,22 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
 
 void sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
 {
+       struct stat stb;
+       char fname[MAX_SYSFS_PATH_LEN];
+
        mdi->sys_name[0] = 0;
-       if (fd >= 0) {
-               mdu_version_t vers;
-               if (ioctl(fd, RAID_VERSION, &vers) != 0)
-                       return;
+       if (fd >= 0)
                devnm = fd2devnm(fd);
-       }
+
        if (devnm == NULL)
                return;
+
+       snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm);
+
+       if (stat(fname, &stb))
+               return;
+       if (!S_ISDIR(stb.st_mode))
+               return;
        strcpy(mdi->sys_name, devnm);
 }
 
@@ -242,6 +249,17 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
        } else
                sra->sysfs_array_state[0] = 0;
 
+       if (options & GET_CONSISTENCY_POLICY) {
+               strcpy(base, "consistency_policy");
+               if (load_sys(fname, buf, sizeof(buf))) {
+                       sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+               } else {
+                       sra->consistency_policy = map_name(consistency_policies, buf);
+                       if (sra->consistency_policy == UnSet)
+                               sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+               }
+       }
+
        if (! (options & GET_DEVS))
                return sra;
 
@@ -400,14 +418,8 @@ unsigned long long get_component_size(int fd)
        int n;
        if (fstat(fd, &stb))
                return 0;
-       if (major(stb.st_rdev) != (unsigned)get_mdp_major())
-               snprintf(fname, MAX_SYSFS_PATH_LEN,
-                       "/sys/block/md%d/md/component_size",
-                       (int)minor(stb.st_rdev));
-       else
-               snprintf(fname, MAX_SYSFS_PATH_LEN,
-                       "/sys/block/md_d%d/md/component_size",
-                       (int)minor(stb.st_rdev)>>MdpMinorShift);
+       snprintf(fname, MAX_SYSFS_PATH_LEN,
+                "/sys/block/%s/md/component_size", stat2devnm(&stb));
        fd = open(fname, O_RDONLY);
        if (fd < 0)
                return 0;
@@ -684,6 +696,16 @@ int sysfs_set_array(struct mdinfo *info, int vers)
                 * once the reshape completes.
                 */
        }
+
+       if (info->consistency_policy == CONSISTENCY_POLICY_PPL) {
+               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;
+               }
+       }
+
        return rv;
 }
 
@@ -715,6 +737,10 @@ 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) {
+                       rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector);
+                       rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size);
+               }
                if (sd->recovery_start == MaxSector)
                        /* This can correctly fail if array isn't started,
                         * yet, so just ignore status for now.