diff options
author | Karel Zak | 2012-12-06 12:12:41 +0100 |
---|---|---|
committer | Karel Zak | 2013-03-11 11:20:41 +0100 |
commit | aa42788d5f6beded3b36fb45cfaf4a27fff25698 (patch) | |
tree | e453964dc3422dadcd65fce5fa84494b6f9abfed /fdisks/utils.c | |
parent | libfdisk: add firstsector utils (diff) | |
download | kernel-qcow2-util-linux-aa42788d5f6beded3b36fb45cfaf4a27fff25698.tar.gz kernel-qcow2-util-linux-aa42788d5f6beded3b36fb45cfaf4a27fff25698.tar.xz kernel-qcow2-util-linux-aa42788d5f6beded3b36fb45cfaf4a27fff25698.zip |
libfdisk: add topology and geometry functions
- rename __discovery_* to fdisk_discovery_*
- rename fdisk_context_force_sector_size() to fdisk_override_sector_size()
- rename fdisk_context_set_user_geometry() to fdisk_override_geometry()
- remove non-default sector size warning
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'fdisks/utils.c')
-rw-r--r-- | fdisks/utils.c | 260 |
1 files changed, 2 insertions, 258 deletions
diff --git a/fdisks/utils.c b/fdisks/utils.c index 24f169efd..15278bf7d 100644 --- a/fdisks/utils.c +++ b/fdisks/utils.c @@ -69,262 +69,6 @@ static int __probe_labels(struct fdisk_context *cxt) return 1; /* not found */ } -static unsigned long __get_sector_size(int fd) -{ - int sect_sz; - - if (!blkdev_get_sector_size(fd, §_sz)) - return (unsigned long) sect_sz; - return DEFAULT_SECTOR_SIZE; -} - -/** - * fdisk_context_force_sector_size: - * @cxt: fdisk context - * @s: required sector size - * - * Overwrites logical and physical sector size. Note that the default sector - * size is discovered by fdisk_new_context_from_device() from device topology. - * - * Don't use this function, rely on the default behavioer is more safe. - * - * Returns: 0 on success, < 0 on error. - */ -int fdisk_context_force_sector_size(struct fdisk_context *cxt, sector_t s) -{ - if (!cxt) - return -EINVAL; - - cxt->phy_sector_size = cxt->sector_size = s; - cxt->min_io_size = cxt->io_size = s; - - fdisk_reset_alignment(cxt); - return 0; -} - -static void recount_geometry(struct fdisk_context *cxt) -{ - cxt->geom.cylinders = cxt->total_sectors / - (cxt->geom.heads * cxt->geom.sectors); -} - -/** - * fdisk_context_set_user_geometry: - * @cxt: fdisk context - * @cylinders: user specified cylinders - * @heads: user specified heads - * @sectors: user specified sectors - * - * Overrides autodiscovery and apply user specified geometry. - * - * Returns: 0 on success, < 0 on error. - */ -int fdisk_context_set_user_geometry(struct fdisk_context *cxt, - unsigned int cylinders, - unsigned int heads, - unsigned int sectors) -{ - if (!cxt) - return -EINVAL; - if (heads) - cxt->geom.heads = heads; - if (sectors) - cxt->geom.sectors = sectors; - - if (cylinders) - cxt->geom.cylinders = cylinders; - else - recount_geometry(cxt); - - fdisk_reset_alignment(cxt); - return 0; -} - -/* - * Generic (label independent) geometry - */ -static int __discover_system_geometry(struct fdisk_context *cxt) -{ - sector_t nsects; - unsigned int h = 0, s = 0; - - /* get number of 512-byte sectors, and convert it the real sectors */ - if (!blkdev_get_sectors(cxt->dev_fd, &nsects)) - cxt->total_sectors = (nsects / (cxt->sector_size >> 9)); - - /* what the kernel/bios thinks the geometry is */ - blkdev_get_geometry(cxt->dev_fd, &h, &s); - if (!h && !s) { - /* unable to discover geometry, use default values */ - s = 63; - h = 255; - } - - /* obtained heads and sectors */ - cxt->geom.heads = h; - cxt->geom.sectors = s; - recount_geometry(cxt); - - DBG(GEOMETRY, dbgprint("geometry discovered for %s: C/H/S: %lld/%d/%lld", - cxt->dev_path, cxt->geom.cylinders, - cxt->geom.heads, cxt->geom.sectors)); - return 0; -} - -static int __discover_topology(struct fdisk_context *cxt) -{ -#ifdef HAVE_LIBBLKID - blkid_probe pr; - - DBG(TOPOLOGY, dbgprint("initialize libblkid prober")); - - pr = blkid_new_probe(); - if (pr && blkid_probe_set_device(pr, cxt->dev_fd, 0, 0) == 0) { - blkid_topology tp = blkid_probe_get_topology(pr); - - if (tp) { - cxt->min_io_size = blkid_topology_get_minimum_io_size(tp); - cxt->optimal_io_size = blkid_topology_get_optimal_io_size(tp); - cxt->phy_sector_size = blkid_topology_get_physical_sector_size(tp); - cxt->alignment_offset = blkid_topology_get_alignment_offset(tp); - - /* I/O size used by fdisk */ - cxt->io_size = cxt->optimal_io_size; - if (!cxt->io_size) - /* optimal IO is optional, default to minimum IO */ - cxt->io_size = cxt->min_io_size; - } - } - blkid_free_probe(pr); -#endif - - cxt->sector_size = __get_sector_size(cxt->dev_fd); - if (!cxt->phy_sector_size) /* could not discover physical size */ - cxt->phy_sector_size = cxt->sector_size; - - /* no blkid or error, use default values */ - if (!cxt->min_io_size) - cxt->min_io_size = cxt->sector_size; - if (!cxt->io_size) - cxt->io_size = cxt->sector_size; - - DBG(TOPOLOGY, dbgprint("topology discovered for %s:\n" - "\tlogical/physical sector sizes: %ld/%ld\n" - "\tfdisk/minimal/optimal io sizes: %ld/%ld/%ld\n", - cxt->dev_path, cxt->sector_size, cxt->phy_sector_size, - cxt->io_size, cxt->optimal_io_size, cxt->min_io_size)); - return 0; -} - -/** - * fdisk_dev_sectsz_is_default: - * @cxt: fdisk context - * - * Returns 1 if the device's sector size is the default value, otherwise 0. - */ -int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt) -{ - if (!cxt) - return -EINVAL; - - return cxt->sector_size == DEFAULT_SECTOR_SIZE; -} - -/** - * fdisk_dev_has_topology: - * @cxt: fdisk context - * - * Returns 1 if the device provides topology information, otherwise 0. - */ -int fdisk_dev_has_topology(struct fdisk_context *cxt) -{ - /* - * Assume that the device provides topology info if - * optimal_io_size is set or alignment_offset is set or - * minimum_io_size is not power of 2. - */ - if (cxt && - (cxt->optimal_io_size || - cxt->alignment_offset || - !is_power_of_2(cxt->min_io_size))) - return 1; - return 0; -} - -/* - * The LBA of the first partition is based on the device geometry and topology. - * This offset is generic (and recommended) for all labels. - * - * Returns: 0 on error or number of logical sectors. - */ -sector_t fdisk_topology_get_first_lba(struct fdisk_context *cxt) -{ - sector_t x = 0, res; - - if (!cxt) - return 0; - - if (!cxt->io_size) - __discover_topology(cxt); - - /* - * Align the begin of partitions to: - * - * a) topology - * a2) alignment offset - * a1) or physical sector (minimal_io_size, aka "grain") - * - * b) or default to 1MiB (2048 sectrors, Windows Vista default) - * - * c) or for very small devices use 1 phy.sector - */ - if (fdisk_dev_has_topology(cxt)) { - if (cxt->alignment_offset) - x = cxt->alignment_offset; - else if (cxt->io_size > 2048 * 512) - x = cxt->io_size; - } - /* default to 1MiB */ - if (!x) - x = 2048 * 512; - - res = x / cxt->sector_size; - - /* don't use huge offset on small devices */ - if (cxt->total_sectors <= res * 4) - res = cxt->phy_sector_size / cxt->sector_size; - - return res; -} - -/* - * The LBA of the first partition is based on the device geometry and topology. - * This offset is generic generic (and recommended) for all labels. - * - * Returns: 0 on error or number of bytes. - */ -unsigned long fdisk_topology_get_grain(struct fdisk_context *cxt) -{ - unsigned long res; - - if (!cxt) - return 0; - - if (!cxt->io_size) - __discover_topology(cxt); - - res = cxt->io_size; - - /* use 1MiB grain always when possible */ - if (res < 2048 * 512) - res = 2048 * 512; - - /* don't use huge grain on small devices */ - if (cxt->total_sectors <= (res * 4 / cxt->sector_size)) - res = cxt->phy_sector_size; - - return res; -} /** * fdisk_reset_alignment: @@ -437,8 +181,8 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea if (!cxt->dev_path) goto fail; - __discover_topology(cxt); - __discover_system_geometry(cxt); + fdisk_discover_topology(cxt); + fdisk_discover_geometry(cxt); if (fdisk_read_firstsector(cxt) < 0) goto fail; |