diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/rbd.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 2b40a4af4d17..15bd3ecbcf34 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -322,19 +322,28 @@ out_opt: | |||
322 | } | 322 | } |
323 | 323 | ||
324 | /* | 324 | /* |
325 | * Find a ceph client with specific addr and configuration. | 325 | * Find a ceph client with specific addr and configuration. If |
326 | * found, bump its reference count. | ||
326 | */ | 327 | */ |
327 | static struct rbd_client *__rbd_client_find(struct ceph_options *ceph_opts) | 328 | static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts) |
328 | { | 329 | { |
329 | struct rbd_client *client_node; | 330 | struct rbd_client *client_node; |
331 | bool found = false; | ||
330 | 332 | ||
331 | if (ceph_opts->flags & CEPH_OPT_NOSHARE) | 333 | if (ceph_opts->flags & CEPH_OPT_NOSHARE) |
332 | return NULL; | 334 | return NULL; |
333 | 335 | ||
334 | list_for_each_entry(client_node, &rbd_client_list, node) | 336 | spin_lock(&rbd_client_list_lock); |
335 | if (!ceph_compare_options(ceph_opts, client_node->client)) | 337 | list_for_each_entry(client_node, &rbd_client_list, node) { |
336 | return client_node; | 338 | if (!ceph_compare_options(ceph_opts, client_node->client)) { |
337 | return NULL; | 339 | kref_get(&client_node->kref); |
340 | found = true; | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | spin_unlock(&rbd_client_list_lock); | ||
345 | |||
346 | return found ? client_node : NULL; | ||
338 | } | 347 | } |
339 | 348 | ||
340 | /* | 349 | /* |
@@ -416,22 +425,16 @@ static struct rbd_client *rbd_get_client(const char *mon_addr, | |||
416 | return ERR_CAST(ceph_opts); | 425 | return ERR_CAST(ceph_opts); |
417 | } | 426 | } |
418 | 427 | ||
419 | spin_lock(&rbd_client_list_lock); | 428 | rbdc = rbd_client_find(ceph_opts); |
420 | rbdc = __rbd_client_find(ceph_opts); | ||
421 | if (rbdc) { | 429 | if (rbdc) { |
422 | /* using an existing client */ | 430 | /* using an existing client */ |
423 | kref_get(&rbdc->kref); | ||
424 | spin_unlock(&rbd_client_list_lock); | ||
425 | |||
426 | ceph_destroy_options(ceph_opts); | 431 | ceph_destroy_options(ceph_opts); |
427 | kfree(rbd_opts); | 432 | kfree(rbd_opts); |
428 | 433 | ||
429 | return rbdc; | 434 | return rbdc; |
430 | } | 435 | } |
431 | spin_unlock(&rbd_client_list_lock); | ||
432 | 436 | ||
433 | rbdc = rbd_client_create(ceph_opts, rbd_opts); | 437 | rbdc = rbd_client_create(ceph_opts, rbd_opts); |
434 | |||
435 | if (IS_ERR(rbdc)) | 438 | if (IS_ERR(rbdc)) |
436 | kfree(rbd_opts); | 439 | kfree(rbd_opts); |
437 | 440 | ||