diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/rbd.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 145fbf633621..839ab730a1f3 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -98,7 +98,6 @@ struct rbd_options { | |||
98 | */ | 98 | */ |
99 | struct rbd_client { | 99 | struct rbd_client { |
100 | struct ceph_client *client; | 100 | struct ceph_client *client; |
101 | struct rbd_options *rbd_opts; | ||
102 | struct kref kref; | 101 | struct kref kref; |
103 | struct list_head node; | 102 | struct list_head node; |
104 | }; | 103 | }; |
@@ -152,6 +151,7 @@ struct rbd_device { | |||
152 | struct gendisk *disk; /* blkdev's gendisk and rq */ | 151 | struct gendisk *disk; /* blkdev's gendisk and rq */ |
153 | struct request_queue *q; | 152 | struct request_queue *q; |
154 | 153 | ||
154 | struct rbd_options rbd_opts; | ||
155 | struct rbd_client *rbd_client; | 155 | struct rbd_client *rbd_client; |
156 | 156 | ||
157 | char name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */ | 157 | char name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */ |
@@ -273,8 +273,7 @@ static const struct block_device_operations rbd_bd_ops = { | |||
273 | * Initialize an rbd client instance. | 273 | * Initialize an rbd client instance. |
274 | * We own *ceph_opts. | 274 | * We own *ceph_opts. |
275 | */ | 275 | */ |
276 | static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts, | 276 | static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts) |
277 | struct rbd_options *rbd_opts) | ||
278 | { | 277 | { |
279 | struct rbd_client *rbdc; | 278 | struct rbd_client *rbdc; |
280 | int ret = -ENOMEM; | 279 | int ret = -ENOMEM; |
@@ -298,8 +297,6 @@ static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts, | |||
298 | if (ret < 0) | 297 | if (ret < 0) |
299 | goto out_err; | 298 | goto out_err; |
300 | 299 | ||
301 | rbdc->rbd_opts = rbd_opts; | ||
302 | |||
303 | spin_lock(&rbd_client_list_lock); | 300 | spin_lock(&rbd_client_list_lock); |
304 | list_add_tail(&rbdc->node, &rbd_client_list); | 301 | list_add_tail(&rbdc->node, &rbd_client_list); |
305 | spin_unlock(&rbd_client_list_lock); | 302 | spin_unlock(&rbd_client_list_lock); |
@@ -402,42 +399,33 @@ static int parse_rbd_opts_token(char *c, void *private) | |||
402 | * Get a ceph client with specific addr and configuration, if one does | 399 | * Get a ceph client with specific addr and configuration, if one does |
403 | * not exist create it. | 400 | * not exist create it. |
404 | */ | 401 | */ |
405 | static struct rbd_client *rbd_get_client(const char *mon_addr, | 402 | static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, |
406 | size_t mon_addr_len, | 403 | size_t mon_addr_len, char *options) |
407 | char *options) | ||
408 | { | 404 | { |
409 | struct rbd_client *rbdc; | 405 | struct rbd_options *rbd_opts = &rbd_dev->rbd_opts; |
410 | struct ceph_options *ceph_opts; | 406 | struct ceph_options *ceph_opts; |
411 | struct rbd_options *rbd_opts; | 407 | struct rbd_client *rbdc; |
412 | |||
413 | rbd_opts = kzalloc(sizeof(*rbd_opts), GFP_KERNEL); | ||
414 | if (!rbd_opts) | ||
415 | return ERR_PTR(-ENOMEM); | ||
416 | 408 | ||
417 | rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT; | 409 | rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT; |
418 | 410 | ||
419 | ceph_opts = ceph_parse_options(options, mon_addr, | 411 | ceph_opts = ceph_parse_options(options, mon_addr, |
420 | mon_addr + mon_addr_len, | 412 | mon_addr + mon_addr_len, |
421 | parse_rbd_opts_token, rbd_opts); | 413 | parse_rbd_opts_token, rbd_opts); |
422 | if (IS_ERR(ceph_opts)) { | 414 | if (IS_ERR(ceph_opts)) |
423 | kfree(rbd_opts); | 415 | return PTR_ERR(ceph_opts); |
424 | return ERR_CAST(ceph_opts); | ||
425 | } | ||
426 | 416 | ||
427 | rbdc = rbd_client_find(ceph_opts); | 417 | rbdc = rbd_client_find(ceph_opts); |
428 | if (rbdc) { | 418 | if (rbdc) { |
429 | /* using an existing client */ | 419 | /* using an existing client */ |
430 | ceph_destroy_options(ceph_opts); | 420 | ceph_destroy_options(ceph_opts); |
431 | kfree(rbd_opts); | 421 | } else { |
432 | 422 | rbdc = rbd_client_create(ceph_opts); | |
433 | return rbdc; | 423 | if (IS_ERR(rbdc)) |
424 | return PTR_ERR(rbdc); | ||
434 | } | 425 | } |
426 | rbd_dev->rbd_client = rbdc; | ||
435 | 427 | ||
436 | rbdc = rbd_client_create(ceph_opts, rbd_opts); | 428 | return 0; |
437 | if (IS_ERR(rbdc)) | ||
438 | kfree(rbd_opts); | ||
439 | |||
440 | return rbdc; | ||
441 | } | 429 | } |
442 | 430 | ||
443 | /* | 431 | /* |
@@ -455,7 +443,6 @@ static void rbd_client_release(struct kref *kref) | |||
455 | spin_unlock(&rbd_client_list_lock); | 443 | spin_unlock(&rbd_client_list_lock); |
456 | 444 | ||
457 | ceph_destroy_client(rbdc->client); | 445 | ceph_destroy_client(rbdc->client); |
458 | kfree(rbdc->rbd_opts); | ||
459 | kfree(rbdc); | 446 | kfree(rbdc); |
460 | } | 447 | } |
461 | 448 | ||
@@ -2533,13 +2520,9 @@ static ssize_t rbd_add(struct bus_type *bus, | |||
2533 | if (rc) | 2520 | if (rc) |
2534 | goto err_put_id; | 2521 | goto err_put_id; |
2535 | 2522 | ||
2536 | rbd_dev->rbd_client = rbd_get_client(mon_addrs, mon_addrs_size - 1, | 2523 | rc = rbd_get_client(rbd_dev, mon_addrs, mon_addrs_size - 1, options); |
2537 | options); | 2524 | if (rc < 0) |
2538 | if (IS_ERR(rbd_dev->rbd_client)) { | ||
2539 | rc = PTR_ERR(rbd_dev->rbd_client); | ||
2540 | rbd_dev->rbd_client = NULL; | ||
2541 | goto err_put_id; | 2525 | goto err_put_id; |
2542 | } | ||
2543 | 2526 | ||
2544 | /* pick the pool */ | 2527 | /* pick the pool */ |
2545 | osdc = &rbd_dev->rbd_client->client->osdc; | 2528 | osdc = &rbd_dev->rbd_client->client->osdc; |