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.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index d69a53aa406f..f3e664628d7a 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;
@@ -938,23 +937,9 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
938} 937}
939 938
940static int 939static int
941iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) 940iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
942{ 941{
943 return netlink_broadcast(nls, skb, 0, 1, gfp); 942 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} 943}
959 944
960int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, 945int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
@@ -980,7 +965,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
980 return -ENOMEM; 965 return -ENOMEM;
981 } 966 }
982 967
983 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 968 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
984 ev = NLMSG_DATA(nlh); 969 ev = NLMSG_DATA(nlh);
985 memset(ev, 0, sizeof(*ev)); 970 memset(ev, 0, sizeof(*ev));
986 ev->transport_handle = iscsi_handle(conn->transport); 971 ev->transport_handle = iscsi_handle(conn->transport);
@@ -991,10 +976,45 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
991 memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); 976 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
992 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); 977 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
993 978
994 return iscsi_unicast_skb(skb, priv->daemon_pid); 979 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
995} 980}
996EXPORT_SYMBOL_GPL(iscsi_recv_pdu); 981EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
997 982
983int iscsi_offload_mesg(struct Scsi_Host *shost,
984 struct iscsi_transport *transport, uint32_t type,
985 char *data, uint16_t data_size)
986{
987 struct nlmsghdr *nlh;
988 struct sk_buff *skb;
989 struct iscsi_uevent *ev;
990 int len = NLMSG_SPACE(sizeof(*ev) + data_size);
991
992 skb = alloc_skb(len, GFP_NOIO);
993 if (!skb) {
994 printk(KERN_ERR "can not deliver iscsi offload message:OOM\n");
995 return -ENOMEM;
996 }
997
998 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
999 ev = NLMSG_DATA(nlh);
1000 memset(ev, 0, sizeof(*ev));
1001 ev->type = type;
1002 ev->transport_handle = iscsi_handle(transport);
1003 switch (type) {
1004 case ISCSI_KEVENT_PATH_REQ:
1005 ev->r.req_path.host_no = shost->host_no;
1006 break;
1007 case ISCSI_KEVENT_IF_DOWN:
1008 ev->r.notify_if_down.host_no = shost->host_no;
1009 break;
1010 }
1011
1012 memcpy((char *)ev + sizeof(*ev), data, data_size);
1013
1014 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO);
1015}
1016EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
1017
998void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) 1018void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
999{ 1019{
1000 struct nlmsghdr *nlh; 1020 struct nlmsghdr *nlh;
@@ -1014,7 +1034,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1014 return; 1034 return;
1015 } 1035 }
1016 1036
1017 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 1037 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1018 ev = NLMSG_DATA(nlh); 1038 ev = NLMSG_DATA(nlh);
1019 ev->transport_handle = iscsi_handle(conn->transport); 1039 ev->transport_handle = iscsi_handle(conn->transport);
1020 ev->type = ISCSI_KEVENT_CONN_ERROR; 1040 ev->type = ISCSI_KEVENT_CONN_ERROR;
@@ -1022,7 +1042,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1022 ev->r.connerror.cid = conn->cid; 1042 ev->r.connerror.cid = conn->cid;
1023 ev->r.connerror.sid = iscsi_conn_get_sid(conn); 1043 ev->r.connerror.sid = iscsi_conn_get_sid(conn);
1024 1044
1025 iscsi_broadcast_skb(skb, GFP_ATOMIC); 1045 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
1026 1046
1027 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", 1047 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n",
1028 error); 1048 error);
@@ -1030,8 +1050,8 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
1030EXPORT_SYMBOL_GPL(iscsi_conn_error_event); 1050EXPORT_SYMBOL_GPL(iscsi_conn_error_event);
1031 1051
1032static int 1052static int
1033iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, 1053iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
1034 void *payload, int size) 1054 void *payload, int size)
1035{ 1055{
1036 struct sk_buff *skb; 1056 struct sk_buff *skb;
1037 struct nlmsghdr *nlh; 1057 struct nlmsghdr *nlh;
@@ -1045,10 +1065,10 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
1045 return -ENOMEM; 1065 return -ENOMEM;
1046 } 1066 }
1047 1067
1048 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); 1068 nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
1049 nlh->nlmsg_flags = flags; 1069 nlh->nlmsg_flags = flags;
1050 memcpy(NLMSG_DATA(nlh), payload, size); 1070 memcpy(NLMSG_DATA(nlh), payload, size);
1051 return iscsi_unicast_skb(skb, pid); 1071 return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
1052} 1072}
1053 1073
1054static int 1074static int
@@ -1085,7 +1105,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
1085 return -ENOMEM; 1105 return -ENOMEM;
1086 } 1106 }
1087 1107
1088 nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0, 1108 nlhstat = __nlmsg_put(skbstat, 0, 0, 0,
1089 (len - sizeof(*nlhstat)), 0); 1109 (len - sizeof(*nlhstat)), 0);
1090 evstat = NLMSG_DATA(nlhstat); 1110 evstat = NLMSG_DATA(nlhstat);
1091 memset(evstat, 0, sizeof(*evstat)); 1111 memset(evstat, 0, sizeof(*evstat));
@@ -1109,7 +1129,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
1109 skb_trim(skbstat, NLMSG_ALIGN(actual_size)); 1129 skb_trim(skbstat, NLMSG_ALIGN(actual_size));
1110 nlhstat->nlmsg_len = actual_size; 1130 nlhstat->nlmsg_len = actual_size;
1111 1131
1112 err = iscsi_unicast_skb(skbstat, priv->daemon_pid); 1132 err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID,
1133 GFP_ATOMIC);
1113 } while (err < 0 && err != -ECONNREFUSED); 1134 } while (err < 0 && err != -ECONNREFUSED);
1114 1135
1115 return err; 1136 return err;
@@ -1143,7 +1164,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
1143 return -ENOMEM; 1164 return -ENOMEM;
1144 } 1165 }
1145 1166
1146 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 1167 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1147 ev = NLMSG_DATA(nlh); 1168 ev = NLMSG_DATA(nlh);
1148 ev->transport_handle = iscsi_handle(session->transport); 1169 ev->transport_handle = iscsi_handle(session->transport);
1149 1170
@@ -1172,7 +1193,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
1172 * this will occur if the daemon is not up, so we just warn 1193 * 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 1194 * the user and when the daemon is restarted it will handle it
1174 */ 1195 */
1175 rc = iscsi_broadcast_skb(skb, GFP_KERNEL); 1196 rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
1176 if (rc == -ESRCH) 1197 if (rc == -ESRCH)
1177 iscsi_cls_session_printk(KERN_ERR, session, 1198 iscsi_cls_session_printk(KERN_ERR, session,
1178 "Cannot notify userspace of session " 1199 "Cannot notify userspace of session "
@@ -1393,7 +1414,31 @@ iscsi_set_host_param(struct iscsi_transport *transport,
1393} 1414}
1394 1415
1395static int 1416static int
1396iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 1417iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
1418{
1419 struct Scsi_Host *shost;
1420 struct iscsi_path *params;
1421 int err;
1422
1423 if (!transport->set_path)
1424 return -ENOSYS;
1425
1426 shost = scsi_host_lookup(ev->u.set_path.host_no);
1427 if (!shost) {
1428 printk(KERN_ERR "set path could not find host no %u\n",
1429 ev->u.set_path.host_no);
1430 return -ENODEV;
1431 }
1432
1433 params = (struct iscsi_path *)((char *)ev + sizeof(*ev));
1434 err = transport->set_path(shost, params);
1435
1436 scsi_host_put(shost);
1437 return err;
1438}
1439
1440static int
1441iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1397{ 1442{
1398 int err = 0; 1443 int err = 0;
1399 struct iscsi_uevent *ev = NLMSG_DATA(nlh); 1444 struct iscsi_uevent *ev = NLMSG_DATA(nlh);
@@ -1403,6 +1448,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1403 struct iscsi_cls_conn *conn; 1448 struct iscsi_cls_conn *conn;
1404 struct iscsi_endpoint *ep = NULL; 1449 struct iscsi_endpoint *ep = NULL;
1405 1450
1451 if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE)
1452 *group = ISCSI_NL_GRP_UIP;
1453 else
1454 *group = ISCSI_NL_GRP_ISCSID;
1455
1406 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); 1456 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
1407 if (!priv) 1457 if (!priv)
1408 return -EINVAL; 1458 return -EINVAL;
@@ -1411,8 +1461,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1411 if (!try_module_get(transport->owner)) 1461 if (!try_module_get(transport->owner))
1412 return -EINVAL; 1462 return -EINVAL;
1413 1463
1414 priv->daemon_pid = NETLINK_CREDS(skb)->pid;
1415
1416 switch (nlh->nlmsg_type) { 1464 switch (nlh->nlmsg_type) {
1417 case ISCSI_UEVENT_CREATE_SESSION: 1465 case ISCSI_UEVENT_CREATE_SESSION:
1418 err = iscsi_if_create_session(priv, ep, ev, 1466 err = iscsi_if_create_session(priv, ep, ev,
@@ -1506,6 +1554,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1506 case ISCSI_UEVENT_SET_HOST_PARAM: 1554 case ISCSI_UEVENT_SET_HOST_PARAM:
1507 err = iscsi_set_host_param(transport, ev); 1555 err = iscsi_set_host_param(transport, ev);
1508 break; 1556 break;
1557 case ISCSI_UEVENT_PATH_UPDATE:
1558 err = iscsi_set_path(transport, ev);
1559 break;
1509 default: 1560 default:
1510 err = -ENOSYS; 1561 err = -ENOSYS;
1511 break; 1562 break;
@@ -1528,6 +1579,7 @@ iscsi_if_rx(struct sk_buff *skb)
1528 uint32_t rlen; 1579 uint32_t rlen;
1529 struct nlmsghdr *nlh; 1580 struct nlmsghdr *nlh;
1530 struct iscsi_uevent *ev; 1581 struct iscsi_uevent *ev;
1582 uint32_t group;
1531 1583
1532 nlh = nlmsg_hdr(skb); 1584 nlh = nlmsg_hdr(skb);
1533 if (nlh->nlmsg_len < sizeof(*nlh) || 1585 if (nlh->nlmsg_len < sizeof(*nlh) ||
@@ -1540,7 +1592,7 @@ iscsi_if_rx(struct sk_buff *skb)
1540 if (rlen > skb->len) 1592 if (rlen > skb->len)
1541 rlen = skb->len; 1593 rlen = skb->len;
1542 1594
1543 err = iscsi_if_recv_msg(skb, nlh); 1595 err = iscsi_if_recv_msg(skb, nlh, &group);
1544 if (err) { 1596 if (err) {
1545 ev->type = ISCSI_KEVENT_IF_ERROR; 1597 ev->type = ISCSI_KEVENT_IF_ERROR;
1546 ev->iferror = err; 1598 ev->iferror = err;
@@ -1554,8 +1606,7 @@ iscsi_if_rx(struct sk_buff *skb)
1554 */ 1606 */
1555 if (ev->type == ISCSI_UEVENT_GET_STATS && !err) 1607 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
1556 break; 1608 break;
1557 err = iscsi_if_send_reply( 1609 err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
1558 NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
1559 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); 1610 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
1560 } while (err < 0 && err != -ECONNREFUSED); 1611 } while (err < 0 && err != -ECONNREFUSED);
1561 skb_pull(skb, rlen); 1612 skb_pull(skb, rlen);
@@ -1803,7 +1854,6 @@ iscsi_register_transport(struct iscsi_transport *tt)
1803 if (!priv) 1854 if (!priv)
1804 return NULL; 1855 return NULL;
1805 INIT_LIST_HEAD(&priv->list); 1856 INIT_LIST_HEAD(&priv->list);
1806 priv->daemon_pid = -1;
1807 priv->iscsi_transport = tt; 1857 priv->iscsi_transport = tt;
1808 priv->t.user_scan = iscsi_user_scan; 1858 priv->t.user_scan = iscsi_user_scan;
1809 priv->t.create_work_queue = 1; 1859 priv->t.create_work_queue = 1;