From 28ea4298e380d73203890c0f42de68e9798396d8 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 15 Feb 2009 05:51:19 +0000 Subject: [PATCH] volume_id: abort early on read failures. should help with probing missing fdd's --- util-linux/volume_id/cramfs.c | 3 +- util-linux/volume_id/ext.c | 3 +- util-linux/volume_id/fat.c | 3 +- util-linux/volume_id/get_devname.c | 2 +- util-linux/volume_id/hfs.c | 3 +- util-linux/volume_id/iso9660.c | 3 +- util-linux/volume_id/jfs.c | 3 +- util-linux/volume_id/linux_raid.c | 3 +- util-linux/volume_id/linux_swap.c | 3 +- util-linux/volume_id/luks.c | 3 +- util-linux/volume_id/ntfs.c | 3 +- util-linux/volume_id/ocfs2.c | 3 +- util-linux/volume_id/reiserfs.c | 3 +- util-linux/volume_id/romfs.c | 3 +- util-linux/volume_id/sysv.c | 3 +- util-linux/volume_id/udf.c | 3 +- util-linux/volume_id/util.c | 12 +++-- util-linux/volume_id/volume_id.c | 42 ++++++++------- util-linux/volume_id/volume_id_internal.h | 65 ++++++++++++----------- util-linux/volume_id/xfs.c | 3 +- 20 files changed, 99 insertions(+), 70 deletions(-) diff --git a/util-linux/volume_id/cramfs.c b/util-linux/volume_id/cramfs.c index 63b0c7cad..dd939e494 100644 --- a/util-linux/volume_id/cramfs.c +++ b/util-linux/volume_id/cramfs.c @@ -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); diff --git a/util-linux/volume_id/ext.c b/util-linux/volume_id/ext.c index db29dae70..b052e04ce 100644 --- a/util-linux/volume_id/ext.c +++ b/util-linux/volume_id/ext.c @@ -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); diff --git a/util-linux/volume_id/fat.c b/util-linux/volume_id/fat.c index 0e0a57d62..352040f57 100644 --- a/util-linux/volume_id/fat.c +++ b/util-linux/volume_id/fat.c @@ -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; diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c index d82808fa2..45a4aeea9 100644 --- a/util-linux/volume_id/get_devname.c +++ b/util-linux/volume_id/get_devname.c @@ -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') { diff --git a/util-linux/volume_id/hfs.c b/util-linux/volume_id/hfs.c index 79658e4fa..f99b895c4 100644 --- a/util-linux/volume_id/hfs.c +++ b/util-linux/volume_id/hfs.c @@ -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; diff --git a/util-linux/volume_id/iso9660.c b/util-linux/volume_id/iso9660.c index c15608ce0..82f5e4846 100644 --- a/util-linux/volume_id/iso9660.c +++ b/util-linux/volume_id/iso9660.c @@ -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; diff --git a/util-linux/volume_id/jfs.c b/util-linux/volume_id/jfs.c index 63692f946..4c39e537a 100644 --- a/util-linux/volume_id/jfs.c +++ b/util-linux/volume_id/jfs.c @@ -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); diff --git a/util-linux/volume_id/linux_raid.c b/util-linux/volume_id/linux_raid.c index 0877b8ad2..cc024692c 100644 --- a/util-linux/volume_id/linux_raid.c +++ b/util-linux/volume_id/linux_raid.c @@ -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; diff --git a/util-linux/volume_id/linux_swap.c b/util-linux/volume_id/linux_swap.c index e6084542f..c9b62e9bf 100644 --- a/util-linux/volume_id/linux_swap.c +++ b/util-linux/volume_id/linux_swap.c @@ -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; diff --git a/util-linux/volume_id/luks.c b/util-linux/volume_id/luks.c index b0f0f5b21..ebc7d160d 100644 --- a/util-linux/volume_id/luks.c +++ b/util-linux/volume_id/luks.c @@ -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)); diff --git a/util-linux/volume_id/ntfs.c b/util-linux/volume_id/ntfs.c index 7488a41a3..6e8f1dd3d 100644 --- a/util-linux/volume_id/ntfs.c +++ b/util-linux/volume_id/ntfs.c @@ -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; diff --git a/util-linux/volume_id/ocfs2.c b/util-linux/volume_id/ocfs2.c index 8bcaac0b7..8417d91bb 100644 --- a/util-linux/volume_id/ocfs2.c +++ b/util-linux/volume_id/ocfs2.c @@ -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); diff --git a/util-linux/volume_id/reiserfs.c b/util-linux/volume_id/reiserfs.c index d9a37457b..b8cdc9809 100644 --- a/util-linux/volume_id/reiserfs.c +++ b/util-linux/volume_id/reiserfs.c @@ -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; diff --git a/util-linux/volume_id/romfs.c b/util-linux/volume_id/romfs.c index 400bdce2c..2c061bdfc 100644 --- a/util-linux/volume_id/romfs.c +++ b/util-linux/volume_id/romfs.c @@ -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); diff --git a/util-linux/volume_id/sysv.c b/util-linux/volume_id/sysv.c index 76719623b..165033258 100644 --- a/util-linux/volume_id/sysv.c +++ b/util-linux/volume_id/sysv.c @@ -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; diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c index 55e97a7e5..e272e1923 100644 --- a/util-linux/volume_id/udf.c +++ b/util-linux/volume_id/udf.c @@ -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; diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c index 1a1b3f92e..dd75c7ba1 100644 --- a/util-linux/volume_id/util.c +++ b/util-linux/volume_id/util.c @@ -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; } diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c index 6852a8203..1acd90596 100644 --- a/util-linux/volume_id/volume_id.c +++ b/util-linux/volume_id/volume_id.c @@ -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 */ diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h index fe3547d13..d5258c54f 100644 --- a/util-linux/volume_id/volume_id_internal.h +++ b/util-linux/volume_id/volume_id_internal.h @@ -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 diff --git a/util-linux/volume_id/xfs.c b/util-linux/volume_id/xfs.c index 0d904370d..646c81d3b 100644 --- a/util-linux/volume_id/xfs.c +++ b/util-linux/volume_id/xfs.c @@ -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); -- 2.25.1