summaryrefslogtreecommitdiffstats
path: root/fdisks/utils.c
diff options
context:
space:
mode:
authorKarel Zak2012-12-06 12:12:41 +0100
committerKarel Zak2013-03-11 11:20:41 +0100
commitaa42788d5f6beded3b36fb45cfaf4a27fff25698 (patch)
treee453964dc3422dadcd65fce5fa84494b6f9abfed /fdisks/utils.c
parentlibfdisk: add firstsector utils (diff)
downloadkernel-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.c260
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, &sect_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;