Remove hard-coded limit of 32 arguments per target. --- linux-2.4.21/drivers/md/dm-table.c Tue Jul 1 20:17:31 2003 +++ linux/drivers/md/dm-table.c Tue Aug 19 15:43:50 2003 @@ -17,6 +17,7 @@ #define NODE_SIZE L1_CACHE_BYTES #define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) #define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) +#define MAX_TARGET_ARGS 64 struct dm_table { atomic_t holders; @@ -443,10 +444,16 @@ /* * Destructively splits up the argument list to pass to ctr. */ -static int split_args(int max, int *argc, char **argv, char *input) +static int split_args(int *argc, char ***argvp, char *input) { char *start, *end = input, *out; + char **argv; + int max_args = MAX_TARGET_ARGS; + *argc = 0; + argv = kmalloc(sizeof(*argv) * max_args, GFP_NOIO); + if (!argv) + return -ENOMEM; while (1) { start = end; @@ -475,8 +482,20 @@ } /* have we already filled the array ? */ - if ((*argc + 1) > max) - return -EINVAL; + if ((*argc + 1) > max_args) { + char **argv2; + + max_args *= 2; + argv2 = kmalloc(sizeof(*argv2) * max_args, GFP_NOIO); + if (!argv2) { + kfree(argv); + return -ENOMEM; + } + + memcpy(argv2, argv, sizeof(*argv) * *argc); + kfree(argv); + argv = argv2; + } /* we know this is whitespace */ if (*end) @@ -488,6 +507,7 @@ (*argc)++; } + *argvp = argv; return 0; } @@ -495,7 +515,7 @@ sector_t start, sector_t len, char *params) { int r = -EINVAL, argc; - char *argv[32]; + char **argv; struct dm_target *tgt; if ((r = check_space(t))) @@ -524,13 +544,14 @@ goto bad; } - r = split_args(ARRAY_SIZE(argv), &argc, argv, params); + r = split_args(&argc, &argv, params); if (r) { - tgt->error = "couldn't split parameters"; + tgt->error = "couldn't split parameters (insufficient memory)"; goto bad; } r = tgt->type->ctr(tgt, argc, argv); + kfree(argv); if (r) goto bad;