summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog1
-rw-r--r--debian/patches/0001-mdadm-fix-use-after-free-after-free_mdstat.patch37
-rw-r--r--debian/patches/0002-imsm-Allow-create-RAID-volume-with-link-to-container.patch35
-rw-r--r--debian/patches/0003-tests-func.sh-Fix-some-total-breakage-in-the-test-sc.patch80
-rw-r--r--debian/patches/0004-imsm-change-reserved-space-to-4MB.patch32
-rw-r--r--debian/patches/0005-imsm-add-functions-to-get-and-set-imsm-dev-size.patch136
-rw-r--r--debian/patches/0006-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch178
-rw-r--r--debian/patches/0007-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch266
-rw-r--r--debian/patches/0008-Prevent-create-IMSM-volume-with-size-smaller-than-1M.patch57
-rw-r--r--debian/patches/0009-mdadm-grow-correct-size-and-chunk_size-casting.patch32
-rw-r--r--debian/patches/series9
11 files changed, 863 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index bf6b2a69..20da21b0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
mdadm (4.1~rc1-1) unstable; urgency=medium
* New upstream release.
+ * Import patches since rc1.
-- Dimitri John Ledkov <xnox@ubuntu.com> Tue, 15 May 2018 12:10:33 +0100
diff --git a/debian/patches/0001-mdadm-fix-use-after-free-after-free_mdstat.patch b/debian/patches/0001-mdadm-fix-use-after-free-after-free_mdstat.patch
new file mode 100644
index 00000000..4d8ce04b
--- /dev/null
+++ b/debian/patches/0001-mdadm-fix-use-after-free-after-free_mdstat.patch
@@ -0,0 +1,37 @@
+From 1c7c65a3e5d3e5f6d32bfa4cf0d872f87c654eb2 Mon Sep 17 00:00:00 2001
+From: Zhipeng Xie <xiezhipeng1@huawei.com>
+Date: Tue, 10 Apr 2018 09:25:39 +0800
+Subject: [PATCH 1/9] mdadm: fix use-after-free after free_mdstat
+
+e->percent access the mdstat_ent which was already freed in free_mdstat
+
+Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Detail.c b/Detail.c
+index 4dcf81dd..860241ce 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -561,7 +561,6 @@ int Detail(char *dev, struct context *c)
+ printf(" %7s Status : %d%% complete\n",
+ sync_action[e->resync], e->percent);
+ }
+- free_mdstat(ms);
+
+ if ((st && st->sb) && (info && info->reshape_active)) {
+ #if 0
+@@ -609,6 +608,8 @@ This is pretty boring
+ printf("\n");
+ } else if (e && e->percent >= 0)
+ printf("\n");
++ free_mdstat(ms);
++
+ if (st && st->sb)
+ st->ss->detail_super(st, c->homehost);
+
+--
+2.17.0
+
diff --git a/debian/patches/0002-imsm-Allow-create-RAID-volume-with-link-to-container.patch b/debian/patches/0002-imsm-Allow-create-RAID-volume-with-link-to-container.patch
new file mode 100644
index 00000000..d23c534e
--- /dev/null
+++ b/debian/patches/0002-imsm-Allow-create-RAID-volume-with-link-to-container.patch
@@ -0,0 +1,35 @@
+From b91ad097d6eecb85cf28915836370288709fbda8 Mon Sep 17 00:00:00 2001
+From: Michal Zylowski <michal.zylowski@intel.com>
+Date: Wed, 4 Apr 2018 14:20:17 +0200
+Subject: [PATCH 2/9] imsm: Allow create RAID volume with link to container
+
+After 1db03765("Subdevs can't be all missing when create raid device")
+raid volume can't be created with link to container. This feature should
+not be blocked in Create function. IMSM code forbids creation of
+container with missing disk, so case like all dev's missing is already
+handled.
+
+Permit IMSM volume creation when devices are given as link to container.
+
+Signed-off-by: Michal Zylowski <michal.zylowski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Create.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Create.c b/Create.c
+index 50142d81..04b1dfc9 100644
+--- a/Create.c
++++ b/Create.c
+@@ -475,7 +475,7 @@ int Create(struct supertype *st, char *mddev,
+ close(fd);
+ }
+ }
+- if (missing_disks == dnum) {
++ if (missing_disks == dnum && !have_container) {
+ pr_err("Subdevs can't be all missing\n");
+ return 1;
+ }
+--
+2.17.0
+
diff --git a/debian/patches/0003-tests-func.sh-Fix-some-total-breakage-in-the-test-sc.patch b/debian/patches/0003-tests-func.sh-Fix-some-total-breakage-in-the-test-sc.patch
new file mode 100644
index 00000000..320d1f07
--- /dev/null
+++ b/debian/patches/0003-tests-func.sh-Fix-some-total-breakage-in-the-test-sc.patch
@@ -0,0 +1,80 @@
+From 59416da78fc66084f721163b914913dc1da37b44 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 11 Apr 2018 17:01:50 -0400
+Subject: [PATCH 3/9] tests/func.sh: Fix some total breakage in the test
+ scripts
+
+We will never mandate an obsolete file system such as ext[2-4] for
+running the test suite, nor should the test version of mdadm be
+installed on the system for the tests to be run.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+Fixes: 20d10b4be873ba ("mdadm/test: Refactor and revamp 'test' script")
+---
+ test | 2 +-
+ tests/func.sh | 22 +++-------------------
+ 2 files changed, 4 insertions(+), 20 deletions(-)
+
+diff --git a/test b/test
+index 111a2e74..711a3c7a 100755
+--- a/test
++++ b/test
+@@ -5,7 +5,7 @@ mdadm=$PWD/mdadm
+ targetdir="/var/tmp"
+ logdir="$targetdir"
+ config=/tmp/mdadm.conf
+-testdir=
++testdir=$PWD/tests
+ devlist=
+
+ savelogs=0
+diff --git a/tests/func.sh b/tests/func.sh
+index a6995f1b..9710a53b 100644
+--- a/tests/func.sh
++++ b/tests/func.sh
+@@ -101,8 +101,8 @@ check_env() {
+ echo "test: testing can only be done as 'root'."
+ exit 1
+ }
+- [ -x "raid6check" -a -x $mdadm ] || {
+- echo "test: please run 'make everything' before perform testing."
++ [ \! -x $mdadm ] && {
++ echo "test: please run make everything before perform testing."
+ exit 1
+ }
+ cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck seq)
+@@ -113,23 +113,6 @@ check_env() {
+ exit 1
+ }
+ done
+- mdadm_src_ver="$($mdadm -V 2>&1)"
+- mdadm_sbin_ver="$($(which mdadm) -V 2>&1)"
+- if [ "$mdadm_src_ver" != "$mdadm_sbin_ver" ]
+- then
+- # it's nessesary to 'make install' mdadm to /SBIN/DIR,
+- # such as systemd/mdadm-grow-continue@.service, would
+- # run as an instance by systemd when reshape happens,
+- # thus ensure that the correct mdadm is in testing.
+- echo "test: please run 'make install' before testing."
+- exit 1
+- fi
+- if ! $(df -T . | grep -iq ext)
+- then
+- # 'external file' bitmap only supports with ext[2-4] file system
+- echo "test: please run test suite with ext[2-4] file system."
+- exit 1
+- fi
+ if $(lsblk -a | grep -iq raid)
+ then
+ # donot run mdadm -Ss directly if there are RAIDs working.
+@@ -231,6 +214,7 @@ check() {
+ if [ $? -eq 0 ]; then
+ die "This command shouldn't run successfully"
+ fi
++ ;;
+ spares )
+ spares=$(tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0)
+ [ $spares -ne $2 ] &&
+--
+2.17.0
+
diff --git a/debian/patches/0004-imsm-change-reserved-space-to-4MB.patch b/debian/patches/0004-imsm-change-reserved-space-to-4MB.patch
new file mode 100644
index 00000000..fa5a593a
--- /dev/null
+++ b/debian/patches/0004-imsm-change-reserved-space-to-4MB.patch
@@ -0,0 +1,32 @@
+From 611d95290dd41d73bd8f9cc06f7ec293a40b819e Mon Sep 17 00:00:00 2001
+From: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Date: Thu, 5 Apr 2018 13:38:35 +0200
+Subject: [PATCH 4/9] imsm: change reserved space to 4MB
+
+Due to compatibility to the newest OROM, imsm reserved space has to be
+expanded to 4MB.
+
+Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index fb1b6936..52011e5b 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -88,8 +88,8 @@
+ #define MPB_ATTRIB_IGNORED (MPB_ATTRIB_NEVER_USE)
+
+ #define MPB_SECTOR_CNT 2210
+-#define IMSM_RESERVED_SECTORS 4096
+-#define NUM_BLOCKS_DIRTY_STRIPE_REGION 2056
++#define IMSM_RESERVED_SECTORS 8192
++#define NUM_BLOCKS_DIRTY_STRIPE_REGION 2048
+ #define SECT_PER_MB_SHIFT 11
+ #define MAX_SECTOR_SIZE 4096
+ #define MULTIPLE_PPL_AREA_SIZE_IMSM (1024 * 1024) /* Size of the whole
+--
+2.17.0
+
diff --git a/debian/patches/0005-imsm-add-functions-to-get-and-set-imsm-dev-size.patch b/debian/patches/0005-imsm-add-functions-to-get-and-set-imsm-dev-size.patch
new file mode 100644
index 00000000..dfdc7f3a
--- /dev/null
+++ b/debian/patches/0005-imsm-add-functions-to-get-and-set-imsm-dev-size.patch
@@ -0,0 +1,136 @@
+From fcc2c9daede11fcc67e4032fd6fa8da198aaa319 Mon Sep 17 00:00:00 2001
+From: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Date: Thu, 5 Apr 2018 13:38:36 +0200
+Subject: [PATCH 5/9] imsm: add functions to get and set imsm dev size
+
+Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 41 +++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 20 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 52011e5b..fe2a705b 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1201,6 +1201,13 @@ static unsigned long long num_data_stripes(struct imsm_map *map)
+ return join_u32(map->num_data_stripes_lo, map->num_data_stripes_hi);
+ }
+
++static unsigned long long imsm_dev_size(struct imsm_dev *dev)
++{
++ if (dev == NULL)
++ return 0;
++ return join_u32(dev->size_low, dev->size_high);
++}
++
+ static void set_total_blocks(struct imsm_disk *disk, unsigned long long n)
+ {
+ split_ull(n, &disk->total_blocks_lo, &disk->total_blocks_hi);
+@@ -1221,6 +1228,11 @@ static void set_num_data_stripes(struct imsm_map *map, unsigned long long n)
+ split_ull(n, &map->num_data_stripes_lo, &map->num_data_stripes_hi);
+ }
+
++static void set_imsm_dev_size(struct imsm_dev *dev, unsigned long long n)
++{
++ split_ull(n, &dev->size_low, &dev->size_high);
++}
++
+ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
+ {
+ /* find a list of used extents on the given physical device */
+@@ -1503,9 +1515,7 @@ static void print_imsm_dev(struct intel_super *super,
+ } else
+ printf(" This Slot : ?\n");
+ printf(" Sector Size : %u\n", super->sector_size);
+- sz = __le32_to_cpu(dev->size_high);
+- sz <<= 32;
+- sz += __le32_to_cpu(dev->size_low);
++ sz = imsm_dev_size(dev);
+ printf(" Array Size : %llu%s\n",
+ (unsigned long long)sz * 512 / super->sector_size,
+ human_size(sz * 512));
+@@ -1634,8 +1644,7 @@ void convert_to_4k(struct intel_super *super)
+ struct imsm_dev *dev = __get_imsm_dev(mpb, i);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+ /* dev */
+- split_ull((join_u32(dev->size_low, dev->size_high)/IMSM_4K_DIV),
+- &dev->size_low, &dev->size_high);
++ set_imsm_dev_size(dev, imsm_dev_size(dev)/IMSM_4K_DIV);
+ dev->vol.curr_migr_unit /= IMSM_4K_DIV;
+
+ /* map0 */
+@@ -1762,8 +1771,7 @@ void convert_from_4k(struct intel_super *super)
+ struct imsm_dev *dev = __get_imsm_dev(mpb, i);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+ /* dev */
+- split_ull((join_u32(dev->size_low, dev->size_high)*IMSM_4K_DIV),
+- &dev->size_low, &dev->size_high);
++ set_imsm_dev_size(dev, imsm_dev_size(dev)*IMSM_4K_DIV);
+ dev->vol.curr_migr_unit *= IMSM_4K_DIV;
+
+ /* map0 */
+@@ -3240,9 +3248,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ info->array.chunk_size =
+ __le16_to_cpu(map_to_analyse->blocks_per_strip) << 9;
+ info->array.state = !(dev->vol.dirty & RAIDVOL_DIRTY);
+- info->custom_array_size = __le32_to_cpu(dev->size_high);
+- info->custom_array_size <<= 32;
+- info->custom_array_size |= __le32_to_cpu(dev->size_low);
++ info->custom_array_size = imsm_dev_size(dev);
+ info->recovery_blocked = imsm_reshape_blocks_arrays_changes(st->sb);
+
+ if (is_gen_migration(dev)) {
+@@ -5370,8 +5376,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ array_blocks = round_size_to_mb(array_blocks, data_disks);
+ size_per_member = array_blocks / data_disks;
+
+- dev->size_low = __cpu_to_le32((__u32) array_blocks);
+- dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
++ set_imsm_dev_size(dev, array_blocks);
+ dev->status = (DEV_READ_COALESCING | DEV_WRITE_COALESCING);
+ vol = &dev->vol;
+ vol->migr_state = 0;
+@@ -7733,7 +7738,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ level, /* RAID level */
+ imsm_level_to_layout(level),
+ map->num_members, /* raid disks */
+- &chunk, join_u32(dev->size_low, dev->size_high),
++ &chunk, imsm_dev_size(dev),
+ 1 /* verbose */)) {
+ pr_err("IMSM RAID geometry validation failed. Array %s activation is blocked.\n",
+ dev->volume);
+@@ -8143,9 +8148,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
+ /* when problems occures
+ * return current array_blocks value
+ */
+- array_blocks = __le32_to_cpu(dev->size_high);
+- array_blocks = array_blocks << 32;
+- array_blocks += __le32_to_cpu(dev->size_low);
++ array_blocks = imsm_dev_size(dev);
+
+ return array_blocks;
+ }
+@@ -8165,8 +8168,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
+ }
+
+ array_blocks = round_size_to_mb(array_blocks, used_disks);
+- dev->size_low = __cpu_to_le32((__u32)array_blocks);
+- dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
++ set_imsm_dev_size(dev, array_blocks);
+
+ return array_blocks;
+ }
+@@ -9139,8 +9141,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
+ map->blocks_per_strip =
+ __cpu_to_le16(u->new_chunksize * 2);
+ num_data_stripes =
+- (join_u32(dev->size_low, dev->size_high)
+- / used_disks);
++ imsm_dev_size(dev) / used_disks;
+ num_data_stripes /= map->blocks_per_strip;
+ num_data_stripes /= map->num_domains;
+ set_num_data_stripes(map, num_data_stripes);
+--
+2.17.0
+
diff --git a/debian/patches/0006-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch b/debian/patches/0006-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch
new file mode 100644
index 00000000..0a406e80
--- /dev/null
+++ b/debian/patches/0006-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch
@@ -0,0 +1,178 @@
+From 9529d3436771d9f38884861683dee3b40ab9d180 Mon Sep 17 00:00:00 2001
+From: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Date: Thu, 5 Apr 2018 13:38:37 +0200
+Subject: [PATCH 6/9] imsm: pass already existing map to imsm_num_data_members
+
+In almost every place where imsm_num_data_members is called there is
+already existing map so it can be used it to avoid mistake when specifying
+map for imsm_num_data_members.
+
+Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 41 +++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 20 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index fe2a705b..3fc3cf4c 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -2767,13 +2767,11 @@ static __u32 num_stripes_per_unit_rebuild(struct imsm_dev *dev)
+ return num_stripes_per_unit_resync(dev);
+ }
+
+-static __u8 imsm_num_data_members(struct imsm_dev *dev, int second_map)
++static __u8 imsm_num_data_members(struct imsm_map *map)
+ {
+ /* named 'imsm_' because raid0, raid1 and raid10
+ * counter-intuitively have the same number of data disks
+ */
+- struct imsm_map *map = get_imsm_map(dev, second_map);
+-
+ switch (get_imsm_raid_level(map)) {
+ case 0:
+ return map->num_members;
+@@ -2862,7 +2860,7 @@ static __u64 blocks_per_migr_unit(struct intel_super *super,
+ */
+ stripes_per_unit = num_stripes_per_unit_resync(dev);
+ migr_chunk = migr_strip_blocks_resync(dev);
+- disks = imsm_num_data_members(dev, MAP_0);
++ disks = imsm_num_data_members(map);
+ blocks_per_unit = stripes_per_unit * migr_chunk * disks;
+ stripe = __le16_to_cpu(map->blocks_per_strip) * disks;
+ segment = blocks_per_unit / stripe;
+@@ -3381,7 +3379,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ (unsigned long long)blocks_per_unit,
+ info->reshape_progress);
+
+- used_disks = imsm_num_data_members(dev, MAP_1);
++ used_disks = imsm_num_data_members(prev_map);
+ if (used_disks > 0) {
+ array_blocks = blocks_per_member(map) *
+ used_disks;
+@@ -8140,9 +8138,9 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
+ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
+ long long new_size)
+ {
+- int used_disks = imsm_num_data_members(dev, MAP_0);
+ unsigned long long array_blocks;
+- struct imsm_map *map;
++ struct imsm_map *map = get_imsm_map(dev, MAP_0);
++ int used_disks = imsm_num_data_members(map);
+
+ if (used_disks == 0) {
+ /* when problems occures
+@@ -8155,17 +8153,15 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
+
+ /* set array size in metadata
+ */
+- if (new_size <= 0) {
++ if (new_size <= 0)
+ /* OLCE size change is caused by added disks
+ */
+- map = get_imsm_map(dev, MAP_0);
+ array_blocks = blocks_per_member(map) * used_disks;
+- } else {
++ else
+ /* Online Volume Size Change
+ * Using available free space
+ */
+ array_blocks = new_size;
+- }
+
+ array_blocks = round_size_to_mb(array_blocks, used_disks);
+ set_imsm_dev_size(dev, array_blocks);
+@@ -8274,7 +8270,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
+ int used_disks;
+ struct mdinfo *mdi;
+
+- used_disks = imsm_num_data_members(dev, MAP_0);
++ used_disks = imsm_num_data_members(map);
+ if (used_disks > 0) {
+ array_blocks =
+ blocks_per_member(map) *
+@@ -9132,8 +9128,10 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
+ */
+ if (u->new_chunksize > 0) {
+ unsigned long long num_data_stripes;
++ struct imsm_map *dest_map =
++ get_imsm_map(dev, MAP_0);
+ int used_disks =
+- imsm_num_data_members(dev, MAP_0);
++ imsm_num_data_members(dest_map);
+
+ if (used_disks == 0)
+ return ret_val;
+@@ -9210,7 +9208,7 @@ static int apply_size_change_update(struct imsm_update_size_change *u,
+ if (id->index == (unsigned)u->subdev) {
+ struct imsm_dev *dev = get_imsm_dev(super, u->subdev);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+- int used_disks = imsm_num_data_members(dev, MAP_0);
++ int used_disks = imsm_num_data_members(map);
+ unsigned long long blocks_per_member;
+ unsigned long long num_data_stripes;
+
+@@ -10589,7 +10587,7 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev,
+ max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
+ migr_rec->dest_depth_per_unit *=
+ max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
+- new_data_disks = imsm_num_data_members(dev, MAP_0);
++ new_data_disks = imsm_num_data_members(map_dest);
+ migr_rec->blocks_per_unit =
+ __cpu_to_le32(migr_rec->dest_depth_per_unit * new_data_disks);
+ migr_rec->dest_depth_per_unit =
+@@ -10657,7 +10655,7 @@ int save_backup_imsm(struct supertype *st,
+ int dest_layout = 0;
+ int dest_chunk;
+ unsigned long long start;
+- int data_disks = imsm_num_data_members(dev, MAP_0);
++ int data_disks = imsm_num_data_members(map_dest);
+
+ targets = xmalloc(new_disks * sizeof(int));
+
+@@ -11279,6 +11277,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
+ int imsm_layout = -1;
+ int data_disks;
+ struct imsm_dev *dev;
++ struct imsm_map *map;
+ struct intel_super *super;
+ unsigned long long current_size;
+ unsigned long long free_size;
+@@ -11369,7 +11368,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
+
+ super = st->sb;
+ dev = get_imsm_dev(super, super->current_vol);
+- data_disks = imsm_num_data_members(dev , MAP_0);
++ map = get_imsm_map(dev, MAP_0);
++ data_disks = imsm_num_data_members(map);
+ /* compute current size per disk member
+ */
+ current_size = info.custom_array_size / data_disks;
+@@ -11838,7 +11838,7 @@ static int imsm_manage_reshape(
+ struct intel_dev *dv;
+ unsigned int sector_size = super->sector_size;
+ struct imsm_dev *dev = NULL;
+- struct imsm_map *map_src;
++ struct imsm_map *map_src, *map_dest;
+ int migr_vol_qan = 0;
+ int ndata, odata; /* [bytes] */
+ int chunk; /* [bytes] */
+@@ -11876,12 +11876,13 @@ static int imsm_manage_reshape(
+ goto abort;
+ }
+
++ map_dest = get_imsm_map(dev, MAP_0);
+ map_src = get_imsm_map(dev, MAP_1);
+ if (map_src == NULL)
+ goto abort;
+
+- ndata = imsm_num_data_members(dev, MAP_0);
+- odata = imsm_num_data_members(dev, MAP_1);
++ ndata = imsm_num_data_members(map_dest);
++ odata = imsm_num_data_members(map_src);
+
+ chunk = __le16_to_cpu(map_src->blocks_per_strip) * 512;
+ old_data_stripe_length = odata * chunk;
+--
+2.17.0
+
diff --git a/debian/patches/0007-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch b/debian/patches/0007-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch
new file mode 100644
index 00000000..f0fc0c42
--- /dev/null
+++ b/debian/patches/0007-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch
@@ -0,0 +1,266 @@
+From 444909385fdaccf961308c4319d7029b82bf8bb1 Mon Sep 17 00:00:00 2001
+From: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Date: Thu, 5 Apr 2018 13:38:38 +0200
+Subject: [PATCH 7/9] imsm: do not use blocks_per_member in array size
+ calculations
+
+mdadm assumes that blocks_per_member value is equal to num_data_stripes *
+blocks_per_stripe but it is not true. For IMSM arrays created in OROM
+NUM_BLOCKS_DIRTY_STRIPE_REGION sectors are added up to this value. Because
+of this mdadm shows invalid size of arrays created in OROM and to fix this
+we need to use array size calculation based on num data stripes and blocks
+per stripe.
+
+Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 105 ++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 76 insertions(+), 29 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 3fc3cf4c..c55c85f1 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1233,6 +1233,20 @@ static void set_imsm_dev_size(struct imsm_dev *dev, unsigned long long n)
+ split_ull(n, &dev->size_low, &dev->size_high);
+ }
+
++static unsigned long long per_dev_array_size(struct imsm_map *map)
++{
++ unsigned long long array_size = 0;
++
++ if (map == NULL)
++ return array_size;
++
++ array_size = num_data_stripes(map) * map->blocks_per_strip;
++ if (get_imsm_raid_level(map) == 1 || get_imsm_raid_level(map) == 10)
++ array_size *= 2;
++
++ return array_size;
++}
++
+ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
+ {
+ /* find a list of used extents on the given physical device */
+@@ -1259,7 +1273,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
+
+ if (get_imsm_disk_slot(map, dl->index) >= 0) {
+ e->start = pba_of_lba0(map);
+- e->size = blocks_per_member(map);
++ e->size = per_dev_array_size(map);
+ e++;
+ }
+ }
+@@ -2787,6 +2801,36 @@ static __u8 imsm_num_data_members(struct imsm_map *map)
+ }
+ }
+
++static unsigned long long calc_component_size(struct imsm_map *map,
++ struct imsm_dev *dev)
++{
++ unsigned long long component_size;
++ unsigned long long dev_size = imsm_dev_size(dev);
++ unsigned long long calc_dev_size = 0;
++ unsigned int member_disks = imsm_num_data_members(map);
++
++ if (member_disks == 0)
++ return 0;
++
++ component_size = per_dev_array_size(map);
++ calc_dev_size = component_size * member_disks;
++
++ /* Component size is rounded to 1MB so difference between size from
++ * metadata and size calculated from num_data_stripes equals up to
++ * 2048 blocks per each device. If the difference is higher it means
++ * that array size was expanded and num_data_stripes was not updated.
++ */
++ if ((unsigned int)abs(calc_dev_size - dev_size) >
++ (1 << SECT_PER_MB_SHIFT) * member_disks) {
++ component_size = dev_size / member_disks;
++ dprintf("Invalid num_data_stripes in metadata; expected=%llu, found=%llu\n",
++ component_size / map->blocks_per_strip,
++ num_data_stripes(map));
++ }
++
++ return component_size;
++}
++
+ static __u32 parity_segment_depth(struct imsm_dev *dev)
+ {
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+@@ -3306,14 +3350,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ }
+
+ info->data_offset = pba_of_lba0(map_to_analyse);
+-
+- if (info->array.level == 5) {
+- info->component_size = num_data_stripes(map_to_analyse) *
+- map_to_analyse->blocks_per_strip;
+- } else {
+- info->component_size = blocks_per_member(map_to_analyse);
+- }
+-
++ info->component_size = calc_component_size(map, dev);
+ info->component_size = imsm_component_size_aligment_check(
+ info->array.level,
+ info->array.chunk_size,
+@@ -3381,7 +3418,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+
+ used_disks = imsm_num_data_members(prev_map);
+ if (used_disks > 0) {
+- array_blocks = blocks_per_member(map) *
++ array_blocks = per_dev_array_size(map) *
+ used_disks;
+ info->custom_array_size =
+ round_size_to_mb(array_blocks,
+@@ -5383,9 +5420,6 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ vol->curr_migr_unit = 0;
+ map = get_imsm_map(dev, MAP_0);
+ set_pba_of_lba0(map, super->create_offset);
+- set_blocks_per_member(map, info_to_blocks_per_member(info,
+- size_per_member /
+- BLOCKS_PER_KB));
+ map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
+ map->failed_disk_num = ~0;
+ if (info->level > 0)
+@@ -5417,6 +5451,11 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ num_data_stripes /= map->num_domains;
+ set_num_data_stripes(map, num_data_stripes);
+
++ size_per_member += NUM_BLOCKS_DIRTY_STRIPE_REGION;
++ set_blocks_per_member(map, info_to_blocks_per_member(info,
++ size_per_member /
++ BLOCKS_PER_KB));
++
+ map->num_members = info->raid_disks;
+ for (i = 0; i < map->num_members; i++) {
+ /* initialized in add_to_super */
+@@ -7821,18 +7860,14 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+
+ info_d->events = __le32_to_cpu(mpb->generation_num);
+ info_d->data_offset = pba_of_lba0(map);
++ info_d->component_size = calc_component_size(map, dev);
+
+ if (map->raid_level == 5) {
+- info_d->component_size =
+- num_data_stripes(map) *
+- map->blocks_per_strip;
+ info_d->ppl_sector = this->ppl_sector;
+ info_d->ppl_size = this->ppl_size;
+ if (this->consistency_policy == CONSISTENCY_POLICY_PPL &&
+ recovery_start == 0)
+ this->resync_start = 0;
+- } else {
+- info_d->component_size = blocks_per_member(map);
+ }
+
+ info_d->bb.supported = 1;
+@@ -8156,7 +8191,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
+ if (new_size <= 0)
+ /* OLCE size change is caused by added disks
+ */
+- array_blocks = blocks_per_member(map) * used_disks;
++ array_blocks = per_dev_array_size(map) * used_disks;
+ else
+ /* Online Volume Size Change
+ * Using available free space
+@@ -8273,7 +8308,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
+ used_disks = imsm_num_data_members(map);
+ if (used_disks > 0) {
+ array_blocks =
+- blocks_per_member(map) *
++ per_dev_array_size(map) *
+ used_disks;
+ array_blocks =
+ round_size_to_mb(array_blocks,
+@@ -8715,11 +8750,11 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
+ pos = 0;
+ array_start = pba_of_lba0(map);
+ array_end = array_start +
+- blocks_per_member(map) - 1;
++ per_dev_array_size(map) - 1;
+
+ do {
+ /* check that we can start at pba_of_lba0 with
+- * blocks_per_member of space
++ * num_data_stripes*blocks_per_stripe of space
+ */
+ if (array_start >= pos && array_end < ex[j].start) {
+ found = 1;
+@@ -9145,6 +9180,12 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
+ set_num_data_stripes(map, num_data_stripes);
+ }
+
++ /* ensure blocks_per_member has valid value
++ */
++ set_blocks_per_member(map,
++ per_dev_array_size(map) +
++ NUM_BLOCKS_DIRTY_STRIPE_REGION);
++
+ /* add disk
+ */
+ if (u->new_level != 5 || migr_map->raid_level != 0 ||
+@@ -9211,15 +9252,21 @@ static int apply_size_change_update(struct imsm_update_size_change *u,
+ int used_disks = imsm_num_data_members(map);
+ unsigned long long blocks_per_member;
+ unsigned long long num_data_stripes;
++ unsigned long long new_size_per_disk;
++
++ if (used_disks == 0)
++ return 0;
+
+ /* calculate new size
+ */
+- blocks_per_member = u->new_size / used_disks;
+- num_data_stripes = blocks_per_member /
++ new_size_per_disk = u->new_size / used_disks;
++ blocks_per_member = new_size_per_disk +
++ NUM_BLOCKS_DIRTY_STRIPE_REGION;
++ num_data_stripes = new_size_per_disk /
+ map->blocks_per_strip;
+ num_data_stripes /= map->num_domains;
+ dprintf("(size: %llu, blocks per member: %llu, num_data_stipes: %llu)\n",
+- u->new_size, blocks_per_member,
++ u->new_size, new_size_per_disk,
+ num_data_stripes);
+ set_blocks_per_member(map, blocks_per_member);
+ set_num_data_stripes(map, num_data_stripes);
+@@ -9476,7 +9523,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
+ unsigned long long num_data_stripes;
+
+ map->num_domains = 1;
+- num_data_stripes = blocks_per_member(map);
++ num_data_stripes = imsm_dev_size(dev) / 2;
+ num_data_stripes /= map->blocks_per_strip;
+ num_data_stripes /= map->num_domains;
+ set_num_data_stripes(map, num_data_stripes);
+@@ -9692,7 +9739,7 @@ static void imsm_process_update(struct supertype *st,
+
+ new_map = get_imsm_map(&u->dev, MAP_0);
+ new_start = pba_of_lba0(new_map);
+- new_end = new_start + blocks_per_member(new_map);
++ new_end = new_start + per_dev_array_size(new_map);
+ inf = get_disk_info(u);
+
+ /* handle activate_spare versus create race:
+@@ -9703,7 +9750,7 @@ static void imsm_process_update(struct supertype *st,
+ dev = get_imsm_dev(super, i);
+ map = get_imsm_map(dev, MAP_0);
+ start = pba_of_lba0(map);
+- end = start + blocks_per_member(map);
++ end = start + per_dev_array_size(map);
+ if ((new_start >= start && new_start <= end) ||
+ (start >= new_start && start <= new_end))
+ /* overlap */;
+@@ -10492,7 +10539,7 @@ static struct md_bb *imsm_get_badblocks(struct active_array *a, int slot)
+ return NULL;
+
+ get_volume_badblocks(super->bbm_log, ord_to_idx(ord), pba_of_lba0(map),
+- blocks_per_member(map), &super->bb);
++ per_dev_array_size(map), &super->bb);
+
+ return &super->bb;
+ }
+--
+2.17.0
+
diff --git a/debian/patches/0008-Prevent-create-IMSM-volume-with-size-smaller-than-1M.patch b/debian/patches/0008-Prevent-create-IMSM-volume-with-size-smaller-than-1M.patch
new file mode 100644
index 00000000..ab361401
--- /dev/null
+++ b/debian/patches/0008-Prevent-create-IMSM-volume-with-size-smaller-than-1M.patch
@@ -0,0 +1,57 @@
+From 54865c30d5b94920318950e29a4f6c1ce075cae8 Mon Sep 17 00:00:00 2001
+From: Roman Sobanski <roman.sobanski@intel.com>
+Date: Wed, 25 Apr 2018 11:25:06 +0200
+Subject: [PATCH 8/9] Prevent create IMSM volume with size smaller than 1M or
+ chunk
+
+Block creation of the imsm volume when given size is smaller than 1M and
+print appropriate message.
+
+Commit b53bfba6119d3f6f56eb9e10e5a59da6901af159
+(imsm: use rounded size for metadata initialization) introduces issue with
+rounding volume sizes smaller than 1M to 0. There is an inconsistency when
+size smaller than 1M was given depends of what we give as target device:
+1) When block devices was given created volume has maximum available size.
+2) When container symlink was given created volume has size 0. Additionally
+it causes below call trace:
+
+[69587.891556] WARNING: CPU: 28 PID: 22485 at ../drivers/md/md.c:7582 md_seq_show+0x764/0x770 [md_mod]
+[69588.066405] Call Trace:
+[69588.066409] seq_read+0x336/0x430
+[69588.066411] proc_reg_read+0x40/0x70
+[69588.066412] __vfs_read+0x26/0x140
+[69588.066414] vfs_read+0x89/0x130
+[69588.066415] SyS_read+0x42/0x90
+[69588.066417] do_syscall_64+0x74/0x140
+[69588.066419] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+
+Signed-off-by: Roman Sobanski <roman.sobanski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/super-intel.c b/super-intel.c
+index c55c85f1..520abf5d 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7358,6 +7358,16 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
+ verbose);
+ }
+
++ if (size && ((size < 1024) || (*chunk != UnSet &&
++ size < (unsigned long long) *chunk))) {
++ pr_err("Given size must be greater than 1M and chunk size.\n");
++ /* Depends on algorithm in Create.c :
++ * if container was given (dev == NULL) return -1,
++ * if block device was given ( dev != NULL) return 0.
++ */
++ return dev ? -1 : 0;
++ }
++
+ if (!dev) {
+ if (st->sb) {
+ struct intel_super *super = st->sb;
+--
+2.17.0
+
diff --git a/debian/patches/0009-mdadm-grow-correct-size-and-chunk_size-casting.patch b/debian/patches/0009-mdadm-grow-correct-size-and-chunk_size-casting.patch
new file mode 100644
index 00000000..34ef5c8a
--- /dev/null
+++ b/debian/patches/0009-mdadm-grow-correct-size-and-chunk_size-casting.patch
@@ -0,0 +1,32 @@
+From 5d518de84e7cd3382b4984cc1243ddb4102aa4f4 Mon Sep 17 00:00:00 2001
+From: Roman Sobanski <roman.sobanski@intel.com>
+Date: Fri, 27 Apr 2018 12:12:21 +0200
+Subject: [PATCH 9/9] mdadm/grow: correct size and chunk_size casting
+
+With commit 4b74a905a67e
+("mdadm/grow: Component size must be larger than chunk size") mdadm returns
+incorrect message if size given to grow was greater than 2 147 483 647 K.
+Cast chunk_size to "unsigned long long" instead of casting size to "int".
+
+Signed-off-by: Roman Sobanski <roman.sobanski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Grow.c b/Grow.c
+index 87229692..a4be7e7b 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -1821,7 +1821,7 @@ int Grow_reshape(char *devname, int fd,
+ }
+
+ if (array.level > 1 && s->size > 1 &&
+- (array.chunk_size / 1024) > (int)s->size) {
++ (unsigned long long) (array.chunk_size / 1024) > s->size) {
+ pr_err("component size must be larger than chunk size.\n");
+ return 1;
+ }
+--
+2.17.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 728fabf4..5cf73e5f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,12 @@
+0001-mdadm-fix-use-after-free-after-free_mdstat.patch
+0002-imsm-Allow-create-RAID-volume-with-link-to-container.patch
+0003-tests-func.sh-Fix-some-total-breakage-in-the-test-sc.patch
+0004-imsm-change-reserved-space-to-4MB.patch
+0005-imsm-add-functions-to-get-and-set-imsm-dev-size.patch
+0006-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch
+0007-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch
+0008-Prevent-create-IMSM-volume-with-size-smaller-than-1M.patch
+0009-mdadm-grow-correct-size-and-chunk_size-casting.patch
debian-conffile-location.diff
debian-no-Werror.diff
sha1-includes.diff