xprtsock.c (f4a2e418bfd03a1f25f515e8a92ecd584d96cfc1) | xprtsock.c (44b98efdd0a205bdca2cb63493350d06ff6804b1) |
---|---|
1/* 2 * linux/net/sunrpc/xprtsock.c 3 * 4 * Client-side transport implementation for sockets. 5 * 6 * TCP callback races fixes (C) 1998 Red Hat 7 * TCP send fixes (C) 1998 Red Hat 8 * TCP NFS related read + write fixes --- 20 unchanged lines hidden (view full) --- 29#include <linux/net.h> 30#include <linux/mm.h> 31#include <linux/udp.h> 32#include <linux/tcp.h> 33#include <linux/sunrpc/clnt.h> 34#include <linux/sunrpc/sched.h> 35#include <linux/sunrpc/xprtsock.h> 36#include <linux/file.h> | 1/* 2 * linux/net/sunrpc/xprtsock.c 3 * 4 * Client-side transport implementation for sockets. 5 * 6 * TCP callback races fixes (C) 1998 Red Hat 7 * TCP send fixes (C) 1998 Red Hat 8 * TCP NFS related read + write fixes --- 20 unchanged lines hidden (view full) --- 29#include <linux/net.h> 30#include <linux/mm.h> 31#include <linux/udp.h> 32#include <linux/tcp.h> 33#include <linux/sunrpc/clnt.h> 34#include <linux/sunrpc/sched.h> 35#include <linux/sunrpc/xprtsock.h> 36#include <linux/file.h> |
37#ifdef CONFIG_NFS_V4_1 38#include <linux/sunrpc/bc_xprt.h> 39#endif |
|
37 38#include <net/sock.h> 39#include <net/checksum.h> 40#include <net/udp.h> 41#include <net/tcp.h> 42 43/* 44 * xprtsock tunables --- 994 unchanged lines hidden (view full) --- 1039 else 1040 transport->tcp_flags &= ~TCP_RPC_REPLY; 1041 dprintk("RPC: reading %s CALL/REPLY flag %08x\n", 1042 (transport->tcp_flags & TCP_RPC_REPLY) ? 1043 "reply for" : "request with", calldir); 1044 xs_tcp_check_fraghdr(transport); 1045} 1046 | 40 41#include <net/sock.h> 42#include <net/checksum.h> 43#include <net/udp.h> 44#include <net/tcp.h> 45 46/* 47 * xprtsock tunables --- 994 unchanged lines hidden (view full) --- 1042 else 1043 transport->tcp_flags &= ~TCP_RPC_REPLY; 1044 dprintk("RPC: reading %s CALL/REPLY flag %08x\n", 1045 (transport->tcp_flags & TCP_RPC_REPLY) ? 1046 "reply for" : "request with", calldir); 1047 xs_tcp_check_fraghdr(transport); 1048} 1049 |
1047static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) | 1050static inline void xs_tcp_read_common(struct rpc_xprt *xprt, 1051 struct xdr_skb_reader *desc, 1052 struct rpc_rqst *req) |
1048{ | 1053{ |
1049 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 1050 struct rpc_rqst *req; | 1054 struct sock_xprt *transport = 1055 container_of(xprt, struct sock_xprt, xprt); |
1051 struct xdr_buf *rcvbuf; 1052 size_t len; 1053 ssize_t r; 1054 | 1056 struct xdr_buf *rcvbuf; 1057 size_t len; 1058 ssize_t r; 1059 |
1055 /* Find and lock the request corresponding to this xid */ 1056 spin_lock(&xprt->transport_lock); 1057 req = xprt_lookup_rqst(xprt, transport->tcp_xid); 1058 if (!req) { 1059 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1060 dprintk("RPC: XID %08x request not found!\n", 1061 ntohl(transport->tcp_xid)); 1062 spin_unlock(&xprt->transport_lock); 1063 return; 1064 } 1065 | |
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; --- 35 unchanged lines hidden (view full) --- 1109 */ 1110 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1111 dprintk("RPC: XID %08x truncated request\n", 1112 ntohl(transport->tcp_xid)); 1113 dprintk("RPC: xprt = %p, tcp_copied = %lu, " 1114 "tcp_offset = %u, tcp_reclen = %u\n", 1115 xprt, transport->tcp_copied, 1116 transport->tcp_offset, transport->tcp_reclen); | 1060 rcvbuf = &req->rq_private_buf; 1061 1062 if (transport->tcp_flags & TCP_RCV_COPY_CALLDIR) { 1063 /* 1064 * Save the RPC direction in the XDR buffer 1065 */ 1066 __be32 calldir = transport->tcp_flags & TCP_RPC_REPLY ? 1067 htonl(RPC_REPLY) : 0; --- 35 unchanged lines hidden (view full) --- 1103 */ 1104 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1105 dprintk("RPC: XID %08x truncated request\n", 1106 ntohl(transport->tcp_xid)); 1107 dprintk("RPC: xprt = %p, tcp_copied = %lu, " 1108 "tcp_offset = %u, tcp_reclen = %u\n", 1109 xprt, transport->tcp_copied, 1110 transport->tcp_offset, transport->tcp_reclen); |
1117 goto out; | 1111 return; |
1118 } 1119 1120 dprintk("RPC: XID %08x read %Zd bytes\n", 1121 ntohl(transport->tcp_xid), r); 1122 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, " 1123 "tcp_reclen = %u\n", xprt, transport->tcp_copied, 1124 transport->tcp_offset, transport->tcp_reclen); 1125 1126 if (transport->tcp_copied == req->rq_private_buf.buflen) 1127 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1128 else if (transport->tcp_offset == transport->tcp_reclen) { 1129 if (transport->tcp_flags & TCP_RCV_LAST_FRAG) 1130 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1131 } 1132 | 1112 } 1113 1114 dprintk("RPC: XID %08x read %Zd bytes\n", 1115 ntohl(transport->tcp_xid), r); 1116 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, " 1117 "tcp_reclen = %u\n", xprt, transport->tcp_copied, 1118 transport->tcp_offset, transport->tcp_reclen); 1119 1120 if (transport->tcp_copied == req->rq_private_buf.buflen) 1121 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1122 else if (transport->tcp_offset == transport->tcp_reclen) { 1123 if (transport->tcp_flags & TCP_RCV_LAST_FRAG) 1124 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1125 } 1126 |
1133out: | 1127 return; 1128} 1129 1130/* 1131 * Finds the request corresponding to the RPC xid and invokes the common 1132 * tcp read code to read the data. 1133 */ 1134static inline int xs_tcp_read_reply(struct rpc_xprt *xprt, 1135 struct xdr_skb_reader *desc) 1136{ 1137 struct sock_xprt *transport = 1138 container_of(xprt, struct sock_xprt, xprt); 1139 struct rpc_rqst *req; 1140 1141 dprintk("RPC: read reply XID %08x\n", ntohl(transport->tcp_xid)); 1142 1143 /* Find and lock the request corresponding to this xid */ 1144 spin_lock(&xprt->transport_lock); 1145 req = xprt_lookup_rqst(xprt, transport->tcp_xid); 1146 if (!req) { 1147 dprintk("RPC: XID %08x request not found!\n", 1148 ntohl(transport->tcp_xid)); 1149 spin_unlock(&xprt->transport_lock); 1150 return -1; 1151 } 1152 1153 xs_tcp_read_common(xprt, desc, req); 1154 |
1134 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) 1135 xprt_complete_rqst(req->rq_task, transport->tcp_copied); | 1155 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) 1156 xprt_complete_rqst(req->rq_task, transport->tcp_copied); |
1157 |
|
1136 spin_unlock(&xprt->transport_lock); | 1158 spin_unlock(&xprt->transport_lock); |
1137 xs_tcp_check_fraghdr(transport); | 1159 return 0; |
1138} 1139 | 1160} 1161 |
1162#if defined(CONFIG_NFS_V4_1) 1163/* 1164 * Obtains an rpc_rqst previously allocated and invokes the common 1165 * tcp read code to read the data. The result is placed in the callback 1166 * queue. 1167 * If we're unable to obtain the rpc_rqst we schedule the closing of the 1168 * connection and return -1. 1169 */ 1170static inline int xs_tcp_read_callback(struct rpc_xprt *xprt, 1171 struct xdr_skb_reader *desc) 1172{ 1173 struct sock_xprt *transport = 1174 container_of(xprt, struct sock_xprt, xprt); 1175 struct rpc_rqst *req; 1176 1177 req = xprt_alloc_bc_request(xprt); 1178 if (req == NULL) { 1179 printk(KERN_WARNING "Callback slot table overflowed\n"); 1180 xprt_force_disconnect(xprt); 1181 return -1; 1182 } 1183 1184 req->rq_xid = transport->tcp_xid; 1185 dprintk("RPC: read callback XID %08x\n", ntohl(req->rq_xid)); 1186 xs_tcp_read_common(xprt, desc, req); 1187 1188 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) { 1189 struct svc_serv *bc_serv = xprt->bc_serv; 1190 1191 /* 1192 * Add callback request to callback list. The callback 1193 * service sleeps on the sv_cb_waitq waiting for new 1194 * requests. Wake it up after adding enqueing the 1195 * request. 1196 */ 1197 dprintk("RPC: add callback request to list\n"); 1198 spin_lock(&bc_serv->sv_cb_lock); 1199 list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); 1200 spin_unlock(&bc_serv->sv_cb_lock); 1201 wake_up(&bc_serv->sv_cb_waitq); 1202 } 1203 1204 req->rq_private_buf.len = transport->tcp_copied; 1205 1206 return 0; 1207} 1208 1209static inline int _xs_tcp_read_data(struct rpc_xprt *xprt, 1210 struct xdr_skb_reader *desc) 1211{ 1212 struct sock_xprt *transport = 1213 container_of(xprt, struct sock_xprt, xprt); 1214 1215 return (transport->tcp_flags & TCP_RPC_REPLY) ? 1216 xs_tcp_read_reply(xprt, desc) : 1217 xs_tcp_read_callback(xprt, desc); 1218} 1219#else 1220static inline int _xs_tcp_read_data(struct rpc_xprt *xprt, 1221 struct xdr_skb_reader *desc) 1222{ 1223 return xs_tcp_read_reply(xprt, desc); 1224} 1225#endif /* CONFIG_NFS_V4_1 */ 1226 1227/* 1228 * Read data off the transport. This can be either an RPC_CALL or an 1229 * RPC_REPLY. Relay the processing to helper functions. 1230 */ 1231static void xs_tcp_read_data(struct rpc_xprt *xprt, 1232 struct xdr_skb_reader *desc) 1233{ 1234 struct sock_xprt *transport = 1235 container_of(xprt, struct sock_xprt, xprt); 1236 1237 if (_xs_tcp_read_data(xprt, desc) == 0) 1238 xs_tcp_check_fraghdr(transport); 1239 else { 1240 /* 1241 * The transport_lock protects the request handling. 1242 * There's no need to hold it to update the tcp_flags. 1243 */ 1244 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1245 } 1246} 1247 |
|
1140static inline void xs_tcp_read_discard(struct sock_xprt *transport, struct xdr_skb_reader *desc) 1141{ 1142 size_t len; 1143 1144 len = transport->tcp_reclen - transport->tcp_offset; 1145 if (len > desc->count) 1146 len = desc->count; 1147 desc->count -= len; --- 28 unchanged lines hidden (view full) --- 1176 } 1177 /* Read in the call/reply flag */ 1178 if (transport->tcp_flags & TCP_RCV_READ_CALLDIR) { 1179 xs_tcp_read_calldir(transport, &desc); 1180 continue; 1181 } 1182 /* Read in the request data */ 1183 if (transport->tcp_flags & TCP_RCV_COPY_DATA) { | 1248static inline void xs_tcp_read_discard(struct sock_xprt *transport, struct xdr_skb_reader *desc) 1249{ 1250 size_t len; 1251 1252 len = transport->tcp_reclen - transport->tcp_offset; 1253 if (len > desc->count) 1254 len = desc->count; 1255 desc->count -= len; --- 28 unchanged lines hidden (view full) --- 1284 } 1285 /* Read in the call/reply flag */ 1286 if (transport->tcp_flags & TCP_RCV_READ_CALLDIR) { 1287 xs_tcp_read_calldir(transport, &desc); 1288 continue; 1289 } 1290 /* Read in the request data */ 1291 if (transport->tcp_flags & TCP_RCV_COPY_DATA) { |
1184 xs_tcp_read_request(xprt, &desc); | 1292 xs_tcp_read_data(xprt, &desc); |
1185 continue; 1186 } 1187 /* Skip over any trailing bytes on short reads */ 1188 xs_tcp_read_discard(transport, &desc); 1189 } while (desc.count); 1190 dprintk("RPC: xs_tcp_data_recv done\n"); 1191 return len - desc.count; 1192} --- 1110 unchanged lines hidden --- | 1293 continue; 1294 } 1295 /* Skip over any trailing bytes on short reads */ 1296 xs_tcp_read_discard(transport, &desc); 1297 } while (desc.count); 1298 dprintk("RPC: xs_tcp_data_recv done\n"); 1299 return len - desc.count; 1300} --- 1110 unchanged lines hidden --- |