X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=sysfs.c;h=f7967e88489ae45a9306b5aa1fa7c3a94b8e476c;hp=84c7348526c995929a2d7f07b68ee801d3363529;hb=64ec81da7a70adcdc0dbccaacc69aaf90edb4011;hpb=bb758ccad0e9e47af565d4e23b43aa5a8ceb9886 diff --git a/sysfs.c b/sysfs.c index 84c73485..f7967e88 100644 --- a/sysfs.c +++ b/sysfs.c @@ -84,18 +84,30 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) sizeof(mdi->sys_name), "dev-%s", devid2kname(devid)); } -void sysfs_init(struct mdinfo *mdi, int fd, char *devnm) +int sysfs_init(struct mdinfo *mdi, int fd, char *devnm) { + struct stat stb; + char fname[MAX_SYSFS_PATH_LEN]; + int retval = -ENODEV; + 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; + goto out; + + snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm); + + if (stat(fname, &stb)) + goto out; + if (!S_ISDIR(stb.st_mode)) + goto out; strcpy(mdi->sys_name, devnm); + + retval = 0; +out: + return retval; } struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) @@ -110,8 +122,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) struct dirent *de; sra = xcalloc(1, sizeof(*sra)); - sysfs_init(sra, fd, devnm); - if (sra->sys_name[0] == 0) { + if (sysfs_init(sra, fd, devnm)) { free(sra); return NULL; } @@ -236,11 +247,19 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (options & GET_ARRAY_STATE) { strcpy(base, "array_state"); - if (load_sys(fname, sra->sysfs_array_state, - sizeof(sra->sysfs_array_state))) + if (load_sys(fname, buf, sizeof(buf))) goto abort; - } else - sra->sysfs_array_state[0] = 0; + sra->array_state = map_name(sysfs_array_states, buf); + } + + 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 (! (options & GET_DEVS)) return sra; @@ -251,6 +270,8 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (!dir) goto abort; sra->array.spare_disks = 0; + sra->array.active_disks = 0; + sra->array.failed_disks = 0; devp = &sra->devs; sra->devs = NULL; @@ -337,10 +358,14 @@ 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, "in_sync")) + if (strstr(buf, "in_sync")) { dev->disk.state |= (1<array.active_disks++; + } + if (strstr(buf, "faulty")) { dev->disk.state |= (1<array.failed_disks++; + } if (dev->disk.state == 0) sra->array.spare_disks++; } @@ -400,14 +425,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 +703,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 +744,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.