]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
IMSM/DDF: don't recognised these metadata on partitions.
authorNeilBrown <neilb@suse.de>
Thu, 29 Apr 2010 06:09:59 +0000 (16:09 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 29 Apr 2010 06:09:59 +0000 (16:09 +1000)
These metadata are not expected on partitions, and they have
no way of differentiation whether which is correct if they
are found both on the device and on the last partition.

So if the device is a partition, refuse to read the metadata.

Signed-off-by: NeilBrown <neilb@suse.de>
mdadm.h
super-ddf.c
super-intel.c
util.c

diff --git a/mdadm.h b/mdadm.h
index 1bf5ac0a44de67ad51088d339a1365f5e807450b..d9d17b09d2834eb9781e29d1ccc8b94ee5803b9b 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -876,6 +876,7 @@ extern int enough(int level, int raid_disks, int layout, int clean,
 extern int ask(char *mesg);
 extern unsigned long long get_component_size(int fd);
 extern void remove_partitions(int fd);
+extern int test_partition(int fd);
 extern unsigned long long calc_array_size(int level, int raid_disks, int layout,
                                   int chunksize, unsigned long long devsize);
 extern int flush_metadata_updates(struct supertype *st);
index 3feea57796e1242201095ca85659b9279902a1ff..0e6f1e53394de81a9aace6a3a5c8999ed00cb2a0 100644 (file)
@@ -783,6 +783,10 @@ static int load_super_ddf(struct supertype *st, int fd,
        if (get_dev_size(fd, devname, &dsize) == 0)
                return 1;
 
+       if (test_partition(fd))
+               /* DDF is not allowed on partitions */
+               return 1;
+
        /* 32M is a lower bound */
        if (dsize <= 32*1024*1024) {
                if (devname)
index 677396c64a9ab2eb953e915a0230299c81941f7e..bdd7a968abbcd3ed95e082a54220317935791c44 100644 (file)
@@ -2798,6 +2798,10 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
                return 0;
 #endif
 
+       if (test_partition(fd))
+               /* IMSM not allowed on partitions */
+               return 1;
+
        free_super_imsm(st);
 
        super = alloc_super();
diff --git a/util.c b/util.c
index 79d2b0fecdb58077143bca5f8d2f6b2604110b7d..25f1e56ae01d05277765ef6c4779ac08d6a11f75 100644 (file)
--- a/util.c
+++ b/util.c
@@ -302,6 +302,31 @@ void remove_partitions(int fd)
 #endif
 }
 
+int test_partition(int fd)
+{
+       /* Check if fd is a whole-disk or a partition.
+        * BLKPG will return EINVAL on a partition, and BLKPG_DEL_PARTITION
+        * will return ENXIO on an invalid partition number.
+        */
+       struct blkpg_ioctl_arg a;
+       struct blkpg_partition p;
+       a.op = BLKPG_DEL_PARTITION;
+       a.data = (void*)&p;
+       a.datalen = sizeof(p);
+       a.flags = 0;
+       memset(a.data, 0, a.datalen);
+       p.pno = 1<<30;
+       if (ioctl(fd, BLKPG, &a) == 0)
+               /* Very unlikely, but not a partition */
+               return 0;
+       if (errno == ENXIO)
+               /* not a partition */
+               return 0;
+
+       return 1;
+}
+
+
 int enough(int level, int raid_disks, int layout, int clean,
           char *avail, int avail_disks)
 {