if (strncmp(name, "/dev/.tmp.md", 12)==0)
unlink(name);
}
+
+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;
+ 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)
struct superswitch *superlist[] = { &super0, &super1, NULL };
+#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
struct supertype *super_by_fd(int fd)
{
mdu_array_info_t array;
int minor;
struct supertype *st = NULL;
struct mdinfo *sra;
- char *verstr = NULL;
+ char *verstr;
char version[20];
int i;
if (sra) {
vers = sra->array.major_version;
minor = sra->array.minor_version;
+ verstr = sra->text_version;
} else {
if (ioctl(fd, GET_ARRAY_INFO, &array))
array.major_version = array.minor_version = 0;
vers = array.major_version;
minor = array.minor_version;
+ verstr = "";
}
if (vers != -1) {
if (sra)
sysfs_free(sra);
- st->sb = NULL;
+ if (st)
+ st->sb = NULL;
return st;
}
+#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
+
struct supertype *dup_super(struct supertype *st)
{
if (!st)
return st;
- if (st->minor_version == -1)
+ if (st->ss->text_version)
+ strcpy(version, st->ss->text_version);
+ else if (st->minor_version == -1)
sprintf(version, "%d", st->ss->major);
else
sprintf(version, "%d.%d", st->ss->major, st->minor_version);
for (i = 0; stnew == NULL && superlist[i] ; i++)
stnew = superlist[i]->match_metadata_desc(verstr);
- stnew->sb = NULL;
+ if (stnew)
+ stnew->sb = NULL;
return stnew;
}
st->ss = NULL;
rv = superlist[bestsuper]->load_super(st, fd, NULL);
if (rv == 0) {
- ss->free_super(st);
+ superlist[bestsuper]->free_super(st);
return st;
}
}
int get_dev_size(int fd, char *dname, unsigned long long *sizep)
{
unsigned long long ldsize;
+ struct stat st;
+
+ if (fstat(fd, &st) != -1 && S_ISREG(st.st_mode))
+ ldsize = (unsigned long long)st.st_size;
+ else
#ifdef BLKGETSIZE64
if (ioctl(fd, BLKGETSIZE64, &ldsize) != 0)
#endif
if (ioctl(mdfd, GET_DISK_INFO, disk) == 0)
return;
}
+
#ifdef __TINYC__
/* tinyc doesn't optimize this check in ioctl.h out ... */
unsigned int __invalid_size_argument_for_IOC = 0;