aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 8975c10591c3..a48df1449ece 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -270,12 +270,13 @@ struct sock_xprt {
270#define TCP_RCV_COPY_FRAGHDR (1UL << 1) 270#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
271#define TCP_RCV_COPY_XID (1UL << 2) 271#define TCP_RCV_COPY_XID (1UL << 2)
272#define TCP_RCV_COPY_DATA (1UL << 3) 272#define TCP_RCV_COPY_DATA (1UL << 3)
273#define TCP_RCV_COPY_CALLDIR (1UL << 4) 273#define TCP_RCV_READ_CALLDIR (1UL << 4)
274#define TCP_RCV_COPY_CALLDIR (1UL << 5)
274 275
275/* 276/*
276 * TCP RPC flags 277 * TCP RPC flags
277 */ 278 */
278#define TCP_RPC_REPLY (1UL << 5) 279#define TCP_RPC_REPLY (1UL << 6)
279 280
280static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) 281static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
281{ 282{
@@ -997,7 +998,7 @@ static inline void xs_tcp_read_xid(struct sock_xprt *transport, struct xdr_skb_r
997 if (used != len) 998 if (used != len)
998 return; 999 return;
999 transport->tcp_flags &= ~TCP_RCV_COPY_XID; 1000 transport->tcp_flags &= ~TCP_RCV_COPY_XID;
1000 transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; 1001 transport->tcp_flags |= TCP_RCV_READ_CALLDIR;
1001 transport->tcp_copied = 4; 1002 transport->tcp_copied = 4;
1002 dprintk("RPC: reading %s XID %08x\n", 1003 dprintk("RPC: reading %s XID %08x\n",
1003 (transport->tcp_flags & TCP_RPC_REPLY) ? "reply for" 1004 (transport->tcp_flags & TCP_RPC_REPLY) ? "reply for"
@@ -1026,9 +1027,13 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
1026 transport->tcp_offset += used; 1027 transport->tcp_offset += used;
1027 if (used != len) 1028 if (used != len)
1028 return; 1029 return;
1029 transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR; 1030 transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR;
1031 transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
1030 transport->tcp_flags |= TCP_RCV_COPY_DATA; 1032 transport->tcp_flags |= TCP_RCV_COPY_DATA;
1031 transport->tcp_copied += 4; 1033 /*
1034 * We don't yet have the XDR buffer, so we will write the calldir
1035 * out after we get the buffer from the 'struct rpc_rqst'
1036 */
1032 if (ntohl(calldir) == RPC_REPLY) 1037 if (ntohl(calldir) == RPC_REPLY)
1033 transport->tcp_flags |= TCP_RPC_REPLY; 1038 transport->tcp_flags |= TCP_RPC_REPLY;
1034 else 1039 else
@@ -1059,6 +1064,20 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_rea
1059 } 1064 }
1060 1065
1061 rcvbuf = &req->rq_private_buf; 1066 rcvbuf = &req->rq_private_buf;
1067
1068 if (transport->tcp_flags & TCP_RCV_COPY_CALLDIR) {
1069 /*
1070 * Save the RPC direction in the XDR buffer
1071 */
1072 __be32 calldir = transport->tcp_flags & TCP_RPC_REPLY ?
1073 htonl(RPC_REPLY) : 0;
1074
1075 memcpy(rcvbuf->head[0].iov_base + transport->tcp_copied,
1076 &calldir, sizeof(calldir));
1077 transport->tcp_copied += sizeof(calldir);
1078 transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR;
1079 }
1080
1062 len = desc->count; 1081 len = desc->count;
1063 if (len > transport->tcp_reclen - transport->tcp_offset) { 1082 if (len > transport->tcp_reclen - transport->tcp_offset) {
1064 struct xdr_skb_reader my_desc; 1083 struct xdr_skb_reader my_desc;
@@ -1156,7 +1175,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1156 continue; 1175 continue;
1157 } 1176 }
1158 /* Read in the call/reply flag */ 1177 /* Read in the call/reply flag */
1159 if (transport->tcp_flags & TCP_RCV_COPY_CALLDIR) { 1178 if (transport->tcp_flags & TCP_RCV_READ_CALLDIR) {
1160 xs_tcp_read_calldir(transport, &desc); 1179 xs_tcp_read_calldir(transport, &desc);
1161 continue; 1180 continue;
1162 } 1181 }