Unify code into find_free_devnum.
authorNeil Brown <neilb@suse.de>
Mon, 5 May 2008 11:55:36 +0000 (21:55 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 5 May 2008 11:55:36 +0000 (21:55 +1000)
Two places have code to find a free md device number.  Make this
a subroutine.

Incremental.c
mdadm.h
mdopen.c
util.c

index 4c6a2a7..b54c4fc 100644 (file)
@@ -246,20 +246,15 @@ int Incremental(char *devname, int verbose, int runstop,
 
                if (devnum < 0) {
                        /* Haven't found anything yet, choose something free */
-                       /* There is similar code in mdopen.c - should unify */
-                       for (devnum = 127 ; devnum != 128 ;
-                            devnum = devnum ? devnum-1 : (1<<22)-1) {
-                               if (mddev_busy(use_partitions ?
-                                              (-1-devnum) : devnum))
-                                       break;
-                       }
-                       if (devnum == 128) {
+                       devnum = find_free_devnum(use_partitions);
+
+                       if (devnum == NoMdDev) {
                                fprintf(stderr, Name
                                        ": No spare md devices!!\n");
                                return 2;
                        }
-               }
-               devnum = use_partitions ? (-1-devnum) : devnum;
+               } else
+                       devnum = use_partitions ? (-1-devnum) : devnum;
        }
        mdfd = open_mddev_devnum(match ? match->devname : NULL,
                                 devnum,
diff --git a/mdadm.h b/mdadm.h
index 2a5e1c8..2f62c41 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -513,6 +513,9 @@ extern void remove_partitions(int fd);
 extern char *human_size(long long bytes);
 char *human_size_brief(long long bytes);
 
+#define NoMdDev (1<<23)
+extern int find_free_devnum(int use_partitions);
+
 extern void put_md_name(char *name);
 extern char *get_md_name(int dev);
 
index 7f6a2ea..fe98370 100644 (file)
--- a/mdopen.c
+++ b/mdopen.c
@@ -113,7 +113,6 @@ int open_mddev(char *dev, int autof)
        int major_num = MD_MAJOR;
        int minor_num = 0;
        int must_remove = 0;
-       struct mdstat_ent *mdlist;
        int num;
        struct createinfo *ci = conf_get_create_info();
        int parts;
@@ -197,37 +196,12 @@ int open_mddev(char *dev, int autof)
                 */
                if (num < 0) {
                        /* need to pick an unused number */
-                       mdlist = mdstat_read(0, 0);
-                       /* Choose a large number.  Start from 127 and search down,
-                        * but if nothing is found, start really big
-                        */
-                       for (num = 127 ; num != 128 ; num = num ? num-1 : (1<<22)-1) {
-                               struct mdstat_ent *me;
-                               int devnum = num;
-                               if (major_num != MD_MAJOR)
-                                       devnum = -1-num;
+                       int num = find_free_devnum(major_num != MD_MAJOR);
 
-                               for (me=mdlist; me; me=me->next)
-                                       if (me->devnum == devnum)
-                                               break;
-                               if (!me) {
-                                       /* doesn't exist in mdstat.
-                                        * make sure it is new to /dev too
-                                        */
-                                       char *dn;
-                                       if (major_num != MD_MAJOR)
-                                               minor_num = num << MdpMinorShift;
-                                       else
-                                               minor_num = num;
-                                       dn = map_dev(major_num,minor_num, 0);
-                                       if (dn==NULL || is_standard(dn, NULL)) {
-                                               /* this number only used by a 'standard' name,
-                                                * so it is safe to use
-                                                */
-                                               break;
-                                       }
-                               }
-                       }
+                       if (major_num == MD_MAJOR)
+                               minor_num = num;
+                       else
+                               minor_num = (-1-num) << MdpMinorShift;
                } else if (major_num == MD_MAJOR)
                        minor_num = num;
                else
diff --git a/util.c b/util.c
index dbe4640..514b713 100644 (file)
--- a/util.c
+++ b/util.c
@@ -862,6 +862,43 @@ void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk)
                if (ioctl(mdfd, GET_DISK_INFO, disk) == 0)
                        return;
 }
+
+static int dev2major(int d)
+{
+       if (d >= 0)
+               return MD_MAJOR;
+       else
+               return get_mdp_major();
+}
+
+static int dev2minor(int d)
+{
+       if (d >= 0)
+               return d;
+       return (-1-d) << MdpMinorShift;
+}
+
+int find_free_devnum(int use_partitions)
+{
+       int devnum;
+       for (devnum = 127; devnum != 128;
+            devnum = devnum ? devnum-1 : (1<<22)-1) {
+               char *dn;
+               if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
+                       continue;
+               /* make sure it is new to /dev too, at least as a
+                * non-standard */
+               dn = map_dev(dev2major(devnum), dev2minor(devnum), 0);
+               if (dn && ! is_standard(dn, NULL))
+                       continue;
+               break;
+       }
+       if (devnum == 128)
+               return NoMdDev;
+       return use_partitions ? (-1-devnum) : devnum;
+}
+
+
 #ifdef __TINYC__
 /* tinyc doesn't optimize this check in ioctl.h out ... */
 unsigned int __invalid_size_argument_for_IOC = 0;