From dc5ddce956660247e004a4b20a26b7d137ab1644 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 7 Jan 2010 09:42:02 -0500 Subject: sunrpc: parse and return errors reported by gssd The kernel currently ignores any error code sent by gssd and always considers it to be -EACCES. In order to better handle the situation of an expired KRB5 TGT, the kernel needs to be able to parse and deal with the errors that gssd sends. Aside from -EACCES the only error we care about is -EKEYEXPIRED, which we're using to indicate that the upper layers should retry the call a little later. To maintain backward compatibility with older gssd's, any error other than -EKEYEXPIRED is interpreted as -EACCES. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- net/sunrpc/auth_gss/auth_gss.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index f7a7f8380e38..0cfccc2a0297 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -206,8 +206,14 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct ctx->gc_win = window_size; /* gssd signals an error by passing ctx->gc_win = 0: */ if (ctx->gc_win == 0) { - /* in which case, p points to an error code which we ignore */ - p = ERR_PTR(-EACCES); + /* + * in which case, p points to an error code. Anything other + * than -EKEYEXPIRED gets converted to -EACCES. + */ + p = simple_get_bytes(p, end, &ret, sizeof(ret)); + if (!IS_ERR(p)) + p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) : + ERR_PTR(-EACCES); goto err; } /* copy the opaque wire context */ @@ -646,6 +652,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) err = PTR_ERR(p); switch (err) { case -EACCES: + case -EKEYEXPIRED: gss_msg->msg.errno = err; err = mlen; break; -- cgit v1.2.3 From f1a89a118299df9e5afbaaedf83e5709a28632b6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 12 Jan 2010 17:41:10 -0500 Subject: SUNRPC: Deprecate support for site-local addresses RFC 3879 "formally deprecates" site-local IPv6 addresses. We interpret that to mean that the scope ID is ignored for all but link-local addresses. Signed-off-by: Chuck Lever Acked-by: Jeff Layton Signed-off-by: Trond Myklebust --- net/sunrpc/addr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 6dcdd2517819..0756c5da12f4 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c @@ -71,8 +71,7 @@ static size_t rpc_ntop6(const struct sockaddr *sap, if (unlikely(len == 0)) return len; - if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && - !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL)) + if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) return len; rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u", @@ -165,8 +164,7 @@ static int rpc_parse_scope_id(const char *buf, const size_t buflen, if (*delim != IPV6_SCOPE_DELIMITER) return 0; - if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && - !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL)) + if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) return 0; len = (buf + buflen) - delim - 1; -- cgit v1.2.3 From 7a88efe9760de3bc75bde61b0a4c56dbb6cf2494 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 12 Jan 2010 17:41:20 -0500 Subject: SUNRPC: Don't display zero scope IDs A zero scope ID means that it wasn't set, so we don't need to append it to presentation format addresses. Signed-off-by: Chuck Lever Acked-by: Jeff Layton Signed-off-by: Trond Myklebust --- net/sunrpc/addr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 0756c5da12f4..f845d9d72f73 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c @@ -73,6 +73,8 @@ static size_t rpc_ntop6(const struct sockaddr *sap, if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) return len; + if (sin6->sin6_scope_id == 0) + return len; rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u", IPV6_SCOPE_DELIMITER, sin6->sin6_scope_id); -- cgit v1.2.3 From 5a51f13adf7909caec2f8182767485c30e21364e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 14 Jan 2010 15:38:31 -0700 Subject: xprtsock.c: make bc_{malloc/free} static xprtsock.c: make bc_{malloc/free} static The server backchannel buf_alloc and buf_free methods should be static since they are not used outside this file. Signed-off-by: H Hartley Sweeten Cc: J. Bruce Fields Cc: Neil Brown Cc: Trond Myklebust Cc: David S. Miller Signed-off-by: Trond Myklebust --- net/sunrpc/xprtsock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3d739e5d15d8..721bafd95a0f 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2100,7 +2100,7 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) * 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) +static void *bc_malloc(struct rpc_task *task, size_t size) { struct page *page; struct rpc_buffer *buf; @@ -2120,7 +2120,7 @@ void *bc_malloc(struct rpc_task *task, size_t size) /* * Free the space allocated in the bc_alloc routine */ -void bc_free(void *buffer) +static void bc_free(void *buffer) { struct rpc_buffer *buf; -- cgit v1.2.3 From ba17686f62db88f6a591121e768a0c83a2a2647d Mon Sep 17 00:00:00 2001 From: Andy Adamson Date: Tue, 26 Jan 2010 21:24:04 -0500 Subject: nfs41 do not allocate unused back channel pages Signed-off-by: Andy Adamson [Trond.Myklebust@netapp.com: moved definition of svc_is_backchannel() into include/linux/sunrpc/bc_xprt.h.] Signed-off-by: Trond Myklebust --- include/linux/sunrpc/bc_xprt.h | 15 +++++++++++++++ net/sunrpc/svc.c | 4 ++++ 2 files changed, 19 insertions(+) (limited to 'net') diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h index 6508f0dc0eff..d7152b451e21 100644 --- a/include/linux/sunrpc/bc_xprt.h +++ b/include/linux/sunrpc/bc_xprt.h @@ -38,12 +38,27 @@ int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs); void bc_release_request(struct rpc_task *); int bc_send(struct rpc_rqst *req); + +/* + * Determine if a shared backchannel is in use + */ +static inline int svc_is_backchannel(const struct svc_rqst *rqstp) +{ + if (rqstp->rq_server->bc_xprt) + return 1; + return 0; +} #else /* CONFIG_NFS_V4_1 */ static inline int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) { return 0; } + +static inline int svc_is_backchannel(const struct svc_rqst *rqstp) +{ + return 0; +} #endif /* CONFIG_NFS_V4_1 */ #endif /* _LINUX_SUNRPC_BC_XPRT_H */ diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 538ca433a56c..6dcf8c9c784c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -506,6 +506,10 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) { unsigned int pages, arghi; + /* bc_xprt uses fore channel allocated buffers */ + if (svc_is_backchannel(rqstp)) + return 1; + pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply. * We assume one is at most one page */ -- cgit v1.2.3 From 9fcfe0c83c3b04a759cde6b8c5f961237f17808b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 2 Mar 2010 13:06:21 -0500 Subject: SUNRPC: Handle EINVAL error returns from the TCP connect operation This can, for instance, happen if the user specifies a link local IPv6 address. Signed-off-by: Trond Myklebust Cc: stable@kernel.org --- net/sunrpc/xprtsock.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 721bafd95a0f..712412982cee 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1912,6 +1912,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, case -EALREADY: xprt_clear_connecting(xprt); return; + case -EINVAL: + /* Happens, for instance, if the user specified a link + * local IPv6 address without a scope-id. + */ + goto out; } out_eagain: status = -EAGAIN; -- cgit v1.2.3