diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
new file mode 100644
index 0000000..4853f97
--- /dev/null
+++ b/libblkid/src/partitions/partitions.c
@@ -0,0 +1,1512 @@
+/*
+ * 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.).
+ *
+ * @PTUUID: partition table id (uuid for gpt, hex for dos).
+
+ * @PART_ENTRY_SCHEME: partition table type
+ *
+ * @PART_ENTRY_NAME: partition name (gpt and mac only)
+ *
+ * @PART_ENTRY_UUID: partition UUID (gpt, or pseudo IDs for MBR)
+ *
+ * @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,
+	&pmbr_pt_idinfo,	/* always after GPT */
+	&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 (in bytes) */
+	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 (512-bytes sectors) */
+	blkid_loff_t	size;		/* size of the partitions (512-bytes sectors) */
+
+	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(LOWPROBE, ul_debug("partlist reset"));
+}
+
+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(LOWPROBE, ul_debug("parts: initialized partitions list (%p, size=%d)",
+		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(LOWPROBE, ul_debug("parts: create a new partition table "
+		       "(%p, type=%s, offset=%"PRId64")", 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.
+		 */
+		void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
+					sizeof(struct blkid_struct_partition));
+		if (!tmp)
+			return NULL;
+		ls->parts = tmp;
+		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(LOWPROBE, ul_debug("parts: add partition (%p start=%"
+		PRId64 ", size=%" PRId64 ", table=%p)",
+		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 = BLKID_PROBE_NONE;		/* default is nothing */
+
+	if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
+		goto nothing;	/* the device is too small */
+	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+		goto nothing;
+
+	rc = blkid_probe_get_idmag(pr, id, &off, &mag);
+	if (rc != BLKID_PROBE_OK)
+		goto nothing;
+
+	/* final check by probing function */
+	if (id->probefunc) {
+		DBG(LOWPROBE, ul_debug(
+			"%s: ---> call probefunc()", id->name));
+		rc = id->probefunc(pr, mag);
+		if (rc < 0) {
+			/* reset after error */
+			reset_partlist(blkid_probe_get_partlist(pr));
+			if (chn && !chn->binary)
+				blkid_probe_chain_reset_vals(pr, chn);
+			DBG(LOWPROBE, ul_debug("%s probefunc failed, rc %d",
+						  id->name, rc));
+		}
+		if (rc == BLKID_PROBE_OK && mag && chn && !chn->binary)
+			rc = blkid_probe_set_magic(pr, off, mag->len,
+					(unsigned char *) mag->magic);
+
+		DBG(LOWPROBE, ul_debug("%s: <--- (rc = %d)", id->name, rc));
+	}
+
+	return rc;
+
+nothing:
+	return BLKID_PROBE_NONE;
+}
+
+/*
+ * The blkid_do_probe() backend.
+ */
+static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
+{
+	int rc = BLKID_PROBE_NONE;
+	size_t i;
+
+	if (!pr || chn->idx < -1)
+		return -EINVAL;
+
+	blkid_probe_chain_reset_vals(pr, chn);
+
+	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+		return BLKID_PROBE_NONE;
+
+	if (chn->binary)
+		partitions_init_data(chn);
+
+	if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT))
+		goto details_only;
+
+	DBG(LOWPROBE, ul_debug("--> starting probing loop [PARTS idx=%d]",
+		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 */
+		rc = idinfo_probe(pr, idinfos[i], chn);
+		if (rc < 0)
+			break;
+		if (rc != BLKID_PROBE_OK)
+			continue;
+
+		name = idinfos[i]->name;
+
+		if (!chn->binary)
+			/*
+			 * Non-binary interface, set generic variables. Note
+			 * that the another variables could be set in prober
+			 * functions.
+			 */
+			blkid_probe_set_value(pr, "PTTYPE",
+						(unsigned char *) name,
+						strlen(name) + 1);
+
+		DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [PARTS idx=%d]",
+			name, chn->idx));
+		rc = BLKID_PROBE_OK;
+		break;
+	}
+
+	if (rc != BLKID_PROBE_OK) {
+		DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [PARTS idx=%d]",
+			rc, chn->idx));
+	}
+
+details_only:
+	/*
+	 * Gather PART_ENTRY_* values if the current device is a partition.
+	 */
+	if ((rc == BLKID_PROBE_OK || rc == BLKID_PROBE_NONE) && !chn->binary &&
+	    (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) {
+
+		int xrc = blkid_partitions_probe_partition(pr);
+
+		/* partition entry probing is optional, and "not-found" from
+		 * this sub-probing must not to overwrite previous success. */
+		if (xrc < 0)
+			rc = xrc;			/* always propagate errors */
+		else if (rc == BLKID_PROBE_NONE)
+			rc = xrc;
+	}
+
+	DBG(LOWPROBE, ul_debug("partitions probe done [rc=%d]",	rc));
+	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;
+	blkid_partlist ls;
+	blkid_loff_t sz, off;
+
+	DBG(LOWPROBE, ul_debug(
+		"parts: ----> %s subprobe requested (parent=%p)",
+		id->name, parent));
+
+	if (!pr || !parent || !parent->size)
+		return -EINVAL;
+	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+		return BLKID_PROBE_NONE;
+
+	/* 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(LOWPROBE, ul_debug(
+			"ERROR: parts: <---- '%s' subprobe: overflow detected.",
+			id->name));
+		return -ENOSPC;
+	}
+
+	/* create private prober */
+	prc = blkid_clone_probe(pr);
+	if (!prc)
+		return -ENOMEM;
+
+	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(LOWPROBE, ul_debug(
+		"parts: <---- %s subprobe done (parent=%p, rc=%d)",
+		id->name, parent, rc));
+
+	return rc;
+}
+
+static int blkid_partitions_probe_partition(blkid_probe pr)
+{
+	blkid_probe disk_pr = NULL;
+	blkid_partlist ls;
+	blkid_partition par;
+	dev_t devno;
+
+	DBG(LOWPROBE, ul_debug("parts: start probing for partition entry"));
+
+	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+		goto nothing;
+
+	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)
+		goto nothing;
+	else {
+		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));
+	}
+
+	DBG(LOWPROBE, ul_debug("parts: end probing for partition entry [success]"));
+	return BLKID_PROBE_OK;
+
+nothing:
+	DBG(LOWPROBE, ul_debug("parts: end probing for partition entry [nothing]"));
+	return BLKID_PROBE_NONE;
+
+
+}
+
+/*
+ * 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 = NULL;
+	blkid_partlist ls = NULL;
+	blkid_loff_t start, end;
+	int nparts, i, rc = 0;
+
+	DBG(LOWPROBE, ul_debug(
+		"=> checking if off=%jd size=%jd covered by PT",
+		offset, size));
+
+	if (pr->flags & BLKID_FL_NOSCAN_DEV)
+		goto done;
+
+	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(LOWPROBE, ul_debug("partition #%d overflows "
+				"device (off=%" PRId64 " size=%" PRId64 ")",
+				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(LOWPROBE, ul_debug("<= %s covered by PT", 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_get_partition_by_partno
+ * @ls: partitions list
+ * @n: the partition number (e.g. 'N' from sda'N')
+ *
+ * This does not assume any order of the input blkid_partlist.  And correctly
+ * handles "out of order" partition tables.  partition N is located after
+ * partition N+1 on the disk.
+ *
+ * Returns: partition object or NULL in case or error.
+ */
+blkid_partition blkid_partlist_get_partition_by_partno(blkid_partlist ls, int n)
+{
+	int i, nparts;
+	blkid_partition par;
+
+	if (!ls)
+		return NULL;
+
+	nparts = blkid_partlist_numof_partitions(ls);
+	for (i = 0; i < nparts; i++) {
+		par = blkid_partlist_get_partition(ls, i);
+		if (n == blkid_partition_get_partno(par))
+			return par;
+	}
+	return NULL;
+}
+
+
+/**
+ * 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(LOWPROBE, ul_debug("triyng to convert devno 0x%llx to partition",
+			(long long) devno));
+
+	if (sysfs_init(&sysfs, devno, NULL)) {
+		DBG(LOWPROBE, ul_debug("failed t init sysfs context"));
+		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(LOWPROBE, ul_debug("mapped by DM, using partno %d", 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(LOWPROBE, ul_debug("searching by offset/size"));
+
+	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(LOWPROBE, ul_debug("not found partition for device"));
+	return NULL;
+}
+
+
+int blkid_parttable_set_uuid(blkid_parttable tab, const unsigned char *id)
+{
+	if (!tab)
+		return -1;
+
+	blkid_unparse_uuid(id, tab->id, sizeof(tab->id));
+	return 0;
+}
+
+int blkid_parttable_set_id(blkid_parttable tab, const unsigned char *id)
+{
+	if (!tab)
+		return -1;
+
+	strncpy(tab->id, (const char *) id, sizeof(tab->id));
+	return 0;
+}
+
+/* set PTUUID variable for non-binary API */
+int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid)
+{
+	struct blkid_chain *chn = blkid_probe_get_chain(pr);
+	struct blkid_prval *v;
+
+	if (chn->binary || blkid_uuid_is_empty(uuid, 16))
+		return 0;
+
+	v = blkid_probe_assign_value(pr, "PTUUID");
+
+	blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data));
+	v->len = 37;
+
+	return 0;
+}
+
+/* set PTUUID variable for non-binary API for tables where
+ * the ID is just a string */
+int blkid_partitions_strcpy_ptuuid(blkid_probe pr, char *str)
+{
+	struct blkid_chain *chn = blkid_probe_get_chain(pr);
+	struct blkid_prval *v;
+	size_t len;
+
+	if (chn->binary || !str || !*str)
+		return 0;
+
+	len = strlen((char *) str);
+	if (len > BLKID_PROBVAL_BUFSIZ)
+		len = BLKID_PROBVAL_BUFSIZ;
+
+	v = blkid_probe_assign_value(pr, "PTUUID");
+	if (v) {
+		if (len == BLKID_PROBVAL_BUFSIZ)
+			len--;		/* make a space for \0 */
+
+		memcpy((char *) v->data, str, len);
+		v->data[len] = '\0';
+		v->len = len + 1;
+		return 0;
+	}
+	return -1;
+}
+
+/**
+ * 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 : 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 == MBR_DOS_EXTENDED_PARTITION ||
+                   par->type == MBR_W95_EXTENDED_PARTITION ||
+		   par->type == MBR_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;
+}
+
+int blkid_partition_gen_uuid(blkid_partition par)
+{
+	if (!par || !par->tab || !*par->tab->id)
+		return -1;
+
+	snprintf(par->uuid, sizeof(par->uuid), "%s-%02x",
+			par->tab->id, par->partno);
+	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;
+}
+
