]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
mdadm.man: added encouragement to shrink filesystem before array.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 8935ceb94776301c5400a44bbe1023b2cf9397a1..cbefaba45a0f3066ddc6116a7ef2582a8a0990c7 100644 (file)
--- 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 + array.nr_disks; i++) {
+               disk.number = i;
+               if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
+                       continue;
+               if (! (disk.state & (1<<MD_DISK_SYNC)))
+                       continue;
+               if (disk.raid_disk < 0 || disk.raid_disk >= 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);
        }