*/
 struct rbd_client {
        struct ceph_client      *client;
-       struct rbd_options      *rbd_opts;
        struct kref             kref;
        struct list_head        node;
 };
        struct gendisk          *disk;          /* blkdev's gendisk and rq */
        struct request_queue    *q;
 
+       struct rbd_options      rbd_opts;
        struct rbd_client       *rbd_client;
 
        char                    name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */
  * Initialize an rbd client instance.
  * We own *ceph_opts.
  */
-static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts,
-                                           struct rbd_options *rbd_opts)
+static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts)
 {
        struct rbd_client *rbdc;
        int ret = -ENOMEM;
        if (ret < 0)
                goto out_err;
 
-       rbdc->rbd_opts = rbd_opts;
-
        spin_lock(&rbd_client_list_lock);
        list_add_tail(&rbdc->node, &rbd_client_list);
        spin_unlock(&rbd_client_list_lock);
  * Get a ceph client with specific addr and configuration, if one does
  * not exist create it.
  */
-static struct rbd_client *rbd_get_client(const char *mon_addr,
-                                        size_t mon_addr_len,
-                                        char *options)
+static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
+                               size_t mon_addr_len, char *options)
 {
-       struct rbd_client *rbdc;
+       struct rbd_options *rbd_opts = &rbd_dev->rbd_opts;
        struct ceph_options *ceph_opts;
-       struct rbd_options *rbd_opts;
-
-       rbd_opts = kzalloc(sizeof(*rbd_opts), GFP_KERNEL);
-       if (!rbd_opts)
-               return ERR_PTR(-ENOMEM);
+       struct rbd_client *rbdc;
 
        rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT;
 
        ceph_opts = ceph_parse_options(options, mon_addr,
                                        mon_addr + mon_addr_len,
                                        parse_rbd_opts_token, rbd_opts);
-       if (IS_ERR(ceph_opts)) {
-               kfree(rbd_opts);
-               return ERR_CAST(ceph_opts);
-       }
+       if (IS_ERR(ceph_opts))
+               return PTR_ERR(ceph_opts);
 
        rbdc = rbd_client_find(ceph_opts);
        if (rbdc) {
                /* using an existing client */
                ceph_destroy_options(ceph_opts);
-               kfree(rbd_opts);
-
-               return rbdc;
+       } else {
+               rbdc = rbd_client_create(ceph_opts);
+               if (IS_ERR(rbdc))
+                       return PTR_ERR(rbdc);
        }
+       rbd_dev->rbd_client = rbdc;
 
-       rbdc = rbd_client_create(ceph_opts, rbd_opts);
-       if (IS_ERR(rbdc))
-               kfree(rbd_opts);
-
-       return rbdc;
+       return 0;
 }
 
 /*
        spin_unlock(&rbd_client_list_lock);
 
        ceph_destroy_client(rbdc->client);
-       kfree(rbdc->rbd_opts);
        kfree(rbdc);
 }
 
        if (rc)
                goto err_put_id;
 
-       rbd_dev->rbd_client = rbd_get_client(mon_addrs, mon_addrs_size - 1,
-                                               options);
-       if (IS_ERR(rbd_dev->rbd_client)) {
-               rc = PTR_ERR(rbd_dev->rbd_client);
-               rbd_dev->rbd_client = NULL;
+       rc = rbd_get_client(rbd_dev, mon_addrs, mon_addrs_size - 1, options);
+       if (rc < 0)
                goto err_put_id;
-       }
 
        /* pick the pool */
        osdc = &rbd_dev->rbd_client->client->osdc;