Re: [pnfs] [RFC 53/85] nfs41: Add ability to read RPC call direction on TCP stream.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Nov. 10, 2008, 22:27 +0200, Benny Halevy <bhalevy@xxxxxxxxxxx> wrote:
> NFSv4.1 callbacks can arrive over an existing connection. This patch adds
> the logic to read the RPC call direction (call or reply). It does this by
> updating the state machine to look for the call direction invoking
> xs_tcp_read_calldir(...) after reading the XID.
> 
> To avoid confusion, keep tcp_calldir in code in host order.
> 
> Signed-off-by: Ricardo Labiaga <ricardo.labiaga@xxxxxxxxxx>
> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
> ---
>  net/sunrpc/xprtsock.c |   49 +++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 0a50361..1ce05d7 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -222,7 +222,8 @@ struct sock_xprt {
>  	 * State of TCP reply receive
>  	 */
>  	__be32			tcp_fraghdr,
> -				tcp_xid;
> +				tcp_xid,
> +				tcp_calldir;	/* Is this a call or a reply? */
>  
>  	u32			tcp_offset,
>  				tcp_reclen;
> @@ -259,6 +260,7 @@ struct sock_xprt {
>  #define TCP_RCV_COPY_FRAGHDR	(1UL << 1)
>  #define TCP_RCV_COPY_XID	(1UL << 2)
>  #define TCP_RCV_COPY_DATA	(1UL << 3)
> +#define TCP_RCV_COPY_CALLDIR	(1UL << 4)
>  
>  static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
>  {
> @@ -919,7 +921,7 @@ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_rea
>  	transport->tcp_offset = 0;
>  
>  	/* Sanity check of the record length */
> -	if (unlikely(transport->tcp_reclen < 4)) {
> +	if (unlikely(transport->tcp_reclen < 8)) {
>  		dprintk("RPC:       invalid TCP record fragment length\n");
>  		xprt_force_disconnect(xprt);
>  		return;
> @@ -954,13 +956,47 @@ static inline void xs_tcp_read_xid(struct sock_xprt *transport, struct xdr_skb_r
>  	if (used != len)
>  		return;
>  	transport->tcp_flags &= ~TCP_RCV_COPY_XID;
> -	transport->tcp_flags |= TCP_RCV_COPY_DATA;
> +	transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
>  	transport->tcp_copied = 4;
> -	dprintk("RPC:       reading reply for XID %08x\n",
> +	dprintk("RPC:       reading %s XID %08x\n",
> +			(transport->tcp_calldir == RPC_REPLY) ? "reply for"
> +							      : "request with",
>  			ntohl(transport->tcp_xid));
>  	xs_tcp_check_fraghdr(transport);
>  }
>  
> +static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
> +				       struct xdr_skb_reader *desc)
> +{
> +	size_t len, used;
> +	u32 offset;
> +	char *p;
> +
> +	/*
> +	 * We want transport->tcp_offset to be 8 at the end of this routine
> +	 * (4 bytes for the xid and 4 bytes for the call/reply flag).
> +	 * When this function is called for the first time,
> +	 * transport->tcp_offset is 4 (after having already read the xid).
> +	 */
> +	offset = transport->tcp_offset - sizeof(transport->tcp_xid);
> +	len = sizeof(transport->tcp_calldir) - offset;
> +	dprintk("RPC:       reading CALL/REPLY flag (%Zu bytes)\n", len);
> +	p = ((char *) &transport->tcp_calldir) + offset;
> +	used = xdr_skb_read_bits(desc, p, len);
> +	transport->tcp_offset += used;
> +	if (used != len)
> +		return;
> +	transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR;
> +	transport->tcp_flags |= TCP_RCV_COPY_DATA;
> +	transport->tcp_copied += 4;
> +	transport->tcp_calldir = ntohl(transport->tcp_calldir);

review 11-14: introduce direction flag, no need to save the
actual value of calldir.

> +	dprintk("RPC:       reading %s CALL/REPLY flag %08x\n",
> +			(transport->tcp_calldir == RPC_REPLY) ? "reply for"
> +							      : "request with",
> +							transport->tcp_calldir);
> +	xs_tcp_check_fraghdr(transport);
> +}
> +
>  static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
>  {
>  	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
> @@ -1077,6 +1113,11 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
>  			xs_tcp_read_xid(transport, &desc);
>  			continue;
>  		}
> +		/* Read in the call/reply flag */
> +		if (transport->tcp_flags & TCP_RCV_COPY_CALLDIR) {
> +			xs_tcp_read_calldir(transport, &desc);
> +			continue;
> +		}
>  		/* Read in the request data */
>  		if (transport->tcp_flags & TCP_RCV_COPY_DATA) {
>  			xs_tcp_read_request(xprt, &desc);
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux