summaryrefslogtreecommitdiff
path: root/fs/ceph/super.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-10-26 22:07:53 -0700
committerSage Weil <sage@newdream.net>2009-10-26 22:07:53 -0700
commit7b813c46021e8f4909772a5bbfb5212bd140764c (patch)
tree50655ab84f6347ec11a4423f22093fbb7a944e87 /fs/ceph/super.c
parentecb19c4649d7396737eb0d91a475661fe9d7c028 (diff)
downloadlwn-7b813c46021e8f4909772a5bbfb5212bd140764c.tar.gz
lwn-7b813c46021e8f4909772a5bbfb5212bd140764c.zip
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.c25
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,
int err;
substring_t argstr[MAX_OPT_ARGS];
int num_mon;
- struct ceph_entity_addr mon_addr[CEPH_MAX_MON];
+ struct ceph_entity_addr *mon_addr;
int i;
dout("parse_mount_args dev_name '%s'\n", dev_name);
memset(args, 0, sizeof(*args));
+ mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL);
+ if (!mon_addr)
+ return -ENOMEM;
+
/* start with defaults */
args->sb_flags = flags;
args->flags = CEPH_OPT_DEFAULT;
@@ -333,27 +337,29 @@ static int parse_mount_args(struct ceph_client *client,
args->max_readdir = 1024;
/* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+ err = -EINVAL;
if (!dev_name)
- return -EINVAL;
+ goto out;
*path = strstr(dev_name, ":/");
if (*path == NULL) {
pr_err("device name is missing path (no :/ in %s)\n",
dev_name);
- return -EINVAL;
+ goto out;
}
/* get mon ip(s) */
err = ceph_parse_ips(dev_name, *path, mon_addr,
CEPH_MAX_MON, &num_mon);
if (err < 0)
- return err;
+ goto out;
/* build initial monmap */
+ err = -ENOMEM;
client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) +
num_mon*sizeof(client->monc.monmap->mon_inst[0]),
GFP_KERNEL);
if (!client->monc.monmap)
- return -ENOMEM;
+ goto out;
for (i = 0; i < num_mon; i++) {
client->monc.monmap->mon_inst[i].addr = mon_addr[i];
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;
if (!*c)
continue;
+ err = -EINVAL;
token = match_token((char *)c, arg_tokens, argstr);
if (token < 0) {
pr_err("bad mount option at '%s'\n", c);
- return -EINVAL;
-
+ goto out;
}
if (token < Opt_ip) {
ret = match_int(&argstr[0], &intval);
@@ -468,8 +474,11 @@ static int parse_mount_args(struct ceph_client *client,
BUG_ON(token);
}
}
+ err = 0;
- return 0;
+out:
+ kfree(mon_addr);
+ return err;
}
static void release_mount_args(struct ceph_mount_args *args)