+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;
+ int _devnum;
+
+ _devnum = use_partitions ? (-1-devnum) : devnum;
+ if (mddev_busy(_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;
+}
+#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
+
+int dev_open(char *dev, int flags)
+{
+ /* like 'open', but if 'dev' matches %d:%d, create a temp
+ * block device and open that
+ */
+ char *e;
+ int fd = -1;
+ char devname[32];
+ int major;
+ int minor;
+
+ if (!dev) return -1;
+
+ major = strtoul(dev, &e, 0);
+ if (e > dev && *e == ':' && e[1] &&
+ (minor = strtoul(e+1, &e, 0)) >= 0 &&
+ *e == 0) {
+ snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d", major, minor);
+ if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
+ fd = open(devname, flags);
+ unlink(devname);
+ }
+ } else
+ fd = open(dev, flags);
+ return fd;
+}