Author: Trond Myklebust SUNRPC: Fix a potential race in rpc_pipefs. Signed-off-by: Trond Myklebust --- net/sunrpc/rpc_pipe.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 16a2458..24cc23a 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -70,8 +70,11 @@ rpc_timeout_upcall_queue(void *data) struct inode *inode = &rpci->vfs_inode; down(&inode->i_sem); + if (rpci->ops == NULL) + goto out; if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) __rpc_purge_upcall(inode, -ETIMEDOUT); +out: up(&inode->i_sem); } @@ -113,8 +116,6 @@ rpc_close_pipes(struct inode *inode) { struct rpc_inode *rpci = RPC_I(inode); - cancel_delayed_work(&rpci->queue_timeout); - flush_scheduled_work(); down(&inode->i_sem); if (rpci->ops != NULL) { rpci->nreaders = 0; @@ -127,6 +128,8 @@ rpc_close_pipes(struct inode *inode) } rpc_inode_setowner(inode, NULL); up(&inode->i_sem); + cancel_delayed_work(&rpci->queue_timeout); + flush_scheduled_work(); } static struct inode * @@ -166,7 +169,7 @@ rpc_pipe_open(struct inode *inode, struc static int rpc_pipe_release(struct inode *inode, struct file *filp) { - struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); + struct rpc_inode *rpci = RPC_I(inode); struct rpc_pipe_msg *msg; down(&inode->i_sem);