aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
author\"J. Bruce Fields\ <bfields@citi.umich.edu>2008-12-23 16:09:47 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-23 16:09:47 -0500
commite712804ae4bd858bd89272aa3fc1a577294c0940 (patch)
tree67ac6fc6d7e01b43e648c38fdbc46d4d875452ca /net/sunrpc/rpc_pipe.c
parentc381060869317b3c84430d4f54965d409cbfe65f (diff)
rpc: call release_pipe only on last close
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>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index c9b57f47108c..3105efbb182d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -126,13 +126,14 @@ rpc_close_pipes(struct inode *inode)
126{ 126{
127 struct rpc_inode *rpci = RPC_I(inode); 127 struct rpc_inode *rpci = RPC_I(inode);
128 struct rpc_pipe_ops *ops; 128 struct rpc_pipe_ops *ops;
129 int need_release;
129 130
130 mutex_lock(&inode->i_mutex); 131 mutex_lock(&inode->i_mutex);
131 ops = rpci->ops; 132 ops = rpci->ops;
132 if (ops != NULL) { 133 if (ops != NULL) {
133 LIST_HEAD(free_list); 134 LIST_HEAD(free_list);
134
135 spin_lock(&inode->i_lock); 135 spin_lock(&inode->i_lock);
136 need_release = rpci->nreaders != 0 || rpci->nwriters != 0;
136 rpci->nreaders = 0; 137 rpci->nreaders = 0;
137 list_splice_init(&rpci->in_upcall, &free_list); 138 list_splice_init(&rpci->in_upcall, &free_list);
138 list_splice_init(&rpci->pipe, &free_list); 139 list_splice_init(&rpci->pipe, &free_list);
@@ -141,7 +142,7 @@ rpc_close_pipes(struct inode *inode)
141 spin_unlock(&inode->i_lock); 142 spin_unlock(&inode->i_lock);
142 rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); 143 rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
143 rpci->nwriters = 0; 144 rpci->nwriters = 0;
144 if (ops->release_pipe) 145 if (need_release && ops->release_pipe)
145 ops->release_pipe(inode); 146 ops->release_pipe(inode);
146 cancel_delayed_work_sync(&rpci->queue_timeout); 147 cancel_delayed_work_sync(&rpci->queue_timeout);
147 } 148 }
@@ -196,6 +197,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
196{ 197{
197 struct rpc_inode *rpci = RPC_I(inode); 198 struct rpc_inode *rpci = RPC_I(inode);
198 struct rpc_pipe_msg *msg; 199 struct rpc_pipe_msg *msg;
200 int last_close;
199 201
200 mutex_lock(&inode->i_mutex); 202 mutex_lock(&inode->i_mutex);
201 if (rpci->ops == NULL) 203 if (rpci->ops == NULL)
@@ -222,7 +224,8 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
222 rpci->ops->destroy_msg, -EAGAIN); 224 rpci->ops->destroy_msg, -EAGAIN);
223 } 225 }
224 } 226 }
225 if (rpci->ops->release_pipe) 227 last_close = rpci->nwriters == 0 && rpci->nreaders == 0;
228 if (last_close && rpci->ops->release_pipe)
226 rpci->ops->release_pipe(inode); 229 rpci->ops->release_pipe(inode);
227out: 230out:
228 mutex_unlock(&inode->i_mutex); 231 mutex_unlock(&inode->i_mutex);