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>
This commit is contained in:
Sage Weil 2009-10-26 22:07:53 -07:00
parent ecb19c4649
commit 7b813c4602
1 changed files with 17 additions and 8 deletions

View File

@ -314,12 +314,16 @@ static int parse_mount_args(struct ceph_client *client,
int err; int err;
substring_t argstr[MAX_OPT_ARGS]; substring_t argstr[MAX_OPT_ARGS];
int num_mon; int num_mon;
struct ceph_entity_addr mon_addr[CEPH_MAX_MON]; struct ceph_entity_addr *mon_addr;
int i; int i;
dout("parse_mount_args dev_name '%s'\n", dev_name); dout("parse_mount_args dev_name '%s'\n", dev_name);
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL);
if (!mon_addr)
return -ENOMEM;
/* start with defaults */ /* start with defaults */
args->sb_flags = flags; args->sb_flags = flags;
args->flags = CEPH_OPT_DEFAULT; args->flags = CEPH_OPT_DEFAULT;
@ -333,27 +337,29 @@ static int parse_mount_args(struct ceph_client *client,
args->max_readdir = 1024; args->max_readdir = 1024;
/* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
err = -EINVAL;
if (!dev_name) if (!dev_name)
return -EINVAL; goto out;
*path = strstr(dev_name, ":/"); *path = strstr(dev_name, ":/");
if (*path == NULL) { if (*path == NULL) {
pr_err("device name is missing path (no :/ in %s)\n", pr_err("device name is missing path (no :/ in %s)\n",
dev_name); dev_name);
return -EINVAL; goto out;
} }
/* get mon ip(s) */ /* get mon ip(s) */
err = ceph_parse_ips(dev_name, *path, mon_addr, err = ceph_parse_ips(dev_name, *path, mon_addr,
CEPH_MAX_MON, &num_mon); CEPH_MAX_MON, &num_mon);
if (err < 0) if (err < 0)
return err; goto out;
/* build initial monmap */ /* build initial monmap */
err = -ENOMEM;
client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) +
num_mon*sizeof(client->monc.monmap->mon_inst[0]), num_mon*sizeof(client->monc.monmap->mon_inst[0]),
GFP_KERNEL); GFP_KERNEL);
if (!client->monc.monmap) if (!client->monc.monmap)
return -ENOMEM; goto out;
for (i = 0; i < num_mon; i++) { for (i = 0; i < num_mon; i++) {
client->monc.monmap->mon_inst[i].addr = mon_addr[i]; client->monc.monmap->mon_inst[i].addr = mon_addr[i];
client->monc.monmap->mon_inst[i].addr.erank = 0; client->monc.monmap->mon_inst[i].addr.erank = 0;
@ -374,11 +380,11 @@ static int parse_mount_args(struct ceph_client *client,
int token, intval, ret; int token, intval, ret;
if (!*c) if (!*c)
continue; continue;
err = -EINVAL;
token = match_token((char *)c, arg_tokens, argstr); token = match_token((char *)c, arg_tokens, argstr);
if (token < 0) { if (token < 0) {
pr_err("bad mount option at '%s'\n", c); pr_err("bad mount option at '%s'\n", c);
return -EINVAL; goto out;
} }
if (token < Opt_ip) { if (token < Opt_ip) {
ret = match_int(&argstr[0], &intval); ret = match_int(&argstr[0], &intval);
@ -468,8 +474,11 @@ static int parse_mount_args(struct ceph_client *client,
BUG_ON(token); BUG_ON(token);
} }
} }
err = 0;
return 0; out:
kfree(mon_addr);
return err;
} }
static void release_mount_args(struct ceph_mount_args *args) static void release_mount_args(struct ceph_mount_args *args)