From 66d8e050ca3c243094545ce8b0e4c53d54a11715 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 18 May 2010 12:13:48 +0200 Subject: [PATCH] libblkid: improve MD 0.90 detection We don't have to check for collision between partition table and RAID on all RAIDs. This problem is specific to MD, where underlying device could be a partition. The RAIDs like via, intel, ... always use whole-disks only. Signed-off-by: Karel Zak --- shlibs/blkid/src/partitions/partitions.c | 13 +++++++++ shlibs/blkid/src/superblocks/linux_raid.c | 31 ++++++++++++++-------- shlibs/blkid/src/superblocks/superblocks.c | 16 ----------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c index c670cc18..5597181a 100644 --- a/shlibs/blkid/src/partitions/partitions.c +++ b/shlibs/blkid/src/partitions/partitions.c @@ -829,6 +829,19 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr, end = (offset + size) >> 9; start = offset >> 9; + /* check if the partition table fits into the device */ + for (i = 0; i < nparts; i++) { + blkid_partition par = &ls->parts[i]; + + if (par->start + par->size > pr->size) { + DBG(DEBUG_LOWPROBE, printf("partition #%d overflows " + "device (off=%lu size=%lu)\n", + par->partno, par->start, par->size)); + goto done; + } + } + + /* check if the requested area is covered by PT */ for (i = 0; i < nparts; i++) { blkid_partition par = &ls->parts[i]; diff --git a/shlibs/blkid/src/superblocks/linux_raid.c b/shlibs/blkid/src/superblocks/linux_raid.c index d25b3959..41ef261a 100644 --- a/shlibs/blkid/src/superblocks/linux_raid.c +++ b/shlibs/blkid/src/superblocks/linux_raid.c @@ -106,6 +106,7 @@ static int probe_raid0(blkid_probe pr, off_t off) uint32_t ints[4]; uint8_t bytes[16]; } uuid; + uint32_t ma, mi, pa; if (pr->size < 0x10000) return -1; @@ -125,11 +126,9 @@ static int probe_raid0(blkid_probe pr, off_t off) uuid.ints[2] = swab32(mdp0->set_uuid2); uuid.ints[3] = swab32(mdp0->set_uuid3); } - if (blkid_probe_sprintf_version(pr, "%u.%u.%u", - le32_to_cpu(mdp0->major_version), - le32_to_cpu(mdp0->minor_version), - le32_to_cpu(mdp0->patch_version)) != 0) - return -1; + ma = le32_to_cpu(mdp0->major_version); + mi = le32_to_cpu(mdp0->minor_version); + pa = le32_to_cpu(mdp0->patch_version); } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { uuid.ints[0] = mdp0->set_uuid0; @@ -138,14 +137,24 @@ static int probe_raid0(blkid_probe pr, off_t off) uuid.ints[2] = mdp0->set_uuid2; uuid.ints[3] = mdp0->set_uuid3; } - if (blkid_probe_sprintf_version(pr, "%u.%u.%u", - be32_to_cpu(mdp0->major_version), - be32_to_cpu(mdp0->minor_version), - be32_to_cpu(mdp0->patch_version)) != 0) - return -1; + ma = be32_to_cpu(mdp0->major_version); + mi = be32_to_cpu(mdp0->minor_version); + pa = be32_to_cpu(mdp0->patch_version); } else - return -1; + return 1; + /* + * Check for collisions between RAID and partition table + */ + if ((S_ISREG(pr->mode) || blkid_probe_is_wholedisk(pr)) && + blkid_probe_is_covered_by_pt(pr, off, 0x200)) { + /* ignore this superblock, it's within any partition and + * we are working with whole-disk now */ + return 1; + } + + if (blkid_probe_sprintf_version(pr, "%u.%u.%u", ma, mi, pa) != 0) + return -1; if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0) return -1; if (blkid_probe_set_magic(pr, off, sizeof(mdp0->md_magic), diff --git a/shlibs/blkid/src/superblocks/superblocks.c b/shlibs/blkid/src/superblocks/superblocks.c index 1d952737..2a463c85 100644 --- a/shlibs/blkid/src/superblocks/superblocks.c +++ b/shlibs/blkid/src/superblocks/superblocks.c @@ -527,22 +527,6 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) superblocks_copy_data(chn->data, sb); chn->idx = idx; - /* - * Check for collisions between RAID and partition table - */ - if (sb && sb->usage == BLKID_USAGE_RAID && - sb->magic_off > pr->size / 2 && - (S_ISREG(pr->mode) || blkid_probe_is_wholedisk(pr)) && - blkid_probe_is_covered_by_pt(pr, sb->magic_off, 0x200)) { - /* - * Ignore the result if the detected RAID superblock is - * within some existing partition (for example RAID on - * the last partition). - */ - blkid_probe_chain_reset_vals(pr, chn); - return 1; - } - /* * The RAID device could be partitioned. The problem are RAID1 devices * where the partition table is visible from underlaying devices. We -- 2.39.5