summaryrefslogtreecommitdiff
path: root/sysfs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-08-25 19:14:19 -0700
committerNeilBrown <neilb@suse.de>2011-08-30 10:49:42 +1000
commitd8924477b7fc513a54249b1b0c617adbfb78c7fe (patch)
tree55398253b1d81c5f19e7bab70c2d6cf6cc14ccd0 /sysfs.c
parent0ec1f4e8de3bb7c1b1086d39586123993647fa3f (diff)
sysfs: fix sysfs_disk_to_scsi_id
Not sure how this ever worked, but now we just try to parse a directory name that looks like <host>:<bus>:<target>:<lun>. Array creation segfaults on Fedora 14 without this. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'sysfs.c')
-rw-r--r--sysfs.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/sysfs.c b/sysfs.c
index 56813b7d..21462642 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -709,9 +709,9 @@ int sysfs_disk_to_scsi_id(int fd, __u32 *id)
/* from an open block device, try to retrieve it scsi_id */
struct stat st;
char path[256];
- char *c1, *c2;
DIR *dir;
struct dirent *de;
+ int host, bus, target, lun;
if (fstat(fd, &st))
return 1;
@@ -723,32 +723,22 @@ int sysfs_disk_to_scsi_id(int fd, __u32 *id)
if (!dir)
return 1;
- de = readdir(dir);
- while (de) {
- if (strchr(de->d_name, ':'))
+ for (de = readdir(dir); de; de = readdir(dir)) {
+ int count;
+
+ if (de->d_type != DT_DIR)
+ continue;
+
+ count = sscanf(de->d_name, "%d:%d:%d:%d", &host, &bus, &target, &lun);
+ if (count == 4)
break;
- de = readdir(dir);
}
closedir(dir);
if (!de)
return 1;
- c1 = de->d_name;
- c2 = strchr(c1, ':');
- *c2 = '\0';
- *id = strtol(c1, NULL, 10) << 24; /* host */
- c1 = c2 + 1;
- c2 = strchr(c1, ':');
- *c2 = '\0';
- *id |= strtol(c1, NULL, 10) << 16; /* bus */
- c1 = c2 + 1;
- c2 = strchr(c1, ':');
- *c2 = '\0';
- *id |= strtol(c1, NULL, 10) << 8; /* target */
- c1 = c2 + 1;
- *id |= strtol(c1, NULL, 10); /* lun */
-
+ *id = (host << 24) | (bus << 16) | (target << 8) | (lun << 0);
return 0;
}