mdadm/util: unify fstat checking blkdev into function
authorZhilong Liu <zlliu@suse.com>
Thu, 4 May 2017 12:16:21 +0000 (20:16 +0800)
committerJes Sorensen <jsorensen@fb.com>
Fri, 5 May 2017 15:04:02 +0000 (11:04 -0400)
declare function fstat_is_blkdev() to integrate repeated fstat
checking block device operations, it returns true/1 when it is
a block device, and returns false/0 when it isn't.
The fd and devname are necessary parameters, *rdev is optional,
parse the pointer of dev_t *rdev, if valid, assigned the device
number to dev_t *rdev, if NULL, ignores.

Signed-off-by: Zhilong Liu <zlliu@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Assemble.c
Build.c
Create.c
Grow.c
Incremental.c
Manage.c
bitmap.c
mdadm.h
super-intel.c
util.c

index a9442c8..9d0a89f 100644 (file)
@@ -149,6 +149,7 @@ static int select_devices(struct mddev_dev *devlist,
        struct mdinfo *content = NULL;
        int report_mismatch = ((inargv && c->verbose >= 0) || c->verbose > 0);
        struct domainlist *domains = NULL;
+       dev_t rdev;
 
        tmpdev = devlist; num_devs = 0;
        while (tmpdev) {
@@ -169,7 +170,6 @@ static int select_devices(struct mddev_dev *devlist,
             tmpdev = tmpdev ? tmpdev->next : NULL) {
                char *devname = tmpdev->devname;
                int dfd;
-               struct stat stb;
                struct supertype *tst;
                struct dev_policy *pol = NULL;
                int found_container = 0;
@@ -204,14 +204,7 @@ static int select_devices(struct mddev_dev *devlist,
                                pr_err("cannot open device %s: %s\n",
                                       devname, strerror(errno));
                        tmpdev->used = 2;
-               } else if (fstat(dfd, &stb)< 0) {
-                       /* Impossible! */
-                       pr_err("fstat failed for %s: %s\n",
-                              devname, strerror(errno));
-                       tmpdev->used = 2;
-               } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-                       pr_err("%s is not a block device.\n",
-                              devname);
+               } else if (!fstat_is_blkdev(dfd, devname, &rdev)) {
                        tmpdev->used = 2;
                } else if (must_be_container(dfd)) {
                        if (st) {
@@ -234,7 +227,8 @@ static int select_devices(struct mddev_dev *devlist,
                                               devname);
                                tmpdev->used = 2;
                        } else if (auto_assem &&
-                                  !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
+                                  !conf_test_metadata(tst->ss->name,
+                                                      (pol = devid_policy(rdev)),
                                                       tst->ss->match_home(tst, c->homehost) == 1)) {
                                if (report_mismatch)
                                        pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
@@ -261,7 +255,8 @@ static int select_devices(struct mddev_dev *devlist,
                                               tst->ss->name, devname);
                                tmpdev->used = 2;
                        } else if (auto_assem && st == NULL &&
-                                  !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
+                                  !conf_test_metadata(tst->ss->name,
+                                                      (pol = devid_policy(rdev)),
                                                       tst->ss->match_home(tst, c->homehost) == 1)) {
                                if (report_mismatch)
                                        pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
@@ -484,7 +479,7 @@ static int select_devices(struct mddev_dev *devlist,
                /* Collect domain information from members only */
                if (tmpdev && tmpdev->used == 1) {
                        if (!pol)
-                               pol = devid_policy(stb.st_rdev);
+                               pol = devid_policy(rdev);
                        domain_merge(&domains, pol, tst?tst->ss->name:NULL);
                }
                dev_policy_free(pol);
diff --git a/Build.c b/Build.c
index 665d906..2d84b96 100644 (file)
--- a/Build.c
+++ b/Build.c
@@ -42,6 +42,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
         */
        int i;
        struct stat stb;
+       dev_t rdev;
        int subdevs = 0, missing_disks = 0;
        struct mddev_dev *dv;
        int bitmap_fd;
@@ -126,8 +127,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
        array.nr_disks = s->raiddisks;
        array.raid_disks = s->raiddisks;
        array.md_minor = 0;
-       if (fstat(mdfd, &stb) == 0)
-               array.md_minor = minor(stb.st_rdev);
+       if (fstat_is_blkdev(mdfd, mddev, &rdev))
+               array.md_minor = minor(rdev);
        array.not_persistent = 1;
        array.state = 0; /* not clean, but no errors */
        if (s->assume_clean)
index df1bc20..239545f 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -89,8 +89,8 @@ int Create(struct supertype *st, char *mddev,
        char *maxdisc = NULL;
        int dnum, raid_disk_num;
        struct mddev_dev *dv;
+       dev_t rdev;
        int fail = 0, warn = 0;
-       struct stat stb;
        int first_missing = subdevs * 2;
        int second_missing = subdevs * 2;
        int missing_disks = 0;
@@ -325,11 +325,8 @@ int Create(struct supertype *st, char *mddev,
                                dname, strerror(errno));
                        exit(2);
                }
-               if (fstat(dfd, &stb) != 0 ||
-                   (stb.st_mode & S_IFMT) != S_IFBLK) {
+               if (!fstat_is_blkdev(dfd, dname, NULL)) {
                        close(dfd);
-                       pr_err("%s is not a block device\n",
-                               dname);
                        exit(2);
                }
                close(dfd);
@@ -641,8 +638,8 @@ int Create(struct supertype *st, char *mddev,
         * with, but it chooses to trust me instead. Sigh
         */
        info.array.md_minor = 0;
-       if (fstat(mdfd, &stb) == 0)
-               info.array.md_minor = minor(stb.st_rdev);
+       if (fstat_is_blkdev(mdfd, mddev, &rdev))
+               info.array.md_minor = minor(rdev);
        info.array.not_persistent = 0;
 
        if (((s->level == 4 || s->level == 5) &&
@@ -841,7 +838,6 @@ int Create(struct supertype *st, char *mddev,
                for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
                     dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
                        int fd;
-                       struct stat stb2;
                        struct mdinfo *inf = &infos[dnum];
 
                        if (dnum >= total_slots)
@@ -897,9 +893,10 @@ int Create(struct supertype *st, char *mddev,
                                                        dv->devname);
                                                goto abort_locked;
                                        }
-                                       fstat(fd, &stb2);
-                                       inf->disk.major = major(stb2.st_rdev);
-                                       inf->disk.minor = minor(stb2.st_rdev);
+                                       if (!fstat_is_blkdev(fd, dv->devname, &rdev))
+                                               return 1;
+                                       inf->disk.major = major(rdev);
+                                       inf->disk.minor = minor(rdev);
                                }
                                if (fd >= 0)
                                        remove_partitions(fd);
@@ -920,8 +917,8 @@ int Create(struct supertype *st, char *mddev,
 
                                if (!have_container) {
                                        /* getinfo_super might have lost these ... */
-                                       inf->disk.major = major(stb2.st_rdev);
-                                       inf->disk.minor = minor(stb2.st_rdev);
+                                       inf->disk.major = major(rdev);
+                                       inf->disk.minor = minor(rdev);
                                }
                                break;
                        case 2:
diff --git a/Grow.c b/Grow.c
index f4bd301..a527436 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -109,7 +109,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
         */
        struct mdinfo info;
 
-       struct stat stb;
+       dev_t rdev;
        int nfd, fd2;
        int d, nd;
        struct supertype *st = NULL;
@@ -145,9 +145,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                free(st);
                return 1;
        }
-       fstat(nfd, &stb);
-       if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-               pr_err("%s is not a block device!\n", newdev);
+       if (!fstat_is_blkdev(nfd, newdev, &rdev)) {
                close(nfd);
                free(st);
                return 1;
@@ -198,8 +196,8 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
         */
 
        info.disk.number = d;
-       info.disk.major = major(stb.st_rdev);
-       info.disk.minor = minor(stb.st_rdev);
+       info.disk.major = major(rdev);
+       info.disk.minor = minor(rdev);
        info.disk.raid_disk = d;
        info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
        st->ss->update_super(st, &info, "linear-grow-new", newdev,
index 8909f2f..11a34e7 100644 (file)
@@ -87,6 +87,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
         *   start the array (auto-readonly).
         */
        struct stat stb;
+       dev_t rdev;
        struct mdinfo info, dinfo;
        struct mdinfo *sra = NULL, *d;
        struct mddev_ident *match;
@@ -174,21 +175,11 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
        /* 2/ Find metadata, reject if none appropriate (check
         *            version/name from args) */
 
-       if (fstat(dfd, &stb) < 0) {
-               if (c->verbose >= 0)
-                       pr_err("fstat failed for %s: %s.\n",
-                               devname, strerror(errno));
-               goto out;
-       }
-       if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-               if (c->verbose >= 0)
-                       pr_err("%s is not a block device.\n",
-                               devname);
+       if (!fstat_is_blkdev(dfd, devname, &rdev))
                goto out;
-       }
 
-       dinfo.disk.major = major(stb.st_rdev);
-       dinfo.disk.minor = minor(stb.st_rdev);
+       dinfo.disk.major = major(rdev);
+       dinfo.disk.minor = minor(rdev);
 
        policy = disk_policy(&dinfo);
        have_target = policy_check_path(&dinfo, &target_array);
@@ -339,8 +330,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
                }
 
                dinfo = info;
-               dinfo.disk.major = major(stb.st_rdev);
-               dinfo.disk.minor = minor(stb.st_rdev);
+               dinfo.disk.major = major(rdev);
+               dinfo.disk.minor = minor(rdev);
                if (add_disk(mdfd, st, &info, &dinfo) != 0) {
                        pr_err("failed to add %s to new array %s: %s.\n",
                                devname, chosen_name, strerror(errno));
@@ -441,8 +432,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
                                goto out_unlock;
                        }
                }
-               info.disk.major = major(stb.st_rdev);
-               info.disk.minor = minor(stb.st_rdev);
+               info.disk.major = major(rdev);
+               info.disk.minor = minor(rdev);
                /* add disk needs to know about containers */
                if (st->ss->external)
                        sra->array.level = LEVEL_CONTAINER;
@@ -863,12 +854,12 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
         * Return 0 on success, or some exit code on failure, probably 1.
         */
        int rv = 1;
-       struct stat stb;
+       dev_t rdev;
        struct map_ent *mp, *map = NULL;
        struct mdinfo *chosen = NULL;
        int dfd = *dfdp;
 
-       if (fstat(dfd, &stb) != 0)
+       if (!fstat_is_blkdev(dfd, devname, &rdev))
                return 1;
 
        /*
@@ -1038,8 +1029,8 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
                        devlist.writemostly = FlagDefault;
                        devlist.failfast = FlagDefault;
                        devlist.devname = chosen_devname;
-                       sprintf(chosen_devname, "%d:%d", major(stb.st_rdev),
-                               minor(stb.st_rdev));
+                       sprintf(chosen_devname, "%d:%d", major(rdev),
+                               minor(rdev));
                        devlist.disposition = 'a';
                        close(dfd);
                        *dfdp = -1;
index 230309b..af55266 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -1513,7 +1513,7 @@ int Manage_subdevs(char *devname, int fd,
                        struct stat stb;
                        tfd = dev_open(dv->devname, O_RDONLY);
                        if (tfd >= 0) {
-                               fstat(tfd, &stb);
+                               fstat_is_blkdev(tfd, dv->devname, &rdev);
                                close(tfd);
                        } else {
                                int open_err = errno;
index 16a6b73..3653660 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -183,7 +183,6 @@ static int
 bitmap_file_open(char *filename, struct supertype **stp, int node_num)
 {
        int fd;
-       struct stat stb;
        struct supertype *st = *stp;
 
        fd = open(filename, O_RDONLY|O_DIRECT);
@@ -193,14 +192,7 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
                return -1;
        }
 
-       if (fstat(fd, &stb) < 0) {
-               pr_err("failed to determine bitmap file/device type: %s\n",
-                       strerror(errno));
-               close(fd);
-               return -1;
-       }
-
-       if ((stb.st_mode & S_IFMT) == S_IFBLK) {
+       if (fstat_is_blkdev(fd, filename, NULL)) {
                /* block device, so we are probably after an internal bitmap */
                if (!st)
                        st = guess_super(fd);
@@ -221,6 +213,9 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
                }
 
                *stp = st;
+       } else {
+               close(fd);
+               return -1;
        }
 
        return fd;
diff --git a/mdadm.h b/mdadm.h
index 07ee963..4adb840 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1434,6 +1434,7 @@ extern int check_raid(int fd, char *name);
 extern int check_partitions(int fd, char *dname,
                            unsigned long long freesize,
                            unsigned long long size);
+extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
 
 extern int get_mdp_major(void);
 extern int get_maj_min(char *dev, int *major, int *minor);
index 36f77d3..c4196ea 100644 (file)
@@ -6562,7 +6562,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
 
        for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
                char *devname = tmpdev->devname;
-               struct stat stb;
+               dev_t rdev;
                struct supertype *tst;
                int dfd;
                if (tmpdev->used > 1)
@@ -6578,14 +6578,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
                        dprintf("cannot open device %s: %s\n",
                                devname, strerror(errno));
                        tmpdev->used = 2;
-               } else if (fstat(dfd, &stb)< 0) {
-                       /* Impossible! */
-                       dprintf("fstat failed for %s: %s\n",
-                               devname, strerror(errno));
-                       tmpdev->used = 2;
-               } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-                       dprintf("%s is not a block device.\n",
-                               devname);
+               } else if (!fstat_is_blkdev(dfd, devname, &rdev)) {
                        tmpdev->used = 2;
                } else if (must_be_container(dfd)) {
                        struct supertype *cst;
@@ -6607,7 +6600,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
                        if (cst)
                                cst->ss->free_super(cst);
                } else {
-                       tmpdev->st_rdev = stb.st_rdev;
+                       tmpdev->st_rdev = rdev;
                        if (tst->ss->load_super(tst,dfd, NULL)) {
                                dprintf("no RAID superblock on %s\n",
                                        devname);
diff --git a/util.c b/util.c
index c7585ac..a92faf8 100644 (file)
--- a/util.c
+++ b/util.c
@@ -730,6 +730,23 @@ int check_raid(int fd, char *name)
        return 1;
 }
 
+int fstat_is_blkdev(int fd, char *devname, dev_t *rdev)
+{
+       struct stat stb;
+
+       if (fstat(fd, &stb) != 0) {
+               pr_err("fstat failed for %s: %s\n", devname, strerror(errno));
+               return 0;
+       }
+       if ((S_IFMT & stb.st_mode) != S_IFBLK) {
+               pr_err("%s is not a block device.\n", devname);
+               return 0;
+       }
+       if (rdev)
+               *rdev = stb.st_rdev;
+       return 1;
+}
+
 int ask(char *mesg)
 {
        char *add = "";