aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c127
1 files changed, 98 insertions, 29 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7ce177e30a53..da66fb524b5b 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1870,18 +1870,22 @@ tcp_conn_alloc_fail:
1870static void 1870static void
1871iscsi_tcp_release_conn(struct iscsi_conn *conn) 1871iscsi_tcp_release_conn(struct iscsi_conn *conn)
1872{ 1872{
1873 struct iscsi_session *session = conn->session;
1873 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1874 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1875 struct socket *sock = tcp_conn->sock;
1874 1876
1875 if (!tcp_conn->sock) 1877 if (!sock)
1876 return; 1878 return;
1877 1879
1878 sock_hold(tcp_conn->sock->sk); 1880 sock_hold(sock->sk);
1879 iscsi_conn_restore_callbacks(tcp_conn); 1881 iscsi_conn_restore_callbacks(tcp_conn);
1880 sock_put(tcp_conn->sock->sk); 1882 sock_put(sock->sk);
1881 1883
1882 sockfd_put(tcp_conn->sock); 1884 spin_lock_bh(&session->lock);
1883 tcp_conn->sock = NULL; 1885 tcp_conn->sock = NULL;
1884 conn->recv_lock = NULL; 1886 conn->recv_lock = NULL;
1887 spin_unlock_bh(&session->lock);
1888 sockfd_put(sock);
1885} 1889}
1886 1890
1887static void 1891static void
@@ -1912,6 +1916,46 @@ iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
1912 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 1916 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1913} 1917}
1914 1918
1919static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock,
1920 char *buf, int *port,
1921 int (*getname)(struct socket *, struct sockaddr *,
1922 int *addrlen))
1923{
1924 struct sockaddr_storage *addr;
1925 struct sockaddr_in6 *sin6;
1926 struct sockaddr_in *sin;
1927 int rc = 0, len;
1928
1929 addr = kmalloc(GFP_KERNEL, sizeof(*addr));
1930 if (!addr)
1931 return -ENOMEM;
1932
1933 if (getname(sock, (struct sockaddr *) addr, &len)) {
1934 rc = -ENODEV;
1935 goto free_addr;
1936 }
1937
1938 switch (addr->ss_family) {
1939 case AF_INET:
1940 sin = (struct sockaddr_in *)addr;
1941 spin_lock_bh(&conn->session->lock);
1942 sprintf(buf, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
1943 *port = be16_to_cpu(sin->sin_port);
1944 spin_unlock_bh(&conn->session->lock);
1945 break;
1946 case AF_INET6:
1947 sin6 = (struct sockaddr_in6 *)addr;
1948 spin_lock_bh(&conn->session->lock);
1949 sprintf(buf, NIP6_FMT, NIP6(sin6->sin6_addr));
1950 *port = be16_to_cpu(sin6->sin6_port);
1951 spin_unlock_bh(&conn->session->lock);
1952 break;
1953 }
1954free_addr:
1955 kfree(addr);
1956 return rc;
1957}
1958
1915static int 1959static int
1916iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, 1960iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1917 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, 1961 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
@@ -1929,10 +1973,24 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1929 printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err); 1973 printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
1930 return -EEXIST; 1974 return -EEXIST;
1931 } 1975 }
1976 /*
1977 * copy these values now because if we drop the session
1978 * userspace may still want to query the values since we will
1979 * be using them for the reconnect
1980 */
1981 err = iscsi_tcp_get_addr(conn, sock, conn->portal_address,
1982 &conn->portal_port, kernel_getpeername);
1983 if (err)
1984 goto free_socket;
1985
1986 err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
1987 &conn->local_port, kernel_getsockname);
1988 if (err)
1989 goto free_socket;
1932 1990
1933 err = iscsi_conn_bind(cls_session, cls_conn, is_leading); 1991 err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
1934 if (err) 1992 if (err)
1935 return err; 1993 goto free_socket;
1936 1994
1937 /* bind iSCSI connection and socket */ 1995 /* bind iSCSI connection and socket */
1938 tcp_conn->sock = sock; 1996 tcp_conn->sock = sock;
@@ -1956,8 +2014,11 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1956 * set receive state machine into initial state 2014 * set receive state machine into initial state
1957 */ 2015 */
1958 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; 2016 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1959
1960 return 0; 2017 return 0;
2018
2019free_socket:
2020 sockfd_put(sock);
2021 return err;
1961} 2022}
1962 2023
1963/* called with host lock */ 2024/* called with host lock */
@@ -2077,33 +2138,18 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
2077 enum iscsi_param param, char *buf) 2138 enum iscsi_param param, char *buf)
2078{ 2139{
2079 struct iscsi_conn *conn = cls_conn->dd_data; 2140 struct iscsi_conn *conn = cls_conn->dd_data;
2080 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2081 struct inet_sock *inet;
2082 struct ipv6_pinfo *np;
2083 struct sock *sk;
2084 int len; 2141 int len;
2085 2142
2086 switch(param) { 2143 switch(param) {
2087 case ISCSI_PARAM_CONN_PORT: 2144 case ISCSI_PARAM_CONN_PORT:
2088 if (!tcp_conn->sock) 2145 spin_lock_bh(&conn->session->lock);
2089 return -EINVAL; 2146 len = sprintf(buf, "%hu\n", conn->portal_port);
2090 2147 spin_unlock_bh(&conn->session->lock);
2091 inet = inet_sk(tcp_conn->sock->sk);
2092 len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport));
2093 break; 2148 break;
2094 case ISCSI_PARAM_CONN_ADDRESS: 2149 case ISCSI_PARAM_CONN_ADDRESS:
2095 if (!tcp_conn->sock) 2150 spin_lock_bh(&conn->session->lock);
2096 return -EINVAL; 2151 len = sprintf(buf, "%s\n", conn->portal_address);
2097 2152 spin_unlock_bh(&conn->session->lock);
2098 sk = tcp_conn->sock->sk;
2099 if (sk->sk_family == PF_INET) {
2100 inet = inet_sk(sk);
2101 len = sprintf(buf, NIPQUAD_FMT "\n",
2102 NIPQUAD(inet->daddr));
2103 } else {
2104 np = inet6_sk(sk);
2105 len = sprintf(buf, NIP6_FMT "\n", NIP6(np->daddr));
2106 }
2107 break; 2153 break;
2108 default: 2154 default:
2109 return iscsi_conn_get_param(cls_conn, param, buf); 2155 return iscsi_conn_get_param(cls_conn, param, buf);
@@ -2112,6 +2158,29 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
2112 return len; 2158 return len;
2113} 2159}
2114 2160
2161static int
2162iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
2163 char *buf)
2164{
2165 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
2166 int len;
2167
2168 switch (param) {
2169 case ISCSI_HOST_PARAM_IPADDRESS:
2170 spin_lock_bh(&session->lock);
2171 if (!session->leadconn)
2172 len = -ENODEV;
2173 else
2174 len = sprintf(buf, "%s\n",
2175 session->leadconn->local_address);
2176 spin_unlock_bh(&session->lock);
2177 break;
2178 default:
2179 return iscsi_host_get_param(shost, param, buf);
2180 }
2181 return len;
2182}
2183
2115static void 2184static void
2116iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) 2185iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
2117{ 2186{
@@ -2233,7 +2302,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
2233 ISCSI_TARGET_NAME | ISCSI_TPGT | 2302 ISCSI_TARGET_NAME | ISCSI_TPGT |
2234 ISCSI_USERNAME | ISCSI_PASSWORD | 2303 ISCSI_USERNAME | ISCSI_PASSWORD |
2235 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN, 2304 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
2236 .host_param_mask = ISCSI_HOST_HWADDRESS | 2305 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
2237 ISCSI_HOST_INITIATOR_NAME, 2306 ISCSI_HOST_INITIATOR_NAME,
2238 .host_template = &iscsi_sht, 2307 .host_template = &iscsi_sht,
2239 .conndata_size = sizeof(struct iscsi_conn), 2308 .conndata_size = sizeof(struct iscsi_conn),
@@ -2252,7 +2321,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
2252 .start_conn = iscsi_conn_start, 2321 .start_conn = iscsi_conn_start,
2253 .stop_conn = iscsi_tcp_conn_stop, 2322 .stop_conn = iscsi_tcp_conn_stop,
2254 /* iscsi host params */ 2323 /* iscsi host params */
2255 .get_host_param = iscsi_host_get_param, 2324 .get_host_param = iscsi_tcp_host_get_param,
2256 .set_host_param = iscsi_host_set_param, 2325 .set_host_param = iscsi_host_set_param,
2257 /* IO */ 2326 /* IO */
2258 .send_pdu = iscsi_conn_send_pdu, 2327 .send_pdu = iscsi_conn_send_pdu,