From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Tue, 14 May 2013 11:45:36 +0100 Subject: [Cluster-devel] [PATCH 5/6] mkfs.gfs2: Add a struct to store device info In-Reply-To: <1368528337-4236-1-git-send-email-anprice@redhat.com> References: <1368528337-4236-1-git-send-email-anprice@redhat.com> Message-ID: <1368528337-4236-6-git-send-email-anprice@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 --- gfs2/mkfs/main_mkfs.c | 173 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 118 insertions(+), 55 deletions(-) diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 91c89d3..aadd501 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)); @@ -408,25 +429,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 */ @@ -438,15 +460,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; @@ -454,6 +476,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) { @@ -607,7 +634,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); @@ -616,20 +643,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; @@ -651,18 +678,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")); @@ -678,53 +710,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) { @@ -777,18 +840,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); } -- 1.8.1.4