X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=util.c;h=cbefaba45a0f3066ddc6116a7ef2582a8a0990c7;hb=666bba9b5011150ff01de421dd44b06c0a6610a5;hp=8935ceb94776301c5400a44bbe1023b2cf9397a1;hpb=753cf9051223992dc8f18b46d26650fe52e6f2f8;p=thirdparty%2Fmdadm.git diff --git a/util.c b/util.c index 8935ceb9..cbefaba4 100644 --- a/util.c +++ b/util.c @@ -376,6 +376,36 @@ int enough(int level, int raid_disks, int layout, int clean, } } +int enough_fd(int fd) +{ + struct mdu_array_info_s array; + struct mdu_disk_info_s disk; + int avail_disks = 0; + int i; + char *avail; + + if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 || + array.raid_disks <= 0) + return 0; + avail = calloc(array.raid_disks, 1); + for (i=0; i= array.raid_disks) + continue; + avail_disks++; + avail[disk.raid_disk] = 1; + } + /* This is used on an active array, so assume it is clean */ + return enough(array.level, array.raid_disks, array.layout, + 1, + avail, avail_disks); +} + + const int uuid_match_any[4] = { ~0, ~0, ~0, ~0 }; int same_uuid(int a[4], int b[4], int swapuuid) { @@ -959,19 +989,33 @@ int dev_open(char *dev, int flags) int minor; if (!dev) return -1; + flags |= O_DIRECT; 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:%d", - (int)getpid(), major, minor); - if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) { - fd = open(devname, flags|O_DIRECT); - unlink(devname); + char *path = map_dev(major, minor, 0); + if (path) + fd = open(path, flags); + if (fd < 0) { + snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d", + (int)getpid(), major, minor); + if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) { + fd = open(devname, flags); + unlink(devname); + } + } + if (fd < 0) { + snprintf(devname, sizeof(devname), "/tmp/.tmp.md.%d:%d:%d", + (int)getpid(), major, minor); + if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) { + fd = open(devname, flags); + unlink(devname); + } } } else - fd = open(dev, flags|O_DIRECT); + fd = open(dev, flags); return fd; } @@ -980,7 +1024,7 @@ int open_dev(int devnum) char buf[20]; sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum)); - return dev_open(buf, O_RDWR); + return dev_open(buf, O_RDONLY); } int open_dev_excl(int devnum) @@ -1131,7 +1175,7 @@ struct supertype *guess_super(int fd) */ struct superswitch *ss; struct supertype *st; - unsigned long besttime = 0; + time_t besttime = 0; int bestsuper = -1; int i; @@ -1207,7 +1251,7 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart) struct GPT_part_entry *part; unsigned long long curr_part_end; unsigned all_partitions, entry_size; - int part_nr; + unsigned part_nr; *endofpart = 0; @@ -1266,7 +1310,7 @@ static int get_last_partition_end(int fd, unsigned long long *endofpart) struct MBR boot_sect; struct MBR_part_record *part; unsigned long long curr_part_end; - int part_nr; + unsigned part_nr; int retval = 0; *endofpart = 0; @@ -1376,7 +1420,7 @@ int open_container(int fd) continue; n = read(dfd, buf, sizeof(buf)); close(dfd); - if (n <= 0 || n >= sizeof(buf)) + if (n <= 0 || (unsigned)n >= sizeof(buf)) continue; buf[n] = 0; if (sscanf(buf, "%d:%d", &major, &minor) != 2) @@ -1635,7 +1679,7 @@ int stat2devnum(struct stat *st) if ((S_IFMT & st->st_mode) == S_IFBLK) { if (major(st->st_rdev) == MD_MAJOR) return minor(st->st_rdev); - else if (major(st->st_rdev) == get_mdp_major()) + else if (major(st->st_rdev) == (unsigned)get_mdp_major()) return -1- (minor(st->st_rdev)>>MdpMinorShift); /* must be an extended-minor partition. Look at the @@ -1650,7 +1694,7 @@ int stat2devnum(struct stat *st) link[n] = 0; cp = strrchr(link, '/'); if (cp) *cp = 0; - cp = strchr(link, '/'); + cp = strrchr(link, '/'); if (cp && strncmp(cp, "/md", 3) == 0) return devname2devnum(cp+1); }