aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-02-27 13:05:54 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-02-27 13:37:48 -0500
commit591ad7feaec5417681b4112f8df52fc43bb7c92e (patch)
tree0555df9d98236f6a63ca109632a277c4458842e3 /net/sunrpc/rpc_pipe.c
parent2c9030eef9dbd0d737a7f55646da70d217fd6255 (diff)
SUNRPC: move waitq from RPC pipe to RPC inode
Currently, wait queue, used for polling of RPC pipe changes from user-space, is a part of RPC pipe. But the pipe data itself can be released on NFS umount prior to dentry-inode pair, connected to it (is case of this pair is open by some process). This is not a problem for almost all pipe users, because all PipeFS file operations checks pipe reference prior to using it. Except evenfd. This thing registers itself with "poll" file operation and thus has a reference to pipe wait queue. This leads to oopses on destroying eventfd after NFS umount (like rpc_idmapd do) since not pipe data left to the point already. The solution is to wait queue from pipe data to internal RPC inode data. This looks more logical, because this wiat queue used only for user-space processes, which already holds inode reference. Note: upcalls have to get pipe->dentry prior to dereferecing wait queue to make sure, that mount point won't disappear from underneath us. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index b67b2aecc4ff..ac9ee1590739 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -57,7 +57,7 @@ void rpc_pipefs_notifier_unregister(struct notifier_block *nb)
57} 57}
58EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister); 58EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister);
59 59
60static void rpc_purge_list(struct rpc_pipe *pipe, struct list_head *head, 60static void rpc_purge_list(wait_queue_head_t *waitq, struct list_head *head,
61 void (*destroy_msg)(struct rpc_pipe_msg *), int err) 61 void (*destroy_msg)(struct rpc_pipe_msg *), int err)
62{ 62{
63 struct rpc_pipe_msg *msg; 63 struct rpc_pipe_msg *msg;
@@ -70,7 +70,7 @@ static void rpc_purge_list(struct rpc_pipe *pipe, struct list_head *head,
70 msg->errno = err; 70 msg->errno = err;
71 destroy_msg(msg); 71 destroy_msg(msg);
72 } while (!list_empty(head)); 72 } while (!list_empty(head));
73 wake_up(&pipe->waitq); 73 wake_up(waitq);
74} 74}
75 75
76static void 76static void
@@ -80,6 +80,7 @@ rpc_timeout_upcall_queue(struct work_struct *work)
80 struct rpc_pipe *pipe = 80 struct rpc_pipe *pipe =
81 container_of(work, struct rpc_pipe, queue_timeout.work); 81 container_of(work, struct rpc_pipe, queue_timeout.work);
82 void (*destroy_msg)(struct rpc_pipe_msg *); 82 void (*destroy_msg)(struct rpc_pipe_msg *);
83 struct dentry *dentry;
83 84
84 spin_lock(&pipe->lock); 85 spin_lock(&pipe->lock);
85 destroy_msg = pipe->ops->destroy_msg; 86 destroy_msg = pipe->ops->destroy_msg;
@@ -87,8 +88,13 @@ rpc_timeout_upcall_queue(struct work_struct *work)
87 list_splice_init(&pipe->pipe, &free_list); 88 list_splice_init(&pipe->pipe, &free_list);
88 pipe->pipelen = 0; 89 pipe->pipelen = 0;
89 } 90 }
91 dentry = dget(pipe->dentry);
90 spin_unlock(&pipe->lock); 92 spin_unlock(&pipe->lock);
91 rpc_purge_list(pipe, &free_list, destroy_msg, -ETIMEDOUT); 93 if (dentry) {
94 rpc_purge_list(&RPC_I(dentry->d_inode)->waitq,
95 &free_list, destroy_msg, -ETIMEDOUT);
96 dput(dentry);
97 }
92} 98}
93 99
94ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg, 100ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
@@ -125,6 +131,7 @@ int
125rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg) 131rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg)
126{ 132{
127 int res = -EPIPE; 133 int res = -EPIPE;
134 struct dentry *dentry;
128 135
129 spin_lock(&pipe->lock); 136 spin_lock(&pipe->lock);
130 if (pipe->nreaders) { 137 if (pipe->nreaders) {
@@ -140,8 +147,12 @@ rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg)
140 pipe->pipelen += msg->len; 147 pipe->pipelen += msg->len;
141 res = 0; 148 res = 0;
142 } 149 }
150 dentry = dget(pipe->dentry);
143 spin_unlock(&pipe->lock); 151 spin_unlock(&pipe->lock);
144 wake_up(&pipe->waitq); 152 if (dentry) {
153 wake_up(&RPC_I(dentry->d_inode)->waitq);
154 dput(dentry);
155 }
145 return res; 156 return res;
146} 157}
147EXPORT_SYMBOL_GPL(rpc_queue_upcall); 158EXPORT_SYMBOL_GPL(rpc_queue_upcall);
@@ -168,7 +179,7 @@ rpc_close_pipes(struct inode *inode)
168 pipe->pipelen = 0; 179 pipe->pipelen = 0;
169 pipe->dentry = NULL; 180 pipe->dentry = NULL;
170 spin_unlock(&pipe->lock); 181 spin_unlock(&pipe->lock);
171 rpc_purge_list(pipe, &free_list, pipe->ops->destroy_msg, -EPIPE); 182 rpc_purge_list(&RPC_I(inode)->waitq, &free_list, pipe->ops->destroy_msg, -EPIPE);
172 pipe->nwriters = 0; 183 pipe->nwriters = 0;
173 if (need_release && pipe->ops->release_pipe) 184 if (need_release && pipe->ops->release_pipe)
174 pipe->ops->release_pipe(inode); 185 pipe->ops->release_pipe(inode);
@@ -257,7 +268,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
257 list_splice_init(&pipe->pipe, &free_list); 268 list_splice_init(&pipe->pipe, &free_list);
258 pipe->pipelen = 0; 269 pipe->pipelen = 0;
259 spin_unlock(&pipe->lock); 270 spin_unlock(&pipe->lock);
260 rpc_purge_list(pipe, &free_list, 271 rpc_purge_list(&RPC_I(inode)->waitq, &free_list,
261 pipe->ops->destroy_msg, -EAGAIN); 272 pipe->ops->destroy_msg, -EAGAIN);
262 } 273 }
263 } 274 }
@@ -330,16 +341,18 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
330static unsigned int 341static unsigned int
331rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) 342rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
332{ 343{
333 struct rpc_pipe *pipe = RPC_I(filp->f_path.dentry->d_inode)->pipe; 344 struct inode *inode = filp->f_path.dentry->d_inode;
334 unsigned int mask = 0; 345 struct rpc_inode *rpci = RPC_I(inode);
346 unsigned int mask = POLLOUT | POLLWRNORM;
335 347
336 poll_wait(filp, &pipe->waitq, wait); 348 poll_wait(filp, &rpci->waitq, wait);
337 349
338 mask = POLLOUT | POLLWRNORM; 350 mutex_lock(&inode->i_mutex);
339 if (pipe->dentry == NULL) 351 if (rpci->pipe == NULL)
340 mask |= POLLERR | POLLHUP; 352 mask |= POLLERR | POLLHUP;
341 if (filp->private_data || !list_empty(&pipe->pipe)) 353 else if (filp->private_data || !list_empty(&rpci->pipe->pipe))
342 mask |= POLLIN | POLLRDNORM; 354 mask |= POLLIN | POLLRDNORM;
355 mutex_unlock(&inode->i_mutex);
343 return mask; 356 return mask;
344} 357}
345 358
@@ -543,7 +556,6 @@ init_pipe(struct rpc_pipe *pipe)
543 INIT_LIST_HEAD(&pipe->in_downcall); 556 INIT_LIST_HEAD(&pipe->in_downcall);
544 INIT_LIST_HEAD(&pipe->pipe); 557 INIT_LIST_HEAD(&pipe->pipe);
545 pipe->pipelen = 0; 558 pipe->pipelen = 0;
546 init_waitqueue_head(&pipe->waitq);
547 INIT_DELAYED_WORK(&pipe->queue_timeout, 559 INIT_DELAYED_WORK(&pipe->queue_timeout,
548 rpc_timeout_upcall_queue); 560 rpc_timeout_upcall_queue);
549 pipe->ops = NULL; 561 pipe->ops = NULL;
@@ -1165,6 +1177,7 @@ init_once(void *foo)
1165 inode_init_once(&rpci->vfs_inode); 1177 inode_init_once(&rpci->vfs_inode);
1166 rpci->private = NULL; 1178 rpci->private = NULL;
1167 rpci->pipe = NULL; 1179 rpci->pipe = NULL;
1180 init_waitqueue_head(&rpci->waitq);
1168} 1181}
1169 1182
1170int register_rpc_pipefs(void) 1183int register_rpc_pipefs(void)