volume_id: abort early on read failures.
authorDenis Vlasenko <vda.linux@googlemail.com>
Sun, 15 Feb 2009 05:51:19 +0000 (05:51 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sun, 15 Feb 2009 05:51:19 +0000 (05:51 -0000)
 should help with probing missing fdd's

20 files changed:
util-linux/volume_id/cramfs.c
util-linux/volume_id/ext.c
util-linux/volume_id/fat.c
util-linux/volume_id/get_devname.c
util-linux/volume_id/hfs.c
util-linux/volume_id/iso9660.c
util-linux/volume_id/jfs.c
util-linux/volume_id/linux_raid.c
util-linux/volume_id/linux_swap.c
util-linux/volume_id/luks.c
util-linux/volume_id/ntfs.c
util-linux/volume_id/ocfs2.c
util-linux/volume_id/reiserfs.c
util-linux/volume_id/romfs.c
util-linux/volume_id/sysv.c
util-linux/volume_id/udf.c
util-linux/volume_id/util.c
util-linux/volume_id/volume_id.c
util-linux/volume_id/volume_id_internal.h
util-linux/volume_id/xfs.c

index 63b0c7cad26d02a8e94f99ac8c82451da230826f..dd939e4949bc75104cd15c0d3e1cea9a055d462c 100644 (file)
@@ -35,8 +35,9 @@ struct cramfs_super {
        uint8_t         name[16];
 } __attribute__((__packed__));
 
-int volume_id_probe_cramfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_cramfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct cramfs_super *cs;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);
index db29dae705c78a4864ff35cdf8de5dd1f5d3c330..b052e04ce45ff37568b5a0f7ba8c467252b8d68d 100644 (file)
@@ -43,8 +43,9 @@ struct ext2_super_block {
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x00000008
 #define EXT_SUPERBLOCK_OFFSET                  0x400
 
-int volume_id_probe_ext(struct volume_id *id, uint64_t off)
+int volume_id_probe_ext(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct ext2_super_block *es;
 
        dbg("ext: probing at offset 0x%llx", (unsigned long long) off);
index 0e0a57d62c53599c648d3d8b56b3d0ecb8693ec9..352040f57148ad64ddbd06bb9e2acb8c28834979 100644 (file)
@@ -119,8 +119,9 @@ static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, int count)
        return NULL;
 }
 
-int volume_id_probe_vfat(struct volume_id *id, uint64_t fat_partition_off)
+int volume_id_probe_vfat(struct volume_id *id /*,uint64_t fat_partition_off*/)
 {
+#define fat_partition_off ((uint64_t)0)
        struct vfat_super_block *vs;
        struct vfat_dir_entry *dir;
        uint16_t sector_size_bytes;
index d82808fa274c47aae071ff90f7cf7c9d7ca3f4f6..45a4aeea90981b6799ad168bcaa0e6f8c4181216 100644 (file)
@@ -37,7 +37,7 @@ get_label_uuid(int fd, char **label, char **uuid)
        if (ioctl(/*vid->*/fd, BLKGETSIZE64, &size) != 0)
                size = 0;
 
-       if (volume_id_probe_all(vid, 0, size) != 0)
+       if (volume_id_probe_all(vid, /*0,*/ size) != 0)
                goto ret;
 
        if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
index 79658e4fa1cc1ce2419fabb83b94f0468d3f490c..f99b895c48b8217fc7e5170d63fb58026e0b868f 100644 (file)
@@ -131,8 +131,9 @@ struct hfsplus_vol_header {
 #define HFS_NODE_LEAF                  0xff
 #define HFSPLUS_POR_CNID               1
 
-int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off)
+int volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/)
 {
+       uint64_t off = 0;
        unsigned blocksize;
        unsigned cat_block;
        unsigned ext_block_start;
index c15608ce04548438ababcffd2164519f45ecc970..82f5e4846070c266b37c47c9adc931386767a712 100644 (file)
@@ -47,8 +47,9 @@ struct high_sierra_volume_descriptor {
        uint8_t         version;
 } __attribute__((__packed__));
 
-int volume_id_probe_iso9660(struct volume_id *id, uint64_t off)
+int volume_id_probe_iso9660(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        uint8_t *buf;
        struct iso_volume_descriptor *is;
        struct high_sierra_volume_descriptor *hs;
index 63692f94658b6bc61323e28aa6dbd23de7c49243..4c39e537af0b679cbf7c1e3c51cef7a8dce08754 100644 (file)
@@ -35,8 +35,9 @@ struct jfs_super_block {
 
 #define JFS_SUPERBLOCK_OFFSET                  0x8000
 
-int volume_id_probe_jfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_jfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct jfs_super_block *js;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);
index 0877b8ad2dedd1a982a99666c473a4399ab80c15..cc024692cef7fcb987ae13d7782ef080f9c8e906 100644 (file)
@@ -42,8 +42,9 @@ struct mdp_super_block {
 #define MD_RESERVED_BYTES              0x10000
 #define MD_MAGIC                       0xa92b4efc
 
-int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size)
+int volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size)
 {
+#define off ((uint64_t)0)
        uint64_t sboff;
        uint8_t uuid[16];
        struct mdp_super_block *mdp;
index e6084542fbe5a0d106ff1775883eb65fd4c5df2a..c9b62e9bf6bdb3c5a075206e986d0daf41af99e9 100644 (file)
@@ -31,8 +31,9 @@ struct swap_header_v1_2 {
 
 #define LARGEST_PAGESIZE                       0x4000
 
-int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off)
+int volume_id_probe_linux_swap(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct swap_header_v1_2 *sw;
        const uint8_t *buf;
        unsigned page;
index b0f0f5b21a9956a8f5f119df335fdb6006805b17..ebc7d160d1c734339e459f3794905a0ffaca32ab 100644 (file)
@@ -80,8 +80,9 @@ struct BUG_bad_size_luks_phdr {
                1 : -1];
 };
 
-int volume_id_probe_luks(struct volume_id *id, uint64_t off)
+int volume_id_probe_luks(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct luks_phdr *header;
 
        header = volume_id_get_buffer(id, off, sizeof(*header));
index 7488a41a33d21a219532ecea7fc7ce108756df65..6e8f1dd3d9a6c2bf14299b8e11eec18c5f594036 100644 (file)
@@ -84,8 +84,9 @@ struct volume_info {
 #define MFT_RECORD_ATTR_OBJECT_ID              0x40
 #define MFT_RECORD_ATTR_END                    0xffffffffu
 
-int volume_id_probe_ntfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        unsigned sector_size;
        unsigned cluster_size;
        uint64_t mft_cluster;
index 8bcaac0b755efb8e30ea6acfc736e1142b9f864e..8417d91bb204506a6b7bdb02bcc788f30a15b088 100644 (file)
@@ -80,8 +80,9 @@ struct ocfs2_super_block {
        uint8_t         s_uuid[OCFS2_VOL_UUID_LEN];     /* 128-bit uuid */
 } __attribute__((__packed__));
 
-int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off)
+int volume_id_probe_ocfs2(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct ocfs2_super_block *os;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);
index d9a37457b40908654ff500da30b85e0eced239bd..b8cdc98096908a30f6fd6f4e918623317a989978 100644 (file)
@@ -48,8 +48,9 @@ struct reiser4_super_block {
 #define REISERFS1_SUPERBLOCK_OFFSET            0x2000
 #define REISERFS_SUPERBLOCK_OFFSET             0x10000
 
-int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct reiserfs_super_block *rs;
        struct reiser4_super_block *rs4;
 
index 400bdce2c5ffb096463ebd174e9b89956d41b875..2c061bdfc3d4ef4dbbf296220904c84413ed4628 100644 (file)
@@ -27,8 +27,9 @@ struct romfs_super {
        uint8_t name[0];
 } __attribute__((__packed__));
 
-int volume_id_probe_romfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct romfs_super *rfs;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);
index 76719623b61c28737f3a17e4ba849102d81b514f..16503325832f7e30c3186b95e2ca3fdf92971b4a 100644 (file)
@@ -83,8 +83,9 @@ struct xenix_super {
 #define XENIX_MAGIC                            0x2b5544
 #define SYSV_MAX_BLOCKSIZE                     0x800
 
-int volume_id_probe_sysv(struct volume_id *id, uint64_t off)
+int volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct sysv_super *vs;
        struct xenix_super *xs;
        unsigned boff;
index 55e97a7e5088603521b5b7d3148a7c93e0aa374a..e272e1923809b528dc3c9b928e2ef366dfec68da 100644 (file)
@@ -55,8 +55,9 @@ struct volume_structure_descriptor {
 
 #define UDF_VSD_OFFSET                 0x8000
 
-int volume_id_probe_udf(struct volume_id *id, uint64_t off)
+int volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct volume_descriptor *vd;
        struct volume_structure_descriptor *vsd;
        unsigned bs;
index 1a1b3f92e4210aef48d054faa17030e9d1019f48..dd75c7ba1517e88ecfe72e0d3b636a2698296a1d 100644 (file)
@@ -254,9 +254,15 @@ void *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len)
                dbg("requested 0x%x bytes, got 0x%x bytes",
                                (unsigned) len, (unsigned) read_len);
  err:
-               /* id->seekbuf_len or id->sbbuf_len is wrong now! Fixing.
-                * Most likely user will not do any additional
-                * calls anyway, it's a corrupted fs or something. */
+               /* No filesystem can be this tiny. It's most likely
+                * non-associated loop device, empty drive and so on.
+                * Flag it, making it possible to short circuit future
+                * accesses. Rationale:
+                * users complained of slow blkid due to empty floppy drives.
+                */
+               if (off < 64*1024)
+                       id->error = 1;
+               /* id->seekbuf_len or id->sbbuf_len is wrong now! Fixing. */
                volume_id_free_buffer(id);
                return NULL;
        }
index 6852a8203d9f2393ff8e698395b2e0959b0b0f1a..1acd90596aae87854a5d865cc84ae2d84a256876 100644 (file)
@@ -45,8 +45,8 @@
 #define ENABLE_FEATURE_VOLUMEID_UFS           0
 
 
-typedef int (*raid_probe_fptr)(struct volume_id *id, uint64_t off, uint64_t size);
-typedef int (*probe_fptr)(struct volume_id *id, uint64_t off);
+typedef int (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size);
+typedef int (*probe_fptr)(struct volume_id *id /*, uint64_t off*/);
 
 static const raid_probe_fptr raid1[] = {
 #if ENABLE_FEATURE_VOLUMEID_LINUXRAID
@@ -150,43 +150,49 @@ static const probe_fptr fs2[] = {
 #endif
 };
 
-int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
+int volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size)
 {
        unsigned i;
 
-       if (id == NULL)
-               return -EINVAL;
-
        /* probe for raid first, cause fs probes may be successful on raid members */
        if (size) {
-               for (i = 0; i < ARRAY_SIZE(raid1); i++)
-                       if (raid1[i](id, off, size) == 0)
+               for (i = 0; i < ARRAY_SIZE(raid1); i++) {
+                       if (raid1[i](id, /*off,*/ size) == 0)
+                               goto ret;
+                       if (id->error)
                                goto ret;
+               }
        }
 
-       for (i = 0; i < ARRAY_SIZE(raid2); i++)
-               if (raid2[i](id, off) == 0)
+       for (i = 0; i < ARRAY_SIZE(raid2); i++) {
+               if (raid2[i](id /*,off*/) == 0)
                        goto ret;
+               if (id->error)
+                       goto ret;
+       }
 
        /* signature in the first block, only small buffer needed */
-       for (i = 0; i < ARRAY_SIZE(fs1); i++)
-               if (fs1[i](id, off) == 0)
+       for (i = 0; i < ARRAY_SIZE(fs1); i++) {
+               if (fs1[i](id /*,off*/) == 0)
                        goto ret;
+               if (id->error)
+                       goto ret;
+       }
 
        /* fill buffer with maximum */
        volume_id_get_buffer(id, 0, SB_BUFFER_SIZE);
 
-       for (i = 0; i < ARRAY_SIZE(fs2); i++)
-               if (fs2[i](id, off) == 0)
+       for (i = 0; i < ARRAY_SIZE(fs2); i++) {
+               if (fs2[i](id /*,off*/) == 0)
                        goto ret;
-       return -1;
+               if (id->error)
+                       goto ret;
+       }
 
  ret:
-       /* If the filestystem in recognized, we free the allocated buffers,
-          otherwise they will stay in place for the possible next probe call */
        volume_id_free_buffer(id);
+       return (- id->error); /* 0 or -1 */
 
-       return 0;
 }
 
 /* open volume by device node */
index fe3547d13394a2bfc76dd6922c0a679bcf86e497..d5258c54f9499a5b77880852ed694b344ae9fe20 100644 (file)
@@ -63,6 +63,7 @@ struct volume_id_partition {
 struct volume_id {
        int             fd;
 //     int             fd_close:1;
+       int             error;
        size_t          sbbuf_len;
        size_t          seekbuf_len;
        uint8_t         *sbbuf;
@@ -86,7 +87,7 @@ struct volume_id {
 };
 
 struct volume_id *volume_id_open_node(int fd);
-int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size);
+int volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size);
 void free_volume_id(struct volume_id *id);
 
 /* util.h */
@@ -164,67 +165,67 @@ void volume_id_free_buffer(struct volume_id *id);
 
 /* RAID */
 
-//int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off);
-//int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_highpoint_37x_raid(struct volume_id *id /*,uint64_t off*/);
+//int volume_id_probe_highpoint_45x_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_intel_software_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size);
+int volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_lsi_mega_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_nvidia_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_promise_fasttrack_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_silicon_medley_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size);
+//int volume_id_probe_via_raid(struct volume_id *id /*,uint64_t off*/, uint64_t size);
 
-//int volume_id_probe_lvm1(struct volume_id *id, uint64_t off);
-//int volume_id_probe_lvm2(struct volume_id *id, uint64_t off);
+//int volume_id_probe_lvm1(struct volume_id *id /*,uint64_t off*/);
+//int volume_id_probe_lvm2(struct volume_id *id /*,uint64_t off*/);
 
 /* FS */
 
-int volume_id_probe_cramfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_cramfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_ext(struct volume_id *id, uint64_t off);
+int volume_id_probe_ext(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_vfat(struct volume_id *id, uint64_t off);
+int volume_id_probe_vfat(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off);
+int volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/);
 
-//int volume_id_probe_hpfs(struct volume_id *id, uint64_t off);
+//int volume_id_probe_hpfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_iso9660(struct volume_id *id, uint64_t off);
+int volume_id_probe_iso9660(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_jfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_jfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off);
+int volume_id_probe_linux_swap(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_luks(struct volume_id *id, uint64_t off);
+int volume_id_probe_luks(struct volume_id *id /*,uint64_t off*/);
 
-//int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off);
+//int volume_id_probe_mac_partition_map(struct volume_id *id /*,uint64_t off*/);
 
-//int volume_id_probe_minix(struct volume_id *id, uint64_t off);
+//int volume_id_probe_minix(struct volume_id *id /*,uint64_t off*/);
 
-//int volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off);
+//int volume_id_probe_msdos_part_table(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_ntfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off);
+int volume_id_probe_ocfs2(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_romfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_sysv(struct volume_id *id, uint64_t off);
+int volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_udf(struct volume_id *id, uint64_t off);
+int volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/);
 
-//int volume_id_probe_ufs(struct volume_id *id, uint64_t off);
+//int volume_id_probe_ufs(struct volume_id *id /*,uint64_t off*/);
 
-int volume_id_probe_xfs(struct volume_id *id, uint64_t off);
+int volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/);
 
 #if __GNUC_PREREQ(4,1)
 # pragma GCC visibility pop
index 0d904370d66cb2289f7f5ba93d7433897d4c4dec..646c81d3b6e5b87376bcb7250d3c4af0736dd64f 100644 (file)
@@ -35,8 +35,9 @@ struct xfs_super_block {
        uint64_t        fdblocks;
 } __attribute__((__packed__));
 
-int volume_id_probe_xfs(struct volume_id *id, uint64_t off)
+int volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/)
 {
+#define off ((uint64_t)0)
        struct xfs_super_block *xs;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);