From 0a6bff09d41650f27136d56a0604c9af46b6f583 Mon Sep 17 00:00:00 2001 From: Zhilong Liu Date: Thu, 4 May 2017 20:16:21 +0800 Subject: [PATCH] mdadm/util: unify fstat checking blkdev into function 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 Signed-off-by: Jes Sorensen --- Assemble.c | 19 +++++++------------ Build.c | 5 +++-- Create.c | 23 ++++++++++------------- Grow.c | 10 ++++------ Incremental.c | 33 ++++++++++++--------------------- Manage.c | 2 +- bitmap.c | 13 ++++--------- mdadm.h | 1 + super-intel.c | 13 +++---------- util.c | 17 +++++++++++++++++ 10 files changed, 62 insertions(+), 74 deletions(-) diff --git a/Assemble.c b/Assemble.c index a9442c8c..9d0a89ff 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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 665d9067..2d84b96e 100644 --- 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) diff --git a/Create.c b/Create.c index df1bc20c..239545f9 100644 --- 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 f4bd301a..a5274368 100644 --- 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, diff --git a/Incremental.c b/Incremental.c index 8909f2fe..11a34e7c 100644 --- a/Incremental.c +++ b/Incremental.c @@ -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; diff --git a/Manage.c b/Manage.c index 230309b8..af55266b 100644 --- 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; diff --git a/bitmap.c b/bitmap.c index 16a6b735..36536600 100644 --- 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 07ee9635..4adb8409 100644 --- 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); diff --git a/super-intel.c b/super-intel.c index 36f77d3c..c4196ea1 100644 --- a/super-intel.c +++ b/super-intel.c @@ -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 c7585aca..a92faf83 100644 --- 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 = ""; -- 2.39.2