aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c127
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c8
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c4
-rw-r--r--include/scsi/iscsi_if.h2
-rw-r--r--include/scsi/libiscsi.h8
5 files changed, 118 insertions, 31 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,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 315ab691056f..b87b460832ea 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -106,6 +106,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
106 .param_mask = ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS | 106 .param_mask = ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS |
107 ISCSI_TARGET_NAME | ISCSI_TPGT, 107 ISCSI_TARGET_NAME | ISCSI_TPGT,
108 .host_param_mask = ISCSI_HOST_HWADDRESS | 108 .host_param_mask = ISCSI_HOST_HWADDRESS |
109 ISCSI_HOST_IPADDRESS |
109 ISCSI_HOST_INITIATOR_NAME, 110 ISCSI_HOST_INITIATOR_NAME,
110 .sessiondata_size = sizeof(struct ddb_entry), 111 .sessiondata_size = sizeof(struct ddb_entry),
111 .host_template = &qla4xxx_driver_template, 112 .host_template = &qla4xxx_driver_template,
@@ -192,8 +193,13 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
192 case ISCSI_HOST_PARAM_HWADDRESS: 193 case ISCSI_HOST_PARAM_HWADDRESS:
193 len = format_addr(buf, ha->my_mac, MAC_ADDR_LEN); 194 len = format_addr(buf, ha->my_mac, MAC_ADDR_LEN);
194 break; 195 break;
196 case ISCSI_HOST_PARAM_IPADDRESS:
197 len = sprintf(buf, "%d.%d.%d.%d\n", ha->ip_address[0],
198 ha->ip_address[1], ha->ip_address[2],
199 ha->ip_address[3]);
200 break;
195 case ISCSI_HOST_PARAM_INITIATOR_NAME: 201 case ISCSI_HOST_PARAM_INITIATOR_NAME:
196 len = sprintf(buf, ha->name_string); 202 len = sprintf(buf, "%s\n", ha->name_string);
197 break; 203 break;
198 default: 204 default:
199 return -ENOSYS; 205 return -ENOSYS;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 859bd2100856..9b54eea20560 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -32,7 +32,7 @@
32 32
33#define ISCSI_SESSION_ATTRS 15 33#define ISCSI_SESSION_ATTRS 15
34#define ISCSI_CONN_ATTRS 11 34#define ISCSI_CONN_ATTRS 11
35#define ISCSI_HOST_ATTRS 2 35#define ISCSI_HOST_ATTRS 3
36#define ISCSI_TRANSPORT_VERSION "2.0-724" 36#define ISCSI_TRANSPORT_VERSION "2.0-724"
37 37
38struct iscsi_internal { 38struct iscsi_internal {
@@ -1261,6 +1261,7 @@ show_host_param_##param(struct class_device *cdev, char *buf) \
1261static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \ 1261static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \
1262 NULL); 1262 NULL);
1263 1263
1264iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS);
1264iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS); 1265iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS);
1265iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME); 1266iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
1266 1267
@@ -1398,6 +1399,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
1398 priv->t.host_size = sizeof(struct iscsi_host); 1399 priv->t.host_size = sizeof(struct iscsi_host);
1399 transport_container_register(&priv->t.host_attrs); 1400 transport_container_register(&priv->t.host_attrs);
1400 1401
1402 SETUP_HOST_RD_ATTR(ipaddress, ISCSI_HOST_IPADDRESS);
1401 SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS); 1403 SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS);
1402 SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME); 1404 SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME);
1403 BUG_ON(count > ISCSI_HOST_ATTRS); 1405 BUG_ON(count > ISCSI_HOST_ATTRS);
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 81a542506dfe..642998069e00 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -271,11 +271,13 @@ enum iscsi_param {
271enum iscsi_host_param { 271enum iscsi_host_param {
272 ISCSI_HOST_PARAM_HWADDRESS, 272 ISCSI_HOST_PARAM_HWADDRESS,
273 ISCSI_HOST_PARAM_INITIATOR_NAME, 273 ISCSI_HOST_PARAM_INITIATOR_NAME,
274 ISCSI_HOST_PARAM_IPADDRESS,
274 ISCSI_HOST_PARAM_MAX, 275 ISCSI_HOST_PARAM_MAX,
275}; 276};
276 277
277#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS) 278#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS)
278#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME) 279#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME)
280#define ISCSI_HOST_IPADDRESS (1 << ISCSI_HOST_PARAM_IPADDRESS)
279 281
280#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) 282#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
281#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) 283#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 2f303a3b270e..eea33f7b1544 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -72,6 +72,8 @@ struct iscsi_nopin;
72#define ISCSI_AGE_SHIFT 28 72#define ISCSI_AGE_SHIFT 28
73#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) 73#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT)
74 74
75#define ISCSI_ADDRESS_BUF_LEN 64
76
75struct iscsi_mgmt_task { 77struct iscsi_mgmt_task {
76 /* 78 /*
77 * Becuae LLDs allocate their hdr differently, this is a pointer to 79 * Becuae LLDs allocate their hdr differently, this is a pointer to
@@ -174,6 +176,12 @@ struct iscsi_conn {
174 /* values userspace uses to id a conn */ 176 /* values userspace uses to id a conn */
175 int persistent_port; 177 int persistent_port;
176 char *persistent_address; 178 char *persistent_address;
179 /* remote portal currently connected to */
180 int portal_port;
181 char portal_address[ISCSI_ADDRESS_BUF_LEN];
182 /* local address */
183 int local_port;
184 char local_address[ISCSI_ADDRESS_BUF_LEN];
177 185
178 /* MIB-statistics */ 186 /* MIB-statistics */
179 uint64_t txdata_octets; 187 uint64_t txdata_octets;