From: Benny Halevy <bhalevy@panasas.com>
To: pnfs@linux-nfs.org
Cc: "J. Bruce Fields" <bfields@fieldses.org>, linux-nfs@vger.kernel.org
Subject: Re: [pnfs] [RFC 28/51] FIXME: nfsd41: sunrpc: Added rpc server-side backchannel handling
Date: Mon, 17 Nov 2008 16:11:27 +0200 [thread overview]
Message-ID: <49217B8F.8060104@panasas.com> (raw)
In-Reply-To: <1226350216-11150-1-git-send-email-bhalevy@panasas.com>
On Nov. 10, 2008, 22:50 +0200, Benny Halevy <bhalevy@panasas.com> wrote:
> FIXME: bhalevy: write up commit message
>
> Signed-off-by: Mike Sager <sager@netapp.com>
> Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
review 11-13: look into using a similar design to the rdma xprt.
we're essentially adding a new transport type which will eventually
be multi-xprt and will work over multiple connections of different
xprts.
> ---
> include/linux/sunrpc/clnt.h | 1 +
> include/linux/sunrpc/svcsock.h | 1 +
> include/linux/sunrpc/xprt.h | 4 +
> net/sunrpc/clnt.c | 1 +
> net/sunrpc/svcsock.c | 76 +++++++++++
> net/sunrpc/xprt.c | 41 ++++++-
> net/sunrpc/xprtsock.c | 284 +++++++++++++++++++++++++++++++++++++++-
> 7 files changed, 398 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index c6a1179..fe6a699 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -118,6 +118,7 @@ struct rpc_create_args {
> unsigned char minorversion;
> rpc_authflavor_t authflavor;
> unsigned long flags;
> + struct svc_sock *bc_sock; /* NFSv4.1 backchannel */
> };
>
> /* Values for "flags" field */
> diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
> index 6bb1ec4..e01a1c6 100644
> --- a/include/linux/sunrpc/svcsock.h
> +++ b/include/linux/sunrpc/svcsock.h
> @@ -28,6 +28,7 @@ struct svc_sock {
> /* private TCP part */
> u32 sk_reclen; /* length of record */
> u32 sk_tcplen; /* current read length */
> + struct rpc_xprt *sk_bc_xprt; /* NFSv4.1 backchannel xprt */
> };
>
> /*
> diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> index 45a92e2..982dbbc 100644
> --- a/include/linux/sunrpc/xprt.h
> +++ b/include/linux/sunrpc/xprt.h
> @@ -180,6 +180,9 @@ struct rpc_xprt {
> spinlock_t reserve_lock; /* lock slot table */
> u32 xid; /* Next XID value to use */
> struct rpc_task * snd_task; /* Task blocked in send */
> +#if defined(CONFIG_NFSD_V4_1)
review 11-13: get rid of #ifdef?
straighten out the naming convention!!!!!!!
(bc_svc_* on the client/rpc receiver and bc_* on the server, rpc sender)
> + struct svc_sock *bc_sock; /* NFSv4.1 backchannel */
> +#endif /* CONFIG_NFSD_V4_1 */
> #if defined(CONFIG_NFS_V4_1)
> struct svc_serv *bc_serv; /* The RPC service which will */
> /* process the callback */
> @@ -232,6 +235,7 @@ struct xprt_create {
> struct sockaddr * srcaddr; /* optional local address */
> struct sockaddr * dstaddr; /* remote peer address */
> size_t addrlen;
> + struct svc_sock *bc_sock; /* NFSv4.1 backchannel */
> };
>
> struct xprt_class {
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index fcadd8e..5e8fba0 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -262,6 +262,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
> .srcaddr = args->saddress,
> .dstaddr = args->address,
> .addrlen = args->addrsize,
> + .bc_sock = args->bc_sock,
> };
> char servername[48];
>
> diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
> index c2b6fa4..0cc826d 100644
> --- a/net/sunrpc/svcsock.c
> +++ b/net/sunrpc/svcsock.c
> @@ -49,6 +49,7 @@
> #include <linux/sunrpc/msg_prot.h>
> #include <linux/sunrpc/svcsock.h>
> #include <linux/sunrpc/stats.h>
> +#include <linux/sunrpc/xprt.h>
>
> #define RPCDBG_FACILITY RPCDBG_SVCXPRT
>
> @@ -795,6 +796,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
> int len;
> struct kvec *vec;
> int pnum, vlen;
> +#if defined(CONFIG_NFSD_V4_1)
> + struct rpc_rqst *req = NULL;
> +#endif
>
> dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
> svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags),
> @@ -878,12 +882,71 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
> len = svsk->sk_reclen;
> set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
>
> + /*
> + * We have enough data for the whole tcp record. Let's try and read the
> + * first 8 bytes to get the xid and the call direction. We can use this
> + * to figure out if this is a call or a reply to a callback. If
> + * sk_reclen is < 8 (xid and calldir), then this is a malformed packet.
> + * In that case, don't bother with the calldir and just read the data.
> + * It will be rejected in svc_process.
> + */
> +
> vec = rqstp->rq_vec;
> vec[0] = rqstp->rq_arg.head[0];
> vlen = PAGE_SIZE;
> +
> + if (len >= 8) {
> + u32 *p;
> + u32 xid;
> + u32 calldir;
> +
> + len = svc_recvfrom(rqstp, vec, 1, 8);
> + if (len < 0)
> + goto error;
> +
> + p = (u32 *)vec[0].iov_base;
> + p = (u32 *)rqstp->rq_arg.head[0].iov_base;
> + xid = *p++;
> + calldir = *p;
> +
> +#if defined(CONFIG_NFSD_V4_1)
> + if (calldir) {
> + /* REPLY */
> + if (svsk->sk_bc_xprt)
> + req = xprt_lookup_rqst(svsk->sk_bc_xprt, xid);
> + if (req) {
> + memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
> + sizeof(struct xdr_buf));
> + vec[0] = req->rq_private_buf.head[0];
> + } else
> + printk(KERN_NOTICE
> + "%s: Got unrecognized reply: "
> + "calldir 0x%x sk_bc_xprt %p xid %08x\n",
> + __func__, ntohl(calldir),
> + svsk->sk_bc_xprt, xid);
> + }
> +
> + if (!calldir || !req)
> + vec[0] = rqstp->rq_arg.head[0];
> +
> +#else /* CONFIG_NFSD_V4_1 */
> + vec[0] = rqstp->rq_arg.head[0];
> +#endif /* CONFIG_NFSD_V4_1 */
> + vec[0].iov_base += 8;
> + vec[0].iov_len -= 8;
> + len = svsk->sk_reclen - 8;
> + vlen -= 8;
> + }
> +
> pnum = 1;
> while (vlen < len) {
> +#if defined(CONFIG_NFSD_V4_1)
> + vec[pnum].iov_base = (req) ?
> + page_address(req->rq_private_buf.pages[pnum - 1]):
> + page_address(rqstp->rq_pages[pnum]);
> +#else /* CONFIG_NFSD_V4_1 */
> vec[pnum].iov_base = page_address(rqstp->rq_pages[pnum]);
> +#endif /* CONFIG_NFSD_V4_1 */
> vec[pnum].iov_len = PAGE_SIZE;
> pnum++;
> vlen += PAGE_SIZE;
> @@ -895,6 +958,18 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
> if (len < 0)
> goto error;
>
> + /*
> + * Account for the 8 bytes we read earlier
> + */
> + len += 8;
> +
> +#if defined(CONFIG_NFSD_V4_1)
> + if (req) {
> + xprt_complete_rqst(req->rq_task, len);
> + len = 0;
> + goto out;
> + }
> +#endif /* CONFIG_NFSD_V4_1 */
> dprintk("svc: TCP complete record (%d bytes)\n", len);
> rqstp->rq_arg.len = len;
> rqstp->rq_arg.page_base = 0;
> @@ -908,6 +983,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
> rqstp->rq_xprt_ctxt = NULL;
> rqstp->rq_prot = IPPROTO_TCP;
>
> +out:
> /* Reset TCP read info */
> svsk->sk_reclen = 0;
> svsk->sk_tcplen = 0;
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index e71f1be..5eeb660 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -1022,6 +1022,27 @@ void xprt_release(struct rpc_task *task)
> spin_unlock(&xprt->reserve_lock);
> }
>
> +/*
> + * The autoclose function for the back channel
> + *
> + * The callback channel should never close the channel,
> + * let the forechannel do that.
> + */
> +static void bc_autoclose(struct work_struct *work)
> +{
> + return;
> +}
> +
> +
> +/*
> + * The autodisconnect routine for the back channel. We never disconnect
> + */
> +static void
> +bc_init_autodisconnect(unsigned long data)
review 11-13: rename to noop_init_autodisconnect and noop_autoclose.
> +{
> + return;
> +}
> +
> /**
> * xprt_create_transport - create an RPC transport
> * @args: rpc transport creation arguments
> @@ -1063,9 +1084,16 @@ found:
> INIT_LIST_HEAD(&xprt->bc_pa_list);
> #endif /* CONFIG_NFS_V4_1 */
>
> - INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
> - setup_timer(&xprt->timer, xprt_init_autodisconnect,
> - (unsigned long)xprt);
> + if (args->bc_sock) {
> + INIT_WORK(&xprt->task_cleanup, bc_autoclose);
> + setup_timer(&xprt->timer, bc_init_autodisconnect,
> + (unsigned long)xprt);
> + } else {
> + INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
> + setup_timer(&xprt->timer, xprt_init_autodisconnect,
> + (unsigned long)xprt);
> + }
> +
> xprt->last_used = jiffies;
> xprt->cwnd = RPC_INITCWND;
> xprt->bind_index = 0;
> @@ -1085,6 +1113,13 @@ found:
> dprintk("RPC: created transport %p with %u slots\n", xprt,
> xprt->max_reqs);
>
> + /*
> + * Since we don't want connections for the backchannel, we set
> + * the xprt status to connected
> + */
> + if (args->bc_sock)
> + xprt_set_connected(xprt);
> +
> return xprt;
> }
>
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 8513d50..5531e50 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -32,6 +32,7 @@
> #include <linux/tcp.h>
> #include <linux/sunrpc/clnt.h>
> #include <linux/sunrpc/sched.h>
> +#include <linux/sunrpc/svcsock.h>
> #include <linux/sunrpc/xprtsock.h>
> #include <linux/file.h>
> #ifdef CONFIG_NFS_V4_1
> @@ -2018,6 +2019,221 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
> xprt->stat.bklog_u);
> }
>
> +#if defined(CONFIG_NFSD_V4_1)
> +/*
> + * The connect worker for the backchannel
> + * This should never be called as we should never need to connect
> + */
> +static void bc_connect_worker(struct work_struct *work)
> +{
> + BUG();
> +}
> +
> +/*
> + * The set_port routine of the rpc_xprt_ops. This is related to the portmapper
> + * and should never be called
> + */
> +
> +static void bc_set_port(struct rpc_xprt *xprt, unsigned short port)
> +{
> + BUG();
> +}
> +
> +/*
> + * The connect routine for the backchannel rpc_xprt ops
> + * Again, should never be called!
> + */
> +
> +static void bc_connect(struct rpc_task *task)
> +{
> + BUG();
> +}
> +
> +struct rpc_buffer {
> + size_t len;
> + char data[];
> +};
> +/*
> + * Allocate a bunch of pages for a scratch buffer for the rpc code. The reason
> + * we allocate pages instead doing a kmalloc like rpc_malloc is because we want
> + * to use the server side send routines.
> + */
> +void *bc_malloc(struct rpc_task *task, size_t size)
> +{
> + struct page *page;
> + struct rpc_buffer *buf;
> +
> + BUG_ON(size > PAGE_SIZE - sizeof(struct rpc_buffer));
> + page = alloc_page(GFP_KERNEL);
> +
> + if (!page)
> + return NULL;
> +
> + buf = page_address(page);
> + buf->len = PAGE_SIZE;
> +
> + return buf->data;
> +}
> +
> +/*
> + * Free the space allocated in the bc_alloc routine
> + */
> +void bc_free(void *buffer)
> +{
> + struct rpc_buffer *buf;
> +
> + if (!buffer)
> + return;
> +
> + buf = container_of(buffer, struct rpc_buffer, data);
> + free_pages((unsigned long)buf, get_order(buf->len));
> +}
> +
> +/*
> + * Use the svc_sock to send the callback. Must be called with svsk->sk_mutex
review 11-13: revise comment. s/svsk->sk_mutex/svc_xprt.xpt_mutex/
> + * held. Borrows heavily from svc_tcp_sendto and xs_tcp_semd_request.
ask Ricardo / Mike Sager if svc_send can be refactored so we'd reuse
the common code.
> + */
> +static int bc_sendto(struct rpc_rqst *req)
> +{
> + int total_len;
> + int len;
> + int size;
> + int result;
> + struct xdr_buf *xbufp = &req->rq_snd_buf;
> + struct page **pages = xbufp->pages;
> + unsigned int flags = MSG_MORE;
> + unsigned int pglen = xbufp->page_len;
> + size_t base = xbufp->page_base;
> + struct rpc_xprt *xprt = req->rq_xprt;
> + struct sock_xprt *transport =
> + container_of(xprt, struct sock_xprt, xprt);
> + struct socket *sock = transport->sock;
> +
> + total_len = xbufp->len;
> +
> + /*
> + * Set up the rpc header and record marker stuff
> + */
> + xs_encode_tcp_record_marker(xbufp);
> +
> + /*
> + * The RPC message is divided into 3 pieces:
> + * - The header: This is what most of the smaller RPC messages consist
> + * of. Often the whole message is in this.
> + *
> + * - xdr->pages: This is a list of pages that contain data, for
> + * example in a write request or while using rpcsec gss
> + *
> + * - The tail: This is the rest of the rpc message
> + *
> + * First we send the header, then the pages and then finally the tail.
> + * The code borrows heavily from svc_sendto.
> + */
> +
> + /*
> + * Send the head
> + */
> + if (total_len == xbufp->head[0].iov_len)
> + flags = 0;
> +
> + len = sock->ops->sendpage(sock, virt_to_page(xbufp->head[0].iov_base),
> + (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK,
> + xbufp->head[0].iov_len, flags);
> +
> + if (len != xbufp->head[0].iov_len)
> + goto out;
> +
> + /*
> + * send page data
> + *
> + * Check the amount of data to be sent. If it is less than the
> + * remaining page, then send it else send the current page
> + */
> +
> + size = PAGE_SIZE - base < pglen ? PAGE_SIZE - base : pglen;
> + while (pglen > 0) {
> + if (total_len == size)
> + flags = 0;
> + result = sock->ops->sendpage(sock, *pages, base, size, flags);
> + if (result > 0)
> + len += result;
> + if (result != size)
> + goto out;
> + total_len -= size;
> + pglen -= size;
> + size = PAGE_SIZE < pglen ? PAGE_SIZE : pglen;
> + base = 0;
> + pages++;
> + }
> + /*
> + * send tail
> + */
> + if (xbufp->tail[0].iov_len) {
> + result = sock->ops->sendpage(sock,
> + xbufp->tail[0].iov_base,
> + (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK,
> + xbufp->tail[0].iov_len,
> + 0);
> +
> + if (result > 0)
> + len += result;
> + }
> +out:
> + if (len != xbufp->len)
> + printk(KERN_NOTICE "Error sending entire callback!\n");
> +
> + return len;
> +}
> +
> +/*
> + * The send routine. Borrows from svc_send
> + */
> +static int bc_send_request(struct rpc_task *task)
> +{
> + struct rpc_rqst *req = task->tk_rqstp;
> + struct rpc_xprt *bc_xprt = req->rq_xprt;
> + struct svc_xprt *xprt;
> + struct svc_sock *svsk;
> + u32 len;
> +
> + dprintk("sending request with xid: %08x\n", ntohl(req->rq_xid));
> + /*
> + * Get the server socket associated with this callback xprt
> + */
> + svsk = bc_xprt->bc_sock;
> + xprt = &svsk->sk_xprt;
> +
> + mutex_lock(&xprt->xpt_mutex);
> + if (test_bit(XPT_DEAD, &xprt->xpt_flags))
> + len = -ENOTCONN;
> + else
> + len = bc_sendto(req);
> + mutex_unlock(&xprt->xpt_mutex);
> +
> + return 0;
> +
> +}
> +
> +/*
> + * The close routine. Since this is client initiated, we do nothing
> + */
> +
> +static void bc_close(struct rpc_xprt *xprt)
> +{
> + return;
> +}
> +
> +/*
> + * The xprt destroy routine. Again, because this connection is client
> + * initiated, we do nothing
> + */
> +
> +static void bc_destroy(struct rpc_xprt *xprt)
> +{
> + return;
> +}
> +#endif /* CONFIG_NFSD_V4_1 */
> +
> static struct rpc_xprt_ops xs_udp_ops = {
> .set_buffer_size = xs_udp_set_buffer_size,
> .reserve_xprt = xprt_reserve_xprt_cong,
> @@ -2054,6 +2270,26 @@ static struct rpc_xprt_ops xs_tcp_ops = {
> .print_stats = xs_tcp_print_stats,
> };
>
> +#if defined(CONFIG_NFSD_V4_1)
> +/*
> + * The rpc_xprt_ops for the server backchannel
> + */
> +
> +static struct rpc_xprt_ops bc_tcp_ops = {
> + .reserve_xprt = xprt_reserve_xprt,
> + .release_xprt = xprt_release_xprt,
> + .set_port = bc_set_port,
> + .connect = bc_connect,
> + .buf_alloc = bc_malloc,
> + .buf_free = bc_free,
> + .send_request = bc_send_request,
> + .set_retrans_timeout = xprt_set_retrans_timeout_def,
> + .close = bc_close,
> + .destroy = bc_destroy,
> + .print_stats = xs_tcp_print_stats,
> +};
> +#endif /* CONFIG_NFSD_V4_1 */
> +
> static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
> unsigned int slot_table_size)
> {
> @@ -2186,13 +2422,31 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
> xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
> xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
>
> - xprt->bind_timeout = XS_BIND_TO;
> - xprt->connect_timeout = XS_TCP_CONN_TO;
> - xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
> - xprt->idle_timeout = XS_IDLE_DISC_TO;
> +#if defined(CONFIG_NFSD_V4_1)
> + if (args->bc_sock) {
review 11-13: get rid if the #ifdef and next: label
(which is just the "else" lag.
> + /* backchannel */
> + xprt_set_bound(xprt);
> + INIT_DELAYED_WORK(&transport->connect_worker,
> + bc_connect_worker);
> + xprt->bind_timeout = 0;
> + xprt->connect_timeout = 0;
> + xprt->reestablish_timeout = 0;
> + xprt->idle_timeout = (~0);
>
> - xprt->ops = &xs_tcp_ops;
> - xprt->timeout = &xs_tcp_default_timeout;
> + /*
> + * The backchannel uses the same socket connection as the
> + * forechannel
> + */
> + xprt->bc_sock = args->bc_sock;
> + xprt->bc_sock->sk_bc_xprt = xprt;
> + transport->sock = xprt->bc_sock->sk_sock;
> + transport->inet = xprt->bc_sock->sk_sk;
> +
> + xprt->ops = &bc_tcp_ops;
> +
> + goto next;
> + }
> +#endif /* CONFIG_NFSD_V4_1 */
>
> switch (addr->sa_family) {
> case AF_INET:
> @@ -2200,13 +2454,29 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
xprt_set_bound(xprt);
INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4);
- xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
break;
case AF_INET6:
if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
> xprt_set_bound(xprt);
>
INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6);
+ break;
+ }
+ xprt->bind_timeout = XS_BIND_TO;
+ xprt->connect_timeout = XS_TCP_CONN_TO;
+ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+ xprt->idle_timeout = XS_IDLE_DISC_TO;
+
+ xprt->ops = &xs_tcp_ops;
+
+next:
+ xprt->timeout = &xs_tcp_default_timeout;
+
+ switch (addr->sa_family) {
+ case AF_INET:
+ xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
+ break;
+ case AF_INET6:
xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
break;
default:
--
1.6.0.1
> INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4);
> - xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
> break;
> case AF_INET6:
> if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
> xprt_set_bound(xprt);
>
> INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6);
> + break;
> + }
> + xprt->bind_timeout = XS_BIND_TO;
> + xprt->connect_timeout = XS_TCP_CONN_TO;
> + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
> + xprt->idle_timeout = XS_IDLE_DISC_TO;
> +
> + xprt->ops = &xs_tcp_ops;
> +
> +next:
> + xprt->timeout = &xs_tcp_default_timeout;
> +
> + switch (addr->sa_family) {
> + case AF_INET:
> + xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
> + break;
> + case AF_INET6:
> xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
> break;
> default:
next prev parent reply other threads:[~2008-11-17 14:11 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-10 20:12 [RFC 0/51] nfs41 server patches for review Benny Halevy
2008-11-10 20:16 ` [RFC 01/51] nfsd: add etoosmall to nfserrno Benny Halevy
2008-11-10 20:39 ` [pnfs] [RFC 0/51] nfs41 server patches for review Benny Halevy
2008-11-10 20:40 ` [RFC 01/51] nfsd: add etoosmall to nfserrno Benny Halevy
2008-11-10 20:41 ` [RFC 02/51] nfsd: dprint each op status in nfsd4_proc_compound Benny Halevy
2008-11-17 13:56 ` [pnfs] " Benny Halevy
2008-11-10 20:41 ` [RFC 03/51] nfsd: git rid of nfs4_cb_null_ops declaration Benny Halevy
2008-11-10 20:41 ` [RFC 04/51] nfsd: fix file comment in fs/nfsd/nfs4xdr.c Benny Halevy
2008-11-17 13:56 ` [pnfs] " Benny Halevy
2008-11-10 20:42 ` [RFC 05/51] nfsd41: Add Kconfig symbols for NFSv4.1 Benny Halevy
2008-11-10 20:42 ` [RFC 06/51] nfsd41: define nfs41 error codes Benny Halevy
2008-11-10 20:43 ` [RFC 07/51] nfsd41: sessions basic data types Benny Halevy
2008-11-17 13:57 ` [pnfs] " Benny Halevy
2008-11-10 20:43 ` [RFC 08/51] nfsd41: introduce nfs4_client cl_sessions list Benny Halevy
2008-11-17 13:58 ` [pnfs] " Benny Halevy
2008-11-10 20:43 ` [RFC 09/51] nfsd41: destroy_session when client is expired Benny Halevy
2008-11-10 20:44 ` [RFC 10/51] nfsd41: sessionid hashing Benny Halevy
2008-11-17 13:58 ` [pnfs] " Benny Halevy
2008-11-10 20:44 ` [RFC 11/51] FIXME: nfsd41: reduce server lease time for nfs41 Benny Halevy
2008-11-17 13:59 ` [pnfs] " Benny Halevy
2008-11-10 20:44 ` [RFC 12/51] nfsd41: provide support for minor version 1 at rpc level Benny Halevy
2008-11-17 14:00 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 13/51] FIXME: nfsd41: introduce current_session Benny Halevy
2008-11-17 14:00 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 14/51] nfsd41: introduce nfs41_{get,set}_slot_state Benny Halevy
2008-11-17 14:01 ` [pnfs] " Benny Halevy
2008-11-10 20:45 ` [RFC 15/51] FIXME: nfsd41: free up slot unless operation is dropped Benny Halevy
2008-11-17 14:01 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 16/51] nfsd41: stateid handling Benny Halevy
2008-11-17 14:02 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 17/51] nfsd41: clientid handling Benny Halevy
2008-11-17 14:03 ` [pnfs] " Benny Halevy
2008-11-10 20:46 ` [RFC 18/51] nfsd41: access_valid Benny Halevy
2008-11-17 14:04 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 19/51] nfsd41: add OPEN4_SHARE_ACCESS_WANT nfs4_stateid bmap Benny Halevy
2008-11-17 14:05 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 20/51] nfsd: last_byte_offset Benny Halevy
2008-11-17 14:06 ` [pnfs] " Benny Halevy
2008-11-10 20:47 ` [RFC 21/51] nfsd41: xdr stubs Benny Halevy
2008-11-17 14:06 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 22/51] nfsd41: proc stubs Benny Halevy
2008-11-17 14:07 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 23/51] nfsd41: exchange_id operation Benny Halevy
2008-11-17 14:07 ` [pnfs] " Benny Halevy
2008-11-10 20:48 ` [RFC 24/51] nfsd41: print exchange flags when purging client Benny Halevy
2008-11-17 14:08 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 25/51] nfsd41: create_session operation Benny Halevy
2008-11-17 14:09 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 26/51] nfsd41: destroy_session operation Benny Halevy
2008-11-17 14:10 ` [pnfs] " Benny Halevy
2008-11-10 20:49 ` [RFC 27/51] nfsd41: sequence operation Benny Halevy
2008-11-17 14:10 ` [pnfs] " Benny Halevy
2008-11-10 20:50 ` [RFC 28/51] FIXME: nfsd41: sunrpc: Added rpc server-side backchannel handling Benny Halevy
2008-11-17 14:11 ` Benny Halevy [this message]
2008-11-10 20:50 ` [RFC 29/51] nfsd: BUG_ON_UNLOCKED_STATE Benny Halevy
2008-11-10 20:50 ` [RFC 30/51] nfsd: lock state around nfs4_put_delegation in nfsd_break_deleg_cb err path Benny Halevy
2008-11-10 20:51 ` [RFC 31/51] FIXME: nfsd: kref_get cb_client while doing the callback Benny Halevy
2008-11-10 20:51 ` [RFC 32/51] nfsd41: callback infrastructure Benny Halevy
2008-11-17 14:12 ` [pnfs] " Benny Halevy
2008-11-10 20:52 ` [RFC 33/51] nfsd41: introduce cl_cb_mutex Benny Halevy
2008-11-10 20:52 ` [RFC 34/51] nfsd41: cb_sequence callback Benny Halevy
2008-11-10 20:52 ` [RFC 35/51] nfsd41: introduce nfs4_cb_call_sync for nfs4 and nfs41 Benny Halevy
2008-11-10 20:53 ` [RFC 36/51] nfsd41: cb_recall callback Benny Halevy
2008-11-10 20:53 ` [RFC 37/51] nfsd41: pass writable attrs mask to nfsd4_decode_fattr Benny Halevy
2008-11-10 20:53 ` [RFC 38/51] nfsd41: support for 3-word long attribute bitmask Benny Halevy
2008-11-17 14:13 ` [pnfs] " Benny Halevy
2008-11-10 20:54 ` [RFC 39/51] nfsd41: SUPPATTR_EXCLCREAT attribute Benny Halevy
2008-11-10 20:54 ` [RFC 40/51] nfsd41: CREATE_EXCLUSIVE4_1 Benny Halevy
2008-11-17 14:13 ` [pnfs] " Benny Halevy
2008-11-10 20:54 ` [RFC 41/51] sunrpc: Add deferral save and restore state callback Benny Halevy
2008-11-10 20:55 ` [RFC 42/51] nfsd: save and restore defer result pages Benny Halevy
2008-11-10 20:55 ` [RFC 43/51] nfsd: deferral processing Benny Halevy
2008-11-10 20:55 ` [RFC 44/51] nfsd41: slab cache for current session Benny Halevy
2008-11-17 14:14 ` [pnfs] " Benny Halevy
2008-11-10 20:56 ` [RFC 45/51] nfsd41: DRC save, restore, and clear functions Benny Halevy
2008-11-17 14:14 ` [pnfs] " Benny Halevy
2008-11-10 20:56 ` [RFC 46/51] nfsd41: nfsd nfsd4_sequence DRC logic Benny Halevy
2008-11-10 20:56 ` [RFC 47/51] nfsd41: enforce NFS4ERR_SEQUENCE_POS operation order rules Benny Halevy
2008-11-17 14:15 ` [pnfs] " Benny Halevy
2008-11-10 20:57 ` [RFC 48/51] nfsd41: nfsd DRC logic Benny Halevy
2008-11-10 20:57 ` [RFC 49/51] nfsd41: clear DRC cache on free_session Benny Halevy
2008-11-10 20:57 ` [RFC 50/51] nfsd41: Add a create session replay cache Benny Halevy
2008-11-17 14:16 ` [pnfs] " Benny Halevy
2008-11-10 20:58 ` [RFC 51/51] nfsd41: print DRC statistics Benny Halevy
2008-11-17 14:17 ` [pnfs] " Benny Halevy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49217B8F.8060104@panasas.com \
--to=bhalevy@panasas.com \
--cc=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
--cc=pnfs@linux-nfs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.