]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Use dev_t for devnm2devid and devid2devnm
authorMike Lovell <mlovell@bluehost.com>
Wed, 18 May 2016 18:23:13 +0000 (12:23 -0600)
committerJes Sorensen <Jes.Sorensen@redhat.com>
Fri, 3 Jun 2016 19:35:26 +0000 (15:35 -0400)
Commit 4dd2df0966ec added a trip through makedev(), major(), and minor() for
device major and minor numbers. This would cause mdadm to fail in operating
on a device with a minor number bigger than (2^19)-1 due to it changing
from dev_t to a signed int and back.

Where this was found as a problem was when a array was created with a device
specified as a name like /dev/md/raidname and there were already 128 arrays
on the system. In this case, mdadm would chose 1048575 ((2^20)-1) for the
array and minor number. This would cause the major and minor number to become
negative when generated from devnm2devid() and passed to major() and minor()
in open_dev_excl(). open_dev_excl() would then call dev_open() which would
detect the negative minor number and call open() on the *char containing the
major:minor pair which isn't a valid file.

Signed-off-by: Mike Lovell <mlovell@bluehost.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Detail.c
Grow.c
lib.c
mapfile.c
mdadm.h
mdopen.c
util.c

index 20c4553f97b5e4bc4c02eba8995d3a651e653242..7a984c83b3fb6fb97bb813586fe95b0b4ebd23de 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -130,7 +130,7 @@ int Detail(char *dev, struct context *c)
                /* This is a subarray of some container.
                 * We want the name of the container, and the member
                 */
-               int devid = devnm2devid(st->container_devnm);
+               dev_t devid = devnm2devid(st->container_devnm);
                int cfd, err;
 
                member = subarray;
@@ -577,7 +577,7 @@ This is pretty boring
                                char path[200];
                                char vbuf[1024];
                                int nlen = strlen(sra->sys_name);
-                               int devid;
+                               dev_t devid;
                                if (de->d_name[0] == '.')
                                        continue;
                                sprintf(path, "/sys/block/%s/md/metadata_version",
diff --git a/Grow.c b/Grow.c
index 98b0fab8fd08a84e9e45b773c01877bc3161a5f9..f184d9c4e988a6be9d444407ec2adc7766413d5f 100755 (executable)
--- a/Grow.c
+++ b/Grow.c
@@ -3533,7 +3533,7 @@ int reshape_container(char *container, char *devname,
                int fd;
                struct mdstat_ent *mdstat;
                char *adev;
-               int devid;
+               dev_t devid;
 
                sysfs_free(cc);
 
diff --git a/lib.c b/lib.c
index 621edf3bfb29afc9250783080488f8149dd2028b..3ee7659b7b43ac7e80de8ecd9086765b7ddcaeda 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -99,7 +99,7 @@ char *fd2kname(int fd)
        return NULL;
 }
 
-char *devid2devnm(int devid)
+char *devid2devnm(dev_t devid)
 {
        char path[30];
        char link[200];
index 243ded18d9fb628b1198555f532ed53c9b2a3b1b..c89d403f4e32b22c9a2e682c85617f354cf86e7c 100644 (file)
--- a/mapfile.c
+++ b/mapfile.c
@@ -374,7 +374,7 @@ void RebuildMap(void)
                        char dn[30];
                        int dfd;
                        int ok;
-                       int devid;
+                       dev_t devid;
                        struct supertype *st;
                        char *subarray = NULL;
                        char *path;
diff --git a/mdadm.h b/mdadm.h
index b8705854aba32b3b1a62e934e4385a57f006187e..3d6c638eb3dd219dabc42c17d0364ab8c8246161 100755 (executable)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1440,8 +1440,8 @@ extern char *find_free_devnm(int use_partitions);
 
 extern void put_md_name(char *name);
 extern char *devid2kname(int devid);
-extern char *devid2devnm(int devid);
-extern int devnm2devid(char *devnm);
+extern char *devid2devnm(dev_t devid);
+extern dev_t devnm2devid(char *devnm);
 extern char *get_md_name(char *devnm);
 
 extern char DefaultConfFile[];
index 28410f467f95010379af600a5254354383e8e733..e71d7586cf79d36023eed8beaf45d62af8aaaf01 100644 (file)
--- a/mdopen.c
+++ b/mdopen.c
@@ -348,7 +348,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
                if (lstat(devname, &stb) == 0) {
                        /* Must be the correct device, else error */
                        if ((stb.st_mode&S_IFMT) != S_IFBLK ||
-                           stb.st_rdev != (dev_t)devnm2devid(devnm)) {
+                           stb.st_rdev != devnm2devid(devnm)) {
                                pr_err("%s exists but looks wrong, please fix\n",
                                        devname);
                                return -1;
@@ -452,7 +452,7 @@ char *find_free_devnm(int use_partitions)
                if (!use_udev()) {
                        /* make sure it is new to /dev too, at least as a
                         * non-standard */
-                       int devid = devnm2devid(devnm);
+                       dev_t devid = devnm2devid(devnm);
                        if (devid) {
                                char *dn = map_dev(major(devid),
                                                   minor(devid), 0);
diff --git a/util.c b/util.c
index 2bcb81fa921a9150aa0ab639f9b68529d61ac1ee..31c407a6489b523dce422c706018607095cbdb62 100644 (file)
--- a/util.c
+++ b/util.c
@@ -928,7 +928,7 @@ int get_data_disks(int level, int layout, int raid_disks)
        return data_disks;
 }
 
-int devnm2devid(char *devnm)
+dev_t devnm2devid(char *devnm)
 {
        /* First look in /sys/block/$DEVNM/dev for %d:%d
         * If that fails, try parsing out a number
@@ -1065,7 +1065,7 @@ int dev_open(char *dev, int flags)
 
 int open_dev_flags(char *devnm, int flags)
 {
-       int devid;
+       dev_t devid;
        char buf[20];
 
        devid = devnm2devid(devnm);
@@ -1083,7 +1083,7 @@ int open_dev_excl(char *devnm)
        char buf[20];
        int i;
        int flags = O_RDWR;
-       int devid = devnm2devid(devnm);
+       dev_t devid = devnm2devid(devnm);
        long delay = 1000;
 
        sprintf(buf, "%d:%d", major(devid), minor(devid));