case 'c':
user_cylinders = read_int(cxt, 1, cxt->geom.cylinders, 1048576, 0,
_("Number of cylinders"));
- fdisk_context_set_user_geometry(cxt, user_cylinders, user_heads, user_sectors);
+ fdisk_override_geometry(cxt, user_cylinders, user_heads, user_sectors);
if (fdisk_is_disklabel(cxt, SUN))
sun_set_ncyl(cxt, cxt->geom.cylinders);
break;
case 'h':
user_heads = read_int(cxt, 1, cxt->geom.heads, 256, 0,
_("Number of heads"));
- fdisk_context_set_user_geometry(cxt, user_cylinders, user_heads, user_sectors);
+ fdisk_override_geometry(cxt, user_cylinders, user_heads, user_sectors);
break;
case 'i':
if (fdisk_is_disklabel(cxt, SUN))
fprintf(stderr, _("Warning: setting "
"sector offset for DOS "
"compatibility\n"));
- fdisk_context_set_user_geometry(cxt, user_cylinders, user_heads, user_sectors);
+ fdisk_override_geometry(cxt, user_cylinders, user_heads, user_sectors);
break;
case 'v':
verify(cxt);
err(EXIT_FAILURE, _("cannot open %s"), device);
if (sector_size) /* passed -b option, override autodiscovery */
- fdisk_context_force_sector_size(cxt, sector_size);
+ fdisk_override_sector_size(cxt, sector_size);
if (user_cylinders || user_heads || user_sectors)
- fdisk_context_set_user_geometry(cxt, user_cylinders,
+ fdisk_override_geometry(cxt, user_cylinders,
user_heads, user_sectors);
if (!fdisk_dev_has_disklabel(cxt)) {
err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);
if (sector_size) /* passed -b option, override autodiscovery */
- fdisk_context_force_sector_size(cxt, sector_size);
+ fdisk_override_sector_size(cxt, sector_size);
if (user_cylinders || user_heads || user_sectors)
- fdisk_context_set_user_geometry(cxt, user_cylinders,
+ fdisk_override_geometry(cxt, user_cylinders,
user_heads, user_sectors);
print_welcome();
- if (!fdisk_dev_sectsz_is_default(cxt))
- printf(_("Note: sector size is %ld (not %d)\n"),
- cxt->sector_size, DEFAULT_SECTOR_SIZE);
-
if (!fdisk_dev_has_disklabel(cxt)) {
update_units(cxt); /* to provide compatible 'p'rint output */
fprintf(stderr,
extern const struct fdisk_label gpt_label;
extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
-extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
-extern int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt);
extern void fdisk_free_context(struct fdisk_context *cxt);
-extern int fdisk_context_force_sector_size(struct fdisk_context *cxt, sector_t s);
-extern int fdisk_context_set_user_geometry(struct fdisk_context *cxt,
- unsigned int cylinders, unsigned int heads,
- unsigned int sectors);
extern int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name);
extern int fdisk_reset_alignment(struct fdisk_context *cxt);
extern struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum);
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:
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;
+#ifdef HAVE_LIBBLKID
+#include <blkid.h>
+#endif
+#include "blkdev.h"
+
#include "fdiskP.h"
+/* temporary */
+extern int fdisk_reset_alignment(struct fdisk_context *cxt);
+
/*
* Alignment according to logical granulity (usually 1MiB)
*/
printf(_("Partition %i does not start on physical sector boundary.\n"),
partition + 1);
}
+
+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_override_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_override_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_override_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_override_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
+ */
+int fdisk_discover_geometry(struct fdisk_context *cxt)
+{
+ sector_t nsects;
+ unsigned int h = 0, s = 0;
+
+ assert(cxt);
+ assert(!cxt->geom.heads);
+
+ /* 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;
+}
+
+int fdisk_discover_topology(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ assert(cxt->sector_size == 0);
+
+#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;
+}
+
+static int 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)
+ fdisk_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 (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)
+ fdisk_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;
+}
sector_t start, sector_t stop);
+extern int fdisk_override_sector_size(struct fdisk_context *cxt, sector_t s);
+extern int fdisk_override_geometry(struct fdisk_context *cxt,
+ unsigned int cylinders, unsigned int heads,
+ unsigned int sectors);
+
+extern int fdisk_discover_geometry(struct fdisk_context *cxt);
+extern int fdisk_discover_topology(struct fdisk_context *cxt);
+
/* utils.c */
extern void fdisk_zeroize_firstsector(struct fdisk_context *cxt);
extern int fdisk_read_firstsector(struct fdisk_context *cxt);