diff options
Diffstat (limited to 'shlibs')
-rw-r--r-- | shlibs/blkid/src/partitions/partitions.c | 49 | ||||
-rw-r--r-- | shlibs/blkid/src/probe.c | 15 |
2 files changed, 41 insertions, 23 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", diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index 5f75d713e..85db814f0 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -527,12 +527,18 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, if (pr->parent && pr->parent->devno == pr->devno && - pr->parent->off == pr->off) + pr->parent->off <= pr->off && + pr->parent->off + pr->parent->size >= pr->off + pr->size) { /* * This is a cloned prober and points to the same area as - * parent. Let's use parent's bufferes. + * parent. Let's use parent's buffers. + * + * Note that pr->off (and pr->parent->off) is always from the + * beginig of the device. */ - return blkid_probe_get_buffer(pr->parent, off, len); + return blkid_probe_get_buffer(pr->parent, + pr->off + off - pr->parent->off, len); + } list_for_each(p, &pr->buffers) { struct blkid_bufinfo *x = @@ -737,8 +743,9 @@ int blkid_probe_set_dimension(blkid_probe pr, return -1; DBG(DEBUG_LOWPROBE, printf( - "changing probing area: size=%llu, off=%llu " + "changing probing area pr=%p: size=%llu, off=%llu " "-to-> size=%llu, off=%llu\n", + pr, (unsigned long long) pr->size, (unsigned long long) pr->off, (unsigned long long) size, |