]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: use cached buffers for nested PT probing
authorKarel Zak <kzak@redhat.com>
Mon, 16 May 2011 08:31:50 +0000 (10:31 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 16 May 2011 18:22:52 +0000 (20:22 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/blkid/src/partitions/partitions.c
shlibs/blkid/src/probe.c

index 42c6c2c79f5275bf6b2e475f47e7c77bf0b455de..b3b52f0f1279914b2aea9ddb2014c42aab98bf18 100644 (file)
@@ -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",
index 5f75d713e2a0cbbe6d61ae59a2f5b40f3ce60782..85db814f0c97debb2da325b419bf9110522c75af 100644 (file)
@@ -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,