From 22dc741f63e6403d59c2c14f56fd4791265f9bbb Mon Sep 17 00:00:00 2001 From: Mariusz Tkaczyk Date: Mon, 1 Apr 2019 16:53:41 +0200 Subject: [PATCH] Create: Block rounding size to max Git-commit: 22dc741f63e6403d59c2c14f56fd4791265f9bbb Patch-mainline: mdadm-4.1+ References: jsc#SLE-10078, jsc#SLE-9348 When passed size is smaller than chunk, mdadm rounds it to 0 but 0 there means max available space. Block it for every metadata. Remove the same check from imsm routine. Signed-off-by: Mariusz Tkaczyk Signed-off-by: Jes Sorensen Signed-off-by: Coly Li --- Create.c | 23 ++++++++++++++++++++--- super-intel.c | 5 ++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Create.c b/Create.c index 6f1b228..292f92a 100644 --- a/Create.c +++ b/Create.c @@ -27,6 +27,18 @@ #include "md_p.h" #include +static int round_size_and_verify(unsigned long long *size, int chunk) +{ + if (*size == 0) + return 0; + *size &= ~(unsigned long long)(chunk - 1); + if (*size == 0) { + pr_err("Size cannot be smaller than chunk.\n"); + return 1; + } + return 0; +} + static int default_layout(struct supertype *st, int level, int verbose) { int layout = UnSet; @@ -248,11 +260,14 @@ int Create(struct supertype *st, char *mddev, pr_err("unknown level %d\n", s->level); return 1; } + if (s->size == MAX_SIZE) /* use '0' to mean 'max' now... */ s->size = 0; if (s->size && s->chunk && s->chunk != UnSet) - s->size &= ~(unsigned long long)(s->chunk - 1); + if (round_size_and_verify(&s->size, s->chunk)) + return 1; + newsize = s->size * 2; if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, &s->chunk, s->size*2, @@ -267,7 +282,8 @@ int Create(struct supertype *st, char *mddev, /* default chunk was just set */ if (c->verbose > 0) pr_err("chunk size defaults to %dK\n", s->chunk); - s->size &= ~(unsigned long long)(s->chunk - 1); + if (round_size_and_verify(&s->size, s->chunk)) + return 1; do_default_chunk = 0; } } @@ -413,7 +429,8 @@ int Create(struct supertype *st, char *mddev, /* default chunk was just set */ if (c->verbose > 0) pr_err("chunk size defaults to %dK\n", s->chunk); - s->size &= ~(unsigned long long)(s->chunk - 1); + if (round_size_and_verify(&s->size, s->chunk)) + return 1; do_default_chunk = 0; } } diff --git a/super-intel.c b/super-intel.c index 5a7c9f8..2ba045a 100644 --- a/super-intel.c +++ b/super-intel.c @@ -7455,9 +7455,8 @@ 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"); + if (size && (size < 1024)) { + pr_err("Given size must be greater than 1M.\n"); /* Depends on algorithm in Create.c : * if container was given (dev == NULL) return -1, * if block device was given ( dev != NULL) return 0. -- 2.25.0