summaryrefslogtreecommitdiffstats
path: root/sysfs.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-10-30 16:37:29 +1100
committerNeilBrown <neilb@suse.de>2008-10-30 16:37:29 +1100
commit4ebd3237119b1c1d701ea0c94795631883e449ed (patch)
tree1d8a361a908f5801cced4616a62e544b84be8d69 /sysfs.c
parent7b403fef7e97c16e1eb63773a278eb65c6dfd9a8 (diff)
downloadmdadm-4ebd3237119b1c1d701ea0c94795631883e449ed.tar.gz
mdadm-4ebd3237119b1c1d701ea0c94795631883e449ed.tar.xz
mdadm-4ebd3237119b1c1d701ea0c94795631883e449ed.zip
Adjust major number testing to allow for extended minor number in 2.6.28
From 2.6.28, normal md device will be able to have partitions. These partitions will have a different major number. Sometimes mdadm tests the major number and so can get confused. Change these tests to test against get_mdp_major(). mdp does not use extended minor number and so this test will always be accurate. Also use /sys/dev links to map major/minor to devnum in sysfs. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'sysfs.c')
-rw-r--r--sysfs.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/sysfs.c b/sysfs.c
index 0255f88..6350242 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -83,11 +83,34 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
if (fstat(fd, &stb)) return NULL;
if (ioctl(fd, RAID_VERSION, &vers) != 0)
return NULL;
- if (major(stb.st_rdev)==9)
+ if (major(stb.st_rdev) == MD_MAJOR)
sprintf(sra->sys_name, "md%d", (int)minor(stb.st_rdev));
- else
+ else if (major(stb.st_rdev) == get_mdp_major())
sprintf(sra->sys_name, "md_d%d",
(int)minor(stb.st_rdev)>>MdpMinorShift);
+ else {
+ /* must be an extended-minor partition. Look at the
+ * /sys/dev/block/%d:%d link which must look like
+ * ../../block/mdXXX/mdXXXpYY
+ */
+ char path[30];
+ char link[200];
+ char *cp;
+ int n;
+ sprintf(path, "/sys/dev/block/%d:%d", major(stb.st_rdev),
+ minor(stb.st_rdev));
+ n = readlink(path, link, sizeof(link)-1);
+ if (n <= 0)
+ return NULL;
+ link[n] = 0;
+ cp = strrchr(link, '/');
+ if (cp) *cp = 0;
+ cp = strchr(link, '/');
+ if (cp && strncmp(cp, "/md", 3) == 0)
+ strcpy(sra->sys_name, cp+1);
+ else
+ return NULL;
+ }
} else {
if (devnum >= 0)
sprintf(sra->sys_name, "md%d", devnum);
@@ -244,7 +267,7 @@ unsigned long long get_component_size(int fd)
char fname[50];
int n;
if (fstat(fd, &stb)) return 0;
- if (major(stb.st_rdev) == 9)
+ if (major(stb.st_rdev) != get_mdp_major())
sprintf(fname, "/sys/block/md%d/md/component_size",
(int)minor(stb.st_rdev));
else