*
  * Note: rbd_dev is assumed to have been initially zero-filled.
  */
-static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
-                                               const char *buf,
-                                               struct rbd_options **opts)
+static int rbd_add_parse_args(struct rbd_device *rbd_dev,
+                               const char *buf,
+                               struct ceph_options **ceph_opts,
+                               struct rbd_options **opts)
 {
        size_t len;
        const char *mon_addrs;
        size_t mon_addrs_size;
        char *options;
-       struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
-       struct ceph_options *ceph_opts;
        struct rbd_options *rbd_opts = NULL;
+       int ret;
 
        /* The first four tokens are required */
 
        len = next_token(&buf);
        if (!len)
-               return err_ptr; /* Missing monitor address(es) */
+               return -EINVAL; /* Missing monitor address(es) */
        mon_addrs = buf;
        mon_addrs_size = len + 1;
        buf += len;
 
+       ret = -EINVAL;
        options = dup_token(&buf, NULL);
        if (!options)
-               goto out_mem;
+               return -ENOMEM;
        if (!*options)
                goto out_err;   /* Missing options */
 
                buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
                len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
        } else if (len > RBD_MAX_SNAP_NAME_LEN) {
-               err_ptr = ERR_PTR(-ENAMETOOLONG);
+               ret = -ENAMETOOLONG;
                goto out_err;
        }
        rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
 
        rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
 
-       ceph_opts = ceph_parse_options(options, mon_addrs,
+       *ceph_opts = ceph_parse_options(options, mon_addrs,
                                        mon_addrs + mon_addrs_size - 1,
                                        parse_rbd_opts_token, rbd_opts);
        kfree(options);
+       if (IS_ERR(*ceph_opts)) {
+               ret = PTR_ERR(*ceph_opts);
+               goto out_err;
+       }
        *opts = rbd_opts;
 
-       return ceph_opts;
+       return 0;
 out_mem:
-       err_ptr = ERR_PTR(-ENOMEM);
+       ret = -ENOMEM;
 out_err:
        kfree(rbd_dev->image_name);
        rbd_dev->image_name = NULL;
        rbd_dev->pool_name = NULL;
        kfree(options);
 
-       return err_ptr;
+       return ret;
 }
 
 /*
                       size_t count)
 {
        struct rbd_device *rbd_dev = NULL;
-       struct ceph_options *ceph_opts;
+       struct ceph_options *ceph_opts = NULL;
        struct rbd_options *rbd_opts = NULL;
        struct ceph_osd_client *osdc;
        int rc = -ENOMEM;
        init_rwsem(&rbd_dev->header_rwsem);
 
        /* parse add command */
-       ceph_opts = rbd_add_parse_args(rbd_dev, buf, &rbd_opts);
-       if (IS_ERR(ceph_opts)) {
-               rc = PTR_ERR(ceph_opts);
+       rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts);
+       if (rc < 0)
                goto err_out_mem;
-       }
        rbd_dev->mapping.read_only = rbd_opts->read_only;
 
        rc = rbd_get_client(rbd_dev, ceph_opts);