summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c29
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 */
327static struct rbd_client *__rbd_client_find(struct ceph_options *ceph_opts) 328static 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