Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f384741c961... Commit: f384741c961d1781a39e61e58d2de2d09b50551f Parent: 531eead1d0ab1bff33e8edbffa2f36ee2e0eadd0 Author: Andrew Price anprice@redhat.com AuthorDate: Thu Mar 21 19:19:47 2013 +0000 Committer: Andrew Price anprice@redhat.com CommitterDate: Tue May 14 14:05:12 2013 +0100
mkfs.gfs2: Add a struct to store device info
Adds a struct mkfs_dev to store the fd, topology and stat info for the target. Not using lgfs2_device_info as we now probe the topology with libblkid so that functionality should eventually disappear from libgfs2.
Signed-off-by: Andrew Price anprice@redhat.com --- gfs2/mkfs/main_mkfs.c | 173 +++++++++++++++++++++++++++++++++---------------- 1 files changed, 118 insertions(+), 55 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 3d6f724..6265c58 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -113,6 +113,27 @@ struct mkfs_opts { unsigned confirm:1; };
+/** + * Values probed by libblkid: + * alignment_offset: offset, in bytes, of the start of the dev from its natural alignment + * logical_sector_size: smallest addressable unit + * minimum_io_size: device's preferred unit of I/O. RAID stripe unit. + * optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width. + * physical_sector_size: the smallest unit we can write atomically + */ +struct mkfs_dev { + int fd; + struct stat stat; + uint64_t size; + unsigned long alignment_offset; + unsigned long logical_sector_size; + unsigned long minimum_io_size; + unsigned long optimal_io_size; + unsigned long physical_sector_size; + + unsigned int got_topol:1; +}; + static void opts_init(struct mkfs_opts *opts) { memset(opts, 0, sizeof(*opts)); @@ -401,25 +422,26 @@ static void are_you_sure(void) free(line); }
-static unsigned choose_blocksize(struct mkfs_opts *opts, struct lgfs2_dev_info *dinfo) +static unsigned choose_blocksize(struct mkfs_opts *opts, const struct mkfs_dev *dev) { unsigned int x; unsigned int bsize = opts->bsize;
- if (!opts->got_bsize) { - if (S_ISREG(dinfo->stat.st_mode)) - bsize = GFS2_DEFAULT_BSIZE; - /* See if optimal_io_size (the biggest I/O we can submit - without incurring a penalty) is a suitable block size. */ - else if (dinfo->io_optimal_size <= getpagesize() && dinfo->io_optimal_size >= dinfo->io_min_size) - bsize = dinfo->io_optimal_size; - /* See if physical_block_size (the smallest unit we can write - without incurring read-modify-write penalty) is suitable. */ - else if (dinfo->physical_block_size <= getpagesize() && dinfo->physical_block_size >= GFS2_DEFAULT_BSIZE) - bsize = dinfo->physical_block_size; - else - bsize = GFS2_DEFAULT_BSIZE; + if (dev->got_topol && opts->debug) { + printf("alignment_offset: %lu\n", dev->alignment_offset); + printf("logical_sector_size: %lu\n", dev->logical_sector_size); + printf("minimum_io_size: %lu\n", dev->minimum_io_size); + printf("optimal_io_size: %lu\n", dev->optimal_io_size); + printf("physical_sector_size: %lu\n", dev->physical_sector_size); + }
+ if (!opts->got_bsize && dev->got_topol) { + if (dev->optimal_io_size <= getpagesize() && + dev->optimal_io_size >= dev->minimum_io_size) + bsize = dev->optimal_io_size; + else if (dev->physical_sector_size <= getpagesize() && + dev->physical_sector_size >= GFS2_DEFAULT_BSIZE) + bsize = dev->physical_sector_size; }
/* Block sizes must be a power of two from 512 to 65536 */ @@ -431,15 +453,15 @@ static unsigned choose_blocksize(struct mkfs_opts *opts, struct lgfs2_dev_info * die( _("Block size must be a power of two between 512 and %d\n"), getpagesize());
- if (bsize < dinfo->logical_block_size) { + if (bsize < dev->logical_sector_size) { die( _("Error: Block size %d is less than minimum logical " - "block size (%d).\n"), bsize, dinfo->logical_block_size); + "block size (%lu).\n"), bsize, dev->logical_sector_size); }
- if (bsize < dinfo->physical_block_size) { + if (bsize < dev->physical_sector_size) { printf( _("Warning: Block size %d is inefficient because it " - "is less than the physical block size (%d).\n"), - bsize, dinfo->physical_block_size); + "is less than the physical block size (%lu).\n"), + bsize, dev->physical_sector_size); opts->confirm = 1; } return bsize; @@ -447,6 +469,11 @@ static unsigned choose_blocksize(struct mkfs_opts *opts, struct lgfs2_dev_info *
static void opts_check(struct mkfs_opts *opts) { + if (!opts->got_device) { + fprintf(stderr, _("No device specified. Use -h for help\n")); + exit(1); + } + if (!opts->expert) test_locking(opts->lockproto, opts->locktable); if (opts->expert) { @@ -600,7 +627,7 @@ static int place_rgrps(struct gfs2_sbd *sdp, const struct mkfs_opts *opts) return 0; }
-static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_dev_info *dinfo, int fd) +static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_dev *dev) { memset(sdp, 0, sizeof(struct gfs2_sbd)); sdp->time = time(NULL); @@ -609,20 +636,20 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_ sdp->qcsize = opts->qcsize; sdp->jsize = opts->jsize; sdp->md.journals = opts->journals; - sdp->device_fd = fd; - sdp->bsize = choose_blocksize(opts, dinfo); + sdp->device_fd = dev->fd; + sdp->bsize = choose_blocksize(opts, dev);
if (compute_constants(sdp)) { perror(_("Failed to compute file system constants")); exit(1); } - sdp->device.length = dinfo->size / sdp->bsize; + sdp->device.length = dev->size / sdp->bsize; if (opts->got_fssize) { if (opts->fssize > sdp->device.length) { fprintf(stderr, _("Specified size is bigger than the device.")); - die("%s %.2f %s (%llu %s)\n", _("Device size:"), - dinfo->size / ((float)(1 << 30)), _("GB"), - (unsigned long long)dinfo->size / sdp->bsize, _("blocks")); + die("%s %.2f %s (%"PRIu64" %s)\n", _("Device size:"), + dev->size / ((float)(1 << 30)), _("GB"), + dev->size / sdp->bsize, _("blocks")); } /* TODO: Check if the fssize is too small, somehow */ sdp->device.length = opts->fssize; @@ -644,18 +671,23 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_ } }
-static int probe_contents(int fd) +static int probe_contents(struct mkfs_dev *dev) { int ret; const char *contents; blkid_probe pr = blkid_new_probe(); - if (pr == NULL || blkid_probe_set_device(pr, fd, 0, 0) != 0 + if (pr == NULL || blkid_probe_set_device(pr, dev->fd, 0, 0) != 0 || blkid_probe_enable_superblocks(pr, TRUE) != 0 || blkid_probe_enable_partitions(pr, TRUE) != 0) { fprintf(stderr, _("Failed to create probe\n")); return -1; }
+ if (!S_ISREG(dev->stat.st_mode) && blkid_probe_enable_topology(pr, TRUE) != 0) { + fprintf(stderr, _("Failed to create probe\n")); + return -1; + } + ret = blkid_do_fullprobe(pr); if (ret == -1) { fprintf(stderr, _("Failed to probe device\n")); @@ -671,53 +703,84 @@ static int probe_contents(int fd) printf(_("It appears to contain a partition table (%s).\n"), contents); }
- blkid_free_probe(pr); + if (!S_ISREG(dev->stat.st_mode)) { + blkid_topology tp = blkid_probe_get_topology(pr); + if (tp != NULL) { + dev->alignment_offset = blkid_topology_get_alignment_offset(tp); + dev->logical_sector_size = blkid_topology_get_logical_sector_size(tp); + dev->minimum_io_size = blkid_topology_get_minimum_io_size(tp); + dev->optimal_io_size = blkid_topology_get_optimal_io_size(tp); + dev->physical_sector_size = blkid_topology_get_physical_sector_size(tp); + dev->got_topol = 1; + } + }
+ blkid_free_probe(pr); return 0; }
+static void open_dev(const char *path, struct mkfs_dev *dev) +{ + int error; + + memset(dev, 0, sizeof(*dev)); + dev->fd = open(path, O_RDWR | O_CLOEXEC); + if (dev->fd < 0) { + perror(path); + exit(1); + } + + error = fstat(dev->fd, &dev->stat); + if (error < 0) { + perror(path); + exit(1); + } + + if (S_ISREG(dev->stat.st_mode)) { + dev->size = dev->stat.st_size; + } else if (S_ISBLK(dev->stat.st_mode)) { + dev->size = lseek(dev->fd, 0, SEEK_END); + if (dev->size < 1) { + fprintf(stderr, _("Device '%s' is too small\n"), path); + exit(1); + } + } else { + fprintf(stderr, _("'%s' is not a block device or regular file\n"), path); + exit(1); + } + + error = probe_contents(dev); + if (error) + exit(1); +} + void main_mkfs(int argc, char *argv[]) { struct gfs2_sbd sbd; struct mkfs_opts opts; - struct lgfs2_dev_info dinfo; + struct mkfs_dev dev; int error; unsigned char uuid[16]; - int fd;
opts_init(&opts); opts_get(argc, argv, &opts); + opts_check(&opts);
- if (!opts.got_device) { - fprintf(stderr, _("No device specified. Use -h for help\n")); - exit(1); - } - - fd = open(opts.device, O_RDWR | O_CLOEXEC); - if (fd < 0){ - perror(opts.device); - exit(EXIT_FAILURE); - } + open_dev(opts.device, &dev);
- if (lgfs2_get_dev_info(fd, &dinfo) < 0) { - perror(opts.device); - exit(EXIT_FAILURE); + if (S_ISREG(dev.stat.st_mode)) { + opts.got_bsize = 1; /* Use default block size for regular files */ }
- opts_check(&opts); warn_of_destruction(opts.device);
- error = probe_contents(fd); - if (error) - exit(EXIT_FAILURE); - - sbd_init(&sbd, &opts, &dinfo, fd); + sbd_init(&sbd, &opts, &dev);
if (opts.confirm && !opts.override) are_you_sure();
- if (!S_ISREG(dinfo.stat.st_mode) && opts.discard) - discard_blocks(fd, sbd.bsize * sbd.device.length, opts.debug); + if (!S_ISREG(dev.stat.st_mode) && opts.discard) + discard_blocks(dev.fd, sbd.bsize * sbd.device.length, opts.debug);
error = place_rgrps(&sbd, &opts); if (error) { @@ -770,18 +833,18 @@ void main_mkfs(int argc, char *argv[]) inode_put(&sbd.md.statfs);
gfs2_rgrp_free(&sbd.rgtree); - error = fsync(fd); + error = fsync(dev.fd); if (error){ perror(opts.device); exit(EXIT_FAILURE); }
- error = close(fd); + error = close(dev.fd); if (error){ perror(opts.device); exit(EXIT_FAILURE); }
if (!opts.quiet) - print_results(&sbd, dinfo.size, &opts, uuid); + print_results(&sbd, dev.size, &opts, uuid); }
cluster-commits@lists.fedorahosted.org