nbd: factor out a helper to get nbd_config without holding 'config_lock'
[linux-2.6-microblaze.git] / drivers / block / nbd.c
index 02f8448..daaf880 100644 (file)
@@ -395,6 +395,14 @@ static u32 req_to_nbd_cmd_type(struct request *req)
        }
 }
 
+static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd)
+{
+       if (refcount_inc_not_zero(&nbd->config_refs))
+               return nbd->config;
+
+       return NULL;
+}
+
 static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
 {
        struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
@@ -409,13 +417,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
                return BLK_EH_DONE;
        }
 
-       if (!refcount_inc_not_zero(&nbd->config_refs)) {
+       config = nbd_get_config_unlocked(nbd);
+       if (!config) {
                cmd->status = BLK_STS_TIMEOUT;
                __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
                mutex_unlock(&cmd->lock);
                goto done;
        }
-       config = nbd->config;
 
        if (config->num_connections > 1 ||
            (config->num_connections == 1 && nbd->tag_set.timeout)) {
@@ -977,12 +985,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
        struct nbd_sock *nsock;
        int ret;
 
-       if (!refcount_inc_not_zero(&nbd->config_refs)) {
+       config = nbd_get_config_unlocked(nbd);
+       if (!config) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Socks array is empty\n");
                return -EINVAL;
        }
-       config = nbd->config;
 
        if (index >= config->num_connections) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
@@ -1560,6 +1568,7 @@ static int nbd_alloc_and_init_config(struct nbd_device *nbd)
 static int nbd_open(struct gendisk *disk, blk_mode_t mode)
 {
        struct nbd_device *nbd;
+       struct nbd_config *config;
        int ret = 0;
 
        mutex_lock(&nbd_index_mutex);
@@ -1572,7 +1581,9 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
                ret = -ENXIO;
                goto out;
        }
-       if (!refcount_inc_not_zero(&nbd->config_refs)) {
+
+       config = nbd_get_config_unlocked(nbd);
+       if (!config) {
                mutex_lock(&nbd->config_lock);
                if (refcount_inc_not_zero(&nbd->config_refs)) {
                        mutex_unlock(&nbd->config_lock);
@@ -1588,7 +1599,7 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
                mutex_unlock(&nbd->config_lock);
                if (max_part)
                        set_bit(GD_NEED_PART_SCAN, &disk->state);
-       } else if (nbd_disconnected(nbd->config)) {
+       } else if (nbd_disconnected(config)) {
                if (max_part)
                        set_bit(GD_NEED_PART_SCAN, &disk->state);
        }
@@ -2205,7 +2216,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
        }
        mutex_unlock(&nbd_index_mutex);
 
-       if (!refcount_inc_not_zero(&nbd->config_refs)) {
+       config = nbd_get_config_unlocked(nbd);
+       if (!config) {
                dev_err(nbd_to_dev(nbd),
                        "not configured, cannot reconfigure\n");
                nbd_put(nbd);
@@ -2213,7 +2225,6 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
        }
 
        mutex_lock(&nbd->config_lock);
-       config = nbd->config;
        if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
            !nbd->pid) {
                dev_err(nbd_to_dev(nbd),