]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/target/iscsi/iscsi_target.c
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[mirror_ubuntu-hirsute-kernel.git] / drivers / target / iscsi / iscsi_target.c
index 339f97f7085b941ea4f2f92c3030b5fd1544c33f..7ea246a07731e17964e904c34f5fff5f4769774c 100644 (file)
@@ -144,23 +144,24 @@ struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf)
        spin_lock_init(&tiqn->login_stats.lock);
        spin_lock_init(&tiqn->logout_stats.lock);
 
-       if (!idr_pre_get(&tiqn_idr, GFP_KERNEL)) {
-               pr_err("idr_pre_get() for tiqn_idr failed\n");
-               kfree(tiqn);
-               return ERR_PTR(-ENOMEM);
-       }
        tiqn->tiqn_state = TIQN_STATE_ACTIVE;
 
+       idr_preload(GFP_KERNEL);
        spin_lock(&tiqn_lock);
-       ret = idr_get_new(&tiqn_idr, NULL, &tiqn->tiqn_index);
+
+       ret = idr_alloc(&tiqn_idr, NULL, 0, 0, GFP_NOWAIT);
        if (ret < 0) {
-               pr_err("idr_get_new() failed for tiqn->tiqn_index\n");
+               pr_err("idr_alloc() failed for tiqn->tiqn_index\n");
                spin_unlock(&tiqn_lock);
+               idr_preload_end();
                kfree(tiqn);
                return ERR_PTR(ret);
        }
+       tiqn->tiqn_index = ret;
        list_add_tail(&tiqn->tiqn_list, &g_tiqn_list);
+
        spin_unlock(&tiqn_lock);
+       idr_preload_end();
 
        pr_debug("CORE[0] - Added iSCSI Target IQN: %s\n", tiqn->tiqn);
 
@@ -264,16 +265,50 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
        return 0;
 }
 
-static struct iscsi_np *iscsit_get_np(
+bool iscsit_check_np_match(
        struct __kernel_sockaddr_storage *sockaddr,
+       struct iscsi_np *np,
        int network_transport)
 {
        struct sockaddr_in *sock_in, *sock_in_e;
        struct sockaddr_in6 *sock_in6, *sock_in6_e;
-       struct iscsi_np *np;
-       int ip_match = 0;
+       bool ip_match = false;
        u16 port;
 
+       if (sockaddr->ss_family == AF_INET6) {
+               sock_in6 = (struct sockaddr_in6 *)sockaddr;
+               sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
+
+               if (!memcmp(&sock_in6->sin6_addr.in6_u,
+                           &sock_in6_e->sin6_addr.in6_u,
+                           sizeof(struct in6_addr)))
+                       ip_match = true;
+
+               port = ntohs(sock_in6->sin6_port);
+       } else {
+               sock_in = (struct sockaddr_in *)sockaddr;
+               sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
+
+               if (sock_in->sin_addr.s_addr == sock_in_e->sin_addr.s_addr)
+                       ip_match = true;
+
+               port = ntohs(sock_in->sin_port);
+       }
+
+       if ((ip_match == true) && (np->np_port == port) &&
+           (np->np_network_transport == network_transport))
+               return true;
+
+       return false;
+}
+
+static struct iscsi_np *iscsit_get_np(
+       struct __kernel_sockaddr_storage *sockaddr,
+       int network_transport)
+{
+       struct iscsi_np *np;
+       bool match;
+
        spin_lock_bh(&np_lock);
        list_for_each_entry(np, &g_np_list, np_list) {
                spin_lock(&np->np_thread_lock);
@@ -282,29 +317,8 @@ static struct iscsi_np *iscsit_get_np(
                        continue;
                }
 
-               if (sockaddr->ss_family == AF_INET6) {
-                       sock_in6 = (struct sockaddr_in6 *)sockaddr;
-                       sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
-
-                       if (!memcmp(&sock_in6->sin6_addr.in6_u,
-                                   &sock_in6_e->sin6_addr.in6_u,
-                                   sizeof(struct in6_addr)))
-                               ip_match = 1;
-
-                       port = ntohs(sock_in6->sin6_port);
-               } else {
-                       sock_in = (struct sockaddr_in *)sockaddr;
-                       sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
-
-                       if (sock_in->sin_addr.s_addr ==
-                           sock_in_e->sin_addr.s_addr)
-                               ip_match = 1;
-
-                       port = ntohs(sock_in->sin_port);
-               }
-
-               if ((ip_match == 1) && (np->np_port == port) &&
-                   (np->np_network_transport == network_transport)) {
+               match = iscsit_check_np_match(sockaddr, np, network_transport);
+               if (match == true) {
                        /*
                         * Increment the np_exports reference count now to
                         * prevent iscsit_del_np() below from being called
@@ -3570,6 +3584,10 @@ check_rsp_state:
                                spin_lock_bh(&cmd->istate_lock);
                                cmd->i_state = ISTATE_SENT_STATUS;
                                spin_unlock_bh(&cmd->istate_lock);
+
+                               if (atomic_read(&conn->check_immediate_queue))
+                                       return 1;
+
                                continue;
                        } else if (ret == 2) {
                                /* Still must send status,
@@ -3659,7 +3677,7 @@ check_rsp_state:
                }
 
                if (atomic_read(&conn->check_immediate_queue))
-                       break;
+                       return 1;
        }
 
        return 0;
@@ -3703,12 +3721,15 @@ restart:
                     signal_pending(current))
                        goto transport_err;
 
+get_immediate:
                ret = handle_immediate_queue(conn);
                if (ret < 0)
                        goto transport_err;
 
                ret = handle_response_queue(conn);
-               if (ret == -EAGAIN)
+               if (ret == 1)
+                       goto get_immediate;
+               else if (ret == -EAGAIN)
                        goto restart;
                else if (ret < 0)
                        goto transport_err;