diff options
author | Alex Elder <elder@inktank.com> | 2012-10-26 00:34:42 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-11-01 08:55:42 -0400 |
commit | 859c31df9cee9d1e1308b3b024b61355e6a629a5 (patch) | |
tree | b13ebb20599f029dedc24f8c4ff801004e43791d /drivers/block | |
parent | 8b8fb99c5c93a0bdfe7b0c0c9fd2d41a3244555e (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.c | 113 |
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 | */ |
2899 | static int rbd_add_parse_args(struct rbd_device *rbd_dev, | 2930 | static 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; |
2977 | out_mem: | 3016 | out_mem: |
2978 | ret = -ENOMEM; | 3017 | ret = -ENOMEM; |
2979 | out_err: | 3018 | out_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); | ||
3324 | err_out_mem: | 3362 | err_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); |