From 8e651bef37733802d984d1b97eff12d525b1ba57 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Fri, 10 Aug 2012 13:12:07 -0700 Subject: [PATCH] --- yaml --- r: 331640 b: refs/heads/master c: 1f7ba3311530993801d6877889efff0382bcd641 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/block/rbd.c | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/[refs] b/[refs] index f7f7cd51d59b..65e25a021586 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cc4829e5967de577794b25dfcd1a65e509d171ed +refs/heads/master: 1f7ba3311530993801d6877889efff0382bcd641 diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 2b40a4af4d17..15bd3ecbcf34 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -322,19 +322,28 @@ static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts, } /* - * Find a ceph client with specific addr and configuration. + * Find a ceph client with specific addr and configuration. If + * found, bump its reference count. */ -static struct rbd_client *__rbd_client_find(struct ceph_options *ceph_opts) +static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts) { struct rbd_client *client_node; + bool found = false; if (ceph_opts->flags & CEPH_OPT_NOSHARE) return NULL; - list_for_each_entry(client_node, &rbd_client_list, node) - if (!ceph_compare_options(ceph_opts, client_node->client)) - return client_node; - return NULL; + spin_lock(&rbd_client_list_lock); + list_for_each_entry(client_node, &rbd_client_list, node) { + if (!ceph_compare_options(ceph_opts, client_node->client)) { + kref_get(&client_node->kref); + found = true; + break; + } + } + spin_unlock(&rbd_client_list_lock); + + return found ? client_node : NULL; } /* @@ -416,22 +425,16 @@ static struct rbd_client *rbd_get_client(const char *mon_addr, return ERR_CAST(ceph_opts); } - spin_lock(&rbd_client_list_lock); - rbdc = __rbd_client_find(ceph_opts); + rbdc = rbd_client_find(ceph_opts); if (rbdc) { /* using an existing client */ - kref_get(&rbdc->kref); - spin_unlock(&rbd_client_list_lock); - ceph_destroy_options(ceph_opts); kfree(rbd_opts); return rbdc; } - spin_unlock(&rbd_client_list_lock); rbdc = rbd_client_create(ceph_opts, rbd_opts); - if (IS_ERR(rbdc)) kfree(rbd_opts);