rpc: call release_pipe only on last close
author\"J. Bruce Fields\ <bfields@citi.umich.edu>
Tue, 23 Dec 2008 21:09:47 +0000 (16:09 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 23 Dec 2008 21:09:47 +0000 (16:09 -0500)
I can't see any reason we need to call this until either the kernel or
the last gssd closes the pipe.

Also, this allows to guarantee that open_pipe and release_pipe are
called strictly in pairs; open_pipe on gssd's first open, release_pipe
on gssd's last close (or on the close of the kernel side of the pipe, if
that comes first).

That will make it very easy for the gss code to keep track of which
pipes gssd is using.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/rpc_pipe.c

index c9b57f47108c7005de24bff6146e7ac90964a665..3105efbb182d463eed47a03f4771820bd889c3ed 100644 (file)
@@ -126,13 +126,14 @@ rpc_close_pipes(struct inode *inode)
 {
        struct rpc_inode *rpci = RPC_I(inode);
        struct rpc_pipe_ops *ops;
+       int need_release;
 
        mutex_lock(&inode->i_mutex);
        ops = rpci->ops;
        if (ops != NULL) {
                LIST_HEAD(free_list);
-
                spin_lock(&inode->i_lock);
+               need_release = rpci->nreaders != 0 || rpci->nwriters != 0;
                rpci->nreaders = 0;
                list_splice_init(&rpci->in_upcall, &free_list);
                list_splice_init(&rpci->pipe, &free_list);
@@ -141,7 +142,7 @@ rpc_close_pipes(struct inode *inode)
                spin_unlock(&inode->i_lock);
                rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
                rpci->nwriters = 0;
-               if (ops->release_pipe)
+               if (need_release && ops->release_pipe)
                        ops->release_pipe(inode);
                cancel_delayed_work_sync(&rpci->queue_timeout);
        }
@@ -196,6 +197,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
 {
        struct rpc_inode *rpci = RPC_I(inode);
        struct rpc_pipe_msg *msg;
+       int last_close;
 
        mutex_lock(&inode->i_mutex);
        if (rpci->ops == NULL)
@@ -222,7 +224,8 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
                                        rpci->ops->destroy_msg, -EAGAIN);
                }
        }
-       if (rpci->ops->release_pipe)
+       last_close = rpci->nwriters == 0 && rpci->nreaders == 0;
+       if (last_close && rpci->ops->release_pipe)
                rpci->ops->release_pipe(inode);
 out:
        mutex_unlock(&inode->i_mutex);