diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index c7d673ffe023b20697f5ae8571d3efd2c5256a73..bf535815592db1882a02a1a5d8382fa38e88854b 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -600,8 +600,8 @@ static int ceph_writepages_start(struct address_space *mapping,
 		pr_warning("writepage_start %p on forced umount\n", inode);
 		return -EIO; /* we're in a forced umount, don't write! */
 	}
-	if (client->mount_args.wsize && client->mount_args.wsize < wsize)
-		wsize = client->mount_args.wsize;
+	if (client->mount_args->wsize && client->mount_args->wsize < wsize)
+		wsize = client->mount_args->wsize;
 	if (wsize < PAGE_CACHE_SIZE)
 		wsize = PAGE_CACHE_SIZE;
 	max_pages_ever = wsize >> PAGE_CACHE_SHIFT;
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 7d166182e98d468484acf18e56d0e6610bec8b01..8b863dbec70ce64d96131eb5e17d76f01486d086 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -270,7 +270,7 @@ static void put_cap(struct ceph_cap *cap,
 	 * lots of free/alloc churn.
 	 */
 	if (caps_avail_count >= caps_reserve_count +
-	    ceph_client(cap->ci->vfs_inode.i_sb)->mount_args.max_readdir) {
+	    ceph_client(cap->ci->vfs_inode.i_sb)->mount_args->max_readdir) {
 		caps_total_count--;
 		kmem_cache_free(ceph_cap_cachep, cap);
 	} else {
@@ -388,7 +388,7 @@ static void __insert_cap_node(struct ceph_inode_info *ci,
 static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
 			       struct ceph_inode_info *ci)
 {
-	struct ceph_mount_args *ma = &mdsc->client->mount_args;
+	struct ceph_mount_args *ma = mdsc->client->mount_args;
 
 	ci->i_hold_caps_min = round_jiffies(jiffies +
 					    ma->caps_wanted_delay_min * HZ);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 7bb8db524e587012b407e679288836ea1d70cb8f..4f7467961b09f9557ccfa8fbe3505ed8bb8772fb 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -225,7 +225,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
 	int err;
 	u32 ftype;
 	struct ceph_mds_reply_info_parsed *rinfo;
-	const int max_entries = client->mount_args.max_readdir;
+	const int max_entries = client->mount_args->max_readdir;
 
 	dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off);
 	if (fi->at_end)
@@ -479,7 +479,8 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
 	/* .snap dir? */
 	if (err == -ENOENT &&
 	    ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */
-	    strcmp(dentry->d_name.name, client->mount_args.snapdir_name) == 0) {
+	    strcmp(dentry->d_name.name,
+		   client->mount_args->snapdir_name) == 0) {
 		struct inode *inode = ceph_get_snapdir(parent);
 		dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
 		     dentry, dentry->d_name.len, dentry->d_name.name, inode);
@@ -550,7 +551,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
 		spin_lock(&dir->i_lock);
 		dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags);
 		if (strncmp(dentry->d_name.name,
-			    client->mount_args.snapdir_name,
+			    client->mount_args->snapdir_name,
 			    dentry->d_name.len) &&
 		    (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
 		    (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 12d66c0572ac8845fab3cd1de2a1c2036d0c8ae2..210cb6623ea2b0f3b28da259d99072882185cec6 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -943,7 +943,7 @@ static int add_cap_releases(struct ceph_mds_client *mdsc,
 	int err = -ENOMEM;
 
 	if (extra < 0)
-		extra = mdsc->client->mount_args.cap_release_safety;
+		extra = mdsc->client->mount_args->cap_release_safety;
 
 	spin_lock(&session->s_cap_lock);
 
@@ -2601,7 +2601,7 @@ static void wait_requests(struct ceph_mds_client *mdsc)
 		mutex_unlock(&mdsc->mutex);
 		dout("wait_requests waiting for requests\n");
 		wait_for_completion_timeout(&mdsc->safe_umount_waiters,
-				    client->mount_args.mount_timeout * HZ);
+				    client->mount_args->mount_timeout * HZ);
 		mutex_lock(&mdsc->mutex);
 
 		/* tear down remaining requests */
@@ -2693,7 +2693,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
 	int i;
 	int n;
 	struct ceph_client *client = mdsc->client;
-	unsigned long started, timeout = client->mount_args.mount_timeout * HZ;
+	unsigned long started, timeout = client->mount_args->mount_timeout * HZ;
 
 	dout("close_sessions\n");
 
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
index e6e954cac6b9303e8fda527f05107f43955a4fd4..61263c99c6a809b542da0c7dde189eca29c4afca 100644
--- a/fs/ceph/mon_client.c
+++ b/fs/ceph/mon_client.c
@@ -527,6 +527,40 @@ static void delayed_work(struct work_struct *work)
 	mutex_unlock(&monc->mutex);
 }
 
+/*
+ * On startup, we build a temporary monmap populated with the IPs
+ * provided by mount(2).
+ */
+static int build_initial_monmap(struct ceph_mon_client *monc)
+{
+	struct ceph_mount_args *args = monc->client->mount_args;
+	struct ceph_entity_addr *mon_addr = args->mon_addr;
+	int num_mon = args->num_mon;
+	int i;
+
+	/* build initial monmap */
+	monc->monmap = kzalloc(sizeof(*monc->monmap) +
+			       num_mon*sizeof(monc->monmap->mon_inst[0]),
+			       GFP_KERNEL);
+	if (!monc->monmap)
+		return -ENOMEM;
+	for (i = 0; i < num_mon; i++) {
+		monc->monmap->mon_inst[i].addr = mon_addr[i];
+		monc->monmap->mon_inst[i].addr.erank = 0;
+		monc->monmap->mon_inst[i].addr.nonce = 0;
+		monc->monmap->mon_inst[i].name.type =
+			CEPH_ENTITY_TYPE_MON;
+		monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
+	}
+	monc->monmap->num_mon = num_mon;
+
+	/* release addr memory */
+	kfree(args->mon_addr);
+	args->mon_addr = NULL;
+	args->num_mon = 0;
+	return 0;
+}
+
 int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
 {
 	int err = 0;
@@ -537,6 +571,10 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
 	monc->monmap = NULL;
 	mutex_init(&monc->mutex);
 
+	err = build_initial_monmap(monc);
+	if (err)
+		goto out;
+
 	monc->con = NULL;
 
 	/* msg pools */
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
index 0a254054a82a1f68caefb67d5290c4b505521ffb..7dc0f6299a52bbd8a0b236c7fa29d9de738eab72 100644
--- a/fs/ceph/osd_client.c
+++ b/fs/ceph/osd_client.c
@@ -444,7 +444,7 @@ static void register_request(struct ceph_osd_client *osdc,
 	osdc->num_requests++;
 
 	req->r_timeout_stamp =
-		jiffies + osdc->client->mount_args.osd_timeout*HZ;
+		jiffies + osdc->client->mount_args->osd_timeout*HZ;
 
 	if (osdc->num_requests == 1) {
 		osdc->timeout_tid = req->r_tid;
@@ -609,7 +609,7 @@ static int __send_request(struct ceph_osd_client *osdc,
 	reqhead->flags |= cpu_to_le32(req->r_flags);  /* e.g., RETRY */
 	reqhead->reassert_version = req->r_reassert_version;
 
-	req->r_timeout_stamp = jiffies+osdc->client->mount_args.osd_timeout*HZ;
+	req->r_timeout_stamp = jiffies+osdc->client->mount_args->osd_timeout*HZ;
 
 	ceph_msg_get(req->r_request); /* send consumes a ref */
 	ceph_con_send(&req->r_osd->o_con, req->r_request);
@@ -632,7 +632,7 @@ static void handle_timeout(struct work_struct *work)
 		container_of(work, struct ceph_osd_client, timeout_work.work);
 	struct ceph_osd_request *req;
 	struct ceph_osd *osd;
-	unsigned long timeout = osdc->client->mount_args.osd_timeout * HZ;
+	unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ;
 	unsigned long next_timeout = timeout + jiffies;
 	struct rb_node *p;
 
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index b094f5003ef848f0d672159fbd3a5d24b51f468c..9b7815dfc0356c69808911400882377b5e49bf86 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -110,7 +110,7 @@ static int ceph_syncfs(struct super_block *sb, int wait)
 static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
 {
 	struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb);
-	struct ceph_mount_args *args = &client->mount_args;
+	struct ceph_mount_args *args = client->mount_args;
 
 	if (args->flags & CEPH_OPT_FSID)
 		seq_printf(m, ",fsidmajor=%llu,fsidminor%llu",
@@ -307,24 +307,24 @@ static match_table_t arg_tokens = {
 };
 
 
-static int parse_mount_args(struct ceph_client *client,
-			    int flags, char *options, const char *dev_name,
-			    const char **path)
+static struct ceph_mount_args *parse_mount_args(int flags, char *options,
+						const char *dev_name,
+						const char **path)
 {
-	struct ceph_mount_args *args = &client->mount_args;
+	struct ceph_mount_args *args;
 	const char *c;
-	int err;
+	int err = -ENOMEM;
 	substring_t argstr[MAX_OPT_ARGS];
-	int num_mon;
-	struct ceph_entity_addr *mon_addr;
-	int i;
 
-	dout("parse_mount_args dev_name '%s'\n", dev_name);
-	memset(args, 0, sizeof(*args));
+	args = kzalloc(sizeof(*args), GFP_KERNEL);
+	if (!args)
+		return ERR_PTR(-ENOMEM);
+	args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr),
+				 GFP_KERNEL);
+	if (!args->mon_addr)
+		goto out;
 
-	mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL);
-	if (!mon_addr)
-		return -ENOMEM;
+	dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name);
 
 	/* start with defaults */
 	args->sb_flags = flags;
@@ -350,29 +350,11 @@ static int parse_mount_args(struct ceph_client *client,
 	}
 
 	/* get mon ip(s) */
-	err = ceph_parse_ips(dev_name, *path, mon_addr,
-			     CEPH_MAX_MON, &num_mon);
+	err = ceph_parse_ips(dev_name, *path, args->mon_addr,
+			     CEPH_MAX_MON, &args->num_mon);
 	if (err < 0)
 		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)
-		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;
-		client->monc.monmap->mon_inst[i].addr.nonce = 0;
-		client->monc.monmap->mon_inst[i].name.type =
-			CEPH_ENTITY_TYPE_MON;
-		client->monc.monmap->mon_inst[i].name.num = cpu_to_le64(i);
-	}
-	client->monc.monmap->num_mon = num_mon;
-	memset(&args->my_addr.in_addr, 0, sizeof(args->my_addr.in_addr));
-
 	/* path on server */
 	*path += 2;
 	dout("server path '%s'\n", *path);
@@ -415,7 +397,7 @@ static int parse_mount_args(struct ceph_client *client,
 					     &args->my_addr,
 					     1, NULL);
 			if (err < 0)
-				return err;
+				goto out;
 			args->flags |= CEPH_OPT_MYIP;
 			break;
 
@@ -481,25 +463,28 @@ static int parse_mount_args(struct ceph_client *client,
 			BUG_ON(token);
 		}
 	}
-	err = 0;
+	return args;
 
 out:
-	kfree(mon_addr);
-	return err;
+	kfree(args->mon_addr);
+	kfree(args);
+	return ERR_PTR(err);
 }
 
-static void release_mount_args(struct ceph_mount_args *args)
+static void destroy_mount_args(struct ceph_mount_args *args)
 {
+	dout("destroy_mount_args %p\n", args);
 	kfree(args->snapdir_name);
 	args->snapdir_name = NULL;
 	kfree(args->secret);
 	args->secret = NULL;
+	kfree(args);
 }
 
 /*
  * create a fresh client instance
  */
-static struct ceph_client *ceph_create_client(void)
+static struct ceph_client *ceph_create_client(struct ceph_mount_args *args)
 {
 	struct ceph_client *client;
 	int err = -ENOMEM;
@@ -515,6 +500,7 @@ static struct ceph_client *ceph_create_client(void)
 	client->sb = NULL;
 	client->mount_state = CEPH_MOUNT_MOUNTING;
 	client->whoami = -1;
+	client->mount_args = args;
 
 	client->msgr = NULL;
 
@@ -577,7 +563,7 @@ static void ceph_destroy_client(struct ceph_client *client)
 	if (client->wb_pagevec_pool)
 		mempool_destroy(client->wb_pagevec_pool);
 
-	release_mount_args(&client->mount_args);
+	destroy_mount_args(client->mount_args);
 
 	kfree(client);
 	dout("destroy_client %p done\n", client);
@@ -613,7 +599,7 @@ static struct dentry *open_root_dentry(struct ceph_client *client,
 	req->r_ino1.ino = CEPH_INO_ROOT;
 	req->r_ino1.snap = CEPH_NOSNAP;
 	req->r_started = started;
-	req->r_timeout = client->mount_args.mount_timeout * HZ;
+	req->r_timeout = client->mount_args->mount_timeout * HZ;
 	req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
 	req->r_num_caps = 2;
 	err = ceph_mdsc_do_request(mdsc, NULL, req);
@@ -641,7 +627,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
 {
 	struct ceph_entity_addr *myaddr = NULL;
 	int err;
-	unsigned long timeout = client->mount_args.mount_timeout * HZ;
+	unsigned long timeout = client->mount_args->mount_timeout * HZ;
 	unsigned long started = jiffies;  /* note the start time */
 	struct dentry *root;
 
@@ -651,7 +637,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
 	/* initialize the messenger */
 	if (client->msgr == NULL) {
 		if (ceph_test_opt(client, MYIP))
-			myaddr = &client->mount_args.my_addr;
+			myaddr = &client->mount_args->my_addr;
 		client->msgr = ceph_messenger_create(myaddr);
 		if (IS_ERR(client->msgr)) {
 			err = PTR_ERR(client->msgr);
@@ -727,7 +713,7 @@ static int ceph_set_super(struct super_block *s, void *data)
 
 	dout("set_super %p data %p\n", s, data);
 
-	s->s_flags = client->mount_args.sb_flags;
+	s->s_flags = client->mount_args->sb_flags;
 	s->s_maxbytes = 1ULL << 40;  /* temp value until we get mdsmap */
 
 	s->s_fs_info = client;
@@ -756,7 +742,7 @@ static int ceph_set_super(struct super_block *s, void *data)
 static int ceph_compare_super(struct super_block *sb, void *data)
 {
 	struct ceph_client *new = data;
-	struct ceph_mount_args *args = &new->mount_args;
+	struct ceph_mount_args *args = new->mount_args;
 	struct ceph_client *other = ceph_sb_to_client(sb);
 	int i;
 
@@ -778,7 +764,7 @@ static int ceph_compare_super(struct super_block *sb, void *data)
 		}
 		dout("mon ip matches existing sb %p\n", sb);
 	}
-	if (args->sb_flags != other->mount_args.sb_flags) {
+	if (args->sb_flags != other->mount_args->sb_flags) {
 		dout("flags differ\n");
 		return 0;
 	}
@@ -798,9 +784,9 @@ static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client)
 	sb->s_bdi = &client->backing_dev_info;
 
 	/* set ra_pages based on rsize mount option? */
-	if (client->mount_args.rsize >= PAGE_CACHE_SIZE)
+	if (client->mount_args->rsize >= PAGE_CACHE_SIZE)
 		client->backing_dev_info.ra_pages =
-			(client->mount_args.rsize + PAGE_CACHE_SIZE - 1)
+			(client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
 			>> PAGE_SHIFT;
 
 	err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
@@ -816,19 +802,23 @@ static int ceph_get_sb(struct file_system_type *fs_type,
 	int err;
 	int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
 	const char *path = 0;
+	struct ceph_mount_args *args;
 
 	dout("ceph_get_sb\n");
+	args = parse_mount_args(flags, data, dev_name, &path);
+	if (IS_ERR(args)) {
+		err = PTR_ERR(args);
+		goto out_final;
+	}
 
 	/* create client (which we may/may not use) */
-	client = ceph_create_client();
-	if (IS_ERR(client))
-		return PTR_ERR(client);
-
-	err = parse_mount_args(client, flags, data, dev_name, &path);
-	if (err < 0)
-		goto out;
+	client = ceph_create_client(args);
+	if (IS_ERR(client)) {
+		err = PTR_ERR(client);
+		goto out_final;
+	}
 
-	if (client->mount_args.flags & CEPH_OPT_NOSHARE)
+	if (client->mount_args->flags & CEPH_OPT_NOSHARE)
 		compare_super = NULL;
 	sb = sget(fs_type, compare_super, ceph_set_super, client);
 	if (IS_ERR(sb)) {
@@ -846,7 +836,7 @@ static int ceph_get_sb(struct file_system_type *fs_type,
 		/* set up mempools */
 		err = -ENOMEM;
 		client->wb_pagevec_pool = mempool_create_kmalloc_pool(10,
-			      client->mount_args.wsize >> PAGE_CACHE_SHIFT);
+			      client->mount_args->wsize >> PAGE_CACHE_SHIFT);
 		if (!client->wb_pagevec_pool)
 			goto out_splat;
 
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 3af42d9097ec0952498e57b2d6e96806fb281472..a3d4943581d0ec01ae254e0a5c1534d5669d27a5 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -42,13 +42,15 @@
 #define CEPH_OPT_DEFAULT   (CEPH_OPT_RBYTES)
 
 #define ceph_set_opt(client, opt) \
-	(client)->mount_args.flags |= CEPH_OPT_##opt;
+	(client)->mount_args->flags |= CEPH_OPT_##opt;
 #define ceph_test_opt(client, opt) \
-	(!!((client)->mount_args.flags & CEPH_OPT_##opt))
+	(!!((client)->mount_args->flags & CEPH_OPT_##opt))
 
 
 struct ceph_mount_args {
 	int sb_flags;
+	int num_mon;
+	struct ceph_entity_addr *mon_addr;
 	int flags;
 	int mount_timeout;
 	int caps_wanted_delay_min, caps_wanted_delay_max;
@@ -115,7 +117,7 @@ struct ceph_client {
 	struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
 
 	struct mutex mount_mutex;       /* serialize mount attempts */
-	struct ceph_mount_args mount_args;
+	struct ceph_mount_args *mount_args;
 	struct ceph_fsid fsid;
 
 	struct super_block *sb;