aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-08-10 16:12:07 -0400
committerAlex Elder <elder@inktank.com>2012-10-01 15:30:49 -0400
commit1f7ba3311530993801d6877889efff0382bcd641 (patch)
treeddc5c41d5d572933ef4a4f5dcd36138f069c5bc9 /drivers/block
parentcc4829e5967de577794b25dfcd1a65e509d171ed (diff)
rbd: handle locking inside __rbd_client_find()
There is only caller of __rbd_client_find(), and it somewhat clumsily gets the appropriate lock and gets a reference to the existing ceph_client structure if it's found. Instead, have that function handle its own locking, and acquire the reference if found while it holds the lock. Drop the underscores from the name because there's no need to signify anything special about this function. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
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