aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c174
1 files changed, 127 insertions, 47 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 0a2ce7b6325c..783e33c65eb7 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -37,7 +37,6 @@
37#define ISCSI_TRANSPORT_VERSION "2.0-870" 37#define ISCSI_TRANSPORT_VERSION "2.0-870"
38 38
39struct iscsi_internal { 39struct iscsi_internal {
40 int daemon_pid;
41 struct scsi_transport_template t; 40 struct scsi_transport_template t;
42 struct iscsi_transport *iscsi_transport; 41 struct iscsi_transport *iscsi_transport;
43 struct list_head list; 42 struct list_head list;
@@ -693,6 +692,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
693 "Too many iscsi targets. Max " 692 "Too many iscsi targets. Max "
694 "number of targets is %d.\n", 693 "number of targets is %d.\n",
695 ISCSI_MAX_TARGET - 1); 694 ISCSI_MAX_TARGET - 1);
695 err = -EOVERFLOW;
696 goto release_host; 696 goto release_host;
697 } 697 }
698 } 698 }
@@ -938,23 +938,9 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
938} 938}
939 939
940static int 940static int
941iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) 941iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
942{ 942{
943 return netlink_broadcast(nls, skb, 0, 1, gfp); 943 return nlmsg_multicast(nls, skb, 0, group, gfp);
944}
945
946static int
947iscsi_unicast_skb(struct sk_buff *skb, int pid)
948{
949 int rc;
950
951 rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
952 if (rc < 0) {
953 printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
954 return rc;
955 }
956
957 return 0;
958} 944}
959 945
960int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, 946int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
@@ -980,7 +966,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
980 return -ENOMEM; 966 return -ENOMEM;
981 } 967 }
982 968
983 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 969 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
984 ev = NLMSG_DATA(nlh); 970 ev = NLMSG_DATA(nlh);
985 memset(ev, 0, sizeof(*ev)); 971 memset(ev, 0, sizeof(*ev));
986 ev->transport_handle = iscsi_handle(conn->transport); 972 ev->transport_handle = iscsi_handle(conn->transport);
@@ -991,10 +977,45 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
991 memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); 977 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
992 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); 978 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
993 979
994 return iscsi_unicast_skb(skb, priv->daemon_pid); 980 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
995} 981}
996EXPORT_SYMBOL_GPL(iscsi_recv_pdu); 982EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
997 983
984int iscsi_offload_mesg(struct Scsi_Host *shost,
985 struct iscsi_transport *transport, uint32_t type,
986 char *data, uint16_t data_size)
987{
988 struct nlmsghdr *nlh;
989 struct sk_buff *skb;
990 struct iscsi_uevent *ev;
991 int len = NLMSG_SPACE(sizeof(*ev) + data_size);
992
993 skb = alloc_skb(len, GFP_NOIO);
994 if (!skb) {
995 printk(KERN_ERR "can not deliver iscsi offload message:OOM\n");
996 return -ENOMEM;
997 }
998
999 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1000 ev = NLMSG_DATA(nlh);
1001 memset(ev, 0, sizeof(*ev));
1002 ev->type = type;
1003 ev->transport_handle = iscsi_handle(transport);
1004 switch (type) {
1005 case ISCSI_KEVENT_PATH_REQ:
1006 ev->r.req_path.host_no = shost->host_no;
1007 break;
1008 case ISCSI_KEVENT_IF_DOWN:
1009 ev->r.notify_if_down.host_no = shost->host_no;
1010 break;
1011 }
1012
1013 memcpy((char *)ev + sizeof(*ev), data, data_size);
1014
1015 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO);
1016}
1017EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
1018
998void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) 1019void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
999{ 1020{
1000 struct nlmsghdr *nlh; 1021 struct nlmsghdr *nlh;
@@ -1014,7 +1035,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1014 return; 1035 return;
1015 } 1036 }
1016 1037
1017 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 1038 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1018 ev = NLMSG_DATA(nlh); 1039 ev = NLMSG_DATA(nlh);
1019 ev->transport_handle = iscsi_handle(conn->transport); 1040 ev->transport_handle = iscsi_handle(conn->transport);
1020 ev->type = ISCSI_KEVENT_CONN_ERROR; 1041 ev->type = ISCSI_KEVENT_CONN_ERROR;
@@ -1022,7 +1043,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1022 ev->r.connerror.cid = conn->cid; 1043 ev->r.connerror.cid = conn->cid;
1023 ev->r.connerror.sid = iscsi_conn_get_sid(conn); 1044 ev->r.connerror.sid = iscsi_conn_get_sid(conn);
1024 1045
1025 iscsi_broadcast_skb(skb, GFP_ATOMIC); 1046 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
1026 1047
1027 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", 1048 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n",
1028 error); 1049 error);
@@ -1030,8 +1051,8 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1030EXPORT_SYMBOL_GPL(iscsi_conn_error_event); 1051EXPORT_SYMBOL_GPL(iscsi_conn_error_event);
1031 1052
1032static int 1053static int
1033iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, 1054iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
1034 void *payload, int size) 1055 void *payload, int size)
1035{ 1056{
1036 struct sk_buff *skb; 1057 struct sk_buff *skb;
1037 struct nlmsghdr *nlh; 1058 struct nlmsghdr *nlh;
@@ -1045,10 +1066,10 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
1045 return -ENOMEM; 1066 return -ENOMEM;
1046 } 1067 }
1047 1068
1048 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); 1069 nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
1049 nlh->nlmsg_flags = flags; 1070 nlh->nlmsg_flags = flags;
1050 memcpy(NLMSG_DATA(nlh), payload, size); 1071 memcpy(NLMSG_DATA(nlh), payload, size);
1051 return iscsi_unicast_skb(skb, pid); 1072 return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
1052} 1073}
1053 1074
1054static int 1075static int
@@ -1085,7 +1106,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
1085 return -ENOMEM; 1106 return -ENOMEM;
1086 } 1107 }
1087 1108
1088 nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0, 1109 nlhstat = __nlmsg_put(skbstat, 0, 0, 0,
1089 (len - sizeof(*nlhstat)), 0); 1110 (len - sizeof(*nlhstat)), 0);
1090 evstat = NLMSG_DATA(nlhstat); 1111 evstat = NLMSG_DATA(nlhstat);
1091 memset(evstat, 0, sizeof(*evstat)); 1112 memset(evstat, 0, sizeof(*evstat));
@@ -1109,7 +1130,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
1109 skb_trim(skbstat, NLMSG_ALIGN(actual_size)); 1130 skb_trim(skbstat, NLMSG_ALIGN(actual_size));
1110 nlhstat->nlmsg_len = actual_size; 1131 nlhstat->nlmsg_len = actual_size;
1111 1132
1112 err = iscsi_unicast_skb(skbstat, priv->daemon_pid); 1133 err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID,
1134 GFP_ATOMIC);
1113 } while (err < 0 && err != -ECONNREFUSED); 1135 } while (err < 0 && err != -ECONNREFUSED);
1114 1136
1115 return err; 1137 return err;
@@ -1143,7 +1165,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
1143 return -ENOMEM; 1165 return -ENOMEM;
1144 } 1166 }
1145 1167
1146 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 1168 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1147 ev = NLMSG_DATA(nlh); 1169 ev = NLMSG_DATA(nlh);
1148 ev->transport_handle = iscsi_handle(session->transport); 1170 ev->transport_handle = iscsi_handle(session->transport);
1149 1171
@@ -1172,7 +1194,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
1172 * this will occur if the daemon is not up, so we just warn 1194 * this will occur if the daemon is not up, so we just warn
1173 * the user and when the daemon is restarted it will handle it 1195 * the user and when the daemon is restarted it will handle it
1174 */ 1196 */
1175 rc = iscsi_broadcast_skb(skb, GFP_KERNEL); 1197 rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
1176 if (rc == -ESRCH) 1198 if (rc == -ESRCH)
1177 iscsi_cls_session_printk(KERN_ERR, session, 1199 iscsi_cls_session_printk(KERN_ERR, session,
1178 "Cannot notify userspace of session " 1200 "Cannot notify userspace of session "
@@ -1268,26 +1290,54 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
1268 return err; 1290 return err;
1269} 1291}
1270 1292
1293static int iscsi_if_ep_connect(struct iscsi_transport *transport,
1294 struct iscsi_uevent *ev, int msg_type)
1295{
1296 struct iscsi_endpoint *ep;
1297 struct sockaddr *dst_addr;
1298 struct Scsi_Host *shost = NULL;
1299 int non_blocking, err = 0;
1300
1301 if (!transport->ep_connect)
1302 return -EINVAL;
1303
1304 if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) {
1305 shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no);
1306 if (!shost) {
1307 printk(KERN_ERR "ep connect failed. Could not find "
1308 "host no %u\n",
1309 ev->u.ep_connect_through_host.host_no);
1310 return -ENODEV;
1311 }
1312 non_blocking = ev->u.ep_connect_through_host.non_blocking;
1313 } else
1314 non_blocking = ev->u.ep_connect.non_blocking;
1315
1316 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
1317 ep = transport->ep_connect(shost, dst_addr, non_blocking);
1318 if (IS_ERR(ep)) {
1319 err = PTR_ERR(ep);
1320 goto release_host;
1321 }
1322
1323 ev->r.ep_connect_ret.handle = ep->id;
1324release_host:
1325 if (shost)
1326 scsi_host_put(shost);
1327 return err;
1328}
1329
1271static int 1330static int
1272iscsi_if_transport_ep(struct iscsi_transport *transport, 1331iscsi_if_transport_ep(struct iscsi_transport *transport,
1273 struct iscsi_uevent *ev, int msg_type) 1332 struct iscsi_uevent *ev, int msg_type)
1274{ 1333{
1275 struct iscsi_endpoint *ep; 1334 struct iscsi_endpoint *ep;
1276 struct sockaddr *dst_addr;
1277 int rc = 0; 1335 int rc = 0;
1278 1336
1279 switch (msg_type) { 1337 switch (msg_type) {
1338 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
1280 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: 1339 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
1281 if (!transport->ep_connect) 1340 rc = iscsi_if_ep_connect(transport, ev, msg_type);
1282 return -EINVAL;
1283
1284 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
1285 ep = transport->ep_connect(dst_addr,
1286 ev->u.ep_connect.non_blocking);
1287 if (IS_ERR(ep))
1288 return PTR_ERR(ep);
1289
1290 ev->r.ep_connect_ret.handle = ep->id;
1291 break; 1341 break;
1292 case ISCSI_UEVENT_TRANSPORT_EP_POLL: 1342 case ISCSI_UEVENT_TRANSPORT_EP_POLL:
1293 if (!transport->ep_poll) 1343 if (!transport->ep_poll)
@@ -1365,7 +1415,31 @@ iscsi_set_host_param(struct iscsi_transport *transport,
1365} 1415}
1366 1416
1367static int 1417static int
1368iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 1418iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
1419{
1420 struct Scsi_Host *shost;
1421 struct iscsi_path *params;
1422 int err;
1423
1424 if (!transport->set_path)
1425 return -ENOSYS;
1426
1427 shost = scsi_host_lookup(ev->u.set_path.host_no);
1428 if (!shost) {
1429 printk(KERN_ERR "set path could not find host no %u\n",
1430 ev->u.set_path.host_no);
1431 return -ENODEV;
1432 }
1433
1434 params = (struct iscsi_path *)((char *)ev + sizeof(*ev));
1435 err = transport->set_path(shost, params);
1436
1437 scsi_host_put(shost);
1438 return err;
1439}
1440
1441static int
1442iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1369{ 1443{
1370 int err = 0; 1444 int err = 0;
1371 struct iscsi_uevent *ev = NLMSG_DATA(nlh); 1445 struct iscsi_uevent *ev = NLMSG_DATA(nlh);
@@ -1375,6 +1449,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1375 struct iscsi_cls_conn *conn; 1449 struct iscsi_cls_conn *conn;
1376 struct iscsi_endpoint *ep = NULL; 1450 struct iscsi_endpoint *ep = NULL;
1377 1451
1452 if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE)
1453 *group = ISCSI_NL_GRP_UIP;
1454 else
1455 *group = ISCSI_NL_GRP_ISCSID;
1456
1378 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); 1457 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
1379 if (!priv) 1458 if (!priv)
1380 return -EINVAL; 1459 return -EINVAL;
@@ -1383,8 +1462,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1383 if (!try_module_get(transport->owner)) 1462 if (!try_module_get(transport->owner))
1384 return -EINVAL; 1463 return -EINVAL;
1385 1464
1386 priv->daemon_pid = NETLINK_CREDS(skb)->pid;
1387
1388 switch (nlh->nlmsg_type) { 1465 switch (nlh->nlmsg_type) {
1389 case ISCSI_UEVENT_CREATE_SESSION: 1466 case ISCSI_UEVENT_CREATE_SESSION:
1390 err = iscsi_if_create_session(priv, ep, ev, 1467 err = iscsi_if_create_session(priv, ep, ev,
@@ -1469,6 +1546,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1469 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: 1546 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
1470 case ISCSI_UEVENT_TRANSPORT_EP_POLL: 1547 case ISCSI_UEVENT_TRANSPORT_EP_POLL:
1471 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: 1548 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
1549 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
1472 err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); 1550 err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
1473 break; 1551 break;
1474 case ISCSI_UEVENT_TGT_DSCVR: 1552 case ISCSI_UEVENT_TGT_DSCVR:
@@ -1477,6 +1555,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1477 case ISCSI_UEVENT_SET_HOST_PARAM: 1555 case ISCSI_UEVENT_SET_HOST_PARAM:
1478 err = iscsi_set_host_param(transport, ev); 1556 err = iscsi_set_host_param(transport, ev);
1479 break; 1557 break;
1558 case ISCSI_UEVENT_PATH_UPDATE:
1559 err = iscsi_set_path(transport, ev);
1560 break;
1480 default: 1561 default:
1481 err = -ENOSYS; 1562 err = -ENOSYS;
1482 break; 1563 break;
@@ -1499,6 +1580,7 @@ iscsi_if_rx(struct sk_buff *skb)
1499 uint32_t rlen; 1580 uint32_t rlen;
1500 struct nlmsghdr *nlh; 1581 struct nlmsghdr *nlh;
1501 struct iscsi_uevent *ev; 1582 struct iscsi_uevent *ev;
1583 uint32_t group;
1502 1584
1503 nlh = nlmsg_hdr(skb); 1585 nlh = nlmsg_hdr(skb);
1504 if (nlh->nlmsg_len < sizeof(*nlh) || 1586 if (nlh->nlmsg_len < sizeof(*nlh) ||
@@ -1511,7 +1593,7 @@ iscsi_if_rx(struct sk_buff *skb)
1511 if (rlen > skb->len) 1593 if (rlen > skb->len)
1512 rlen = skb->len; 1594 rlen = skb->len;
1513 1595
1514 err = iscsi_if_recv_msg(skb, nlh); 1596 err = iscsi_if_recv_msg(skb, nlh, &group);
1515 if (err) { 1597 if (err) {
1516 ev->type = ISCSI_KEVENT_IF_ERROR; 1598 ev->type = ISCSI_KEVENT_IF_ERROR;
1517 ev->iferror = err; 1599 ev->iferror = err;
@@ -1525,8 +1607,7 @@ iscsi_if_rx(struct sk_buff *skb)
1525 */ 1607 */
1526 if (ev->type == ISCSI_UEVENT_GET_STATS && !err) 1608 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
1527 break; 1609 break;
1528 err = iscsi_if_send_reply( 1610 err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
1529 NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
1530 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); 1611 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
1531 } while (err < 0 && err != -ECONNREFUSED); 1612 } while (err < 0 && err != -ECONNREFUSED);
1532 skb_pull(skb, rlen); 1613 skb_pull(skb, rlen);
@@ -1774,7 +1855,6 @@ iscsi_register_transport(struct iscsi_transport *tt)
1774 if (!priv) 1855 if (!priv)
1775 return NULL; 1856 return NULL;
1776 INIT_LIST_HEAD(&priv->list); 1857 INIT_LIST_HEAD(&priv->list);
1777 priv->daemon_pid = -1;
1778 priv->iscsi_transport = tt; 1858 priv->iscsi_transport = tt;
1779 priv->t.user_scan = iscsi_user_scan; 1859 priv->t.user_scan = iscsi_user_scan;
1780 priv->t.create_work_queue = 1; 1860 priv->t.create_work_queue = 1;