aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
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)