diff --git a/libblkid/libfdisk/src/context.c b/libblkid/libfdisk/src/context.c
new file mode 100644
index 0000000..2a4d377
--- /dev/null
+++ b/libblkid/libfdisk/src/context.c
@@ -0,0 +1,1017 @@
+#ifdef HAVE_LIBBLKID
+# include <blkid.h>
+#endif
+
+#include "fdiskP.h"
+
+
+/**
+ * SECTION: context
+ * @title: Context
+ * @short_description: stores info about device, labels etc.
+ *
+ * The library distinguish between three types of partitioning objects.
+ *
+ * on-disk data
+ *    - disk label specific
+ *    - probed and read  by disklabel drivers when assign device to the context
+ *      or when switch to another disk label type
+ *    - only fdisk_write_disklabel() modify on-disk data
+ *
+ * in-memory data
+ *    - generic data and disklabel specific data stored in struct fdisk_label
+ *    - all partitioning operations are based on in-memory data only
+ *
+ * struct fdisk_partition
+ *    - provides abstraction to present partitions to users
+ *    - fdisk_partition is possible to gather to fdisk_table container
+ *    - used as unified template for new partitions
+ *    - the struct fdisk_partition is always completely independent object and
+ *      any change to the object has no effect to in-memory (or on-disk) label data
+ */
+
+/**
+ * fdisk_new_context:
+ *
+ * Returns: newly allocated libfdisk handler
+ */
+struct fdisk_context *fdisk_new_context(void)
+{
+	struct fdisk_context *cxt;
+
+	cxt = calloc(1, sizeof(*cxt));
+	if (!cxt)
+		return NULL;
+
+	DBG(CXT, ul_debugobj(cxt, "alloc"));
+	cxt->dev_fd = -1;
+	cxt->refcount = 1;
+
+	/*
+	 * Allocate label specific structs.
+	 *
+	 * This is necessary (for example) to store label specific
+	 * context setting.
+	 */
+	cxt->labels[ cxt->nlabels++ ] = fdisk_new_gpt_label(cxt);
+	cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt);
+	cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
+	cxt->labels[ cxt->nlabels++ ] = fdisk_new_sgi_label(cxt);
+	cxt->labels[ cxt->nlabels++ ] = fdisk_new_sun_label(cxt);
+
+	return cxt;
+}
+
+static int init_nested_from_parent(struct fdisk_context *cxt, int isnew)
+{
+	struct fdisk_context *parent;
+
+	assert(cxt);
+	assert(cxt->parent);
+
+	parent = cxt->parent;
+
+	cxt->alignment_offset = parent->alignment_offset;
+	cxt->ask_cb =		parent->ask_cb;
+	cxt->ask_data =		parent->ask_data;
+	cxt->dev_fd =		parent->dev_fd;
+	cxt->first_lba =        parent->first_lba;
+	cxt->firstsector_bufsz = parent->firstsector_bufsz;
+	cxt->firstsector =	parent->firstsector;
+	cxt->geom =		parent->geom;
+	cxt->grain =            parent->grain;
+	cxt->io_size =          parent->io_size;
+	cxt->last_lba =		parent->last_lba;
+	cxt->min_io_size =      parent->min_io_size;
+	cxt->optimal_io_size =  parent->optimal_io_size;
+	cxt->phy_sector_size =  parent->phy_sector_size;
+	cxt->readonly =		parent->readonly;
+	cxt->script =		parent->script;
+	fdisk_ref_script(cxt->script);
+	cxt->sector_size =      parent->sector_size;
+	cxt->total_sectors =    parent->total_sectors;
+	cxt->user_geom =	parent->user_geom;
+	cxt->user_log_sector =	parent->user_log_sector;
+	cxt->user_pyh_sector =  parent->user_pyh_sector;
+
+	/* parent <--> nested independent setting, initialize for new nested 
+	 * contexts only */
+	if (isnew) {
+		cxt->listonly =	parent->listonly;
+		cxt->display_details =	parent->display_details;
+		cxt->display_in_cyl_units = parent->display_in_cyl_units;
+	}
+
+	free(cxt->dev_path);
+	cxt->dev_path = NULL;
+
+	if (parent->dev_path) {
+		cxt->dev_path =	strdup(parent->dev_path);
+		if (!cxt->dev_path)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * fdisk_new_nested_context:
+ * @parent: parental context
+ * @name: optional label name (e.g. "bsd")
+ *
+ * Create a new nested fdisk context for nested disk labels (e.g. BSD or PMBR).
+ * The function also probes for the nested label on the device if device is
+ * already assigned to parent.
+ *
+ * The new context is initialized according to @parent and both context shares
+ * some settings and file descriptor to the device. The child propagate some
+ * changes (like fdisk_assign_device()) to parent, but it does not work
+ * vice-versa. The behavior is undefined if you assign another device to
+ * parent.
+ *
+ * Returns: new context for nested partition table.
+ */
+struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent,
+				const char *name)
+{
+	struct fdisk_context *cxt;
+	struct fdisk_label *lb = NULL;
+
+	assert(parent);
+
+	cxt = calloc(1, sizeof(*cxt));
+	if (!cxt)
+		return NULL;
+
+	DBG(CXT, ul_debugobj(parent, "alloc nested [%p]", cxt));
+	cxt->refcount = 1;
+
+	fdisk_ref_context(parent);
+	cxt->parent = parent;
+
+	if (init_nested_from_parent(cxt, 1) != 0)
+		return NULL;
+
+	if (name) {
+		if (strcmp(name, "bsd") == 0)
+			lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
+		else if (strcmp(name, "dos") == 0)
+			lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt);
+	}
+
+	if (lb && parent->dev_fd >= 0) {
+		DBG(CXT, ul_debugobj(cxt, "probing for nested %s", lb->name));
+
+		cxt->label = lb;
+
+		if (lb->op->probe(cxt) == 1)
+			__fdisk_switch_label(cxt, lb);
+		else {
+			DBG(CXT, ul_debugobj(cxt, "not found %s label", lb->name));
+			if (lb->op->deinit)
+				lb->op->deinit(lb);
+			cxt->label = NULL;
+		}
+	}
+
+	return cxt;
+}
+
+
+/**
+ * fdisk_ref_context:
+ * @cxt: context pointer
+ *
+ * Increments reference counter.
+ */
+void fdisk_ref_context(struct fdisk_context *cxt)
+{
+	if (cxt)
+		cxt->refcount++;
+}
+
+/**
+ * fdisk_get_label:
+ * @cxt: context instance
+ * @name: label name (e.g. "gpt")
+ *
+ * If no @name specified then returns the current context label.
+ *
+ * The label is allocated and maintained within the context #cxt. There is
+ * nothing like reference counting for labels, you cannot delallocate the
+ * label.
+ *
+ * Returns: label struct or NULL in case of error.
+ */
+struct fdisk_label *fdisk_get_label(struct fdisk_context *cxt, const char *name)
+{
+	size_t i;
+
+	assert(cxt);
+
+	if (!name)
+		return cxt->label;
+
+	for (i = 0; i < cxt->nlabels; i++)
+		if (cxt->labels[i]
+		    && strcmp(cxt->labels[i]->name, name) == 0)
+			return cxt->labels[i];
+
+	DBG(CXT, ul_debugobj(cxt, "failed to found %s label driver", name));
+	return NULL;
+}
+
+/**
+ * fdisk_next_label:
+ * @cxt: context instance
+ * @lb: returns pointer to the next label
+ *
+ * <informalexample>
+ *   <programlisting>
+ *      // print all supported labels
+ *	struct fdisk_context *cxt = fdisk_new_context();
+ *	struct fdisk_label *lb = NULL;
+ *
+ *	while (fdisk_next_label(cxt, &lb) == 0)
+ *		print("label name: %s\n", fdisk_label_get_name(lb));
+ *	fdisk_unref_context(cxt);
+ *   </programlisting>
+ * </informalexample>
+ *
+ * Returns: <0 in case of error, 0 on success, 1 at the end.
+ */
+int fdisk_next_label(struct fdisk_context *cxt, struct fdisk_label **lb)
+{
+	size_t i;
+	struct fdisk_label *res = NULL;
+
+	if (!lb || !cxt)
+		return -EINVAL;
+
+	if (!*lb)
+		res = cxt->labels[0];
+	else {
+		for (i = 1; i < cxt->nlabels; i++) {
+			if (*lb == cxt->labels[i - 1]) {
+				res = cxt->labels[i];
+				break;
+			}
+		}
+	}
+
+	*lb = res;
+	return res ? 0 : 1;
+}
+
+/**
+ * fdisk_get_nlabels:
+ * @cxt: context
+ *
+ * Returns: number of supported label types
+ */
+size_t fdisk_get_nlabels(struct fdisk_context *cxt)
+{
+	return cxt ? cxt->nlabels : 0;
+}
+
+int __fdisk_switch_label(struct fdisk_context *cxt, struct fdisk_label *lb)
+{
+	if (!lb || !cxt)
+		return -EINVAL;
+	if (lb->disabled) {
+		DBG(CXT, ul_debugobj(cxt, "*** attempt to switch to disabled label %s -- ignore!", lb->name));
+		return -EINVAL;
+	}
+	cxt->label = lb;
+	DBG(CXT, ul_debugobj(cxt, "--> switching context to %s!", lb->name));
+	return 0;
+}
+
+/**
+ * fdisk_has_label:
+ * @cxt: fdisk context
+ *
+ * Returns: return 1 if there is label on the device.
+ */
+int fdisk_has_label(struct fdisk_context *cxt)
+{
+	return cxt && cxt->label;
+}
+
+/**
+ * fdisk_get_npartitions:
+ * @cxt: context
+ *
+ * The maximal number of the partitions depends on disklabel and does not
+ * have to describe the real limit of PT.
+ *
+ * For example the limit for MBR without extend partition is 4, with extended
+ * partition it's unlimited (so the function returns the current number of all
+ * partitions in this case).
+ *
+ * And for example for GPT it depends on space allocated on disk for array of
+ * entry records (usually 128).
+ *
+ * It's fine to use fdisk_get_npartitions() in loops, but don't forget that
+ * partition may be unused (see fdisk_is_partition_used()).
+ *
+ * <informalexample>
+ *   <programlisting>
+ *	struct fdisk_partition *pa = NULL;
+ *	size_t i, nmax = fdisk_get_npartitions(cxt);
+ *
+ *	for (i = 0; i < nmax; i++) {
+ *		if (!fdisk_is_partition_used(cxt, i))
+ *			continue;
+ *		... do something ...
+ *	}
+ *   </programlisting>
+ * </informalexample>
+ *
+ * Note that the recommended way to list partitions is to use
+ * fdisk_get_partitions() and struct fdisk_table than ask disk driver for each
+ * individual partitions.
+ *
+ * Returns: maximal number of partitions for the current label.
+ */
+size_t fdisk_get_npartitions(struct fdisk_context *cxt)
+{
+	return cxt && cxt->label ? cxt->label->nparts_max : 0;
+}
+
+/**
+ * fdisk_is_labeltype:
+ * @cxt: fdisk context
+ * @id: FDISK_DISKLABEL_*
+ *
+ * See also fdisk_is_label() macro in libfdisk.h.
+ *
+ * Returns: return 1 if the current label is @id
+ */
+int fdisk_is_labeltype(struct fdisk_context *cxt, enum fdisk_labeltype id)
+{
+	assert(cxt);
+
+	return cxt->label && fdisk_label_get_type(cxt->label) == id;
+}
+
+/**
+ * fdisk_get_parent:
+ * @cxt: nested fdisk context
+ *
+ * Returns: pointer to parental context, or NULL
+ */
+struct fdisk_context *fdisk_get_parent(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->parent;
+}
+
+static void reset_context(struct fdisk_context *cxt)
+{
+	size_t i;
+
+	DBG(CXT, ul_debugobj(cxt, "*** resetting context"));
+
+	/* reset drives' private data */
+	for (i = 0; i < cxt->nlabels; i++)
+		fdisk_deinit_label(cxt->labels[i]);
+
+	if (cxt->parent) {
+		/* the first sector may be independent on parent */
+		if (cxt->parent->firstsector != cxt->firstsector)
+			free(cxt->firstsector);
+	} else {
+		/* we close device only in primary context */
+		if (cxt->dev_fd > -1)
+			close(cxt->dev_fd);
+		free(cxt->firstsector);
+	}
+
+	free(cxt->dev_path);
+	cxt->dev_path = NULL;
+
+	cxt->dev_fd = -1;
+	cxt->firstsector = NULL;
+	cxt->firstsector_bufsz = 0;
+
+	fdisk_zeroize_device_properties(cxt);
+
+	fdisk_unref_script(cxt->script);
+	cxt->script = NULL;
+
+	cxt->label = NULL;
+}
+
+/*
+ * This function prints a warning if the device is not wiped (e.g. wipefs(8).
+ * Please don't call this function if there is already a PT.
+ *
+ * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
+ */
+static int warn_wipe(struct fdisk_context *cxt)
+{
+#ifdef HAVE_LIBBLKID
+	blkid_probe pr;
+#endif
+	int rc = 0;
+
+	assert(cxt);
+
+	if (fdisk_has_label(cxt) || cxt->dev_fd < 0)
+		return -EINVAL;
+#ifdef HAVE_LIBBLKID
+	DBG(CXT, ul_debugobj(cxt, "wipe check: initialize libblkid prober"));
+
+	pr = blkid_new_probe();
+	if (!pr)
+		return -ENOMEM;
+	rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
+	if (rc)
+		return rc;
+
+	blkid_probe_enable_superblocks(pr, 1);
+	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
+	blkid_probe_enable_partitions(pr, 1);
+
+	/* we care about the first found FS/raid, so don't call blkid_do_probe()
+	 * in loop or don't use blkid_do_fullprobe() ... */
+	rc = blkid_do_probe(pr);
+	if (rc == 0) {
+		const char *name = NULL;
+
+		if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0 ||
+		    blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
+			fdisk_warnx(cxt, _(
+				"%s: device contains a valid '%s' signature; it is "
+				"strongly recommended to wipe the device with "
+				"wipefs(8) if this is unexpected, in order to "
+				"avoid possible collisions"), cxt->dev_path, name);
+			rc = 1;
+		}
+	}
+
+	blkid_free_probe(pr);
+#endif
+	return rc;
+}
+
+/**
+ * fdisk_assign_device:
+ * @cxt: context
+ * @fname: path to the device to be handled
+ * @readonly: how to open the device
+ *
+ * Open the device, discovery topology, geometry, detect disklabel and switch
+ * the current label driver to reflect the probing result.
+ *
+ * Note that this function resets all generic setting in context. If the @cxt
+ * is nested context then the device is assigned to the parental context and
+ * necessary properties are copied to the @cxt. The change is propagated in
+ * child->parent direction only. It's impossible to use a different device for
+ * primary and nested contexts.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_assign_device(struct fdisk_context *cxt,
+			const char *fname, int readonly)
+{
+	int fd;
+
+	DBG(CXT, ul_debugobj(cxt, "assigning device %s", fname));
+	assert(cxt);
+
+	/* redirect request to parent */
+	if (cxt->parent) {
+		int rc, org = fdisk_is_listonly(cxt->parent);
+
+		/* assign_device() is sensitive to "listonly" mode, so let's
+		 * follow the current context setting for the parent to avoid 
+		 * unwanted extra warnings. */
+		fdisk_enable_listonly(cxt->parent, fdisk_is_listonly(cxt));
+
+		rc = fdisk_assign_device(cxt->parent, fname, readonly);
+		fdisk_enable_listonly(cxt->parent, org);
+
+		if (!rc)
+			rc = init_nested_from_parent(cxt, 0);
+		if (!rc)
+			fdisk_probe_labels(cxt);
+		return rc;
+	}
+
+	reset_context(cxt);
+
+	fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
+	if (fd < 0)
+		return -errno;
+
+	cxt->readonly = readonly;
+	cxt->dev_fd = fd;
+	cxt->dev_path = strdup(fname);
+	if (!cxt->dev_path)
+		goto fail;
+
+	fdisk_discover_topology(cxt);
+	fdisk_discover_geometry(cxt);
+
+	if (fdisk_read_firstsector(cxt) < 0)
+		goto fail;
+
+	/* detect labels and apply labes specific stuff (e.g geomery)
+	 * to the context */
+	fdisk_probe_labels(cxt);
+
+	/* let's apply user geometry *after* label prober
+	 * to make it possible to override in-label setting */
+	fdisk_apply_user_device_properties(cxt);
+
+	/* warn about obsolete stuff on the device if we aren't in
+	 * list-only mode and there is not PT yet */
+	if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt))
+		warn_wipe(cxt);
+
+	DBG(CXT, ul_debugobj(cxt, "initialized for %s [%s]",
+			      fname, readonly ? "READ-ONLY" : "READ-WRITE"));
+	return 0;
+fail:
+	DBG(CXT, ul_debugobj(cxt, "failed to assign device"));
+	return -errno;
+}
+
+/**
+ * fdisk_deassign_device:
+ * @cxt: context
+ * @nosync: disable fsync()
+ *
+ * Close device and call fsync(). If the @cxt is nested context than the
+ * request is redirected to the parent.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_deassign_device(struct fdisk_context *cxt, int nosync)
+{
+	assert(cxt);
+	assert(cxt->dev_fd >= 0);
+
+	if (cxt->parent) {
+		int rc = fdisk_deassign_device(cxt->parent, nosync);
+
+		if (!rc)
+			rc = init_nested_from_parent(cxt, 0);
+		return rc;
+	}
+
+	if (cxt->readonly)
+		close(cxt->dev_fd);
+	else {
+		if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
+			fdisk_warn(cxt, _("%s: close device failed"),
+					cxt->dev_path);
+			return -errno;
+		}
+
+		if (!nosync) {
+			fdisk_info(cxt, _("Syncing disks."));
+			sync();
+		}
+	}
+
+	free(cxt->dev_path);
+	cxt->dev_path = NULL;
+
+	cxt->dev_fd = -1;
+
+	return 0;
+}
+
+/**
+ * fdisk_is_readonly:
+ * @cxt: context
+ *
+ * Returns: 1 if device open readonly
+ */
+int fdisk_is_readonly(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->readonly;
+}
+
+/**
+ * fdisk_unref_context:
+ * @cxt: fdisk context
+ *
+ * Deallocates context struct.
+ */
+void fdisk_unref_context(struct fdisk_context *cxt)
+{
+	int i;
+
+	if (!cxt)
+		return;
+
+	cxt->refcount--;
+	if (cxt->refcount <= 0) {
+		DBG(CXT, ul_debugobj(cxt, "freeing context %p for %s", cxt, cxt->dev_path));
+
+		reset_context(cxt);	/* this is sensitive to parent<->child relationship! */
+
+		/* deallocate label's private stuff */
+		for (i = 0; i < cxt->nlabels; i++) {
+			if (!cxt->labels[i])
+				continue;
+			if (cxt->labels[i]->op->free)
+				cxt->labels[i]->op->free(cxt->labels[i]);
+			else
+				free(cxt->labels[i]);
+		}
+
+		fdisk_unref_context(cxt->parent);
+		cxt->parent = NULL;
+
+		free(cxt);
+	}
+}
+
+
+/**
+ * fdisk_enable_details:
+ * @cxt: context
+ * @enable: true/flase
+ *
+ * Enables or disables "details" display mode. This function has effect to
+ * fdisk_partition_to_string() function.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_enable_details(struct fdisk_context *cxt, int enable)
+{
+	assert(cxt);
+	cxt->display_details = enable ? 1 : 0;
+	return 0;
+}
+
+/**
+ * fdisk_is_details:
+ * @cxt: context
+ *
+ * Returns: 1 if details are enabled
+ */
+int fdisk_is_details(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->display_details == 1;
+}
+
+/**
+ * fdisk_enable_listonly:
+ * @cxt: context
+ * @enable: true/flase
+ *
+ * Just list partition only, don't care about another details, mistakes, ...
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_enable_listonly(struct fdisk_context *cxt, int enable)
+{
+	assert(cxt);
+	cxt->listonly = enable ? 1 : 0;
+	return 0;
+}
+
+/**
+ * fdisk_is_listonly:
+ * @cxt: context
+ *
+ * Returns: 1 if list-only mode enabled
+ */
+int fdisk_is_listonly(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->listonly == 1;
+}
+
+
+/**
+ * fdisk_set_unit:
+ * @cxt: context
+ * @str: "cylinder" or "sector".
+ *
+ * This is pure shit, unfortunately for example Sun addresses begin of the
+ * partition by cylinders...
+ *
+ * Returns: 0 on succes, <0 on error.
+ */
+int fdisk_set_unit(struct fdisk_context *cxt, const char *str)
+{
+	assert(cxt);
+
+	cxt->display_in_cyl_units = 0;
+
+	if (!str)
+		return 0;
+
+	if (strcmp(str, "cylinder") == 0 || strcmp(str, "cylinders") == 0)
+		cxt->display_in_cyl_units = 1;
+
+	else if (strcmp(str, "sector") == 0 || strcmp(str, "sectors") == 0)
+		cxt->display_in_cyl_units = 0;
+
+	DBG(CXT, ul_debugobj(cxt, "display unit: %s", fdisk_get_unit(cxt, 0)));
+	return 0;
+}
+
+/**
+ * fdisk_get_unit:
+ * @cxt: context
+ * @n: FDISK_PLURAL or FDISK_SINGULAR
+ *
+ * Returns: unit name.
+ */
+const char *fdisk_get_unit(struct fdisk_context *cxt, int n)
+{
+	assert(cxt);
+
+	if (fdisk_use_cylinders(cxt))
+		return P_("cylinder", "cylinders", n);
+	return P_("sector", "sectors", n);
+}
+
+/**
+ * fdisk_use_cylinders:
+ * @cxt: context
+ *
+ * Returns: 1 if user wants to display in cylinders.
+ */
+int fdisk_use_cylinders(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->display_in_cyl_units == 1;
+}
+
+/**
+ * fdisk_get_units_per_sector:
+ * @cxt: context
+ *
+ * This is necessary only for brain dead situations when we use "cylinders";
+ *
+ * Returns: number of "units" per sector, default is 1 if display unit is sector.
+ */
+unsigned int fdisk_get_units_per_sector(struct fdisk_context *cxt)
+{
+	assert(cxt);
+
+	if (fdisk_use_cylinders(cxt)) {
+		assert(cxt->geom.heads);
+		return cxt->geom.heads * cxt->geom.sectors;
+	}
+	return 1;
+}
+
+/**
+ * fdisk_get_optimal_iosize:
+ * @cxt: context
+ *
+ * The optimal I/O is optional and does not have to be provided by device,
+ * anyway libfdisk never returns zero. If the optimal I/O size is not provided
+ * then libfdisk returns minimal I/O size or sector size.
+ *
+ * Returns: optimal I/O size in bytes.
+ */
+unsigned long fdisk_get_optimal_iosize(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->optimal_io_size ? cxt->optimal_io_size : cxt->io_size;
+}
+
+/**
+ * fdisk_get_minimal_iosize:
+ * @cxt: context
+ *
+ * Returns: minimal I/O size in bytes
+ */
+unsigned long fdisk_get_minimal_iosize(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->min_io_size;
+}
+
+/**
+ * fdisk_get_physector_size:
+ * @cxt: context
+ *
+ * Returns: physical sector size in bytes
+ */
+unsigned long fdisk_get_physector_size(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->phy_sector_size;
+}
+
+/**
+ * fdisk_get_sector_size:
+ * @cxt: context
+ *
+ * Returns: logical sector size in bytes
+ */
+unsigned long fdisk_get_sector_size(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->sector_size;
+}
+
+/**
+ * fdisk_get_alignment_offset
+ * @cxt: context
+ *
+ * The alignment offset is offset between logical and physical sectors. For
+ * backward compatibility the first logical sector on 4K disks does no have to
+ * start on the same place like physical sectors.
+ *
+ * Returns: alignment offset in bytes
+ */
+unsigned long fdisk_get_alignment_offset(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->alignment_offset;
+}
+
+/**
+ * fdisk_get_grain_size:
+ * @cxt: context
+ *
+ * Returns: grain in bytes used to align partitions (usually 1MiB)
+ */
+unsigned long fdisk_get_grain_size(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->grain;
+}
+
+/**
+ * fdisk_get_first_lba:
+ * @cxt: context
+ *
+ * Returns: first possible LBA on disk for data partitions.
+ */
+fdisk_sector_t fdisk_get_first_lba(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->first_lba;
+}
+
+/**
+ * fdisk_set_first_lba:
+ * @cxt: fdisk context
+ * @lba: first possible logical sector for data
+ *
+ * It's strongly recommended to use the default library setting. The first LBA
+ * is always reseted by fdisk_assign_device(), fdisk_override_geometry()
+ * and fdisk_reset_alignment(). This is very low level function and library
+ * does not check if your setting makes any sense.
+ *
+ * This function is necessary only when you want to work with very unusual
+ * partition tables like GPT protective MBR or hybrid partition tables on
+ * bootable media where the first partition may start on very crazy offsets.
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+fdisk_sector_t fdisk_set_first_lba(struct fdisk_context *cxt, fdisk_sector_t lba)
+{
+	assert(cxt);
+	DBG(CXT, ul_debugobj(cxt, "setting first LBA from %ju to %ju",
+			(uintmax_t) cxt->first_lba, (uintmax_t) lba));
+	cxt->first_lba = lba;
+	return 0;
+}
+
+/**
+ * fdisk_get_last_lba:
+ * @cxt: fdisk context
+ *
+ * Note that the device has to be already assigned.
+ *
+ * Returns: last possible LBA on device
+ */
+fdisk_sector_t fdisk_get_last_lba(struct fdisk_context *cxt)
+{
+	return cxt->last_lba;
+}
+
+/**
+ * fdisk_set_last_lba:
+ * @cxt: fdisk context
+ * @lba: last possible logical sector
+ *
+ * It's strongly recommended to use the default library setting. The last LBA
+ * is always reseted by fdisk_assign_device(), fdisk_override_geometry() and
+ * fdisk_reset_alignment().
+ *
+ * The default is number of sectors on the device, but maybe modified by the
+ * current disklabel driver (for example GPT uses and of disk for backup
+ * header, so last_lba is smaller than total number of sectors).
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+fdisk_sector_t fdisk_set_last_lba(struct fdisk_context *cxt, fdisk_sector_t lba)
+{
+	assert(cxt);
+
+	if (lba > cxt->total_sectors - 1 && lba < 1)
+		return -ERANGE;
+	cxt->last_lba = lba;
+	return 0;
+}
+
+
+/**
+ * fdisk_get_nsectors:
+ * @cxt: context
+ *
+ * Returns: size of the device in logical sectors.
+ */
+fdisk_sector_t fdisk_get_nsectors(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->total_sectors;
+}
+
+/**
+ * fdisk_get_devname:
+ * @cxt: context
+ *
+ * Returns: device name.
+ */
+const char *fdisk_get_devname(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->dev_path;
+}
+
+/**
+ * fdisk_get_devfd:
+ * @cxt: context
+ *
+ * Retruns: device file descriptor.
+ */
+int fdisk_get_devfd(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->dev_fd;
+}
+
+/**
+ * fdisk_get_geom_heads:
+ * @cxt: context
+ *
+ * Returns: number of geometry heads.
+ */
+unsigned int fdisk_get_geom_heads(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->geom.heads;
+}
+/**
+ * fdisk_get_geom_sectors:
+ * @cxt: context
+ *
+ * Returns: number of geometry sectors.
+ */
+fdisk_sector_t fdisk_get_geom_sectors(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->geom.sectors;
+
+}
+
+/**
+ * fdisk_get_geom_cylinders:
+ * @cxt: context
+ *
+ * Returns: number of geometry cylinders
+ */
+fdisk_sector_t fdisk_get_geom_cylinders(struct fdisk_context *cxt)
+{
+	assert(cxt);
+	return cxt->geom.cylinders;
+}
+
+int fdisk_missing_geometry(struct fdisk_context *cxt)
+{
+	int rc;
+
+	assert(cxt);
+
+	if (!cxt || !cxt->label)
+		return 0;
+
+	rc = (fdisk_label_require_geometry(cxt->label) &&
+		    (!cxt->geom.heads || !cxt->geom.sectors
+				      || !cxt->geom.cylinders));
+
+	if (rc && !fdisk_is_listonly(cxt))
+		fdisk_warnx(cxt, _("Incomplete geometry setting."));
+
+	return rc;
+}
+
