Whamcloud - gitweb
LU-10391 socklnd: don't deref lnet_hdr in LNDs
[fs/lustre-release.git] / lnet / klnds / socklnd / socklnd_cb.c
index 614b864..3ad0eee 100644 (file)
@@ -425,12 +425,12 @@ ksocknal_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int error)
 
        while ((tx = list_first_entry_or_null(txlist, struct ksock_tx,
                                              tx_list)) != NULL) {
-               if (error && tx->tx_lnetmsg != NULL) {
+               if (error && tx->tx_lnetmsg) {
                        CNETERR("Deleting packet type %d len %d %s->%s\n",
-                               le32_to_cpu(tx->tx_lnetmsg->msg_hdr.type),
-                               le32_to_cpu(tx->tx_lnetmsg->msg_hdr.payload_length),
-                               libcfs_nid2str(le64_to_cpu(tx->tx_lnetmsg->msg_hdr.src_nid)),
-                               libcfs_nid2str(le64_to_cpu(tx->tx_lnetmsg->msg_hdr.dest_nid)));
+                               tx->tx_lnetmsg->msg_type,
+                               tx->tx_lnetmsg->msg_len,
+                               libcfs_nidstr(&tx->tx_lnetmsg->msg_initiator),
+                               libcfs_nidstr(&tx->tx_lnetmsg->msg_target.nid));
                } else if (error) {
                        CNETERR("Deleting noop packet\n");
                }
@@ -770,10 +770,9 @@ ksocknal_queue_tx_locked(struct ksock_tx *tx, struct ksock_conn *conn)
        LASSERT(tx->tx_niov >= 1);
        LASSERT(tx->tx_resid == tx->tx_nob);
 
-        CDEBUG (D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n",
-                tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type:
-                                               KSOCK_MSG_NOOP,
-                tx->tx_nob, tx->tx_niov, tx->tx_nkiov);
+       CDEBUG(D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n",
+              tx, tx->tx_lnetmsg ? tx->tx_lnetmsg->msg_type : KSOCK_MSG_NOOP,
+              tx->tx_nob, tx->tx_niov, tx->tx_nkiov);
 
        bufnob = conn->ksnc_sock->sk->sk_wmem_queued;
        spin_lock_bh(&sched->kss_lock);
@@ -982,7 +981,7 @@ ksocknal_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
        /* '1' for consistency with code that checks !mpflag to restore */
        unsigned int mpflag = 1;
        int type = lntmsg->msg_type;
-       struct lnet_processid target;
+       struct lnet_processid *target = &lntmsg->msg_target;
        unsigned int payload_niov = lntmsg->msg_niov;
        struct bio_vec *payload_kiov = lntmsg->msg_kiov;
        unsigned int payload_offset = lntmsg->msg_offset;
@@ -994,11 +993,9 @@ ksocknal_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
        /* NB 'private' is different depending on what we're sending.
         * Just ignore it...
         */
-       target.pid = lntmsg->msg_target.pid;
-       lnet_nid4_to_nid(lntmsg->msg_target.nid, &target.nid);
 
        CDEBUG(D_NET, "sending %u bytes in %d frags to %s\n",
-              payload_nob, payload_niov, libcfs_idstr(&target));
+              payload_nob, payload_niov, libcfs_idstr(target));
 
        LASSERT (payload_nob == 0 || payload_niov > 0);
        LASSERT (payload_niov <= LNET_MAX_IOV);
@@ -1037,7 +1034,7 @@ ksocknal_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
        tx->tx_msg.ksm_zc_cookies[1] = 0;
 
        /* The first fragment will be set later in pro_pack */
-       rc = ksocknal_launch_packet(ni, tx, &target);
+       rc = ksocknal_launch_packet(ni, tx, target);
        /*
         * We can't test lntsmg->msg_vmflush again as lntmsg may
         * have been freed.
@@ -1082,14 +1079,15 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
                switch (conn->ksnc_proto->pro_version) {
                case  KSOCK_PROTO_V2:
                case  KSOCK_PROTO_V3:
-                        conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
+                       conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
                        conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
-                        conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg;
+                       conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg;
 
-                       conn->ksnc_rx_nob_wanted = offsetof(struct ksock_msg, ksm_u);
-                       conn->ksnc_rx_nob_left = offsetof(struct ksock_msg, ksm_u);
-                       conn->ksnc_rx_iov[0].iov_len  = offsetof(struct ksock_msg, ksm_u);
-                        break;
+                       conn->ksnc_rx_nob_wanted = sizeof(struct ksock_msg_hdr);
+                       conn->ksnc_rx_nob_left = sizeof(struct ksock_msg_hdr);
+                       conn->ksnc_rx_iov[0].iov_len =
+                               sizeof(struct ksock_msg_hdr);
+                       break;
 
                case KSOCK_PROTO_V1:
                        /* Receiving bare struct lnet_hdr */
@@ -1198,16 +1196,6 @@ ksocknal_process_receive(struct ksock_conn *conn,
                        __swab64s(&conn->ksnc_msg.ksm_zc_cookies[1]);
                }
 
-               if (conn->ksnc_msg.ksm_type != KSOCK_MSG_NOOP &&
-                   conn->ksnc_msg.ksm_type != KSOCK_MSG_LNET) {
-                       CERROR("%s: Unknown message type: %x\n",
-                              libcfs_idstr(&conn->ksnc_peer->ksnp_id),
-                              conn->ksnc_msg.ksm_type);
-                       ksocknal_new_packet(conn, 0);
-                       ksocknal_close_conn_and_siblings(conn, -EPROTO);
-                       return (-EPROTO);
-               }
-
                if (conn->ksnc_msg.ksm_type == KSOCK_MSG_NOOP &&
                    conn->ksnc_msg.ksm_csum != 0 &&     /* has checksum */
                    conn->ksnc_msg.ksm_csum != conn->ksnc_rx_csum) {
@@ -1242,25 +1230,36 @@ ksocknal_process_receive(struct ksock_conn *conn,
                        }
                }
 
-               if (conn->ksnc_msg.ksm_type == KSOCK_MSG_NOOP) {
+               switch (conn->ksnc_msg.ksm_type) {
+               case KSOCK_MSG_NOOP:
                        ksocknal_new_packet(conn, 0);
                        return 0;       /* NOOP is done and just return */
-               }
 
-               conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
-               conn->ksnc_rx_nob_wanted = sizeof(struct ksock_lnet_msg);
-               conn->ksnc_rx_nob_left = sizeof(struct ksock_lnet_msg);
+               case KSOCK_MSG_LNET:
 
-               conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
-               conn->ksnc_rx_iov[0].iov_base =
-                       (char *)&conn->ksnc_msg.ksm_u.lnetmsg;
-               conn->ksnc_rx_iov[0].iov_len  = sizeof(struct ksock_lnet_msg);
+                       conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
+                       conn->ksnc_rx_nob_wanted = sizeof(struct lnet_hdr);
+                       conn->ksnc_rx_nob_left = sizeof(struct lnet_hdr);
 
-               conn->ksnc_rx_niov = 1;
-               conn->ksnc_rx_kiov = NULL;
-               conn->ksnc_rx_nkiov = 0;
+                       conn->ksnc_rx_iov = conn->ksnc_rx_iov_space.iov;
+                       conn->ksnc_rx_iov[0].iov_base =
+                               (void *)&conn->ksnc_msg.ksm_u.lnetmsg;
+                       conn->ksnc_rx_iov[0].iov_len = sizeof(struct lnet_hdr);
+
+                       conn->ksnc_rx_niov = 1;
+                       conn->ksnc_rx_kiov = NULL;
+                       conn->ksnc_rx_nkiov = 0;
 
-               goto again;     /* read lnet header now */
+                       goto again;     /* read lnet header now */
+
+               default:
+                       CERROR("%s: Unknown message type: %x\n",
+                              libcfs_idstr(&conn->ksnc_peer->ksnp_id),
+                              conn->ksnc_msg.ksm_type);
+                       ksocknal_new_packet(conn, 0);
+                       ksocknal_close_conn_and_siblings(conn, -EPROTO);
+                       return -EPROTO;
+               }
 
        case SOCKNAL_RX_LNET_HEADER:
                /* unpack message header */
@@ -1268,7 +1267,7 @@ ksocknal_process_receive(struct ksock_conn *conn,
 
                if ((conn->ksnc_peer->ksnp_id.pid & LNET_PID_USERFLAG) != 0) {
                        /* Userspace peer_ni */
-                       lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr;
+                       lhdr = &conn->ksnc_msg.ksm_u.lnetmsg;
                        id = &conn->ksnc_peer->ksnp_id;
 
                        /* Substitute process ID assigned at connection time */
@@ -1280,7 +1279,7 @@ ksocknal_process_receive(struct ksock_conn *conn,
                ksocknal_conn_addref(conn);     /* ++ref while parsing */
 
                rc = lnet_parse(conn->ksnc_peer->ksnp_ni,
-                               &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr,
+                               &conn->ksnc_msg.ksm_u.lnetmsg,
                                lnet_nid_to_nid4(&conn->ksnc_peer->ksnp_id.nid),
                                conn, 0);
                if (rc < 0) {
@@ -1317,7 +1316,7 @@ ksocknal_process_receive(struct ksock_conn *conn,
                if (rc == 0 && conn->ksnc_msg.ksm_zc_cookies[0] != 0) {
                        LASSERT(conn->ksnc_proto != &ksocknal_protocol_v1x);
 
-                       lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr;
+                       lhdr = &conn->ksnc_msg.ksm_u.lnetmsg;
                        id = &conn->ksnc_peer->ksnp_id;
 
                        rc = conn->ksnc_proto->pro_handle_zcreq(