diff --git a/libblkid/partitions.c b/libblkid/partitions.c
new file mode 100644
index 0000000..93ec4d2
--- /dev/null
+++ b/libblkid/partitions.c
@@ -0,0 +1,1385 @@
+/*
+ * partitions - partition tables parsing
+ *
+ * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdarg.h>
+
+#include "partitions.h"
+#include "sysfs.h"
+
+/**
+ * SECTION: partitions
+ * @title: Partitions probing
+ * @short_description: partitions tables detection and parsing
+ *
+ * This chain supports binary and NAME=value interfaces, but complete PT
+ * description is provided by binary interface only. The libblkid prober is
+ * compatible with kernel partition tables parser. The parser does not return
+ * empty (size=0) partitions or special hidden partitions.
+ *
+ * NAME=value interface, supported tags:
+ *
+ * @PTTYPE: partition table type (dos, gpt, etc.).
+ *
+ * @PART_ENTRY_SCHEME: partition table type
+ *
+ * @PART_ENTRY_NAME: partition name (gpt and mac only)
+ *
+ * @PART_ENTRY_UUID: partition UUID (gpt only)
+ *
+ * @PART_ENTRY_TYPE: partition type, 0xNN (e.g 0x82) or type UUID (gpt only) or type string (mac)
+ *
+ * @PART_ENTRY_FLAGS: partition flags (e.g. boot_ind) or  attributes (e.g. gpt attributes)
+ *
+ * @PART_ENTRY_NUMBER: partition number
+ *
+ * @PART_ENTRY_OFFSET: the begin of the partition
+ *
+ * @PART_ENTRY_SIZE: size of the partition
+ *
+ * @PART_ENTRY_DISK: whole-disk maj:min
+ *
+ * Example:
+ *
+ * <informalexample>
+ *  <programlisting>
+ * blkid_probe pr;
+ * const char *ptname;
+ *
+ * pr = blkid_new_probe_from_filename(devname);
+ * if (!pr)
+ *	err("%s: faild to open device", devname);
+ *
+ * blkid_probe_enable_partitions(pr, TRUE);
+ * blkid_do_fullprobe(pr);
+ *
+ * blkid_probe_lookup_value(pr, "PTTYPE", &ptname, NULL);
+ * printf("%s partition type detected\n", pttype);
+ *
+ * blkid_free_probe(pr);
+ *
+ * // don't forget to check return codes in your code!
+ *  </programlisting>
+ * </informalexample>
+ *
+ * Binary interface:
+ *
+ * <informalexample>
+ *  <programlisting>
+ * blkid_probe pr;
+ * blkid_partlist ls;
+ * int nparts, i;
+ *
+ * pr = blkid_new_probe_from_filename(devname);
+ * if (!pr)
+ *	err("%s: faild to open device", devname);
+ *
+ * ls = blkid_probe_get_partitions(pr);
+ * nparts = blkid_partlist_numof_partitions(ls);
+ *
+ * for (i = 0; i < nparts; i++) {
+ *      blkid_partition par = blkid_partlist_get_partition(ls, i);
+ *      printf("#%d: %llu %llu  0x%x",
+ *               blkid_partition_get_partno(par),
+ *               blkid_partition_get_start(par),
+ *               blkid_partition_get_size(par),
+ *               blkid_partition_get_type(par));
+ * }
+ *
+ * blkid_free_probe(pr);
+ *
+ * // don't forget to check return codes in your code!
+ *  </programlisting>
+ * </informalexample>
+ */
+
+/*
+ * Chain driver function
+ */
+static int partitions_probe(blkid_probe pr, struct blkid_chain *chn);
+static void partitions_free_data(blkid_probe pr, void *data);
+
+/*
+ * Partitions chain probing functions
+ */
+static const struct blkid_idinfo *idinfos[] =
+{
+	&aix_pt_idinfo,
+	&sgi_pt_idinfo,
+	&sun_pt_idinfo,
+	&dos_pt_idinfo,
+	&gpt_pt_idinfo,
+	&mac_pt_idinfo,
+	&ultrix_pt_idinfo,
+	&bsd_pt_idinfo,
+	&unixware_pt_idinfo,
+	&solaris_x86_pt_idinfo,
+	&minix_pt_idinfo
+};
+
+/*
+ * Driver definition
+ */
+const struct blkid_chaindrv partitions_drv = {
+	.id           = BLKID_CHAIN_PARTS,
+	.name         = "partitions",
+	.dflt_enabled = FALSE,
+	.idinfos      = idinfos,
+	.nidinfos     = ARRAY_SIZE(idinfos),
+	.has_fltr     = TRUE,
+	.probe        = partitions_probe,
+	.safeprobe    = partitions_probe,
+	.free_data    = partitions_free_data
+};
+
+
+/*
+ * For compatibility with the rest of libblkid API (with the old high-level
+ * API) we use completely opaque typedefs for all structs. Don't forget that
+ * the final blkid_* types are pointers! See blkid.h.
+ *
+ * [Just for the record, I hate typedef for pointers --kzak]
+ */
+
+/* exported as opaque type "blkid_parttable" */
+struct blkid_struct_parttable {
+	const char	*type;		/* partition table type */
+	blkid_loff_t	offset;		/* begin of the partition table */
+	int		nparts;		/* number of partitions */
+	blkid_partition	parent;		/* parent of nested partition table */
+	char		id[37];		/* PT identifier (e.g. UUID for GPT) */
+
+	struct list_head t_tabs;	/* all tables */
+};
+
+/* exported as opaque type "blkid_partition" */
+struct blkid_struct_partition {
+	blkid_loff_t	start;		/* begin of the partition */
+	blkid_loff_t	size;		/* size of the partitions */
+
+	int		type;		/* partition type */
+	char		typestr[37];	/* partition type string (GPT and Mac) */
+
+	unsigned long long flags;	/* partition flags / attributes */
+
+	int		partno;		/* partition number */
+	char		uuid[37];	/* UUID (when supported by PT), e.g GPT */
+	unsigned char	name[128];	/* Partition in UTF8 name (when supporte by PT), e.g. Mac */
+
+	blkid_parttable	tab;		/* partition table */
+};
+
+/* exported as opaque type "blkid_partlist" */
+struct blkid_struct_partlist {
+	int		next_partno;	/* next partition number */
+	blkid_partition next_parent;	/* next parent if parsing nested PT */
+
+	int		nparts;		/* number of partitions */
+	int		nparts_max;	/* max.number of partitions */
+	blkid_partition	parts;		/* array of partitions */
+
+	struct list_head l_tabs;	/* list of partition tables */
+};
+
+static int blkid_partitions_probe_partition(blkid_probe pr);
+
+/**
+ * blkid_probe_enable_partitions:
+ * @pr: probe
+ * @enable: TRUE/FALSE
+ *
+ * Enables/disables the partitions probing for non-binary interface.
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_enable_partitions(blkid_probe pr, int enable)
+{
+	if (!pr)
+		return -1;
+	pr->chains[BLKID_CHAIN_PARTS].enabled = enable;
+	return 0;
+}
+
+/**
+ * blkid_probe_set_partitions_flags:
+ * @pr: prober
+ * @flags: BLKID_PARTS_* flags
+ *
+ * Sets probing flags to the partitions prober. This function is optional.
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_set_partitions_flags(blkid_probe pr, int flags)
+{
+	if (!pr)
+		return -1;
+	pr->chains[BLKID_CHAIN_PARTS].flags = flags;
+	return 0;
+}
+
+/**
+ * blkid_probe_reset_partitions_filter:
+ * @pr: prober
+ *
+ * Resets partitions probing filter
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_reset_partitions_filter(blkid_probe pr)
+{
+	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_PARTS);
+}
+
+/**
+ * blkid_probe_invert_partitions_filter:
+ * @pr: prober
+ *
+ * Inverts partitions probing filter
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_invert_partitions_filter(blkid_probe pr)
+{
+	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_PARTS);
+}
+
+/**
+ * blkid_probe_filter_partitions_type:
+ * @pr: prober
+ * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
+ * @names: NULL terminated array of probing function names (e.g. "vfat").
+ *
+ *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @names
+ *
+ *  %BLKID_FLTR_ONLYIN - probe for items which are IN @names
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[])
+{
+	return __blkid_probe_filter_types(pr, BLKID_CHAIN_PARTS, flag, names);
+}
+
+/**
+ * blkid_probe_get_partitions:
+ * @pr: probe
+ *
+ * This is a binary interface for partitions. See also blkid_partlist_*
+ * functions.
+ *
+ * This function is independent on blkid_do_[safe,full]probe() and
+ * blkid_probe_enable_partitions() calls.
+ *
+ * WARNING: the returned object will be overwritten by the next
+ *          blkid_probe_get_partitions() call for the same @pr. If you want to
+ *          use more blkid_partlist objects in the same time you have to create
+ *          more blkid_probe handlers (see blkid_new_probe()).
+ *
+ * Returns: list of partitions, or NULL in case of error.
+ */
+blkid_partlist blkid_probe_get_partitions(blkid_probe pr)
+{
+	return (blkid_partlist) blkid_probe_get_binary_data(pr,
+			&pr->chains[BLKID_CHAIN_PARTS]);
+}
+
+/* for internal usage only */
+blkid_partlist blkid_probe_get_partlist(blkid_probe pr)
+{
+	return (blkid_partlist) pr->chains[BLKID_CHAIN_PARTS].data;
+}
+
+static void blkid_probe_set_partlist(blkid_probe pr, blkid_partlist ls)
+{
+	pr->chains[BLKID_CHAIN_PARTS].data = ls;
+}
+
+static void ref_parttable(blkid_parttable tab)
+{
+	tab->nparts++;
+}
+
+static void unref_parttable(blkid_parttable tab)
+{
+	tab->nparts--;
+
+	if (tab->nparts <= 0) {
+		list_del(&tab->t_tabs);
+		free(tab);
+	}
+}
+
+/* free all allocated parttables */
+static void free_parttables(blkid_partlist ls)
+{
+	if (!ls || !ls->l_tabs.next)
+		return;
+
+	/* remove unassigned partition tables */
+	while (!list_empty(&ls->l_tabs)) {
+		blkid_parttable tab = list_entry(ls->l_tabs.next,
+					struct blkid_struct_parttable, t_tabs);
+		unref_parttable(tab);
+	}
+}
+
+static void reset_partlist(blkid_partlist ls)
+{
+	if (!ls)
+		return;
+
+	free_parttables(ls);
+
+	if (ls->next_partno) {
+		/* already initialized - reset */
+		int tmp_nparts = ls->nparts_max;
+		blkid_partition tmp_parts = ls->parts;
+
+		memset(ls, 0, sizeof(struct blkid_struct_partlist));
+
+		ls->nparts_max = tmp_nparts;
+		ls->parts = tmp_parts;
+	}
+
+	ls->nparts = 0;
+	ls->next_partno = 1;
+	INIT_LIST_HEAD(&ls->l_tabs);
+
+	DBG(DEBUG_LOWPROBE, printf("partlist reset\n"));
+}
+
+static blkid_partlist partitions_init_data(struct blkid_chain *chn)
+{
+	blkid_partlist ls;
+
+	if (chn->data)
+		ls = (blkid_partlist) chn->data;
+	else {
+		/* allocate the new list of partitions */
+		ls = calloc(1, sizeof(struct blkid_struct_partlist));
+		if (!ls)
+			return NULL;
+		chn->data = (void *) ls;
+	}
+
+	reset_partlist(ls);
+
+	DBG(DEBUG_LOWPROBE,
+		printf("parts: initialized partitions list (%p, size=%d)\n",
+		ls, ls->nparts_max));
+	return ls;
+}
+
+static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
+				 void *data)
+{
+	blkid_partlist ls = (blkid_partlist) data;
+
+	if (!ls)
+		return;
+
+	free_parttables(ls);
+
+	/* deallocate partitions and partlist */
+	free(ls->parts);
+	free(ls);
+}
+
+blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls,
+				const char *type, blkid_loff_t offset)
+{
+	blkid_parttable tab;
+
+	tab = calloc(1, sizeof(struct blkid_struct_parttable));
+	if (!tab)
+		return NULL;
+	tab->type = type;
+	tab->offset = offset;
+	tab->parent = ls->next_parent;
+
+	INIT_LIST_HEAD(&tab->t_tabs);
+	list_add_tail(&tab->t_tabs, &ls->l_tabs);
+
+	DBG(DEBUG_LOWPROBE,
+		printf("parts: create a new partition table "
+		       "(%p, type=%s, offset=%"PRId64")\n", tab, type, offset));
+	return tab;
+}
+
+static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
+{
+	blkid_partition par;
+
+	if (ls->nparts + 1 > ls->nparts_max) {
+		/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
+		 * generic Linux machine -- let start with 32 partititions.
+		 */
+		ls->parts = realloc(ls->parts, (ls->nparts_max + 32) *
+					sizeof(struct blkid_struct_partition));
+		if (!ls->parts)
+			return NULL;
+		ls->nparts_max += 32;
+	}
+
+	par = &ls->parts[ls->nparts++];
+	memset(par, 0, sizeof(struct blkid_struct_partition));
+
+	ref_parttable(tab);
+	par->tab = tab;
+	par->partno = blkid_partlist_increment_partno(ls);
+
+	return par;
+}
+
+blkid_partition blkid_partlist_add_partition(blkid_partlist ls,
+					blkid_parttable tab,
+					blkid_loff_t start, blkid_loff_t size)
+{
+	blkid_partition par = new_partition(ls, tab);
+
+	if (!par)
+		return NULL;
+
+	par->start = start;
+	par->size = size;
+
+	DBG(DEBUG_LOWPROBE,
+		printf("parts: add partition (%p start=%"
+		PRId64 ", size=%" PRId64 ", table=%p)\n",
+		par, par->start, par->size, tab));
+	return par;
+}
+
+/* allows to modify used partitions numbers (for example for logical partitions) */
+int blkid_partlist_set_partno(blkid_partlist ls, int partno)
+{
+	if (!ls)
+		return -1;
+	ls->next_partno = partno;
+	return 0;
+}
+
+int blkid_partlist_increment_partno(blkid_partlist ls)
+{
+	return ls ? ls->next_partno++ : -1;
+}
+
+/* allows to set "parent" for the next nested partition */
+int blkid_partlist_set_parent(blkid_partlist ls, blkid_partition par)
+{
+	if (!ls)
+		return -1;
+	ls->next_parent = par;
+	return 0;
+}
+
+blkid_partition blkid_partlist_get_parent(blkid_partlist ls)
+{
+	if (!ls)
+		return NULL;
+	return ls->next_parent;
+}
+
+int blkid_partitions_need_typeonly(blkid_probe pr)
+{
+	struct blkid_chain *chn = blkid_probe_get_chain(pr);
+
+	return chn && chn->data && chn->binary ? FALSE : TRUE;
+}
+
+/* get private chain flags */
+int blkid_partitions_get_flags(blkid_probe pr)
+{
+	struct blkid_chain *chn = blkid_probe_get_chain(pr);
+
+	return chn ? chn->flags : 0;
+}
+
+/* check if @start and @size are within @par partition */
+int blkid_is_nested_dimension(blkid_partition par,
+			blkid_loff_t start, blkid_loff_t size)
+{
+	blkid_loff_t pstart;
+	blkid_loff_t psize;
+
+	if (!par)
+		return 0;
+
+	pstart = blkid_partition_get_start(par);
+	psize = blkid_partition_get_size(par);
+
+	if (start < pstart || start + size > pstart + psize)
+		return 0;
+
+	return 1;
+}
+
+static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id,
+			struct blkid_chain *chn)
+{
+	const struct blkid_idmag *mag = NULL;
+	blkid_loff_t off;
+	int rc = 1;		/* = nothing detected */
+
+	if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
+		goto nothing;	/* the device is too small */
+
+	if (blkid_probe_get_idmag(pr, id, &off, &mag))
+		goto nothing;
+
+	/* final check by probing function */
+	if (id->probefunc) {
+		DBG(DEBUG_LOWPROBE, printf(
+			"%s: ---> call probefunc()\n", id->name));
+		rc = id->probefunc(pr, mag);
+	        if (rc == -1) {
+			/* reset after error */
+			reset_partlist(blkid_probe_get_partlist(pr));
+			if (chn && !chn->binary)
+				blkid_probe_chain_reset_vals(pr, chn);
+			DBG(DEBUG_LOWPROBE, printf(
+				"%s probefunc failed\n", id->name));
+		}
+		if (rc == 0 && mag && chn && !chn->binary)
+			rc = blkid_probe_set_magic(pr, off, mag->len,
+					(unsigned char *) mag->magic);
+
+		DBG(DEBUG_LOWPROBE, printf(
+			"%s: <--- (rc = %d)\n", id->name, rc));
+	}
+
+nothing:
+	return rc;
+}
+
+/*
+ * The blkid_do_probe() backend.
+ */
+static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
+{
+	int rc = 1;
+	size_t i;
+
+	if (!pr || chn->idx < -1)
+		return -1;
+	blkid_probe_chain_reset_vals(pr, chn);
+
+	if (chn->binary)
+		partitions_init_data(chn);
+
+	if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT))
+		goto details_only;
+
+	DBG(DEBUG_LOWPROBE,
+		printf("--> starting probing loop [PARTS idx=%d]\n",
+		chn->idx));
+
+	i = chn->idx < 0 ? 0 : chn->idx + 1U;
+
+	for ( ; i < ARRAY_SIZE(idinfos); i++) {
+		const char *name;
+
+		chn->idx = i;
+
+		/* apply filter */
+		if (chn->fltr && blkid_bmp_get_item(chn->fltr, i))
+			continue;
+
+		/* apply checks from idinfo */
+		if (idinfo_probe(pr, idinfos[i], chn) != 0)
+			continue;
+
+		name = idinfos[i]->name;
+
+		/* all checks passed */
+		if (!chn->binary)
+			blkid_probe_set_value(pr, "PTTYPE",
+						(unsigned char *) name,
+						strlen(name) + 1);
+		DBG(DEBUG_LOWPROBE,
+			printf("<-- leaving probing loop (type=%s) [PARTS idx=%d]\n",
+			name, chn->idx));
+		rc = 0;
+		break;
+	}
+
+	if (rc == 1) {
+		DBG(DEBUG_LOWPROBE,
+			printf("<-- leaving probing loop (failed) [PARTS idx=%d]\n",
+			chn->idx));
+	}
+
+details_only:
+	/*
+	 * Gather PART_ENTRY_* values if the current device is a partition.
+	 */
+	if (!chn->binary &&
+	    (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) {
+
+		if (!blkid_partitions_probe_partition(pr))
+			rc = 0;
+	}
+
+	return rc;
+}
+
+/* Probe for nested partition table within the parental partition */
+int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent,
+		const struct blkid_idinfo *id)
+{
+	blkid_probe prc;
+	int rc = 1;
+	blkid_partlist ls;
+	blkid_loff_t sz, off;
+
+	DBG(DEBUG_LOWPROBE, printf(
+		"parts: ----> %s subprobe requested (parent=%p)\n",
+		id->name, parent));
+
+	if (!pr || !parent || !parent->size)
+		return -1;
+
+	/* range defined by parent */
+	sz = ((blkid_loff_t) parent->size) << 9;
+	off = ((blkid_loff_t) parent->start) << 9;
+
+	if (off < pr->off || pr->off + pr->size < off + sz) {
+		DBG(DEBUG_LOWPROBE, printf(
+			"ERROR: parts: <---- '%s' subprobe: overflow detected.\n",
+			id->name));
+		return -1;
+	}
+
+	/* create private prober */
+	prc = blkid_clone_probe(pr);
+	if (!prc)
+		return -1;
+
+	blkid_probe_set_dimension(prc, off, sz);
+
+	/* clone is always with reset chain, fix it */
+	prc->cur_chain = blkid_probe_get_chain(pr);
+
+	/*
+	 * Set 'parent' to the current list of the partitions and use the list
+	 * in cloned prober (so the cloned prober will extend the current list
+	 * of partitions rather than create a new).
+	 */
+	ls = blkid_probe_get_partlist(pr);
+	blkid_partlist_set_parent(ls, parent);
+
+	blkid_probe_set_partlist(prc, ls);
+
+	rc = idinfo_probe(prc, id, blkid_probe_get_chain(pr));
+
+	blkid_probe_set_partlist(prc, NULL);
+	blkid_partlist_set_parent(ls, NULL);
+
+	blkid_free_probe(prc);	/* free cloned prober */
+
+	DBG(DEBUG_LOWPROBE, printf(
+		"parts: <---- %s subprobe done (parent=%p, rc=%d)\n",
+		id->name, parent, rc));
+
+	return rc;
+}
+
+static int blkid_partitions_probe_partition(blkid_probe pr)
+{
+	int rc = 1;
+	blkid_probe disk_pr = NULL;
+	blkid_partlist ls;
+	blkid_partition par;
+	dev_t devno;
+
+	devno = blkid_probe_get_devno(pr);
+	if (!devno)
+		goto nothing;
+
+	disk_pr = blkid_probe_get_wholedisk_probe(pr);
+	if (!disk_pr)
+		goto nothing;
+
+	/* parse PT */
+	ls = blkid_probe_get_partitions(disk_pr);
+	if (!ls)
+		goto nothing;
+
+	par = blkid_partlist_devno_to_partition(ls, devno);
+	if (par) {
+		const char *v;
+		blkid_parttable tab = blkid_partition_get_table(par);
+		dev_t disk = blkid_probe_get_devno(disk_pr);
+
+		if (tab) {
+			v = blkid_parttable_get_type(tab);
+			if (v)
+				blkid_probe_set_value(pr, "PART_ENTRY_SCHEME",
+					(unsigned char *) v, strlen(v) + 1);
+		}
+
+		v = blkid_partition_get_name(par);
+		if (v)
+			blkid_probe_set_value(pr, "PART_ENTRY_NAME",
+				(unsigned char *) v, strlen(v) + 1);
+
+		v = blkid_partition_get_uuid(par);
+		if (v)
+			blkid_probe_set_value(pr, "PART_ENTRY_UUID",
+				(unsigned char *) v, strlen(v) + 1);
+
+		/* type */
+		v = blkid_partition_get_type_string(par);
+		if (v)
+			blkid_probe_set_value(pr, "PART_ENTRY_TYPE",
+				(unsigned char *) v, strlen(v) + 1);
+		else
+			blkid_probe_sprintf_value(pr, "PART_ENTRY_TYPE",
+				"0x%x", blkid_partition_get_type(par));
+
+		if (blkid_partition_get_flags(par))
+			blkid_probe_sprintf_value(pr, "PART_ENTRY_FLAGS",
+				"0x%llx", blkid_partition_get_flags(par));
+
+		blkid_probe_sprintf_value(pr, "PART_ENTRY_NUMBER",
+				"%d", blkid_partition_get_partno(par));
+
+		blkid_probe_sprintf_value(pr, "PART_ENTRY_OFFSET", "%jd",
+				blkid_partition_get_start(par));
+		blkid_probe_sprintf_value(pr, "PART_ENTRY_SIZE", "%jd",
+				blkid_partition_get_size(par));
+
+		blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u",
+				major(disk), minor(disk));
+	}
+	rc = 0;
+nothing:
+	return rc;
+}
+
+/*
+ * Returns 1 if the device is whole-disk and the area specified by @offset and
+ * @size is covered by any partition.
+ */
+int blkid_probe_is_covered_by_pt(blkid_probe pr,
+				 blkid_loff_t offset, blkid_loff_t size)
+{
+	blkid_probe prc;
+	blkid_partlist ls = NULL;
+	blkid_loff_t start, end;
+	int nparts, i, rc = 0;
+
+	DBG(DEBUG_LOWPROBE, printf(
+		"=> checking if off=%jd size=%jd covered by PT\n",
+		offset, size));
+
+	prc = blkid_clone_probe(pr);
+	if (!prc)
+		goto done;
+
+	ls = blkid_probe_get_partitions(prc);
+	if (!ls)
+		goto done;
+
+	nparts = blkid_partlist_numof_partitions(ls);
+	if (!nparts)
+		goto done;
+
+	end = (offset + size) >> 9;
+	start = offset >> 9;
+
+	/* check if the partition table fits into the device */
+	for (i = 0; i < nparts; i++) {
+		blkid_partition par = &ls->parts[i];
+
+		if (par->start + par->size > (pr->size >> 9)) {
+			DBG(DEBUG_LOWPROBE, printf("partition #%d overflows "
+				"device (off=%" PRId64 " size=%" PRId64 ")\n",
+				par->partno, par->start, par->size));
+			goto done;
+		}
+	}
+
+	/* check if the requested area is covered by PT */
+	for (i = 0; i < nparts; i++) {
+		blkid_partition par = &ls->parts[i];
+
+		if (start >= par->start && end <= par->start + par->size) {
+			rc = 1;
+			break;
+		}
+	}
+done:
+	blkid_free_probe(prc);
+
+	DBG(DEBUG_LOWPROBE, printf("<= %s covered by PT\n", rc ? "IS" : "NOT"));
+	return rc;
+}
+
+/**
+ * blkid_known_pttype:
+ * @pttype: partiton name
+ *
+ * Returns: 1 for known or 0 for unknown partition type.
+ */
+int blkid_known_pttype(const char *pttype)
+{
+	size_t i;
+
+	if (!pttype)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
+		const struct blkid_idinfo *id = idinfos[i];
+		if (strcmp(id->name, pttype) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+/**
+ * blkid_partlist_numof_partitions:
+ * @ls: partitions list
+ *
+ * Returns: number of partitions in the list or -1 in case of error.
+ */
+int blkid_partlist_numof_partitions(blkid_partlist ls)
+{
+	return ls ? ls->nparts : -1;
+}
+
+/**
+ * blkid_partlist_get_table:
+ * @ls: partitions list
+ *
+ * Returns: top-level partition table or NULL of there is not a partition table
+ * on the device.
+ */
+blkid_parttable blkid_partlist_get_table(blkid_partlist ls)
+{
+	if (!ls || list_empty(&ls->l_tabs))
+		return NULL;
+
+	return list_entry(ls->l_tabs.next,
+			struct blkid_struct_parttable, t_tabs);
+}
+
+
+/**
+ * blkid_partlist_get_partition:
+ * @ls: partitions list
+ * @n: partition number in range 0..N, where 'N' is blkid_partlist_numof_partitions().
+ *
+ * It's possible that the list of partitions is *empty*, but there is a valid
+ * partition table on the disk. This happen when on-disk details about
+ * partitions are unknown or the partition table is empty.
+ *
+ * See also blkid_partlist_get_table().
+ *
+ * Returns: partition object or NULL in case or error.
+ */
+blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
+{
+	if (!ls || n < 0 || n >= ls->nparts)
+		return NULL;
+
+	return &ls->parts[n];
+}
+
+/**
+ * blkid_partlist_devno_to_partition:
+ * @ls: partitions list
+ * @devno: requested partition
+ *
+ * This function tries to get start and size for @devno from sysfs and
+ * returns a partition from @ls which matches with the values from sysfs.
+ *
+ * This function is necessary when you want to make a relation between an entry
+ * in the partition table (@ls) and block devices in your system.
+ *
+ * Returns: partition object or NULL in case or error.
+ */
+blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno)
+{
+	struct sysfs_cxt sysfs;
+	uint64_t start, size;
+	int i, rc, partno = 0;
+
+	if (!ls)
+		return NULL;
+
+	DBG(DEBUG_LOWPROBE,
+		printf("triyng to convert devno 0x%llx to partition\n",
+			(long long) devno));
+
+	if (sysfs_init(&sysfs, devno, NULL)) {
+		DBG(DEBUG_LOWPROBE, printf("failed t init sysfs context\n"));
+		return NULL;
+	}
+	rc = sysfs_read_u64(&sysfs, "size", &size);
+	if (!rc) {
+		rc = sysfs_read_u64(&sysfs, "start", &start);
+		if (rc) {
+			/* try to get partition number from DM uuid.
+			 */
+			char *uuid = sysfs_strdup(&sysfs, "dm/uuid");
+			char *tmp = uuid;
+			char *prefix = uuid ? strsep(&tmp, "-") : NULL;
+
+			if (prefix && strncasecmp(prefix, "part", 4) == 0) {
+				char *end = NULL;
+
+				partno = strtol(prefix + 4, &end, 10);
+				if (prefix == end || (end && *end))
+					partno = 0;
+				else
+					rc = 0;		/* success */
+			}
+			free(uuid);
+		}
+	}
+
+	sysfs_deinit(&sysfs);
+
+	if (rc)
+		return NULL;
+
+	if (partno) {
+		DBG(DEBUG_LOWPROBE, printf("mapped by DM, using partno %d\n", partno));
+
+		/*
+		 * Partition mapped by kpartx does not provide "start" offset
+		 * in /sys, but if we know partno and size of the partition
+		 * that we can probably make the releation bettween the device
+		 * and an entry in partition table.
+		 */
+		 for (i = 0; i < ls->nparts; i++) {
+			 blkid_partition par = &ls->parts[i];
+
+			 if (partno != blkid_partition_get_partno(par))
+				 continue;
+
+			 if ((blkid_loff_t) size == blkid_partition_get_size(par) ||
+			     (blkid_partition_is_extended(par) && size <= 1024))
+				 return par;
+
+		 }
+		 return NULL;
+	}
+
+	DBG(DEBUG_LOWPROBE, printf("searching by offset/size\n"));
+
+	for (i = 0; i < ls->nparts; i++) {
+		blkid_partition par = &ls->parts[i];
+
+		if (blkid_partition_get_start(par) == (blkid_loff_t) start &&
+		    blkid_partition_get_size(par) == (blkid_loff_t) size)
+			return par;
+
+		/* exception for extended dos partitions */
+		if (blkid_partition_get_start(par) == (blkid_loff_t) start &&
+		    blkid_partition_is_extended(par) && size <= 1024)
+			return par;
+
+	}
+
+	DBG(DEBUG_LOWPROBE, printf("not found partition for device\n"));
+	return NULL;
+}
+
+int blkid_parttable_set_id(blkid_parttable tab, const unsigned char *id)
+{
+	if (!tab)
+		return -1;
+
+	if (strcmp(tab->type, "gpt") == 0)
+		blkid_unparse_uuid(id, tab->id, sizeof(tab->id));
+	else if (strcmp(tab->type, "dos") == 0)
+		strncpy(tab->id, (const char *) id, sizeof(tab->id));
+
+	return 0;
+}
+
+/**
+ * blkid_parttable_get_id:
+ * @tab: partition table
+ *
+ * The ID is GPT disk UUID or DOS disk ID (in hex format).
+ *
+ * Returns: partition table ID (for example GPT disk UUID) or NULL
+ */
+const char *blkid_parttable_get_id(blkid_parttable tab)
+{
+	return tab && tab->id && *tab->id ? tab->id : NULL;
+}
+
+
+int blkid_partition_set_type(blkid_partition par, int type)
+{
+	if (!par)
+		return -1;
+	par->type = type;
+	return 0;
+}
+
+/**
+ * blkid_parttable_get_type:
+ * @tab: partition table
+ *
+ * Returns: partition table type (type name, e.g. "dos", "gpt", ...)
+ */
+const char *blkid_parttable_get_type(blkid_parttable tab)
+{
+	return tab ? tab->type : NULL;
+}
+
+/**
+ * blkid_parttable_get_parent:
+ * @tab: partition table
+ *
+ * Returns: parent for nexted partitition tables or NULL.
+ */
+blkid_partition blkid_parttable_get_parent(blkid_parttable tab)
+{
+	return tab ? tab->parent : NULL;
+}
+
+/**
+ * blkid_parttable_get_offset:
+ * @tab: partition table
+ *
+ * Note the position is relative to begin of the device as defined by
+ * blkid_probe_set_device() for primary partition table, and relative
+ * to parental partition for nested patition tables.
+ *
+ * <informalexample>
+ *   <programlisting>
+ * off_t offset;
+ * blkid_partition parent = blkid_parttable_get_parent(tab);
+ *
+ * offset = blkid_parttable_get_offset(tab);
+ *
+ * if (parent)
+ *      / * 'tab' is nested partition table * /
+ *	offset += blkid_partition_get_start(parent);
+ *   </programlisting>
+ * </informalexample>
+
+ * Returns: position (in bytes) of the partition table or -1 in case of error.
+ *
+ */
+blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab)
+{
+	return tab ? tab->offset : -1;
+}
+
+/**
+ * blkid_partition_get_table:
+ * @par: partition
+ *
+ * The "parttable" describes partition table. The table is usually the same for
+ * all partitions -- except nested partition tables.
+ *
+ * For example bsd, solaris, etc. use a nested partition table within
+ * standard primary dos partition:
+ *
+ * <informalexample>
+ *   <programlisting>
+ *
+ *  -- dos partition table
+ *  0: sda1     dos primary partition
+ *  1: sda2     dos primary partition
+ *     -- bsd partition table (with in sda2)
+ *  2:    sda5  bds partition
+ *  3:    sda6  bds partition
+ *
+ *   </programlisting>
+ * </informalexample>
+ *
+ * The library does not to use a separate partition table object for dos logical
+ * partitions (partitions within extended partition). It's possible to
+ * differentiate between logical, extended and primary partitions by
+ *
+ *	blkid_partition_is_{extended,primary,logical}().
+ *
+ * Returns: partition table object or NULL in case of error.
+ */
+blkid_parttable blkid_partition_get_table(blkid_partition par)
+{
+	return par ? par->tab : NULL;
+}
+
+static int partition_get_logical_type(blkid_partition par)
+{
+	blkid_parttable tab;
+
+	if (!par)
+		return -1;
+
+	tab = blkid_partition_get_table(par);
+	if (!tab || !tab->type)
+		return -1;
+
+	if (tab->parent)
+		return 'L';  /* report nested partitions as logical */
+
+	if (!strcmp(tab->type, "dos")) {
+		if (par->partno > 4)
+			return 'L';	/* logical */
+
+	        if(par->type == BLKID_DOS_EXTENDED_PARTITION ||
+                   par->type == BLKID_W95_EXTENDED_PARTITION ||
+		   par->type == BLKID_LINUX_EXTENDED_PARTITION)
+			return 'E';
+	}
+	return 'P';
+}
+
+/**
+ * blkid_partition_is_primary:
+ * @par: partition
+ *
+ * Note, this function returns FALSE for DOS extended partitions and
+ * all partitions in nested partition tables.
+ *
+ * Returns: 1 if the partitions is primary partition or 0 if not.
+ */
+int blkid_partition_is_primary(blkid_partition par)
+{
+	return partition_get_logical_type(par) == 'P' ? TRUE : FALSE;
+}
+
+/**
+ * blkid_partition_is_extended:
+ * @par: partition
+ *
+ * Returns: 1 if the partitions is extended (dos, windows or linux)
+ * partition or 0 if not.
+ */
+int blkid_partition_is_extended(blkid_partition par)
+{
+	return partition_get_logical_type(par) == 'E' ? TRUE : FALSE;
+}
+
+/**
+ * blkid_partition_is_logical:
+ * @par: partition
+ *
+ * Note that this function returns TRUE for all partitions in all
+ * nested partition tables (e.g. BSD labels).
+ *
+ * Returns: 1 if the partitions is logical partition or 0 if not.
+ */
+int blkid_partition_is_logical(blkid_partition par)
+{
+	return partition_get_logical_type(par) == 'L' ? TRUE : FALSE;
+}
+
+static void set_string(unsigned char *item, size_t max,
+				const unsigned char *data, size_t len)
+{
+	if (len >= max)
+		len = max - 1;
+
+	memcpy(item, data, len);
+	item[len] = '\0';
+
+	blkid_rtrim_whitespace(item);
+}
+
+int blkid_partition_set_name(blkid_partition par,
+		const unsigned char *name, size_t len)
+{
+	if (!par)
+		return -1;
+
+	set_string(par->name, sizeof(par->name), name, len);
+	return 0;
+}
+
+int blkid_partition_set_utf8name(blkid_partition par, const unsigned char *name,
+		size_t len, int enc)
+{
+	if (!par)
+		return -1;
+
+	blkid_encode_to_utf8(enc, par->name, sizeof(par->name), name, len);
+	blkid_rtrim_whitespace(par->name);
+	return 0;
+}
+
+int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid)
+{
+	if (!par)
+		return -1;
+
+	blkid_unparse_uuid(uuid, par->uuid, sizeof(par->uuid));
+	return 0;
+}
+
+/**
+ * blkid_partition_get_name:
+ * @par: partition
+ *
+ * Returns: partition name string if supported by PT (e.g. Mac) or NULL.
+ */
+const char *blkid_partition_get_name(blkid_partition par)
+{
+	return par && *par->name ? (char *) par->name : NULL;
+}
+
+/**
+ * blkid_partition_get_uuid:
+ * @par: partition
+ *
+ * Returns: partition UUID string if supported by PT (e.g. GPT) or NULL.
+ */
+const char *blkid_partition_get_uuid(blkid_partition par)
+{
+	return par && *par->uuid ? par->uuid : NULL;
+}
+
+/**
+ * blkid_partition_get_partno:
+ * @par: partition
+ *
+ * Returns: proposed partitin number (e.g. 'N' from sda'N') or -1 in case of
+ * error. Note that the number is generate by library independenly on your OS.
+ */
+int blkid_partition_get_partno(blkid_partition par)
+{
+	return par ? par->partno : -1;
+}
+
+/**
+ * blkid_partition_get_start:
+ * @par: partition
+ *
+ * Be careful if you _not_ probe whole disk:
+ *
+ * 1) the offset is usully relative to begin of the disk -- but if you probe a
+ *    fragment of the disk only -- then the offset could be still relative to
+ *    the begin of the disk rather that relative to the fragment.
+ *
+ * 2) the offset for nested partitions could be releative to parent (e.g. Solaris)
+ *    _or_ relative to the begin of the whole disk (e.g. bsd).
+ *
+ * You don't have to care about such details if you proble whole disk. In such
+ * a case libblkid always returns the offset relative to the begin of the disk.
+ *
+ * Returns: start of the partition (in 512-sectors).
+ */
+blkid_loff_t blkid_partition_get_start(blkid_partition par)
+{
+	return par ? par->start : -1;
+}
+
+/**
+ * blkid_partition_get_size:
+ * @par: partition
+ *
+ * WARNING: be very careful when you work with MS-DOS extended partitions. The
+ *          library always returns full size of the partition. If you want add
+ *          the partition to the Linux system (BLKPG_ADD_PARTITION ioctl) you
+ *          need to reduce the size of the partition to 1 or 2 blocks. The
+ *          rest of the partition has to be unaccessible for mkfs or mkswap
+ *          programs, we need a small space for boot loaders only.
+ *
+ *          For some unknown reason this (safe) practice is not to used for
+ *          nested BSD, Solaris, ..., partition tables in Linux kernel.
+ *
+ * Returns: size of the partition (in 512-sectors).
+ */
+blkid_loff_t blkid_partition_get_size(blkid_partition par)
+{
+	return par ? par->size : -1;
+}
+
+/**
+ * blkid_partition_get_type:
+ * @par: partition
+ *
+ * Returns: partition type.
+ */
+int blkid_partition_get_type(blkid_partition par)
+{
+	return par->type;
+}
+
+/* Sets partition 'type' for PT where the type is defined by string rather
+ * than by number
+ */
+int blkid_partition_set_type_string(blkid_partition par,
+		const unsigned char *type, size_t len)
+{
+	if (!par)
+		return -1;
+
+	set_string((unsigned char *) par->typestr,
+			sizeof(par->typestr), type, len);
+	return 0;
+}
+
+/* Sets partition 'type' for PT where the type is defined by UUIDrather
+ * than by number
+ */
+int blkid_partition_set_type_uuid(blkid_partition par, const unsigned char *uuid)
+{
+	if (!par)
+		return -1;
+
+	blkid_unparse_uuid(uuid, par->typestr, sizeof(par->typestr));
+	return 0;
+}
+
+/**
+ * blkid_partition_get_type_string:
+ * @par: partition
+ *
+ * The type string is supported by a small subset of partition tables (e.g Mac
+ * and EFI GPT).  Note that GPT uses type UUID and this function returns this
+ * UUID as string.
+ *
+ * Returns: partition type string or NULL.
+ */
+const char *blkid_partition_get_type_string(blkid_partition par)
+{
+	return par && *par->typestr ? par->typestr : NULL;
+}
+
+
+int blkid_partition_set_flags(blkid_partition par, unsigned long long flags)
+{
+	if (!par)
+		return -1;
+	par->flags = flags;
+	return 0;
+}
+
+/**
+ * blkid_partition_get_flags
+ * @par: partition
+ *
+ * Returns: partition flags (or attributes for gpt).
+ */
+unsigned long long blkid_partition_get_flags(blkid_partition par)
+{
+	return par->flags;
+}
+
