aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-10-26 00:34:42 -0400
committerAlex Elder <elder@inktank.com>2012-11-01 08:55:42 -0400
commit859c31df9cee9d1e1308b3b024b61355e6a629a5 (patch)
treeb13ebb20599f029dedc24f8c4ff801004e43791d /drivers/block
parent8b8fb99c5c93a0bdfe7b0c0c9fd2d41a3244555e (diff)
rbd: fill rbd_spec in rbd_add_parse_args()
Pass the address of an rbd_spec structure to rbd_add_parse_args(). Use it to hold the information defining the rbd image to be mapped in an rbd_add() call. Use the result in the caller to initialize the rbd_dev->id field. This means rbd_dev is no longer needed in rbd_add_parse_args(), so get rid of it. Now that this transformation of rbd_add_parse_args() is complete, correct and expand on the its header documentation to reflect the new reality. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c113
1 files changed, 75 insertions, 38 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 86206a75017d..be85d925dfdb 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2887,25 +2887,58 @@ static inline char *dup_token(const char **buf, size_t *lenp)
2887} 2887}
2888 2888
2889/* 2889/*
2890 * This fills in the pool_name, image_name, image_name_len, rbd_dev, 2890 * Parse the options provided for an "rbd add" (i.e., rbd image
2891 * rbd_md_name, and name fields of the given rbd_dev, based on the 2891 * mapping) request. These arrive via a write to /sys/bus/rbd/add,
2892 * list of monitor addresses and other options provided via 2892 * and the data written is passed here via a NUL-terminated buffer.
2893 * /sys/bus/rbd/add. Returns a pointer to a dynamically-allocated 2893 * Returns 0 if successful or an error code otherwise.
2894 * copy of the snapshot name to map if successful, or a
2895 * pointer-coded error otherwise.
2896 * 2894 *
2897 * Note: rbd_dev is assumed to have been initially zero-filled. 2895 * The information extracted from these options is recorded in
2896 * the other parameters which return dynamically-allocated
2897 * structures:
2898 * ceph_opts
2899 * The address of a pointer that will refer to a ceph options
2900 * structure. Caller must release the returned pointer using
2901 * ceph_destroy_options() when it is no longer needed.
2902 * rbd_opts
2903 * Address of an rbd options pointer. Fully initialized by
2904 * this function; caller must release with kfree().
2905 * spec
2906 * Address of an rbd image specification pointer. Fully
2907 * initialized by this function based on parsed options.
2908 * Caller must release with rbd_spec_put().
2909 *
2910 * The options passed take this form:
2911 * <mon_addrs> <options> <pool_name> <image_name> [<snap_id>]
2912 * where:
2913 * <mon_addrs>
2914 * A comma-separated list of one or more monitor addresses.
2915 * A monitor address is an ip address, optionally followed
2916 * by a port number (separated by a colon).
2917 * I.e.: ip1[:port1][,ip2[:port2]...]
2918 * <options>
2919 * A comma-separated list of ceph and/or rbd options.
2920 * <pool_name>
2921 * The name of the rados pool containing the rbd image.
2922 * <image_name>
2923 * The name of the image in that pool to map.
2924 * <snap_id>
2925 * An optional snapshot id. If provided, the mapping will
2926 * present data from the image at the time that snapshot was
2927 * created. The image head is used if no snapshot id is
2928 * provided. Snapshot mappings are always read-only.
2898 */ 2929 */
2899static int rbd_add_parse_args(struct rbd_device *rbd_dev, 2930static int rbd_add_parse_args(const char *buf,
2900 const char *buf,
2901 struct ceph_options **ceph_opts, 2931 struct ceph_options **ceph_opts,
2902 struct rbd_options **opts) 2932 struct rbd_options **opts,
2933 struct rbd_spec **rbd_spec)
2903{ 2934{
2904 size_t len; 2935 size_t len;
2936 char *options;
2905 const char *mon_addrs; 2937 const char *mon_addrs;
2906 size_t mon_addrs_size; 2938 size_t mon_addrs_size;
2907 char *options; 2939 struct rbd_spec *spec = NULL;
2908 struct rbd_options *rbd_opts = NULL; 2940 struct rbd_options *rbd_opts = NULL;
2941 struct ceph_options *copts;
2909 int ret; 2942 int ret;
2910 2943
2911 /* The first four tokens are required */ 2944 /* The first four tokens are required */
@@ -2924,17 +2957,20 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
2924 if (!*options) 2957 if (!*options)
2925 goto out_err; /* Missing options */ 2958 goto out_err; /* Missing options */
2926 2959
2927 rbd_dev->spec->pool_name = dup_token(&buf, NULL); 2960 spec = rbd_spec_alloc();
2928 if (!rbd_dev->spec->pool_name) 2961 if (!spec)
2929 goto out_mem; 2962 goto out_mem;
2930 if (!*rbd_dev->spec->pool_name) 2963
2964 spec->pool_name = dup_token(&buf, NULL);
2965 if (!spec->pool_name)
2966 goto out_mem;
2967 if (!*spec->pool_name)
2931 goto out_err; /* Missing pool name */ 2968 goto out_err; /* Missing pool name */
2932 2969
2933 rbd_dev->spec->image_name = 2970 spec->image_name = dup_token(&buf, &spec->image_name_len);
2934 dup_token(&buf, &rbd_dev->spec->image_name_len); 2971 if (!spec->image_name)
2935 if (!rbd_dev->spec->image_name)
2936 goto out_mem; 2972 goto out_mem;
2937 if (!*rbd_dev->spec->image_name) 2973 if (!*spec->image_name)
2938 goto out_err; /* Missing image name */ 2974 goto out_err; /* Missing image name */
2939 2975
2940 /* 2976 /*
@@ -2949,11 +2985,11 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
2949 ret = -ENAMETOOLONG; 2985 ret = -ENAMETOOLONG;
2950 goto out_err; 2986 goto out_err;
2951 } 2987 }
2952 rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL); 2988 spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
2953 if (!rbd_dev->spec->snap_name) 2989 if (!spec->snap_name)
2954 goto out_mem; 2990 goto out_mem;
2955 memcpy(rbd_dev->spec->snap_name, buf, len); 2991 memcpy(spec->snap_name, buf, len);
2956 *(rbd_dev->spec->snap_name + len) = '\0'; 2992 *(spec->snap_name + len) = '\0';
2957 2993
2958 /* Initialize all rbd options to the defaults */ 2994 /* Initialize all rbd options to the defaults */
2959 2995
@@ -2963,25 +2999,25 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
2963 2999
2964 rbd_opts->read_only = RBD_READ_ONLY_DEFAULT; 3000 rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
2965 3001
2966 *ceph_opts = ceph_parse_options(options, mon_addrs, 3002 copts = ceph_parse_options(options, mon_addrs,
2967 mon_addrs + mon_addrs_size - 1, 3003 mon_addrs + mon_addrs_size - 1,
2968 parse_rbd_opts_token, rbd_opts); 3004 parse_rbd_opts_token, rbd_opts);
2969 kfree(options); 3005 if (IS_ERR(copts)) {
2970 if (IS_ERR(*ceph_opts)) { 3006 ret = PTR_ERR(copts);
2971 ret = PTR_ERR(*ceph_opts);
2972 goto out_err; 3007 goto out_err;
2973 } 3008 }
3009 kfree(options);
3010
3011 *ceph_opts = copts;
2974 *opts = rbd_opts; 3012 *opts = rbd_opts;
3013 *rbd_spec = spec;
2975 3014
2976 return 0; 3015 return 0;
2977out_mem: 3016out_mem:
2978 ret = -ENOMEM; 3017 ret = -ENOMEM;
2979out_err: 3018out_err:
2980 kfree(rbd_dev->spec->image_name); 3019 kfree(rbd_opts);
2981 rbd_dev->spec->image_name = NULL; 3020 rbd_spec_put(spec);
2982 rbd_dev->spec->image_name_len = 0;
2983 kfree(rbd_dev->spec->pool_name);
2984 rbd_dev->spec->pool_name = NULL;
2985 kfree(options); 3021 kfree(options);
2986 3022
2987 return ret; 3023 return ret;
@@ -3195,6 +3231,7 @@ static ssize_t rbd_add(struct bus_type *bus,
3195 struct rbd_device *rbd_dev = NULL; 3231 struct rbd_device *rbd_dev = NULL;
3196 struct ceph_options *ceph_opts = NULL; 3232 struct ceph_options *ceph_opts = NULL;
3197 struct rbd_options *rbd_opts = NULL; 3233 struct rbd_options *rbd_opts = NULL;
3234 struct rbd_spec *spec = NULL;
3198 struct ceph_osd_client *osdc; 3235 struct ceph_osd_client *osdc;
3199 int rc = -ENOMEM; 3236 int rc = -ENOMEM;
3200 3237
@@ -3204,9 +3241,6 @@ static ssize_t rbd_add(struct bus_type *bus,
3204 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); 3241 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
3205 if (!rbd_dev) 3242 if (!rbd_dev)
3206 return -ENOMEM; 3243 return -ENOMEM;
3207 rbd_dev->spec = rbd_spec_alloc();
3208 if (!rbd_dev->spec)
3209 goto err_out_mem;
3210 3244
3211 /* static rbd_device initialization */ 3245 /* static rbd_device initialization */
3212 spin_lock_init(&rbd_dev->lock); 3246 spin_lock_init(&rbd_dev->lock);
@@ -3215,9 +3249,10 @@ static ssize_t rbd_add(struct bus_type *bus,
3215 init_rwsem(&rbd_dev->header_rwsem); 3249 init_rwsem(&rbd_dev->header_rwsem);
3216 3250
3217 /* parse add command */ 3251 /* parse add command */
3218 rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts); 3252 rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec);
3219 if (rc < 0) 3253 if (rc < 0)
3220 goto err_out_mem; 3254 goto err_out_mem;
3255
3221 rbd_dev->mapping.read_only = rbd_opts->read_only; 3256 rbd_dev->mapping.read_only = rbd_opts->read_only;
3222 3257
3223 rc = rbd_get_client(rbd_dev, ceph_opts); 3258 rc = rbd_get_client(rbd_dev, ceph_opts);
@@ -3227,10 +3262,12 @@ static ssize_t rbd_add(struct bus_type *bus,
3227 3262
3228 /* pick the pool */ 3263 /* pick the pool */
3229 osdc = &rbd_dev->rbd_client->client->osdc; 3264 osdc = &rbd_dev->rbd_client->client->osdc;
3230 rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name); 3265 rc = ceph_pg_poolid_by_name(osdc->osdmap, spec->pool_name);
3231 if (rc < 0) 3266 if (rc < 0)
3232 goto err_out_client; 3267 goto err_out_client;
3233 rbd_dev->spec->pool_id = (u64) rc; 3268 spec->pool_id = (u64) rc;
3269
3270 rbd_dev->spec = spec;
3234 3271
3235 rc = rbd_dev_probe(rbd_dev); 3272 rc = rbd_dev_probe(rbd_dev);
3236 if (rc < 0) 3273 if (rc < 0)
@@ -3321,8 +3358,8 @@ err_out_args:
3321 if (ceph_opts) 3358 if (ceph_opts)
3322 ceph_destroy_options(ceph_opts); 3359 ceph_destroy_options(ceph_opts);
3323 kfree(rbd_opts); 3360 kfree(rbd_opts);
3361 rbd_spec_put(spec);
3324err_out_mem: 3362err_out_mem:
3325 rbd_spec_put(rbd_dev->spec);
3326 kfree(rbd_dev); 3363 kfree(rbd_dev);
3327 3364
3328 dout("Error adding device %s\n", buf); 3365 dout("Error adding device %s\n", buf);