summaryrefslogtreecommitdiffstats
path: root/shlibs/blkid/src/partitions/partitions.c
diff options
context:
space:
mode:
authorKarel Zak2011-05-16 10:31:50 +0200
committerKarel Zak2011-05-16 20:22:52 +0200
commitac8874cad39711d588c95dfbce79eaf13b14e361 (patch)
tree41f5a786ae8b36fb2b12d1553f92df2a772a8da4 /shlibs/blkid/src/partitions/partitions.c
parentlibblkid: make whole disk probing more robust (diff)
downloadkernel-qcow2-util-linux-ac8874cad39711d588c95dfbce79eaf13b14e361.tar.gz
kernel-qcow2-util-linux-ac8874cad39711d588c95dfbce79eaf13b14e361.tar.xz
kernel-qcow2-util-linux-ac8874cad39711d588c95dfbce79eaf13b14e361.zip
libblkid: use cached buffers for nested PT probing
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/blkid/src/partitions/partitions.c')
-rw-r--r--shlibs/blkid/src/partitions/partitions.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c
index 42c6c2c79..b3b52f0f1 100644
--- a/shlibs/blkid/src/partitions/partitions.c
+++ b/shlibs/blkid/src/partitions/partitions.c
@@ -297,6 +297,11 @@ 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++;
@@ -620,9 +625,10 @@ details_only:
int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent,
const struct blkid_idinfo *id)
{
- int rc = 1, flags;
+ blkid_probe prc;
+ int rc = 1;
blkid_partlist ls;
- blkid_loff_t saved_sz, saved_off, sz, off;
+ blkid_loff_t sz, off;
DBG(DEBUG_LOWPROBE, printf(
"parts: ----> %s subprobe requested (parent=%p)\n",
@@ -631,38 +637,43 @@ int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent,
if (!pr || !parent || !parent->size)
return -1;
- ls = blkid_probe_get_partlist(pr);
-
+ /* range defined by parent */
sz = ((blkid_loff_t) parent->size) << 9;
off = ((blkid_loff_t) parent->start) << 9;
- /* get the current setting in bytes */
- blkid_probe_get_dimension(pr, &saved_off, &saved_sz);
-
- /* check the requested range */
- if (off < saved_off || saved_off + saved_sz < off + sz) {
+ if (off < pr->off || pr->off + pr->size < off + sz) {
DBG(DEBUG_LOWPROBE, printf(
- "ERROR: parts: <---- '%s' sub-probe: overflow detected.\n",
+ "ERROR: parts: <---- '%s' subprobe: overflow detected.\n",
id->name));
return -1;
}
- /* flags depends on size of the partition */
- flags = pr->flags;
+ /* create private prober */
+ prc = blkid_clone_probe(pr);
+ if (!prc)
+ return -1;
- /* define sub-range with in device */
- blkid_probe_set_dimension(pr, off, sz);
+ blkid_probe_set_dimension(prc, off, sz);
+ /* clone is always with reseted 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);
- rc = idinfo_probe(pr, id);
+ blkid_probe_set_partlist(prc, ls);
- blkid_partlist_set_parent(ls, NULL);
+ rc = idinfo_probe(prc, id);
- /* restore the original setting */
- blkid_probe_set_dimension(pr, saved_off, saved_sz);
+ blkid_probe_set_partlist(prc, NULL);
+ blkid_partlist_set_parent(ls, NULL);
- pr->flags = flags;
+ blkid_free_probe(prc); /* free cloned prober */
DBG(DEBUG_LOWPROBE, printf(
"parts: <---- %s subprobe done (parent=%p, rc=%d)\n",