summaryrefslogtreecommitdiff
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
parent7b403fef7e97c16e1eb63773a278eb65c6dfd9a8 (diff)
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>
-rw-r--r--Detail.c2
-rw-r--r--sysfs.c29
2 files changed, 27 insertions, 4 deletions
diff --git a/Detail.c b/Detail.c
index 9ba8af1d..3cee66fe 100644
--- a/Detail.c
+++ b/Detail.c
@@ -169,7 +169,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
struct mdstat_ent *ms = mdstat_read(0, 0);
struct mdstat_ent *e;
int devnum = array.md_minor;
- if (major(stb.st_rdev) != MD_MAJOR)
+ if (major(stb.st_rdev) == get_mdp_major())
devnum = -1 - devnum;
for (e=ms; e; e=e->next)
diff --git a/sysfs.c b/sysfs.c
index 0255f882..6350242b 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