Commit 6070fe6f authored by Trond Myklebust's avatar Trond Myklebust

RPC: Ensure that nobody can queue up new upcalls after rpc_close_pipes()

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent bec273b4
...@@ -76,25 +76,35 @@ int ...@@ -76,25 +76,35 @@ int
rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
{ {
struct rpc_inode *rpci = RPC_I(inode); struct rpc_inode *rpci = RPC_I(inode);
int res = 0; int res = -EPIPE;
down(&inode->i_sem); down(&inode->i_sem);
if (rpci->ops == NULL)
goto out;
if (rpci->nreaders) { if (rpci->nreaders) {
list_add_tail(&msg->list, &rpci->pipe); list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len; rpci->pipelen += msg->len;
res = 0;
} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
if (list_empty(&rpci->pipe)) if (list_empty(&rpci->pipe))
schedule_delayed_work(&rpci->queue_timeout, schedule_delayed_work(&rpci->queue_timeout,
RPC_UPCALL_TIMEOUT); RPC_UPCALL_TIMEOUT);
list_add_tail(&msg->list, &rpci->pipe); list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len; rpci->pipelen += msg->len;
} else res = 0;
res = -EPIPE; }
out:
up(&inode->i_sem); up(&inode->i_sem);
wake_up(&rpci->waitq); wake_up(&rpci->waitq);
return res; return res;
} }
static inline void
rpc_inode_setowner(struct inode *inode, void *private)
{
RPC_I(inode)->private = private;
}
static void static void
rpc_close_pipes(struct inode *inode) rpc_close_pipes(struct inode *inode)
{ {
...@@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode) ...@@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode)
rpci->ops->release_pipe(inode); rpci->ops->release_pipe(inode);
rpci->ops = NULL; rpci->ops = NULL;
} }
rpc_inode_setowner(inode, NULL);
up(&inode->i_sem); up(&inode->i_sem);
} }
static inline void
rpc_inode_setowner(struct inode *inode, void *private)
{
RPC_I(inode)->private = private;
}
static struct inode * static struct inode *
rpc_alloc_inode(struct super_block *sb) rpc_alloc_inode(struct super_block *sb)
{ {
...@@ -501,7 +506,6 @@ rpc_depopulate(struct dentry *parent) ...@@ -501,7 +506,6 @@ rpc_depopulate(struct dentry *parent)
dentry = dvec[--n]; dentry = dvec[--n];
if (dentry->d_inode) { if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode); rpc_close_pipes(dentry->d_inode);
rpc_inode_setowner(dentry->d_inode, NULL);
simple_unlink(dir, dentry); simple_unlink(dir, dentry);
} }
dput(dentry); dput(dentry);
...@@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
int error; int error;
shrink_dcache_parent(dentry); shrink_dcache_parent(dentry);
if (dentry->d_inode) { if (dentry->d_inode)
rpc_close_pipes(dentry->d_inode); rpc_close_pipes(dentry->d_inode);
rpc_inode_setowner(dentry->d_inode, NULL);
}
if ((error = simple_rmdir(dir, dentry)) != 0) if ((error = simple_rmdir(dir, dentry)) != 0)
return error; return error;
if (!error) { if (!error) {
...@@ -732,7 +734,6 @@ rpc_unlink(char *path) ...@@ -732,7 +734,6 @@ rpc_unlink(char *path)
d_drop(dentry); d_drop(dentry);
if (dentry->d_inode) { if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode); rpc_close_pipes(dentry->d_inode);
rpc_inode_setowner(dentry->d_inode, NULL);
error = simple_unlink(dir, dentry); error = simple_unlink(dir, dentry);
} }
dput(dentry); dput(dentry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment