]> git.hungrycats.org Git - linux/commitdiff
NFSv4/RPCSEC_GSS: Ensure that RPC userland upcalls time out
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:23:52 +0000 (16:23 +0100)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:23:52 +0000 (16:23 +0100)
correctly if the corresponding userland daemon is not up
and running.

fs/nfs/idmap.c
include/linux/sunrpc/rpc_pipe_fs.h
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
net/sunrpc/sunrpc_syms.c

index 5373803719576fd0d7941c268b9735774e9218c4..f984e0156fa2bd91916f57b32362200e18301db7 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/sched.h>
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
 #include <linux/nfs_fs_sb.h>
index eabb2ebf228933c7e02d97d4733b3c66c8b8afa9..c3752710c74c10ef74d5f0787d03edbf7c71cbba 100644 (file)
@@ -27,6 +27,7 @@ struct rpc_inode {
 #define RPC_PIPE_WAIT_FOR_OPEN 1
        int flags;
        struct rpc_pipe_ops *ops;
+       struct work_struct queue_timeout;
 };
 
 static inline struct rpc_inode *
index 79dbcca25f1e83af578c6b25b754f19d7723aca0..ee2438bf57a8f0208083895961b3faf9502796b1 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/auth_gss.h>
 #include <linux/sunrpc/gss_err.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <asm/uaccess.h>
 
index fdb5554eb246ce1589f36dd2df8b900697cf4cc6..badaa121f29c409844a7d255471a792fd3dafcb4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/utsname.h>
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
 #include <linux/nfs.h>
index d6cf592d6c6cc05841338793e981ec36d367aa5c..1841ac8cb0dab80003d7b1c24a4dac7b430fb7de 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/seq_file.h>
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
 static struct vfsmount *rpc_mount;
@@ -35,6 +36,8 @@ static struct file_system_type rpc_pipe_fs_type;
 
 static kmem_cache_t *rpc_inode_cachep;
 
+#define RPC_UPCALL_TIMEOUT (30*HZ)
+
 static void
 __rpc_purge_upcall(struct inode *inode, int err)
 {
@@ -59,6 +62,18 @@ rpc_purge_upcall(struct inode *inode, int err)
        up(&inode->i_sem);
 }
 
+static void
+rpc_timeout_upcall_queue(void *data)
+{
+       struct rpc_inode *rpci = (struct rpc_inode *)data;
+       struct inode *inode = &rpci->vfs_inode;
+
+       down(&inode->i_sem);
+       if (rpci->nreaders == 0 && !list_empty(&rpci->pipe))
+               __rpc_purge_upcall(inode, -ETIMEDOUT);
+       up(&inode->i_sem);
+}
+
 int
 rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
 {
@@ -66,7 +81,13 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
        int res = 0;
 
        down(&inode->i_sem);
-       if (rpci->nreaders || (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN)) {
+       if (rpci->nreaders) {
+               list_add_tail(&msg->list, &rpci->pipe);
+               rpci->pipelen += msg->len;
+       } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
+               if (list_empty(&rpci->pipe))
+                       schedule_delayed_work(&rpci->queue_timeout,
+                                       RPC_UPCALL_TIMEOUT);
                list_add_tail(&msg->list, &rpci->pipe);
                rpci->pipelen += msg->len;
        } else
@@ -80,6 +101,9 @@ void
 rpc_inode_setowner(struct inode *inode, void *private)
 {
        struct rpc_inode *rpci = RPC_I(inode);
+
+       cancel_delayed_work(&rpci->queue_timeout);
+       flush_scheduled_work();
        down(&inode->i_sem);
        rpci->private = private;
        if (!private)
@@ -133,7 +157,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
        down(&inode->i_sem);
        if (filp->f_mode & FMODE_READ)
                rpci->nreaders --;
-       if (!rpci->nreaders && !(rpci->flags & RPC_PIPE_WAIT_FOR_OPEN))
+       if (!rpci->nreaders)
                __rpc_purge_upcall(inode, -EPIPE);
        up(&inode->i_sem);
        return 0;
@@ -769,6 +793,7 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
                INIT_LIST_HEAD(&rpci->pipe);
                rpci->pipelen = 0;
                init_waitqueue_head(&rpci->waitq);
+               INIT_WORK(&rpci->queue_timeout, rpc_timeout_upcall_queue, rpci);
                rpci->ops = NULL;
        }
 }
index bb05bd79a133064b419c40c4e991990d58114777..ff8d2bb7bb1865b7414561afd114787947d72791 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/auth.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>