summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdadm.h1
-rw-r--r--super-ddf.c4
-rw-r--r--super-intel.c4
-rw-r--r--util.c25
4 files changed, 34 insertions, 0 deletions
diff --git a/mdadm.h b/mdadm.h
index 1bf5ac0..d9d17b0 100644
--- 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);
diff --git a/super-ddf.c b/super-ddf.c
index 3feea57..0e6f1e5 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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)
diff --git a/super-intel.c b/super-intel.c
index 677396c..bdd7a96 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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 79d2b0f..25f1e56 100644
--- 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)
{