2006-10-12 21:15:20

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 0/9] RFC: Remove socket-specific fields from rpc_xprt

Please review the following patches for 2.6.20. They are part of the RPC
transport switch patch set.

--
corporate: <chuck dot lever at oracle dot com>

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs


2006-10-18 20:19:10

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 2/9] SUNRPC: Allocate a private data area for socket-specific rpc_xprt fields

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> When setting up a new transport instance, allocate enough memory for an
> rpc_xprt and a private area. As part of the same memory allocation, it
> will be easy to find one, given a pointer to the other.
>
> Test plan:
> Compile kernel with CONFIG_NFS enabled.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> net/sunrpc/xprtsock.c | 15 +++++++++++++--
> 1 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index a6f778f..5ddb20d 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -125,6 +125,15 @@ static inline void xs_pktdump(char *msg,
> }
> #endif
>
> +struct xs_xprt {
> + struct rpc_xprt xprt;
> +};

That name tells you nothing about what it contains. How about something
like 'struct rpc_xprt_sock' instead?

> +static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
> +{
> + return (struct xs_xprt *) xprt;

Should use container_of() instead of a cast.

Why do we want this extra wrapper anyway? It gives you no extra type
security compared to container_of().

> +}
> +
> static void xs_format_peer_addresses(struct rpc_xprt *xprt)
> {
> struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
> @@ -1352,6 +1361,7 @@ static struct rpc_xprt_ops xs_tcp_ops =
>
> static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
> {
> + struct xs_xprt *private;
> struct rpc_xprt *xprt;
>
> if (addrlen > sizeof(xprt->addr)) {
> @@ -1359,11 +1369,12 @@ static struct rpc_xprt *xs_setup_xprt(st
> return ERR_PTR(-EBADF);
> }
>
> - xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL);
> - if (xprt == NULL) {
> + private = kzalloc(sizeof(struct xs_xprt), GFP_KERNEL);
> + if (private == NULL) {
> dprintk("RPC: xs_setup_xprt: couldn't allocate rpc_xprt\n");
> return ERR_PTR(-ENOMEM);
> }
> + xprt = &private->xprt;
>
> xprt->max_reqs = slot_table_size;
> xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL);


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:26:57

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 3/9] SUNRPC: Remove sock and inet fields from rpc_xprt

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> The "sock" and "inet" fields are socket-specific. Move them to a private
> data structure maintained entirely within net/sunrpc/xprtsock.c
>
> Test plan:
> Connectathon.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> include/linux/sunrpc/xprt.h | 4 +--
> net/sunrpc/xprtsock.c | 68 ++++++++++++++++++++++++++-----------------
> 2 files changed, 43 insertions(+), 29 deletions(-)
>
> diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> index d791901..4c074a7 100644
> --- a/include/linux/sunrpc/xprt.h
> +++ b/include/linux/sunrpc/xprt.h
> @@ -17,6 +17,8 @@ #include <linux/sunrpc/sched.h>
> #include <linux/sunrpc/xdr.h>
> #include <linux/sunrpc/msg_prot.h>
>
> +#include <net/sock.h>
> +
> extern unsigned int xprt_udp_slot_table_entries;
> extern unsigned int xprt_tcp_slot_table_entries;
>
> @@ -126,8 +128,6 @@ struct rpc_xprt_ops {
> struct rpc_xprt {
> struct kref kref; /* Reference count */
> struct rpc_xprt_ops * ops; /* transport methods */
> - struct socket * sock; /* BSD socket layer */
> - struct sock * inet; /* INET layer */
>
> struct rpc_timeout timeout; /* timeout parms */
> struct sockaddr_storage addr; /* server address */
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 5ddb20d..79088e8 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -127,6 +127,12 @@ #endif
>
> struct xs_xprt {
> struct rpc_xprt xprt;
> +
> + /*
> + * Network layer
> + */
> + struct socket * sock;
> + struct sock * inet;
> };
>
> static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
> @@ -134,6 +140,11 @@ static inline struct xs_xprt *xs_private
> return (struct xs_xprt *) xprt;
> }
>
> +static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
> +{
> + return (struct rpc_xprt *) sk->sk_user_data;
> +}
> +
> static void xs_format_peer_addresses(struct rpc_xprt *xprt)
> {
> struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
> @@ -300,19 +311,20 @@ static void xs_nospace(struct rpc_task *
> {
> struct rpc_rqst *req = task->tk_rqstp;
> struct rpc_xprt *xprt = req->rq_xprt;
> + struct socket *sock = xs_private_data(xprt)->sock;
>
> dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
> task->tk_pid, req->rq_slen - req->rq_bytes_sent,
> req->rq_slen);
>
> - if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
> + if (test_bit(SOCK_ASYNC_NOSPACE, &sock->flags)) {
> /* Protect against races with write_space */
> spin_lock_bh(&xprt->transport_lock);
>
> /* Don't race with disconnect */
> if (!xprt_connected(xprt))
> task->tk_status = -ENOTCONN;
> - else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags))
> + else if (test_bit(SOCK_NOSPACE, &sock->flags))
> xprt_wait_for_buffer_space(task);
>
> spin_unlock_bh(&xprt->transport_lock);
> @@ -344,8 +356,10 @@ static int xs_udp_send_request(struct rp
> req->rq_svec->iov_len);
>
> req->rq_xtime = jiffies;
> - status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
> - xprt->addrlen, xdr, req->rq_bytes_sent);
> + status = xs_sendpages(xs_private_data(xprt)->sock,
> + (struct sockaddr *) &xprt->addr,
> + xprt->addrlen, xdr,
> + req->rq_bytes_sent);
>
> dprintk("RPC: xs_udp_send_request(%u) = %d\n",
> xdr->len - req->rq_bytes_sent, status);
> @@ -415,8 +429,8 @@ static int xs_tcp_send_request(struct rp
> * called sendmsg(). */
> while (1) {
> req->rq_xtime = jiffies;
> - status = xs_sendpages(xprt->sock, NULL, 0, xdr,
> - req->rq_bytes_sent);
> + status = xs_sendpages(xs_private_data(xprt)->sock,
> + NULL, 0, xdr, req->rq_bytes_sent);
>
> dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
> xdr->len - req->rq_bytes_sent, status);
> @@ -494,8 +508,9 @@ out_release:
> */
> static void xs_close(struct rpc_xprt *xprt)
> {
> - struct socket *sock = xprt->sock;
> - struct sock *sk = xprt->inet;
> + struct xs_xprt *private = xs_private_data(xprt);
> + struct socket *sock = private->sock;
> + struct sock *sk = private->inet;
>
> if (!sk)
> goto clear_close_wait;
> @@ -503,8 +518,8 @@ static void xs_close(struct rpc_xprt *xp
> dprintk("RPC: xs_close xprt %p\n", xprt);
>
> write_lock_bh(&sk->sk_callback_lock);
> - xprt->inet = NULL;
> - xprt->sock = NULL;
> + private->inet = NULL;
> + private->sock = NULL;
>
> sk->sk_user_data = NULL;
> sk->sk_data_ready = xprt->old_data_ready;
> @@ -540,11 +555,6 @@ static void xs_destroy(struct rpc_xprt *
> kfree(xprt);
> }
>
> -static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
> -{
> - return (struct rpc_xprt *) sk->sk_user_data;
> -}
> -
> /**
> * xs_udp_data_ready - "data ready" callback for UDP sockets
> * @sk: socket with data to read
> @@ -961,7 +971,8 @@ static void xs_tcp_write_space(struct so
>
> static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
> {
> - struct sock *sk = xprt->inet;
> + struct xs_xprt *private = xs_private_data(xprt);

Please don't use 'private' as a variable name. That just serves to
obfuscate.

> + struct sock *sk = private->inet;
>
> if (xprt->rcvsize) {
> sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
> @@ -1077,7 +1088,8 @@ static int xs_bindresvport(struct rpc_xp
> static void xs_udp_connect_worker(void *args)
> {
> struct rpc_xprt *xprt = (struct rpc_xprt *) args;
> - struct socket *sock = xprt->sock;
> + struct xs_xprt *private = xs_private_data(xprt);
> + struct socket *sock = private->sock;
> int err, status = -EIO;
>
> if (xprt->shutdown || !xprt_bound(xprt))
> @@ -1099,7 +1111,7 @@ static void xs_udp_connect_worker(void *
> dprintk("RPC: worker connecting xprt %p to address: %s\n",
> xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL));
>
> - if (!xprt->inet) {
> + if (!private->inet) {
> struct sock *sk = sock->sk;
>
> write_lock_bh(&sk->sk_callback_lock);
> @@ -1116,8 +1128,8 @@ static void xs_udp_connect_worker(void *
> xprt_set_connected(xprt);
>
> /* Reset to new socket */
> - xprt->sock = sock;
> - xprt->inet = sk;
> + private->sock = sock;
> + private->inet = sk;
>
> write_unlock_bh(&sk->sk_callback_lock);
> }
> @@ -1135,7 +1147,7 @@ out:
> static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
> {
> int result;
> - struct socket *sock = xprt->sock;
> + struct socket *sock = xs_private_data(xprt)->sock;
> struct sockaddr any;
>
> dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
> @@ -1161,13 +1173,14 @@ static void xs_tcp_reuse_connection(stru
> static void xs_tcp_connect_worker(void *args)
> {
> struct rpc_xprt *xprt = (struct rpc_xprt *)args;
> - struct socket *sock = xprt->sock;
> + struct xs_xprt *private = xs_private_data(xprt);
> + struct socket *sock = private->sock;
> int err, status = -EIO;
>
> if (xprt->shutdown || !xprt_bound(xprt))
> goto out;
>
> - if (!xprt->sock) {
> + if (!private->sock) {
> /* start from scratch */
> if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
> dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
> @@ -1185,7 +1198,7 @@ static void xs_tcp_connect_worker(void *
> dprintk("RPC: worker connecting xprt %p to address: %s\n",
> xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL));
>
> - if (!xprt->inet) {
> + if (!private->inet) {
> struct sock *sk = sock->sk;
>
> write_lock_bh(&sk->sk_callback_lock);
> @@ -1208,8 +1221,8 @@ static void xs_tcp_connect_worker(void *
> xprt_clear_connected(xprt);
>
> /* Reset to new socket */
> - xprt->sock = sock;
> - xprt->inet = sk;
> + private->sock = sock;
> + private->inet = sk;
>
> write_unlock_bh(&sk->sk_callback_lock);
> }
> @@ -1258,11 +1271,12 @@ out_clear:
> static void xs_connect(struct rpc_task *task)
> {
> struct rpc_xprt *xprt = task->tk_xprt;
> + struct xs_xprt *private = xs_private_data(xprt);
>
> if (xprt_test_and_set_connecting(xprt))
> return;
>
> - if (xprt->sock != NULL) {
> + if (private->sock != NULL) {
> dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
> xprt, xprt->reestablish_timeout / HZ);
> schedule_delayed_work(&xprt->connect_worker,


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:30:50

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 4/9] SUNRPC: Move TCP receive state variables into private data structure

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> Move the TCP receive state variables from the generic rpc_xprt structure to
> a private structure maintained inside net/sunrpc/xprtsock.c.
>
> Also rename a function/variable pair to refer to RPC fragment headers
> instead of record markers, to be consistent with types defined in
> sunrpc/*.h.
>
> Test plan:
> Connectathon with NFS over TCP.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> include/linux/sunrpc/xprt.h | 14 ----
> net/sunrpc/xprtsock.c | 159 +++++++++++++++++++++++++------------------
> 2 files changed, 91 insertions(+), 82 deletions(-)
>
> diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> index 4c074a7..3ff8230 100644
> --- a/include/linux/sunrpc/xprt.h
> +++ b/include/linux/sunrpc/xprt.h
> @@ -158,15 +158,6 @@ struct rpc_xprt {
> resvport : 1; /* use a reserved port */
>
> /*
> - * State of TCP reply receive stuff
> - */
> - __be32 tcp_recm, /* Fragment header */
> - tcp_xid; /* Current XID */
> - u32 tcp_reclen, /* fragment length */
> - tcp_offset; /* fragment offset */
> - unsigned long tcp_copied, /* copied to request */
> - tcp_flags;
> - /*
> * Connection of transports
> */
> unsigned long connect_timeout,
> @@ -212,11 +203,6 @@ struct rpc_xprt {
> char * address_strings[RPC_DISPLAY_MAX];
> };
>
> -#define XPRT_LAST_FRAG (1 << 0)
> -#define XPRT_COPY_RECM (1 << 1)
> -#define XPRT_COPY_XID (1 << 2)
> -#define XPRT_COPY_DATA (1 << 3)
> -
> #ifdef __KERNEL__
>
> /*
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 79088e8..363b2fc 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -133,8 +133,28 @@ struct xs_xprt {
> */
> struct socket * sock;
> struct sock * inet;
> +
> + /*
> + * State of TCP reply receive
> + */
> + __be32 tcp_fraghdr,
> + tcp_xid;
> +
> + u32 tcp_offset,
> + tcp_reclen;
> +
> + unsigned long tcp_copied,
> + tcp_flags;
> };
>
> +/*
> + * tcp_flags
> + */
> +#define XS_LAST_FRAG (1UL << 0)
> +#define XS_COPY_FRGH (1UL << 1)
> +#define XS_COPY_XID (1UL << 2)
> +#define XS_COPY_DATA (1UL << 3)

Why are you renaming these?

> +
> static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
> {
> return (struct xs_xprt *) xprt;
> @@ -641,73 +661,73 @@ static inline size_t xs_tcp_copy_data(sk
>
> static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
> {
> + struct xs_xprt *private = xs_private_data(xprt);

See previous comments about using 'private' as a variable name, and
apply everywhere.

> size_t len, used;
> char *p;
>
> - p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
> - len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
> + p = ((char *) &private->tcp_fraghdr) + private->tcp_offset;
> + len = sizeof(private->tcp_fraghdr) - private->tcp_offset;
> used = xs_tcp_copy_data(desc, p, len);
> - xprt->tcp_offset += used;
> + private->tcp_offset += used;
> if (used != len)
> return;
>
> - xprt->tcp_reclen = ntohl(xprt->tcp_recm);
> - if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
> - xprt->tcp_flags |= XPRT_LAST_FRAG;
> + private->tcp_reclen = ntohl(private->tcp_fraghdr);
> + if (private->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
> + private->tcp_flags |= XS_LAST_FRAG;
> else
> - xprt->tcp_flags &= ~XPRT_LAST_FRAG;
> - xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
> + private->tcp_flags &= ~XS_LAST_FRAG;
> + private->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
>
> - xprt->tcp_flags &= ~XPRT_COPY_RECM;
> - xprt->tcp_offset = 0;
> + private->tcp_flags &= ~XS_COPY_FRGH;
> + private->tcp_offset = 0;
>
> /* Sanity check of the record length */
> - if (unlikely(xprt->tcp_reclen < 4)) {
> + if (unlikely(private->tcp_reclen < 4)) {
> dprintk("RPC: invalid TCP record fragment length\n");
> xprt_disconnect(xprt);
> return;
> }
> dprintk("RPC: reading TCP record fragment of length %d\n",
> - xprt->tcp_reclen);
> + private->tcp_reclen);
> }
>
> -static void xs_tcp_check_recm(struct rpc_xprt *xprt)
> +static void xs_tcp_check_fraghdr(struct xs_xprt *private)
> {
> - dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
> - xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
> - if (xprt->tcp_offset == xprt->tcp_reclen) {
> - xprt->tcp_flags |= XPRT_COPY_RECM;
> - xprt->tcp_offset = 0;
> - if (xprt->tcp_flags & XPRT_LAST_FRAG) {
> - xprt->tcp_flags &= ~XPRT_COPY_DATA;
> - xprt->tcp_flags |= XPRT_COPY_XID;
> - xprt->tcp_copied = 0;
> + if (private->tcp_offset == private->tcp_reclen) {
> + private->tcp_flags |= XS_COPY_FRGH;
> + private->tcp_offset = 0;
> + if (private->tcp_flags & XS_LAST_FRAG) {
> + private->tcp_flags &= ~XS_COPY_DATA;
> + private->tcp_flags |= XS_COPY_XID;
> + private->tcp_copied = 0;
> }
> }
> }
>
> -static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
> +static inline void xs_tcp_read_xid(struct xs_xprt *private, skb_reader_t *desc)
> {
> size_t len, used;
> char *p;
>
> - len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
> + len = sizeof(private->tcp_xid) - private->tcp_offset;
> dprintk("RPC: reading XID (%Zu bytes)\n", len);
> - p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
> + p = ((char *) &private->tcp_xid) + private->tcp_offset;
> used = xs_tcp_copy_data(desc, p, len);
> - xprt->tcp_offset += used;
> + private->tcp_offset += used;
> if (used != len)
> return;
> - xprt->tcp_flags &= ~XPRT_COPY_XID;
> - xprt->tcp_flags |= XPRT_COPY_DATA;
> - xprt->tcp_copied = 4;
> + private->tcp_flags &= ~XS_COPY_XID;
> + private->tcp_flags |= XS_COPY_DATA;
> + private->tcp_copied = 4;
> dprintk("RPC: reading reply for XID %08x\n",
> - ntohl(xprt->tcp_xid));
> - xs_tcp_check_recm(xprt);
> + ntohl(private->tcp_xid));
> + xs_tcp_check_fraghdr(private);
> }
>
> static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
> {
> + struct xs_xprt *private = xs_private_data(xprt);
> struct rpc_rqst *req;
> struct xdr_buf *rcvbuf;
> size_t len;
> @@ -715,116 +735,116 @@ static inline void xs_tcp_read_request(s
>
> /* Find and lock the request corresponding to this xid */
> spin_lock(&xprt->transport_lock);
> - req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
> + req = xprt_lookup_rqst(xprt, private->tcp_xid);
> if (!req) {
> - xprt->tcp_flags &= ~XPRT_COPY_DATA;
> + private->tcp_flags &= ~XS_COPY_DATA;
> dprintk("RPC: XID %08x request not found!\n",
> - ntohl(xprt->tcp_xid));
> + ntohl(private->tcp_xid));
> spin_unlock(&xprt->transport_lock);
> return;
> }
>
> rcvbuf = &req->rq_private_buf;
> len = desc->count;
> - if (len > xprt->tcp_reclen - xprt->tcp_offset) {
> + if (len > private->tcp_reclen - private->tcp_offset) {
> skb_reader_t my_desc;
>
> - len = xprt->tcp_reclen - xprt->tcp_offset;
> + len = private->tcp_reclen - private->tcp_offset;
> memcpy(&my_desc, desc, sizeof(my_desc));
> my_desc.count = len;
> - r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
> + r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
> &my_desc, xs_tcp_copy_data);
> desc->count -= r;
> desc->offset += r;
> } else
> - r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
> + r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
> desc, xs_tcp_copy_data);
>
> if (r > 0) {
> - xprt->tcp_copied += r;
> - xprt->tcp_offset += r;
> + private->tcp_copied += r;
> + private->tcp_offset += r;
> }
> if (r != len) {
> /* Error when copying to the receive buffer,
> * usually because we weren't able to allocate
> * additional buffer pages. All we can do now
> - * is turn off XPRT_COPY_DATA, so the request
> + * is turn off XS_COPY_DATA, so the request
> * will not receive any additional updates,
> * and time out.
> * Any remaining data from this record will
> * be discarded.
> */
> - xprt->tcp_flags &= ~XPRT_COPY_DATA;
> + private->tcp_flags &= ~XS_COPY_DATA;
> dprintk("RPC: XID %08x truncated request\n",
> - ntohl(xprt->tcp_xid));
> + ntohl(private->tcp_xid));
> dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
> - xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
> + xprt, private->tcp_copied, private->tcp_offset, private->tcp_reclen);
> goto out;
> }
>
> dprintk("RPC: XID %08x read %Zd bytes\n",
> - ntohl(xprt->tcp_xid), r);
> + ntohl(private->tcp_xid), r);
> dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
> - xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
> + xprt, private->tcp_copied, private->tcp_offset, private->tcp_reclen);
>
> - if (xprt->tcp_copied == req->rq_private_buf.buflen)
> - xprt->tcp_flags &= ~XPRT_COPY_DATA;
> - else if (xprt->tcp_offset == xprt->tcp_reclen) {
> - if (xprt->tcp_flags & XPRT_LAST_FRAG)
> - xprt->tcp_flags &= ~XPRT_COPY_DATA;
> + if (private->tcp_copied == req->rq_private_buf.buflen)
> + private->tcp_flags &= ~XS_COPY_DATA;
> + else if (private->tcp_offset == private->tcp_reclen) {
> + if (private->tcp_flags & XS_LAST_FRAG)
> + private->tcp_flags &= ~XS_COPY_DATA;
> }
>
> out:
> - if (!(xprt->tcp_flags & XPRT_COPY_DATA))
> - xprt_complete_rqst(req->rq_task, xprt->tcp_copied);
> + if (!(private->tcp_flags & XS_COPY_DATA))
> + xprt_complete_rqst(req->rq_task, private->tcp_copied);
> spin_unlock(&xprt->transport_lock);
> - xs_tcp_check_recm(xprt);
> + xs_tcp_check_fraghdr(private);
> }
>
> -static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
> +static inline void xs_tcp_read_discard(struct xs_xprt *private, skb_reader_t *desc)
> {
> size_t len;
>
> - len = xprt->tcp_reclen - xprt->tcp_offset;
> + len = private->tcp_reclen - private->tcp_offset;
> if (len > desc->count)
> len = desc->count;
> desc->count -= len;
> desc->offset += len;
> - xprt->tcp_offset += len;
> + private->tcp_offset += len;
> dprintk("RPC: discarded %Zu bytes\n", len);
> - xs_tcp_check_recm(xprt);
> + xs_tcp_check_fraghdr(private);
> }
>
> static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
> {
> struct rpc_xprt *xprt = rd_desc->arg.data;
> + struct xs_xprt *private = xs_private_data(xprt);
> skb_reader_t desc = {
> .skb = skb,
> .offset = offset,
> .count = len,
> - .csum = 0
> };
>
> dprintk("RPC: xs_tcp_data_recv started\n");
> do {
> /* Read in a new fragment marker if necessary */
> /* Can we ever really expect to get completely empty fragments? */
> - if (xprt->tcp_flags & XPRT_COPY_RECM) {
> + if (private->tcp_flags & XS_COPY_FRGH) {
> xs_tcp_read_fraghdr(xprt, &desc);
> continue;
> }
> /* Read in the xid if necessary */
> - if (xprt->tcp_flags & XPRT_COPY_XID) {
> - xs_tcp_read_xid(xprt, &desc);
> + if (private->tcp_flags & XS_COPY_XID) {
> + xs_tcp_read_xid(private, &desc);
> continue;
> }
> /* Read in the request data */
> - if (xprt->tcp_flags & XPRT_COPY_DATA) {
> + if (private->tcp_flags & XS_COPY_DATA) {
> xs_tcp_read_request(xprt, &desc);
> continue;
> }
> /* Skip over any trailing bytes on short reads */
> - xs_tcp_read_discard(xprt, &desc);
> + xs_tcp_read_discard(private, &desc);
> } while (desc.count);
> dprintk("RPC: xs_tcp_data_recv done\n");
> return len - desc.count;
> @@ -878,11 +898,14 @@ static void xs_tcp_state_change(struct s
> case TCP_ESTABLISHED:
> spin_lock_bh(&xprt->transport_lock);
> if (!xprt_test_and_set_connected(xprt)) {
> + struct xs_xprt *private = xs_private_data(xprt);
> +
> /* Reset TCP record info */
> - xprt->tcp_offset = 0;
> - xprt->tcp_reclen = 0;
> - xprt->tcp_copied = 0;
> - xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
> + private->tcp_offset = 0;
> + private->tcp_reclen = 0;
> + private->tcp_copied = 0;
> + private->tcp_flags = XS_COPY_FRGH | XS_COPY_XID;
> +
> xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
> xprt_wake_pending_tasks(xprt, 0);
> }


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:34:25

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 5/9] SUNRPC: Move rpc_xprt socket connect fields into private data structure

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> Move the socket-specific connection management fields out of the generic
> rpc_xprt structure into a private data structure maintained in
> net/sunrpc/xprtsock.c.
>
> Test plan:
> Connectathon.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> include/linux/sunrpc/xprt.h | 2 --
> net/sunrpc/xprtsock.c | 36 +++++++++++++++++++++++++-----------
> 2 files changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> index 3ff8230..18bf72c 100644
> --- a/include/linux/sunrpc/xprt.h
> +++ b/include/linux/sunrpc/xprt.h
> @@ -163,8 +163,6 @@ struct rpc_xprt {
> unsigned long connect_timeout,
> bind_timeout,
> reestablish_timeout;
> - struct work_struct connect_worker;
> - unsigned short port;
>
> /*
> * Disconnection of idle transports
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 363b2fc..b0bead5 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -145,6 +145,12 @@ struct xs_xprt {
>
> unsigned long tcp_copied,
> tcp_flags;
> +
> + /*
> + * Connection of transports
> + */
> + struct work_struct connect_worker;
> + unsigned short port;
> };
>
> /*
> @@ -565,7 +571,7 @@ static void xs_destroy(struct rpc_xprt *
> {
> dprintk("RPC: xs_destroy xprt %p\n", xprt);
>
> - cancel_delayed_work(&xprt->connect_worker);
> + cancel_delayed_work(&xs_private_data(xprt)->connect_worker);
> flush_scheduled_work();
>
> xprt_disconnect(xprt);
> @@ -1076,18 +1082,19 @@ static void xs_set_port(struct rpc_xprt
>
> static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
> {
> + struct xs_xprt *private = xs_private_data(xprt);
> struct sockaddr_in myaddr = {
> .sin_family = AF_INET,
> };
> int err;
> - unsigned short port = xprt->port;
> + unsigned short port = private->port;
>
> do {
> myaddr.sin_port = htons(port);
> err = kernel_bind(sock, (struct sockaddr *) &myaddr,
> sizeof(myaddr));
> if (err == 0) {
> - xprt->port = port;
> + private->port = port;
> dprintk("RPC: xs_bindresvport bound to port %u\n",
> port);
> return 0;
> @@ -1096,7 +1103,7 @@ static int xs_bindresvport(struct rpc_xp
> port = xprt_max_resvport;
> else
> port--;
> - } while (err == -EADDRINUSE && port != xprt->port);
> + } while (err == -EADDRINUSE && port != private->port);
>
> dprintk("RPC: can't bind to reserved port (%d).\n", -err);
> return err;
> @@ -1302,14 +1309,14 @@ static void xs_connect(struct rpc_task *
> if (private->sock != NULL) {
> dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
> xprt, xprt->reestablish_timeout / HZ);
> - schedule_delayed_work(&xprt->connect_worker,
> + schedule_delayed_work(&private->connect_worker,
> xprt->reestablish_timeout);
> xprt->reestablish_timeout <<= 1;
> if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
> xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
> } else {
> dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
> - schedule_work(&xprt->connect_worker);
> + schedule_work(&private->connect_worker);
>
> /* flush_scheduled_work can sleep... */
> if (!RPC_IS_ASYNC(task))
> @@ -1325,8 +1332,10 @@ static void xs_connect(struct rpc_task *
> */
> static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
> {
> + struct xs_xprt *private = xs_private_data(xprt);
> +
> seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
> - xprt->port,
> + private->port,
> xprt->stat.bind_count,
> xprt->stat.sends,
> xprt->stat.recvs,
> @@ -1343,13 +1352,14 @@ static void xs_udp_print_stats(struct rp
> */
> static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
> {
> + struct xs_xprt *private = xs_private_data(xprt);
> long idle_time = 0;
>
> if (xprt_connected(xprt))
> idle_time = (long)(jiffies - xprt->last_used) / HZ;
>
> seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
> - xprt->port,
> + private->port,
> xprt->stat.bind_count,
> xprt->stat.connect_count,
> xprt->stat.connect_time,
> @@ -1423,7 +1433,7 @@ static struct rpc_xprt *xs_setup_xprt(st
>
> memcpy(&xprt->addr, addr, addrlen);
> xprt->addrlen = addrlen;
> - xprt->port = xs_get_random_port();
> + private->port = xs_get_random_port();
>
> return xprt;
> }
> @@ -1438,10 +1448,12 @@ static struct rpc_xprt *xs_setup_xprt(st
> struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
> {
> struct rpc_xprt *xprt;
> + struct xs_xprt *private;
>
> xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
> if (IS_ERR(xprt))
> return xprt;
> + private = xs_private_data(xprt);
>
> if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
> xprt_set_bound(xprt);
> @@ -1451,7 +1463,7 @@ struct rpc_xprt *xs_setup_udp(struct soc
> /* XXX: header size can vary due to auth type, IPv6, etc. */
> xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
>
> - INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
> + INIT_WORK(&private->connect_worker, xs_udp_connect_worker, xprt);

Why keep 'xprt' as the data parameter for the connect_worker instead of
just passing the struct rpc_xprt_sock?

> xprt->bind_timeout = XS_BIND_TO;
> xprt->connect_timeout = XS_UDP_CONN_TO;
> xprt->reestablish_timeout = XS_UDP_REEST_TO;
> @@ -1481,10 +1493,12 @@ struct rpc_xprt *xs_setup_udp(struct soc
> struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
> {
> struct rpc_xprt *xprt;
> + struct xs_xprt *private;
>
> xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
> if (IS_ERR(xprt))
> return xprt;
> + private = xs_private_data(xprt);
>
> if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
> xprt_set_bound(xprt);
> @@ -1493,7 +1507,7 @@ struct rpc_xprt *xs_setup_tcp(struct soc
> xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
> xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
>
> - INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
> + INIT_WORK(&private->connect_worker, xs_tcp_connect_worker, xprt);
> xprt->bind_timeout = XS_BIND_TO;
> xprt->connect_timeout = XS_TCP_CONN_TO;
> xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:36:22

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> Hide buffers that store formatted IP addresses in a private data structure
> maintained in net/sunrpc/xprtsock.c.

Why? Aren't those generic?

Cheers,
Trond


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:36:39

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 4/9] SUNRPC: Move TCP receive state variables into private data structure

Hi Trond-

On 10/18/06, Trond Myklebust <[email protected]> wrote:
> On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > Move the TCP receive state variables from the generic rpc_xprt structure to
> > a private structure maintained inside net/sunrpc/xprtsock.c.
> >
> > Also rename a function/variable pair to refer to RPC fragment headers
> > instead of record markers, to be consistent with types defined in
> > sunrpc/*.h.
> >
> > Test plan:
> > Connectathon with NFS over TCP.
> >
> > Signed-off-by: Chuck Lever <[email protected]>
> > ---
> >
> > include/linux/sunrpc/xprt.h | 14 ----
> > net/sunrpc/xprtsock.c | 159 +++++++++++++++++++++++++------------------
> > 2 files changed, 91 insertions(+), 82 deletions(-)
> >
> > diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> > index 4c074a7..3ff8230 100644
> > --- a/include/linux/sunrpc/xprt.h
> > +++ b/include/linux/sunrpc/xprt.h
> > @@ -158,15 +158,6 @@ struct rpc_xprt {
> > resvport : 1; /* use a reserved port */
> >
> > /*
> > - * State of TCP reply receive stuff
> > - */
> > - __be32 tcp_recm, /* Fragment header */
> > - tcp_xid; /* Current XID */
> > - u32 tcp_reclen, /* fragment length */
> > - tcp_offset; /* fragment offset */
> > - unsigned long tcp_copied, /* copied to request */
> > - tcp_flags;
> > - /*
> > * Connection of transports
> > */
> > unsigned long connect_timeout,
> > @@ -212,11 +203,6 @@ struct rpc_xprt {
> > char * address_strings[RPC_DISPLAY_MAX];
> > };
> >
> > -#define XPRT_LAST_FRAG (1 << 0)
> > -#define XPRT_COPY_RECM (1 << 1)
> > -#define XPRT_COPY_XID (1 << 2)
> > -#define XPRT_COPY_DATA (1 << 3)
> > -
> > #ifdef __KERNEL__
> >
> > /*
> > diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> > index 79088e8..363b2fc 100644
> > --- a/net/sunrpc/xprtsock.c
> > +++ b/net/sunrpc/xprtsock.c
> > @@ -133,8 +133,28 @@ struct xs_xprt {
> > */
> > struct socket * sock;
> > struct sock * inet;
> > +
> > + /*
> > + * State of TCP reply receive
> > + */
> > + __be32 tcp_fraghdr,
> > + tcp_xid;
> > +
> > + u32 tcp_offset,
> > + tcp_reclen;
> > +
> > + unsigned long tcp_copied,
> > + tcp_flags;
> > };
> >
> > +/*
> > + * tcp_flags
> > + */
> > +#define XS_LAST_FRAG (1UL << 0)
> > +#define XS_COPY_FRGH (1UL << 1)
> > +#define XS_COPY_XID (1UL << 2)
> > +#define XS_COPY_DATA (1UL << 3)
>
> Why are you renaming these?

Because XPRT_LAST_FRAG is generic. XS_ is the naming scheme used in
net/sunrpc/xprtsock.c. These flags are specific to the TCP socket
implementation in xprtsock.c

--
"We who cut mere stones must always be envisioning cathedrals"
-- Quarry worker's creed

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 20:41:15

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

On 10/18/06, Trond Myklebust <[email protected]> wrote:
> On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > Hide buffers that store formatted IP addresses in a private data structure
> > maintained in net/sunrpc/xprtsock.c.
>
> Why? Aren't those generic?

Not necessarily. A transport may choose to use a dynamic algorithm to
generate the addresses, for example; in which case, it would have no
need for such buffers.

--
"We who cut mere stones must always be envisioning cathedrals"
-- Quarry worker's creed

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 21:00:01

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

On Wed, 2006-10-18 at 16:41 -0400, Chuck Lever wrote:
> On 10/18/06, Trond Myklebust <[email protected]> wrote:
> > On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > > Hide buffers that store formatted IP addresses in a private data structure
> > > maintained in net/sunrpc/xprtsock.c.
> >
> > Why? Aren't those generic?
>
> Not necessarily. A transport may choose to use a dynamic algorithm to
> generate the addresses, for example; in which case, it would have no
> need for such buffers.

Do we have such a user today, or do we expect to have one in the near
future? AFAIK the infiniband folks will be using standard IP addresses
too.

Trond


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 21:35:49

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

On 10/18/06, Trond Myklebust <[email protected]> wrote:
> On Wed, 2006-10-18 at 16:41 -0400, Chuck Lever wrote:
> > On 10/18/06, Trond Myklebust <[email protected]> wrote:
> > > On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > > > Hide buffers that store formatted IP addresses in a private data structure
> > > > maintained in net/sunrpc/xprtsock.c.
> > >
> > > Why? Aren't those generic?
> >
> > Not necessarily. A transport may choose to use a dynamic algorithm to
> > generate the addresses, for example; in which case, it would have no
> > need for such buffers.
>
> Do we have such a user today, or do we expect to have one in the near
> future? AFAIK the infiniband folks will be using standard IP addresses
> too.

We can drop this patch if you prefer.

--
"We who cut mere stones must always be envisioning cathedrals"
-- Quarry worker's creed

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-18 21:45:42

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

On Wed, 2006-10-18 at 17:35 -0400, Chuck Lever wrote:
> On 10/18/06, Trond Myklebust <[email protected]> wrote:
> > On Wed, 2006-10-18 at 16:41 -0400, Chuck Lever wrote:
> > > On 10/18/06, Trond Myklebust <[email protected]> wrote:
> > > > On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > > > > Hide buffers that store formatted IP addresses in a private data structure
> > > > > maintained in net/sunrpc/xprtsock.c.
> > > >
> > > > Why? Aren't those generic?
> > >
> > > Not necessarily. A transport may choose to use a dynamic algorithm to
> > > generate the addresses, for example; in which case, it would have no
> > > need for such buffers.
> >
> > Do we have such a user today, or do we expect to have one in the near
> > future? AFAIK the infiniband folks will be using standard IP addresses
> > too.
>
> We can drop this patch if you prefer.

Yup. In fact, we might want to revert the rpc_xprt_ops->print_addr()
indirection too.



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:29

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 7/9] SUNRPC: move saved socket callback functions to a private data structure

Move the three fields for saving socket callback functions out of the
rpc_xprt structure and into a private data structure maintained in
net/sunrpc/xprtsock.c.

Test plan:
Compile kernel with CONFIG_NFS enabled.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 6 ------
net/sunrpc/xprtsock.c | 25 ++++++++++++++++---------
2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 21beb56..17f3227 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -17,8 +17,6 @@ #include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>

-#include <net/sock.h>
-
extern unsigned int xprt_udp_slot_table_entries;
extern unsigned int xprt_tcp_slot_table_entries;

@@ -191,10 +189,6 @@ struct rpc_xprt {
bklog_u; /* backlog queue utilization */
} stat;

- void (*old_data_ready)(struct sock *, int);
- void (*old_state_change)(struct sock *);
- void (*old_write_space)(struct sock *);
-
char * address_strings[RPC_DISPLAY_MAX];
};

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index c0e23e3..5eeccc4 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -157,6 +157,13 @@ struct xs_xprt {
*/
size_t rcvsize,
sndsize;
+
+ /*
+ * Saved socket callback addresses
+ */
+ void (*old_data_ready)(struct sock *, int);
+ void (*old_state_change)(struct sock *);
+ void (*old_write_space)(struct sock *);
};

/*
@@ -554,9 +561,9 @@ static void xs_close(struct rpc_xprt *xp
private->sock = NULL;

sk->sk_user_data = NULL;
- sk->sk_data_ready = xprt->old_data_ready;
- sk->sk_state_change = xprt->old_state_change;
- sk->sk_write_space = xprt->old_write_space;
+ sk->sk_data_ready = private->old_data_ready;
+ sk->sk_state_change = private->old_state_change;
+ sk->sk_write_space = private->old_write_space;
write_unlock_bh(&sk->sk_callback_lock);

sk->sk_no_check = 0;
@@ -1155,9 +1162,9 @@ static void xs_udp_connect_worker(void *
write_lock_bh(&sk->sk_callback_lock);

sk->sk_user_data = xprt;
- xprt->old_data_ready = sk->sk_data_ready;
- xprt->old_state_change = sk->sk_state_change;
- xprt->old_write_space = sk->sk_write_space;
+ private->old_data_ready = sk->sk_data_ready;
+ private->old_state_change = sk->sk_state_change;
+ private->old_write_space = sk->sk_write_space;
sk->sk_data_ready = xs_udp_data_ready;
sk->sk_write_space = xs_udp_write_space;
sk->sk_no_check = UDP_CSUM_NORCV;
@@ -1242,9 +1249,9 @@ static void xs_tcp_connect_worker(void *
write_lock_bh(&sk->sk_callback_lock);

sk->sk_user_data = xprt;
- xprt->old_data_ready = sk->sk_data_ready;
- xprt->old_state_change = sk->sk_state_change;
- xprt->old_write_space = sk->sk_write_space;
+ private->old_data_ready = sk->sk_data_ready;
+ private->old_state_change = sk->sk_state_change;
+ private->old_write_space = sk->sk_write_space;
sk->sk_data_ready = xs_tcp_data_ready;
sk->sk_state_change = xs_tcp_state_change;
sk->sk_write_space = xs_tcp_write_space;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:28

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 5/9] SUNRPC: Move rpc_xprt socket connect fields into private data structure

Move the socket-specific connection management fields out of the generic
rpc_xprt structure into a private data structure maintained in
net/sunrpc/xprtsock.c.

Test plan:
Connectathon.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 2 --
net/sunrpc/xprtsock.c | 36 +++++++++++++++++++++++++-----------
2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 3ff8230..18bf72c 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -163,8 +163,6 @@ struct rpc_xprt {
unsigned long connect_timeout,
bind_timeout,
reestablish_timeout;
- struct work_struct connect_worker;
- unsigned short port;

/*
* Disconnection of idle transports
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 363b2fc..b0bead5 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -145,6 +145,12 @@ struct xs_xprt {

unsigned long tcp_copied,
tcp_flags;
+
+ /*
+ * Connection of transports
+ */
+ struct work_struct connect_worker;
+ unsigned short port;
};

/*
@@ -565,7 +571,7 @@ static void xs_destroy(struct rpc_xprt *
{
dprintk("RPC: xs_destroy xprt %p\n", xprt);

- cancel_delayed_work(&xprt->connect_worker);
+ cancel_delayed_work(&xs_private_data(xprt)->connect_worker);
flush_scheduled_work();

xprt_disconnect(xprt);
@@ -1076,18 +1082,19 @@ static void xs_set_port(struct rpc_xprt

static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
{
+ struct xs_xprt *private = xs_private_data(xprt);
struct sockaddr_in myaddr = {
.sin_family = AF_INET,
};
int err;
- unsigned short port = xprt->port;
+ unsigned short port = private->port;

do {
myaddr.sin_port = htons(port);
err = kernel_bind(sock, (struct sockaddr *) &myaddr,
sizeof(myaddr));
if (err == 0) {
- xprt->port = port;
+ private->port = port;
dprintk("RPC: xs_bindresvport bound to port %u\n",
port);
return 0;
@@ -1096,7 +1103,7 @@ static int xs_bindresvport(struct rpc_xp
port = xprt_max_resvport;
else
port--;
- } while (err == -EADDRINUSE && port != xprt->port);
+ } while (err == -EADDRINUSE && port != private->port);

dprintk("RPC: can't bind to reserved port (%d).\n", -err);
return err;
@@ -1302,14 +1309,14 @@ static void xs_connect(struct rpc_task *
if (private->sock != NULL) {
dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
xprt, xprt->reestablish_timeout / HZ);
- schedule_delayed_work(&xprt->connect_worker,
+ schedule_delayed_work(&private->connect_worker,
xprt->reestablish_timeout);
xprt->reestablish_timeout <<= 1;
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
} else {
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
- schedule_work(&xprt->connect_worker);
+ schedule_work(&private->connect_worker);

/* flush_scheduled_work can sleep... */
if (!RPC_IS_ASYNC(task))
@@ -1325,8 +1332,10 @@ static void xs_connect(struct rpc_task *
*/
static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{
+ struct xs_xprt *private = xs_private_data(xprt);
+
seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
- xprt->port,
+ private->port,
xprt->stat.bind_count,
xprt->stat.sends,
xprt->stat.recvs,
@@ -1343,13 +1352,14 @@ static void xs_udp_print_stats(struct rp
*/
static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{
+ struct xs_xprt *private = xs_private_data(xprt);
long idle_time = 0;

if (xprt_connected(xprt))
idle_time = (long)(jiffies - xprt->last_used) / HZ;

seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
- xprt->port,
+ private->port,
xprt->stat.bind_count,
xprt->stat.connect_count,
xprt->stat.connect_time,
@@ -1423,7 +1433,7 @@ static struct rpc_xprt *xs_setup_xprt(st

memcpy(&xprt->addr, addr, addrlen);
xprt->addrlen = addrlen;
- xprt->port = xs_get_random_port();
+ private->port = xs_get_random_port();

return xprt;
}
@@ -1438,10 +1448,12 @@ static struct rpc_xprt *xs_setup_xprt(st
struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{
struct rpc_xprt *xprt;
+ struct xs_xprt *private;

xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
if (IS_ERR(xprt))
return xprt;
+ private = xs_private_data(xprt);

if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt);
@@ -1451,7 +1463,7 @@ struct rpc_xprt *xs_setup_udp(struct soc
/* XXX: header size can vary due to auth type, IPv6, etc. */
xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);

- INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
+ INIT_WORK(&private->connect_worker, xs_udp_connect_worker, xprt);
xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_UDP_CONN_TO;
xprt->reestablish_timeout = XS_UDP_REEST_TO;
@@ -1481,10 +1493,12 @@ struct rpc_xprt *xs_setup_udp(struct soc
struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{
struct rpc_xprt *xprt;
+ struct xs_xprt *private;

xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
if (IS_ERR(xprt))
return xprt;
+ private = xs_private_data(xprt);

if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt);
@@ -1493,7 +1507,7 @@ struct rpc_xprt *xs_setup_tcp(struct soc
xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;

- INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
+ INIT_WORK(&private->connect_worker, xs_tcp_connect_worker, xprt);
xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_TCP_CONN_TO;
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:22

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 3/9] SUNRPC: Remove sock and inet fields from rpc_xprt

The "sock" and "inet" fields are socket-specific. Move them to a private
data structure maintained entirely within net/sunrpc/xprtsock.c

Test plan:
Connectathon.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 4 +--
net/sunrpc/xprtsock.c | 68 ++++++++++++++++++++++++++-----------------
2 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index d791901..4c074a7 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -17,6 +17,8 @@ #include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>

+#include <net/sock.h>
+
extern unsigned int xprt_udp_slot_table_entries;
extern unsigned int xprt_tcp_slot_table_entries;

@@ -126,8 +128,6 @@ struct rpc_xprt_ops {
struct rpc_xprt {
struct kref kref; /* Reference count */
struct rpc_xprt_ops * ops; /* transport methods */
- struct socket * sock; /* BSD socket layer */
- struct sock * inet; /* INET layer */

struct rpc_timeout timeout; /* timeout parms */
struct sockaddr_storage addr; /* server address */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 5ddb20d..79088e8 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -127,6 +127,12 @@ #endif

struct xs_xprt {
struct rpc_xprt xprt;
+
+ /*
+ * Network layer
+ */
+ struct socket * sock;
+ struct sock * inet;
};

static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
@@ -134,6 +140,11 @@ static inline struct xs_xprt *xs_private
return (struct xs_xprt *) xprt;
}

+static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
+{
+ return (struct rpc_xprt *) sk->sk_user_data;
+}
+
static void xs_format_peer_addresses(struct rpc_xprt *xprt)
{
struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
@@ -300,19 +311,20 @@ static void xs_nospace(struct rpc_task *
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
+ struct socket *sock = xs_private_data(xprt)->sock;

dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
task->tk_pid, req->rq_slen - req->rq_bytes_sent,
req->rq_slen);

- if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
+ if (test_bit(SOCK_ASYNC_NOSPACE, &sock->flags)) {
/* Protect against races with write_space */
spin_lock_bh(&xprt->transport_lock);

/* Don't race with disconnect */
if (!xprt_connected(xprt))
task->tk_status = -ENOTCONN;
- else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags))
+ else if (test_bit(SOCK_NOSPACE, &sock->flags))
xprt_wait_for_buffer_space(task);

spin_unlock_bh(&xprt->transport_lock);
@@ -344,8 +356,10 @@ static int xs_udp_send_request(struct rp
req->rq_svec->iov_len);

req->rq_xtime = jiffies;
- status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
- xprt->addrlen, xdr, req->rq_bytes_sent);
+ status = xs_sendpages(xs_private_data(xprt)->sock,
+ (struct sockaddr *) &xprt->addr,
+ xprt->addrlen, xdr,
+ req->rq_bytes_sent);

dprintk("RPC: xs_udp_send_request(%u) = %d\n",
xdr->len - req->rq_bytes_sent, status);
@@ -415,8 +429,8 @@ static int xs_tcp_send_request(struct rp
* called sendmsg(). */
while (1) {
req->rq_xtime = jiffies;
- status = xs_sendpages(xprt->sock, NULL, 0, xdr,
- req->rq_bytes_sent);
+ status = xs_sendpages(xs_private_data(xprt)->sock,
+ NULL, 0, xdr, req->rq_bytes_sent);

dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
xdr->len - req->rq_bytes_sent, status);
@@ -494,8 +508,9 @@ out_release:
*/
static void xs_close(struct rpc_xprt *xprt)
{
- struct socket *sock = xprt->sock;
- struct sock *sk = xprt->inet;
+ struct xs_xprt *private = xs_private_data(xprt);
+ struct socket *sock = private->sock;
+ struct sock *sk = private->inet;

if (!sk)
goto clear_close_wait;
@@ -503,8 +518,8 @@ static void xs_close(struct rpc_xprt *xp
dprintk("RPC: xs_close xprt %p\n", xprt);

write_lock_bh(&sk->sk_callback_lock);
- xprt->inet = NULL;
- xprt->sock = NULL;
+ private->inet = NULL;
+ private->sock = NULL;

sk->sk_user_data = NULL;
sk->sk_data_ready = xprt->old_data_ready;
@@ -540,11 +555,6 @@ static void xs_destroy(struct rpc_xprt *
kfree(xprt);
}

-static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
-{
- return (struct rpc_xprt *) sk->sk_user_data;
-}
-
/**
* xs_udp_data_ready - "data ready" callback for UDP sockets
* @sk: socket with data to read
@@ -961,7 +971,8 @@ static void xs_tcp_write_space(struct so

static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
{
- struct sock *sk = xprt->inet;
+ struct xs_xprt *private = xs_private_data(xprt);
+ struct sock *sk = private->inet;

if (xprt->rcvsize) {
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
@@ -1077,7 +1088,8 @@ static int xs_bindresvport(struct rpc_xp
static void xs_udp_connect_worker(void *args)
{
struct rpc_xprt *xprt = (struct rpc_xprt *) args;
- struct socket *sock = xprt->sock;
+ struct xs_xprt *private = xs_private_data(xprt);
+ struct socket *sock = private->sock;
int err, status = -EIO;

if (xprt->shutdown || !xprt_bound(xprt))
@@ -1099,7 +1111,7 @@ static void xs_udp_connect_worker(void *
dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL));

- if (!xprt->inet) {
+ if (!private->inet) {
struct sock *sk = sock->sk;

write_lock_bh(&sk->sk_callback_lock);
@@ -1116,8 +1128,8 @@ static void xs_udp_connect_worker(void *
xprt_set_connected(xprt);

/* Reset to new socket */
- xprt->sock = sock;
- xprt->inet = sk;
+ private->sock = sock;
+ private->inet = sk;

write_unlock_bh(&sk->sk_callback_lock);
}
@@ -1135,7 +1147,7 @@ out:
static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
{
int result;
- struct socket *sock = xprt->sock;
+ struct socket *sock = xs_private_data(xprt)->sock;
struct sockaddr any;

dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
@@ -1161,13 +1173,14 @@ static void xs_tcp_reuse_connection(stru
static void xs_tcp_connect_worker(void *args)
{
struct rpc_xprt *xprt = (struct rpc_xprt *)args;
- struct socket *sock = xprt->sock;
+ struct xs_xprt *private = xs_private_data(xprt);
+ struct socket *sock = private->sock;
int err, status = -EIO;

if (xprt->shutdown || !xprt_bound(xprt))
goto out;

- if (!xprt->sock) {
+ if (!private->sock) {
/* start from scratch */
if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
@@ -1185,7 +1198,7 @@ static void xs_tcp_connect_worker(void *
dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL));

- if (!xprt->inet) {
+ if (!private->inet) {
struct sock *sk = sock->sk;

write_lock_bh(&sk->sk_callback_lock);
@@ -1208,8 +1221,8 @@ static void xs_tcp_connect_worker(void *
xprt_clear_connected(xprt);

/* Reset to new socket */
- xprt->sock = sock;
- xprt->inet = sk;
+ private->sock = sock;
+ private->inet = sk;

write_unlock_bh(&sk->sk_callback_lock);
}
@@ -1258,11 +1271,12 @@ out_clear:
static void xs_connect(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
+ struct xs_xprt *private = xs_private_data(xprt);

if (xprt_test_and_set_connecting(xprt))
return;

- if (xprt->sock != NULL) {
+ if (private->sock != NULL) {
dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
xprt, xprt->reestablish_timeout / HZ);
schedule_delayed_work(&xprt->connect_worker,

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:29

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 6/9] SUNRPC: Move the UDP socket bufsize parameters to a private data structure

Move the socket-specific buffer size parameters for UDP sockets to a
private data structure maintained in net/sunrpc/xprtsock.c.

Test plan:
Connectathon with NFS over UDP.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 3 ---
net/sunrpc/xprtsock.c | 24 ++++++++++++++++--------
2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 18bf72c..21beb56 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -137,9 +137,6 @@ struct rpc_xprt {
unsigned long cong; /* current congestion */
unsigned long cwnd; /* congestion window */

- size_t rcvsize, /* transport rcv buffer size */
- sndsize; /* transport send buffer size */
-
size_t max_payload; /* largest RPC payload size,
in bytes */
unsigned int tsh_size; /* size of transport specific
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b0bead5..c0e23e3 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -151,6 +151,12 @@ struct xs_xprt {
*/
struct work_struct connect_worker;
unsigned short port;
+
+ /*
+ * UDP socket buffer size parameters
+ */
+ size_t rcvsize,
+ sndsize;
};

/*
@@ -1003,13 +1009,13 @@ static void xs_udp_do_set_buffer_size(st
struct xs_xprt *private = xs_private_data(xprt);
struct sock *sk = private->inet;

- if (xprt->rcvsize) {
+ if (private->rcvsize) {
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
- sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2;
+ sk->sk_rcvbuf = private->rcvsize * xprt->max_reqs * 2;
}
- if (xprt->sndsize) {
+ if (private->sndsize) {
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
- sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
+ sk->sk_sndbuf = private->sndsize * xprt->max_reqs * 2;
sk->sk_write_space(sk);
}
}
@@ -1024,12 +1030,14 @@ static void xs_udp_do_set_buffer_size(st
*/
static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize)
{
- xprt->sndsize = 0;
+ struct xs_xprt *private = xs_private_data(xprt);
+
+ private->sndsize = 0;
if (sndsize)
- xprt->sndsize = sndsize + 1024;
- xprt->rcvsize = 0;
+ private->sndsize = sndsize + 1024;
+ private->rcvsize = 0;
if (rcvsize)
- xprt->rcvsize = rcvsize + 1024;
+ private->rcvsize = rcvsize + 1024;

xs_udp_do_set_buffer_size(xprt);
}

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:29

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 4/9] SUNRPC: Move TCP receive state variables into private data structure

Move the TCP receive state variables from the generic rpc_xprt structure to
a private structure maintained inside net/sunrpc/xprtsock.c.

Also rename a function/variable pair to refer to RPC fragment headers
instead of record markers, to be consistent with types defined in
sunrpc/*.h.

Test plan:
Connectathon with NFS over TCP.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 14 ----
net/sunrpc/xprtsock.c | 159 +++++++++++++++++++++++++------------------
2 files changed, 91 insertions(+), 82 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 4c074a7..3ff8230 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -158,15 +158,6 @@ struct rpc_xprt {
resvport : 1; /* use a reserved port */

/*
- * State of TCP reply receive stuff
- */
- __be32 tcp_recm, /* Fragment header */
- tcp_xid; /* Current XID */
- u32 tcp_reclen, /* fragment length */
- tcp_offset; /* fragment offset */
- unsigned long tcp_copied, /* copied to request */
- tcp_flags;
- /*
* Connection of transports
*/
unsigned long connect_timeout,
@@ -212,11 +203,6 @@ struct rpc_xprt {
char * address_strings[RPC_DISPLAY_MAX];
};

-#define XPRT_LAST_FRAG (1 << 0)
-#define XPRT_COPY_RECM (1 << 1)
-#define XPRT_COPY_XID (1 << 2)
-#define XPRT_COPY_DATA (1 << 3)
-
#ifdef __KERNEL__

/*
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 79088e8..363b2fc 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -133,8 +133,28 @@ struct xs_xprt {
*/
struct socket * sock;
struct sock * inet;
+
+ /*
+ * State of TCP reply receive
+ */
+ __be32 tcp_fraghdr,
+ tcp_xid;
+
+ u32 tcp_offset,
+ tcp_reclen;
+
+ unsigned long tcp_copied,
+ tcp_flags;
};

+/*
+ * tcp_flags
+ */
+#define XS_LAST_FRAG (1UL << 0)
+#define XS_COPY_FRGH (1UL << 1)
+#define XS_COPY_XID (1UL << 2)
+#define XS_COPY_DATA (1UL << 3)
+
static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
{
return (struct xs_xprt *) xprt;
@@ -641,73 +661,73 @@ static inline size_t xs_tcp_copy_data(sk

static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
{
+ struct xs_xprt *private = xs_private_data(xprt);
size_t len, used;
char *p;

- p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
- len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+ p = ((char *) &private->tcp_fraghdr) + private->tcp_offset;
+ len = sizeof(private->tcp_fraghdr) - private->tcp_offset;
used = xs_tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
+ private->tcp_offset += used;
if (used != len)
return;

- xprt->tcp_reclen = ntohl(xprt->tcp_recm);
- if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
- xprt->tcp_flags |= XPRT_LAST_FRAG;
+ private->tcp_reclen = ntohl(private->tcp_fraghdr);
+ if (private->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
+ private->tcp_flags |= XS_LAST_FRAG;
else
- xprt->tcp_flags &= ~XPRT_LAST_FRAG;
- xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
+ private->tcp_flags &= ~XS_LAST_FRAG;
+ private->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;

- xprt->tcp_flags &= ~XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
+ private->tcp_flags &= ~XS_COPY_FRGH;
+ private->tcp_offset = 0;

/* Sanity check of the record length */
- if (unlikely(xprt->tcp_reclen < 4)) {
+ if (unlikely(private->tcp_reclen < 4)) {
dprintk("RPC: invalid TCP record fragment length\n");
xprt_disconnect(xprt);
return;
}
dprintk("RPC: reading TCP record fragment of length %d\n",
- xprt->tcp_reclen);
+ private->tcp_reclen);
}

-static void xs_tcp_check_recm(struct rpc_xprt *xprt)
+static void xs_tcp_check_fraghdr(struct xs_xprt *private)
{
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
- if (xprt->tcp_offset == xprt->tcp_reclen) {
- xprt->tcp_flags |= XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
- if (xprt->tcp_flags & XPRT_LAST_FRAG) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- xprt->tcp_flags |= XPRT_COPY_XID;
- xprt->tcp_copied = 0;
+ if (private->tcp_offset == private->tcp_reclen) {
+ private->tcp_flags |= XS_COPY_FRGH;
+ private->tcp_offset = 0;
+ if (private->tcp_flags & XS_LAST_FRAG) {
+ private->tcp_flags &= ~XS_COPY_DATA;
+ private->tcp_flags |= XS_COPY_XID;
+ private->tcp_copied = 0;
}
}
}

-static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
+static inline void xs_tcp_read_xid(struct xs_xprt *private, skb_reader_t *desc)
{
size_t len, used;
char *p;

- len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+ len = sizeof(private->tcp_xid) - private->tcp_offset;
dprintk("RPC: reading XID (%Zu bytes)\n", len);
- p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+ p = ((char *) &private->tcp_xid) + private->tcp_offset;
used = xs_tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
+ private->tcp_offset += used;
if (used != len)
return;
- xprt->tcp_flags &= ~XPRT_COPY_XID;
- xprt->tcp_flags |= XPRT_COPY_DATA;
- xprt->tcp_copied = 4;
+ private->tcp_flags &= ~XS_COPY_XID;
+ private->tcp_flags |= XS_COPY_DATA;
+ private->tcp_copied = 4;
dprintk("RPC: reading reply for XID %08x\n",
- ntohl(xprt->tcp_xid));
- xs_tcp_check_recm(xprt);
+ ntohl(private->tcp_xid));
+ xs_tcp_check_fraghdr(private);
}

static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
{
+ struct xs_xprt *private = xs_private_data(xprt);
struct rpc_rqst *req;
struct xdr_buf *rcvbuf;
size_t len;
@@ -715,116 +735,116 @@ static inline void xs_tcp_read_request(s

/* Find and lock the request corresponding to this xid */
spin_lock(&xprt->transport_lock);
- req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
+ req = xprt_lookup_rqst(xprt, private->tcp_xid);
if (!req) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ private->tcp_flags &= ~XS_COPY_DATA;
dprintk("RPC: XID %08x request not found!\n",
- ntohl(xprt->tcp_xid));
+ ntohl(private->tcp_xid));
spin_unlock(&xprt->transport_lock);
return;
}

rcvbuf = &req->rq_private_buf;
len = desc->count;
- if (len > xprt->tcp_reclen - xprt->tcp_offset) {
+ if (len > private->tcp_reclen - private->tcp_offset) {
skb_reader_t my_desc;

- len = xprt->tcp_reclen - xprt->tcp_offset;
+ len = private->tcp_reclen - private->tcp_offset;
memcpy(&my_desc, desc, sizeof(my_desc));
my_desc.count = len;
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
&my_desc, xs_tcp_copy_data);
desc->count -= r;
desc->offset += r;
} else
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
desc, xs_tcp_copy_data);

if (r > 0) {
- xprt->tcp_copied += r;
- xprt->tcp_offset += r;
+ private->tcp_copied += r;
+ private->tcp_offset += r;
}
if (r != len) {
/* Error when copying to the receive buffer,
* usually because we weren't able to allocate
* additional buffer pages. All we can do now
- * is turn off XPRT_COPY_DATA, so the request
+ * is turn off XS_COPY_DATA, so the request
* will not receive any additional updates,
* and time out.
* Any remaining data from this record will
* be discarded.
*/
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ private->tcp_flags &= ~XS_COPY_DATA;
dprintk("RPC: XID %08x truncated request\n",
- ntohl(xprt->tcp_xid));
+ ntohl(private->tcp_xid));
dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+ xprt, private->tcp_copied, private->tcp_offset, private->tcp_reclen);
goto out;
}

dprintk("RPC: XID %08x read %Zd bytes\n",
- ntohl(xprt->tcp_xid), r);
+ ntohl(private->tcp_xid), r);
dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+ xprt, private->tcp_copied, private->tcp_offset, private->tcp_reclen);

- if (xprt->tcp_copied == req->rq_private_buf.buflen)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- else if (xprt->tcp_offset == xprt->tcp_reclen) {
- if (xprt->tcp_flags & XPRT_LAST_FRAG)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ if (private->tcp_copied == req->rq_private_buf.buflen)
+ private->tcp_flags &= ~XS_COPY_DATA;
+ else if (private->tcp_offset == private->tcp_reclen) {
+ if (private->tcp_flags & XS_LAST_FRAG)
+ private->tcp_flags &= ~XS_COPY_DATA;
}

out:
- if (!(xprt->tcp_flags & XPRT_COPY_DATA))
- xprt_complete_rqst(req->rq_task, xprt->tcp_copied);
+ if (!(private->tcp_flags & XS_COPY_DATA))
+ xprt_complete_rqst(req->rq_task, private->tcp_copied);
spin_unlock(&xprt->transport_lock);
- xs_tcp_check_recm(xprt);
+ xs_tcp_check_fraghdr(private);
}

-static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
+static inline void xs_tcp_read_discard(struct xs_xprt *private, skb_reader_t *desc)
{
size_t len;

- len = xprt->tcp_reclen - xprt->tcp_offset;
+ len = private->tcp_reclen - private->tcp_offset;
if (len > desc->count)
len = desc->count;
desc->count -= len;
desc->offset += len;
- xprt->tcp_offset += len;
+ private->tcp_offset += len;
dprintk("RPC: discarded %Zu bytes\n", len);
- xs_tcp_check_recm(xprt);
+ xs_tcp_check_fraghdr(private);
}

static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
{
struct rpc_xprt *xprt = rd_desc->arg.data;
+ struct xs_xprt *private = xs_private_data(xprt);
skb_reader_t desc = {
.skb = skb,
.offset = offset,
.count = len,
- .csum = 0
};

dprintk("RPC: xs_tcp_data_recv started\n");
do {
/* Read in a new fragment marker if necessary */
/* Can we ever really expect to get completely empty fragments? */
- if (xprt->tcp_flags & XPRT_COPY_RECM) {
+ if (private->tcp_flags & XS_COPY_FRGH) {
xs_tcp_read_fraghdr(xprt, &desc);
continue;
}
/* Read in the xid if necessary */
- if (xprt->tcp_flags & XPRT_COPY_XID) {
- xs_tcp_read_xid(xprt, &desc);
+ if (private->tcp_flags & XS_COPY_XID) {
+ xs_tcp_read_xid(private, &desc);
continue;
}
/* Read in the request data */
- if (xprt->tcp_flags & XPRT_COPY_DATA) {
+ if (private->tcp_flags & XS_COPY_DATA) {
xs_tcp_read_request(xprt, &desc);
continue;
}
/* Skip over any trailing bytes on short reads */
- xs_tcp_read_discard(xprt, &desc);
+ xs_tcp_read_discard(private, &desc);
} while (desc.count);
dprintk("RPC: xs_tcp_data_recv done\n");
return len - desc.count;
@@ -878,11 +898,14 @@ static void xs_tcp_state_change(struct s
case TCP_ESTABLISHED:
spin_lock_bh(&xprt->transport_lock);
if (!xprt_test_and_set_connected(xprt)) {
+ struct xs_xprt *private = xs_private_data(xprt);
+
/* Reset TCP record info */
- xprt->tcp_offset = 0;
- xprt->tcp_reclen = 0;
- xprt->tcp_copied = 0;
- xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+ private->tcp_offset = 0;
+ private->tcp_reclen = 0;
+ private->tcp_copied = 0;
+ private->tcp_flags = XS_COPY_FRGH | XS_COPY_XID;
+
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
xprt_wake_pending_tasks(xprt, 0);
}

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:37

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 9/9] SUNRPC: skb_read_bits is the same as xs_tcp_copy_data

Clean-up: eliminate xs_tcp_copy_data -- it's exactly the same logic as the
common routine skb_read_bits. The UDP and TCP socket read code now share
the same routine for copying data into an xdr_buf.

Test plan:
None.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xdr.h | 1 +
net/sunrpc/socklib.c | 5 +++--
net/sunrpc/xprtsock.c | 24 ++++--------------------
3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 953723b..73b700e 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -155,6 +155,7 @@ typedef struct {

typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);

+size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len);
extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
skb_reader_t *, skb_read_actor_t);
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 6f17527..9d20136 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -24,16 +24,17 @@ #include <linux/sunrpc/xdr.h>
* Possibly called several times to iterate over an sk_buff and copy
* data out of it.
*/
-static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
+size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
{
if (len > desc->count)
len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, to, len))
+ if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
return 0;
desc->count -= len;
desc->offset += len;
return len;
}
+EXPORT_SYMBOL_GPL(skb_read_bits);

/**
* skb_read_and_csum_bits - copy and checksum from skb to buffer
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index de15e42..0eb958f 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -667,22 +667,6 @@ static void xs_udp_data_ready(struct soc
read_unlock(&sk->sk_callback_lock);
}

-static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
-{
- if (len > desc->count)
- len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
- dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return 0;
- }
- desc->offset += len;
- desc->count -= len;
- dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return len;
-}
-
static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
{
struct xs_xprt *private = xs_private_data(xprt);
@@ -691,7 +675,7 @@ static inline void xs_tcp_read_fraghdr(s

p = ((char *) &private->tcp_fraghdr) + private->tcp_offset;
len = sizeof(private->tcp_fraghdr) - private->tcp_offset;
- used = xs_tcp_copy_data(desc, p, len);
+ used = skb_read_bits(desc, p, len);
private->tcp_offset += used;
if (used != len)
return;
@@ -737,7 +721,7 @@ static inline void xs_tcp_read_xid(struc
len = sizeof(private->tcp_xid) - private->tcp_offset;
dprintk("RPC: reading XID (%Zu bytes)\n", len);
p = ((char *) &private->tcp_xid) + private->tcp_offset;
- used = xs_tcp_copy_data(desc, p, len);
+ used = skb_read_bits(desc, p, len);
private->tcp_offset += used;
if (used != len)
return;
@@ -777,12 +761,12 @@ static inline void xs_tcp_read_request(s
memcpy(&my_desc, desc, sizeof(my_desc));
my_desc.count = len;
r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
- &my_desc, xs_tcp_copy_data);
+ &my_desc, skb_read_bits);
desc->count -= r;
desc->offset += r;
} else
r = xdr_partial_copy_from_skb(rcvbuf, private->tcp_copied,
- desc, xs_tcp_copy_data);
+ desc, skb_read_bits);

if (r > 0) {
private->tcp_copied += r;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:20

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 1/9] SUNRPC: Make the transport-specific setup routine allocate rpc_xprt

Change the location where the rpc_xprt structure is allocated so each
transport implementation can allocate a private area from the same
chunk of memory.

Note also that xprt->ops->destroy, rather than xprt_destroy, is now
responsible for freeing rpc_xprt when the transport is destroyed.

Test plan:
Connectathon.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 4 +-
net/sunrpc/xprt.c | 31 ++++++------------
net/sunrpc/xprtsock.c | 73 +++++++++++++++++++++++++++++--------------
3 files changed, 61 insertions(+), 47 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 0321fb5..d791901 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -265,8 +265,8 @@ void xprt_disconnect(struct rpc_xprt *
/*
* Socket transport setup operations
*/
-int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to);
-int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to);
+struct rpc_xprt * xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);
+struct rpc_xprt * xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);

/*
* Reserved bit positions in xprt->state
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 8085747..8cc2afa 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -891,39 +891,25 @@ void xprt_set_timeout(struct rpc_timeout
*/
struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
{
- int result;
struct rpc_xprt *xprt;
struct rpc_rqst *req;

- if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
- dprintk("RPC: xprt_create_transport: no memory\n");
- return ERR_PTR(-ENOMEM);
- }
- if (size <= sizeof(xprt->addr)) {
- memcpy(&xprt->addr, ap, size);
- xprt->addrlen = size;
- } else {
- kfree(xprt);
- dprintk("RPC: xprt_create_transport: address too large\n");
- return ERR_PTR(-EBADF);
- }
-
switch (proto) {
case IPPROTO_UDP:
- result = xs_setup_udp(xprt, to);
+ xprt = xs_setup_udp(ap, size, to);
break;
case IPPROTO_TCP:
- result = xs_setup_tcp(xprt, to);
+ xprt = xs_setup_tcp(ap, size, to);
break;
default:
printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
proto);
return ERR_PTR(-EIO);
}
- if (result) {
- kfree(xprt);
- dprintk("RPC: xprt_create_transport: failed, %d\n", result);
- return ERR_PTR(result);
+ if (IS_ERR(xprt)) {
+ dprintk("RPC: xprt_create_transport: failed, %ld\n",
+ -PTR_ERR(xprt));
+ return xprt;
}

kref_init(&xprt->kref);
@@ -969,8 +955,11 @@ static void xprt_destroy(struct kref *kr
dprintk("RPC: destroying transport %p\n", xprt);
xprt->shutdown = 1;
del_timer_sync(&xprt->timer);
+
+ /*
+ * Tear down transport state and free the rpc_xprt
+ */
xprt->ops->destroy(xprt);
- kfree(xprt);
}

/**
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 757fc91..a6f778f 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -528,6 +528,7 @@ static void xs_destroy(struct rpc_xprt *
xs_close(xprt);
xs_free_peer_addresses(xprt);
kfree(xprt->slot);
+ kfree(xprt);
}

static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -1349,26 +1350,53 @@ static struct rpc_xprt_ops xs_tcp_ops =
.print_stats = xs_tcp_print_stats,
};

+static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
+{
+ struct rpc_xprt *xprt;
+
+ if (addrlen > sizeof(xprt->addr)) {
+ dprintk("RPC: xs_setup_xprt: address too large\n");
+ return ERR_PTR(-EBADF);
+ }
+
+ xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL);
+ if (xprt == NULL) {
+ dprintk("RPC: xs_setup_xprt: couldn't allocate rpc_xprt\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ xprt->max_reqs = slot_table_size;
+ xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL);
+ if (xprt->slot == NULL) {
+ kfree(xprt);
+ dprintk("RPC: xs_setup_xprt: couldn't allocate slot table\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memcpy(&xprt->addr, addr, addrlen);
+ xprt->addrlen = addrlen;
+ xprt->port = xs_get_random_port();
+
+ return xprt;
+}
+
/**
* xs_setup_udp - Set up transport to use a UDP socket
- * @xprt: transport to set up
+ * @addr: address of remote server
+ * @addrlen: length of address in bytes
* @to: timeout parameters
*
*/
-int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{
- size_t slot_table_size;
- struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
+ struct rpc_xprt *xprt;

- xprt->max_reqs = xprt_udp_slot_table_entries;
- slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
- xprt->slot = kzalloc(slot_table_size, GFP_KERNEL);
- if (xprt->slot == NULL)
- return -ENOMEM;
+ xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
+ if (IS_ERR(xprt))
+ return xprt;

- if (ntohs(addr->sin_port) != 0)
+ if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt);
- xprt->port = xs_get_random_port();

xprt->prot = IPPROTO_UDP;
xprt->tsh_size = 0;
@@ -1392,29 +1420,26 @@ int xs_setup_udp(struct rpc_xprt *xprt,
dprintk("RPC: set up transport to address %s\n",
xs_print_peer_address(xprt, RPC_DISPLAY_ALL));

- return 0;
+ return xprt;
}

/**
* xs_setup_tcp - Set up transport to use a TCP socket
- * @xprt: transport to set up
+ * @addr: address of remote server
+ * @addrlen: length of address in bytes
* @to: timeout parameters
*
*/
-int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{
- size_t slot_table_size;
- struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
+ struct rpc_xprt *xprt;

- xprt->max_reqs = xprt_tcp_slot_table_entries;
- slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
- xprt->slot = kzalloc(slot_table_size, GFP_KERNEL);
- if (xprt->slot == NULL)
- return -ENOMEM;
+ xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
+ if (IS_ERR(xprt))
+ return xprt;

- if (ntohs(addr->sin_port) != 0)
+ if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt);
- xprt->port = xs_get_random_port();

xprt->prot = IPPROTO_TCP;
xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
@@ -1437,5 +1462,5 @@ int xs_setup_tcp(struct rpc_xprt *xprt,
dprintk("RPC: set up transport to address %s\n",
xs_print_peer_address(xprt, RPC_DISPLAY_ALL));

- return 0;
+ return xprt;
}

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 21:15:21

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 2/9] SUNRPC: Allocate a private data area for socket-specific rpc_xprt fields

When setting up a new transport instance, allocate enough memory for an
rpc_xprt and a private area. As part of the same memory allocation, it
will be easy to find one, given a pointer to the other.

Test plan:
Compile kernel with CONFIG_NFS enabled.

Signed-off-by: Chuck Lever <[email protected]>
---

net/sunrpc/xprtsock.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a6f778f..5ddb20d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -125,6 +125,15 @@ static inline void xs_pktdump(char *msg,
}
#endif

+struct xs_xprt {
+ struct rpc_xprt xprt;
+};
+
+static inline struct xs_xprt *xs_private_data(struct rpc_xprt *xprt)
+{
+ return (struct xs_xprt *) xprt;
+}
+
static void xs_format_peer_addresses(struct rpc_xprt *xprt)
{
struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
@@ -1352,6 +1361,7 @@ static struct rpc_xprt_ops xs_tcp_ops =

static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
{
+ struct xs_xprt *private;
struct rpc_xprt *xprt;

if (addrlen > sizeof(xprt->addr)) {
@@ -1359,11 +1369,12 @@ static struct rpc_xprt *xs_setup_xprt(st
return ERR_PTR(-EBADF);
}

- xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL);
- if (xprt == NULL) {
+ private = kzalloc(sizeof(struct xs_xprt), GFP_KERNEL);
+ if (private == NULL) {
dprintk("RPC: xs_setup_xprt: couldn't allocate rpc_xprt\n");
return ERR_PTR(-ENOMEM);
}
+ xprt = &private->xprt;

xprt->max_reqs = slot_table_size;
xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL);

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 22:05:00

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH 8/9] SUNRPC: Store formatted addresses in private data structure

Hide buffers that store formatted IP addresses in a private data structure
maintained in net/sunrpc/xprtsock.c.

Test plan:
Enable RPCDBG_TRANS and run some typical workloads.

Signed-off-by: Chuck Lever <[email protected]>
---

include/linux/sunrpc/xprt.h | 2 --
net/sunrpc/xprtsock.c | 27 +++++++++++++++++----------
2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 17f3227..37a42c8 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -188,8 +188,6 @@ struct rpc_xprt {
unsigned long long req_u, /* average requests on the wire */
bklog_u; /* backlog queue utilization */
} stat;
-
- char * address_strings[RPC_DISPLAY_MAX];
};

#ifdef __KERNEL__
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 5eeccc4..de15e42 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -164,6 +164,8 @@ struct xs_xprt {
void (*old_data_ready)(struct sock *, int);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
+
+ char * address_strings[RPC_DISPLAY_MAX];
};

/*
@@ -187,6 +189,7 @@ static inline struct rpc_xprt *xprt_from
static void xs_format_peer_addresses(struct rpc_xprt *xprt)
{
struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
+ struct xs_xprt *private = xs_private_data(xprt);
char *buf;

buf = kzalloc(20, GFP_KERNEL);
@@ -194,19 +197,19 @@ static void xs_format_peer_addresses(str
snprintf(buf, 20, "%u.%u.%u.%u",
NIPQUAD(addr->sin_addr.s_addr));
}
- xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+ private->address_strings[RPC_DISPLAY_ADDR] = buf;

buf = kzalloc(8, GFP_KERNEL);
if (buf) {
snprintf(buf, 8, "%u",
ntohs(addr->sin_port));
}
- xprt->address_strings[RPC_DISPLAY_PORT] = buf;
+ private->address_strings[RPC_DISPLAY_PORT] = buf;

if (xprt->prot == IPPROTO_UDP)
- xprt->address_strings[RPC_DISPLAY_PROTO] = "udp";
+ private->address_strings[RPC_DISPLAY_PROTO] = "udp";
else
- xprt->address_strings[RPC_DISPLAY_PROTO] = "tcp";
+ private->address_strings[RPC_DISPLAY_PROTO] = "tcp";

buf = kzalloc(48, GFP_KERNEL);
if (buf) {
@@ -215,14 +218,16 @@ static void xs_format_peer_addresses(str
ntohs(addr->sin_port),
xprt->prot == IPPROTO_UDP ? "udp" : "tcp");
}
- xprt->address_strings[RPC_DISPLAY_ALL] = buf;
+ private->address_strings[RPC_DISPLAY_ALL] = buf;
}

static void xs_free_peer_addresses(struct rpc_xprt *xprt)
{
- kfree(xprt->address_strings[RPC_DISPLAY_ADDR]);
- kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
- kfree(xprt->address_strings[RPC_DISPLAY_ALL]);
+ struct xs_xprt *private = xs_private_data(xprt);
+
+ kfree(private->address_strings[RPC_DISPLAY_ADDR]);
+ kfree(private->address_strings[RPC_DISPLAY_PORT]);
+ kfree(private->address_strings[RPC_DISPLAY_ALL]);
}

#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)
@@ -1074,8 +1079,10 @@ static unsigned short xs_get_random_port
*/
static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_format_t format)
{
- if (xprt->address_strings[format] != NULL)
- return xprt->address_strings[format];
+ struct xs_xprt *private = xs_private_data(xprt);
+
+ if (private->address_strings[format] != NULL)
+ return private->address_strings[format];
else
return "unprintable";
}

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-12 23:09:14

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 9/9] SUNRPC: skb_read_bits is the same as xs_tcp_copy_data

On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> Clean-up: eliminate xs_tcp_copy_data -- it's exactly the same logic as the
> common routine skb_read_bits. The UDP and TCP socket read code now share
> the same routine for copying data into an xdr_buf.
>
> Test plan:
> None.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> include/linux/sunrpc/xdr.h | 1 +
> net/sunrpc/socklib.c | 5 +++--
> net/sunrpc/xprtsock.c | 24 ++++--------------------
> 3 files changed, 8 insertions(+), 22 deletions(-)
>
> diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
> index 953723b..73b700e 100644
> --- a/include/linux/sunrpc/xdr.h
> +++ b/include/linux/sunrpc/xdr.h
> @@ -155,6 +155,7 @@ typedef struct {
>
> typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
>
> +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len);
> extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
> extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
> skb_reader_t *, skb_read_actor_t);
> diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
> index 6f17527..9d20136 100644
> --- a/net/sunrpc/socklib.c
> +++ b/net/sunrpc/socklib.c
> @@ -24,16 +24,17 @@ #include <linux/sunrpc/xdr.h>
> * Possibly called several times to iterate over an sk_buff and copy
> * data out of it.
> */
> -static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> {
> if (len > desc->count)
> len = desc->count;
> - if (skb_copy_bits(desc->skb, desc->offset, to, len))
> + if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
> return 0;
> desc->count -= len;
> desc->offset += len;
> return len;
> }
> +EXPORT_SYMBOL_GPL(skb_read_bits);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Why do you need this?

Cheers,
Trond


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-13 07:25:21

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 9/9] SUNRPC: skb_read_bits is the same as xs_tcp_copy_data

On Thu, Oct 12, 2006 at 05:15:23PM -0400, Chuck Lever wrote:
> Clean-up: eliminate xs_tcp_copy_data -- it's exactly the same logic as the
> common routine skb_read_bits. The UDP and TCP socket read code now share
> the same routine for copying data into an xdr_buf.

Looks good, but skb_read_bits is a pretty bad name for a public function
in sunrpc code.

> diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
> index 6f17527..9d20136 100644
> --- a/net/sunrpc/socklib.c
> +++ b/net/sunrpc/socklib.c
> @@ -24,16 +24,17 @@ #include <linux/sunrpc/xdr.h>
> * Possibly called several times to iterate over an sk_buff and copy
> * data out of it.
> */
> -static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> {
> if (len > desc->count)
> len = desc->count;
> - if (skb_copy_bits(desc->skb, desc->offset, to, len))
> + if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
> return 0;
> desc->count -= len;
> desc->offset += len;
> return len;
> }

But given that this code doesn't contain any sunrpc specifics it could
aswell move to net/core/skbuff.c


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-13 19:13:35

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 9/9] SUNRPC: skb_read_bits is the same as xs_tcp_copy_data

On 10/13/06, Christoph Hellwig <[email protected]> wrote:
> On Thu, Oct 12, 2006 at 05:15:23PM -0400, Chuck Lever wrote:
> > Clean-up: eliminate xs_tcp_copy_data -- it's exactly the same logic as the
> > common routine skb_read_bits. The UDP and TCP socket read code now share
> > the same routine for copying data into an xdr_buf.
>
> Looks good, but skb_read_bits is a pretty bad name for a public function
> in sunrpc code.

OK... the name is historical, but can easily be changed. But see below.

> > diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
> > index 6f17527..9d20136 100644
> > --- a/net/sunrpc/socklib.c
> > +++ b/net/sunrpc/socklib.c
> > @@ -24,16 +24,17 @@ #include <linux/sunrpc/xdr.h>
> > * Possibly called several times to iterate over an sk_buff and copy
> > * data out of it.
> > */
> > -static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> > +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> > {
> > if (len > desc->count)
> > len = desc->count;
> > - if (skb_copy_bits(desc->skb, desc->offset, to, len))
> > + if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
> > return 0;
> > desc->count -= len;
> > desc->offset += len;
> > return len;
> > }
>
> But given that this code doesn't contain any sunrpc specifics it could
> as well move to net/core/skbuff.c

That sounds OK. I can also adopt whatever EXPORT_SYMBOL convention is
used there (to address Trond's question about EXPORT_SYMBOL_GPL).

--
"We who cut mere stones must always be envisioning cathedrals"
-- Quarry worker's creed

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2006-10-13 19:34:09

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 9/9] SUNRPC: skb_read_bits is the same as xs_tcp_copy_data

On 10/12/06, Trond Myklebust <[email protected]> wrote:
> On Thu, 2006-10-12 at 17:15 -0400, Chuck Lever wrote:
> > Clean-up: eliminate xs_tcp_copy_data -- it's exactly the same logic as the
> > common routine skb_read_bits. The UDP and TCP socket read code now share
> > the same routine for copying data into an xdr_buf.
> >
> > Test plan:
> > None.
> >
> > Signed-off-by: Chuck Lever <[email protected]>
> > ---
> >
> > include/linux/sunrpc/xdr.h | 1 +
> > net/sunrpc/socklib.c | 5 +++--
> > net/sunrpc/xprtsock.c | 24 ++++--------------------
> > 3 files changed, 8 insertions(+), 22 deletions(-)
> >
> > diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
> > index 953723b..73b700e 100644
> > --- a/include/linux/sunrpc/xdr.h
> > +++ b/include/linux/sunrpc/xdr.h
> > @@ -155,6 +155,7 @@ typedef struct {
> >
> > typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
> >
> > +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len);
> > extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
> > extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
> > skb_reader_t *, skb_read_actor_t);
> > diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
> > index 6f17527..9d20136 100644
> > --- a/net/sunrpc/socklib.c
> > +++ b/net/sunrpc/socklib.c
> > @@ -24,16 +24,17 @@ #include <linux/sunrpc/xdr.h>
> > * Possibly called several times to iterate over an sk_buff and copy
> > * data out of it.
> > */
> > -static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> > +size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
> > {
> > if (len > desc->count)
> > len = desc->count;
> > - if (skb_copy_bits(desc->skb, desc->offset, to, len))
> > + if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
> > return 0;
> > desc->count -= len;
> > desc->offset += len;
> > return len;
> > }
> > +EXPORT_SYMBOL_GPL(skb_read_bits);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Why do you need this?

Ah. At the moment, we don't. I will add this to a later patch where
it will be clear why this is here.

--
"We who cut mere stones must always be envisioning cathedrals"
-- Quarry worker's creed

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs