chiark / gitweb /
volume_id: always check for all filesystem types and skip conflicting results
authorKay Sievers <kay.sievers@vrfy.org>
Thu, 13 Nov 2008 18:34:41 +0000 (19:34 +0100)
committerKay Sievers <kay.sievers@vrfy.org>
Thu, 13 Nov 2008 18:34:41 +0000 (19:34 +0100)
We probe for all known filesystems to find conflicting signatures. If
we find multiple matching signatures and one of the detected filesystem
types claims that it can not co-exist with any other filesystem type,
we do not return a probing result.

We can not afford to mount a volume with the wrong filesystem code and
possibly corrupt it. Linux ssytems have the problem of dozens of possible
filesystem types, and volumes with left-over signatures from former
filesystem types. Invalid signature need to be removed from the volume
to make the filesystem detection successful.

We do not want to read that many bytes from probed floppies, skip volumes
smaller than a usual floppy disk.

extras/volume_id/lib/fat.c
extras/volume_id/lib/libvolume_id-private.h
extras/volume_id/lib/linux_swap.c
extras/volume_id/lib/volume_id.c

index e30318cf0967477e5931c58efd7dee6252fce42c..2d98b65b50e7e2dca2bb51aaaaab061d2d7901c0 100644 (file)
@@ -497,6 +497,7 @@ fat32:
 found:
        volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
        id->type = "vfat";
-
+       /* we think this is fat, but we make sure no other signatures are found */
+       id->force_unique_result = 1;
        return 0;
 }
index 14f7568fec60f30977bc64a84f7ec8992d5241c8..1b4a782b6513c20022b770029140c6f5dbeee49f 100644 (file)
@@ -120,6 +120,7 @@ struct volume_id {
        uint8_t         *seekbuf;
        uint64_t        seekbuf_off;
        size_t          seekbuf_len;
+       int             force_unique_result;
 };
 
 /* utils */
index c4beeab978c9dc6711577280826087d3ed198645..1698e9dbf73a0014b382d9bee38077fdc0c1a740 100644 (file)
@@ -97,5 +97,7 @@ found_label:
 
 found:
        volume_id_set_usage(id, VOLUME_ID_OTHER);
+       /* we think this is swap, but we make sure no other signatures are found */
+       id->force_unique_result = 1;
        return 0;
 }
index 8f22509ca6be6ab718780dda3e4c428c4cbc0a9a..e4d2ed4cfac725adc092ffc7fe1fa73e6edca181 100644 (file)
@@ -369,9 +369,12 @@ int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size)
 
        info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
 
-       for (i = 0; i < ARRAY_SIZE(prober_raid); i++)
-               if (prober_raid[i].prober(id, off, size) == 0)
+       for (i = 0; i < ARRAY_SIZE(prober_raid); i++) {
+               if (prober_raid[i].prober(id, off, size) == 0) {
+                       info("signature '%s' detected\n", id->type);
                        goto found;
+               }
+       }
        return -1;
 
 found:
@@ -402,11 +405,50 @@ int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size
 
        info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
 
-       for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++)
-               if (prober_filesystem[i].prober(id, off, size) == 0)
+       /*
+        * We probe for all known filesystems to find conflicting signatures. If
+        * we find multiple matching signatures and one of the detected filesystem
+        * types claims that it can not co-exist with any other filesystem type,
+        * we do not return a probing result.
+        *
+        * We can not afford to mount a volume with the wrong filesystem code and
+        * possibly corrupt it. Linux ssytems have the problem of dozens of possible
+        * filesystem types, and volumes with left-over signatures from former
+        * filesystem types. Invalid signature need to be removed from the volume
+        * to make the filesystem detection successful.
+        *
+        * We do not want to read that many bytes from probed floppies, skip volumes
+        * smaller than a usual floppy disk
+        */
+       if (size > 1440 * 1024) {
+               int found = 0;
+               int force_unique_result = 0;
+
+               for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) {
+                       int match;
+
+                       match = (prober_filesystem[i].prober(id, off, size) == 0);
+                       if (match) {
+                               info("signature '%s' detected\n", id->type);
+                               if (id->force_unique_result)
+                                       force_unique_result = id->force_unique_result;
+                               if (found && force_unique_result) {
+                                       info("conflicting signatures found, skip results\n");
+                                       return -1;
+                               }
+                               found = 1;
+                       }
+               }
+       }
+
+       /* return the first match */
+       for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) {
+               if (prober_filesystem[i].prober(id, off, size) == 0) {
+                       info("signature '%s' detected\n", id->type);
                        goto found;
+               }
+       }
        return -1;
-
 found:
        /* If recognized, we free the allocated buffers */
        volume_id_free_buffer(id);