From: Mariusz Tkaczyk Date: Mon, 1 Apr 2019 14:53:41 +0000 (+0200) Subject: Create: Block rounding size to max X-Git-Tag: mdadm-4.2-rc1~110 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22dc741f63e6403d59c2c14f56fd4791265f9bbb;p=thirdparty%2Fmdadm.git Create: Block rounding size to max 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 --- diff --git a/Create.c b/Create.c index 6f1b2288..292f92a9 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 5a7c9f80..2ba045aa 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.