aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c6
-rw-r--r--net/sunrpc/rpc_pipe.c30
-rw-r--r--net/sunrpc/socklib.c5
-rw-r--r--net/sunrpc/svcsock.c10
-rw-r--r--net/sunrpc/xprtsock.c2
5 files changed, 32 insertions, 21 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index f44f46f..8d78228 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -638,7 +638,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
gss_msg);
atomic_inc(&gss_msg->count);
gss_unhash_msg(gss_msg);
- if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
+ if (msg->errno == -ETIMEDOUT) {
unsigned long now = jiffies;
if (time_after(now, ratelimit)) {
printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
@@ -786,7 +786,9 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
cred->gc_flags = 0;
cred->gc_base.cr_ops = &gss_credops;
cred->gc_service = gss_auth->service;
- err = gss_create_upcall(gss_auth, cred);
+ do {
+ err = gss_create_upcall(gss_auth, cred);
+ } while (err == -EAGAIN);
if (err < 0)
goto out_err;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 81e00a6..16a2458 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -39,23 +39,26 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly;
#define RPC_UPCALL_TIMEOUT (30*HZ)
static void
-__rpc_purge_upcall(struct inode *inode, int err)
+__rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err)
{
- struct rpc_inode *rpci = RPC_I(inode);
struct rpc_pipe_msg *msg;
+ void (*destroy_msg)(struct rpc_pipe_msg *);
- while (!list_empty(&rpci->pipe)) {
- msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, list);
- list_del_init(&msg->list);
- msg->errno = err;
- rpci->ops->destroy_msg(msg);
- }
- while (!list_empty(&rpci->in_upcall)) {
- msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, list);
+ destroy_msg = rpci->ops->destroy_msg;
+ while (!list_empty(head)) {
+ msg = list_entry(head->next, struct rpc_pipe_msg, list);
list_del_init(&msg->list);
msg->errno = err;
- rpci->ops->destroy_msg(msg);
+ destroy_msg(msg);
}
+}
+
+static void
+__rpc_purge_upcall(struct inode *inode, int err)
+{
+ struct rpc_inode *rpci = RPC_I(inode);
+
+ __rpc_purge_list(rpci, &rpci->pipe, err);
rpci->pipelen = 0;
wake_up(&rpci->waitq);
}
@@ -115,6 +118,7 @@ rpc_close_pipes(struct inode *inode)
down(&inode->i_sem);
if (rpci->ops != NULL) {
rpci->nreaders = 0;
+ __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);
__rpc_purge_upcall(inode, -EPIPE);
rpci->nwriters = 0;
if (rpci->ops->release_pipe)
@@ -170,7 +174,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
goto out;
msg = (struct rpc_pipe_msg *)filp->private_data;
if (msg != NULL) {
- msg->errno = -EPIPE;
+ msg->errno = -EAGAIN;
list_del_init(&msg->list);
rpci->ops->destroy_msg(msg);
}
@@ -179,7 +183,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
if (filp->f_mode & FMODE_READ)
rpci->nreaders --;
if (!rpci->nreaders)
- __rpc_purge_upcall(inode, -EPIPE);
+ __rpc_purge_upcall(inode, -EAGAIN);
if (rpci->ops->release_pipe)
rpci->ops->release_pipe(inode);
out:
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 8f97e90..eb330d4 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -6,6 +6,9 @@
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/compiler.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/pagemap.h>
#include <linux/udp.h>
@@ -165,6 +168,8 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
return -1;
if ((unsigned short)csum_fold(desc.csum))
return -1;
+ if (unlikely(skb->ip_summed == CHECKSUM_HW))
+ netdev_rx_csum_fault(skb->dev);
return 0;
no_checksum:
if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f16e7cd..c6a5191 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -623,12 +623,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
/* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_len = len;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
- skb_free_datagram(svsk->sk_sk, skb);
- return 0;
- }
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (skb_checksum_complete(skb)) {
+ skb_free_datagram(svsk->sk_sk, skb);
+ return 0;
}
rqstp->rq_skbuff = skb;
}
@@ -1181,6 +1178,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
arg->tail[0].iov_len = 0;
try_to_freeze();
+ cond_resched();
if (signalled())
return -EINTR;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 0a51fd4..77e8800 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -990,6 +990,7 @@ static void xs_udp_connect_worker(void *args)
sk->sk_data_ready = xs_udp_data_ready;
sk->sk_write_space = xs_udp_write_space;
sk->sk_no_check = UDP_CSUM_NORCV;
+ sk->sk_allocation = GFP_ATOMIC;
xprt_set_connected(xprt);
@@ -1074,6 +1075,7 @@ static void xs_tcp_connect_worker(void *args)
sk->sk_data_ready = xs_tcp_data_ready;
sk->sk_state_change = xs_tcp_state_change;
sk->sk_write_space = xs_tcp_write_space;
+ sk->sk_allocation = GFP_ATOMIC;
/* socket options */
sk->sk_userlocks |= SOCK_BINDPORT_LOCK;