diff options
author | Sage Weil <sage@newdream.net> | 2009-10-27 01:07:53 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-10-27 01:07:53 -0400 |
commit | 7b813c46021e8f4909772a5bbfb5212bd140764c (patch) | |
tree | 50655ab84f6347ec11a4423f22093fbb7a944e87 /fs/ceph/super.c | |
parent | ecb19c4649d7396737eb0d91a475661fe9d7c028 (diff) |
ceph: reduce parse_mount_args stack usage
Since we've increased the max mon count, we shouldn't put the addr array
on the parse_mount_args stack. Put it on the heap instead.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/super.c')
-rw-r--r-- | fs/ceph/super.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 81916250f0b6..deb51bd6ed83 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -314,12 +314,16 @@ static int parse_mount_args(struct ceph_client *client, | |||
314 | int err; | 314 | int err; |
315 | substring_t argstr[MAX_OPT_ARGS]; | 315 | substring_t argstr[MAX_OPT_ARGS]; |
316 | int num_mon; | 316 | int num_mon; |
317 | struct ceph_entity_addr mon_addr[CEPH_MAX_MON]; | 317 | struct ceph_entity_addr *mon_addr; |
318 | int i; | 318 | int i; |
319 | 319 | ||
320 | dout("parse_mount_args dev_name '%s'\n", dev_name); | 320 | dout("parse_mount_args dev_name '%s'\n", dev_name); |
321 | memset(args, 0, sizeof(*args)); | 321 | memset(args, 0, sizeof(*args)); |
322 | 322 | ||
323 | mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL); | ||
324 | if (!mon_addr) | ||
325 | return -ENOMEM; | ||
326 | |||
323 | /* start with defaults */ | 327 | /* start with defaults */ |
324 | args->sb_flags = flags; | 328 | args->sb_flags = flags; |
325 | args->flags = CEPH_OPT_DEFAULT; | 329 | args->flags = CEPH_OPT_DEFAULT; |
@@ -333,27 +337,29 @@ static int parse_mount_args(struct ceph_client *client, | |||
333 | args->max_readdir = 1024; | 337 | args->max_readdir = 1024; |
334 | 338 | ||
335 | /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ | 339 | /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ |
340 | err = -EINVAL; | ||
336 | if (!dev_name) | 341 | if (!dev_name) |
337 | return -EINVAL; | 342 | goto out; |
338 | *path = strstr(dev_name, ":/"); | 343 | *path = strstr(dev_name, ":/"); |
339 | if (*path == NULL) { | 344 | if (*path == NULL) { |
340 | pr_err("device name is missing path (no :/ in %s)\n", | 345 | pr_err("device name is missing path (no :/ in %s)\n", |
341 | dev_name); | 346 | dev_name); |
342 | return -EINVAL; | 347 | goto out; |
343 | } | 348 | } |
344 | 349 | ||
345 | /* get mon ip(s) */ | 350 | /* get mon ip(s) */ |
346 | err = ceph_parse_ips(dev_name, *path, mon_addr, | 351 | err = ceph_parse_ips(dev_name, *path, mon_addr, |
347 | CEPH_MAX_MON, &num_mon); | 352 | CEPH_MAX_MON, &num_mon); |
348 | if (err < 0) | 353 | if (err < 0) |
349 | return err; | 354 | goto out; |
350 | 355 | ||
351 | /* build initial monmap */ | 356 | /* build initial monmap */ |
357 | err = -ENOMEM; | ||
352 | client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + | 358 | client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + |
353 | num_mon*sizeof(client->monc.monmap->mon_inst[0]), | 359 | num_mon*sizeof(client->monc.monmap->mon_inst[0]), |
354 | GFP_KERNEL); | 360 | GFP_KERNEL); |
355 | if (!client->monc.monmap) | 361 | if (!client->monc.monmap) |
356 | return -ENOMEM; | 362 | goto out; |
357 | for (i = 0; i < num_mon; i++) { | 363 | for (i = 0; i < num_mon; i++) { |
358 | client->monc.monmap->mon_inst[i].addr = mon_addr[i]; | 364 | client->monc.monmap->mon_inst[i].addr = mon_addr[i]; |
359 | client->monc.monmap->mon_inst[i].addr.erank = 0; | 365 | client->monc.monmap->mon_inst[i].addr.erank = 0; |
@@ -374,11 +380,11 @@ static int parse_mount_args(struct ceph_client *client, | |||
374 | int token, intval, ret; | 380 | int token, intval, ret; |
375 | if (!*c) | 381 | if (!*c) |
376 | continue; | 382 | continue; |
383 | err = -EINVAL; | ||
377 | token = match_token((char *)c, arg_tokens, argstr); | 384 | token = match_token((char *)c, arg_tokens, argstr); |
378 | if (token < 0) { | 385 | if (token < 0) { |
379 | pr_err("bad mount option at '%s'\n", c); | 386 | pr_err("bad mount option at '%s'\n", c); |
380 | return -EINVAL; | 387 | goto out; |
381 | |||
382 | } | 388 | } |
383 | if (token < Opt_ip) { | 389 | if (token < Opt_ip) { |
384 | ret = match_int(&argstr[0], &intval); | 390 | ret = match_int(&argstr[0], &intval); |
@@ -468,8 +474,11 @@ static int parse_mount_args(struct ceph_client *client, | |||
468 | BUG_ON(token); | 474 | BUG_ON(token); |
469 | } | 475 | } |
470 | } | 476 | } |
477 | err = 0; | ||
471 | 478 | ||
472 | return 0; | 479 | out: |
480 | kfree(mon_addr); | ||
481 | return err; | ||
473 | } | 482 | } |
474 | 483 | ||
475 | static void release_mount_args(struct ceph_mount_args *args) | 484 | static void release_mount_args(struct ceph_mount_args *args) |