]> err.no Git - util-linux/commitdiff
blkid: support detection of multiple signatures
authorKarel Zak <kzak@redhat.com>
Thu, 20 Nov 2008 12:00:43 +0000 (13:00 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 11 Feb 2009 22:21:47 +0000 (23:21 +0100)
The classic way is to return the first successfully detected signature
(filesystem/raid).  Unfortunately, sometimes we need to check for all
possible signatures, because on some volumes (e.g. CD-ROMs) is possible
to store multiple filesystems.

Sometimes we need to check for all filesystems to avoid situation that
we return wrong result (e.g. swap and FAT on the same device).

Signed-off-by: Karel Zak <kzak@redhat.com>
libs/blkid/src/blkidP.h
libs/blkid/src/probe.c

index c48a203100e2a2c78aa5f18ae06824cf575b509c..8927947cf433b9524d6f0540a3441a441649ab54 100644 (file)
@@ -103,6 +103,7 @@ struct blkid_struct_probe
        int                     nvals;
 
        int                     probreq;        /* BLKID_PROBREQ_* flags */
+       int                     idx;            /* index of the last prober */
 
        unsigned long           *fltr;          /* filter */
 };
index 118a355a74a7540f3ed211f35b441d6d09a5bfb0..ff75898c4d6a26582f61aa3513593b5e535fecd8 100644 (file)
@@ -263,6 +263,7 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
        if (!blkid_probe_get_buffer(pr, 0, 0x200))
                return -1;
 
+       pr->idx = 0;
        return 0;
 }
 
@@ -280,6 +281,7 @@ int blkid_probe_reset_filter(blkid_probe pr)
                return -1;
        if (pr->fltr)
                memset(pr->fltr, 0, BLKID_FLTR_SIZE * sizeof(unsigned long));
+       pr->idx = 0;
        return 0;
 }
 
@@ -323,6 +325,7 @@ int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
                                blkid_bmp_set_item(pr->fltr, i);
                }
        }
+       pr->idx = 0;
        return 0;
 }
 
@@ -356,6 +359,7 @@ int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
                } else if (flag & BLKID_FLTR_ONLYIN)
                        blkid_bmp_set_item(pr->fltr, i);
        }
+       pr->idx = 0;
        return 0;
 }
 
@@ -368,22 +372,63 @@ int blkid_probe_invert_filter(blkid_probe pr)
                return -1;
        for (i = 0; i < BLKID_FLTR_SIZE; i++)
                pr->fltr[i] = ~pr->fltr[i];
+
+       pr->idx = 0;
        return 0;
 }
 
+/*
+ * The blkid_do_probe() calls the probe functions. This routine could be used
+ * in a loop when you need to probe for all possible filesystems/raids.
+ *
+ * 1/ basic case -- use the first result:
+ *
+ *     if (blkid_do_probe(pr) == 0) {
+ *             int nvals = blkid_probe_numof_values(pr);
+ *             for (n = 0; n < nvals; n++) {
+ *                     if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
+ *                             printf("%s = %s\n", name, data);
+ *             }
+ *     }
+ *
+ * 2/ advanced case -- probe for all signatures (don't forget that some
+ *                     filesystems can co-exist on one volume (e.g. CD-ROM).
+ *
+ *     while (blkid_do_probe(pr) == 0) {
+ *             int nvals = blkid_probe_numof_values(pr);
+ *             ...
+ *     }
+ *
+ *    The internal probing index (pointer to the last probing function) is
+ *    always reseted when you touch probing filter or set a new device. It
+ *    means you cannot use:
+ *
+ *      blkid_probe_invert_filter()
+ *      blkid_probe_filter_usage()
+ *      blkid_probe_filter_types()
+ *      blkid_probe_reset_filter()
+ *      blkid_probe_set_device()
+ *
+ *    in the loop (e.g while()) when you iterate on all signatures.
+ */
 int blkid_do_probe(blkid_probe pr)
 {
-       int i;
+       int i = 0;
 
        if (!pr)
                return -1;
 
        blkid_probe_reset_vals(pr);
 
+       if (pr->idx)
+               i = pr->idx + 1;
+
        for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
                const struct blkid_idinfo *id;
                const struct blkid_idmag *mag;
 
+               pr->idx = i;
+
                if (pr->fltr && blkid_bmp_get_item(pr->fltr, i))
                        continue;