aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p
diff options
context:
space:
mode:
authorTuomas Tynkkynen <tuomas@tuxera.com>2017-09-06 10:59:08 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-10-23 23:10:01 -0400
commit9523feac272ccad2ad8186ba4fcc89103754de52 (patch)
treeb97fef39565c4e8dd15c564cff166753eb2a19df /net/9p
parent8ee031631546cf2f7859cc69593bd60bbdd70b46 (diff)
net/9p: Switch to wait_event_killable()
Because userspace gets Very Unhappy when calls like stat() and execve() return -EINTR on 9p filesystem mounts. For instance, when bash is looking in PATH for things to execute and some SIGCHLD interrupts stat(), bash can throw a spurious 'command not found' since it doesn't retry the stat(). In practice, hitting the problem is rare and needs a really slow/bogged down 9p server. Cc: stable@vger.kernel.org Signed-off-by: Tuomas Tynkkynen <tuomas@tuxera.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/9p')
-rw-r--r--net/9p/client.c3
-rw-r--r--net/9p/trans_virtio.c13
-rw-r--r--net/9p/trans_xen.c4
3 files changed, 9 insertions, 11 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 4674235b0d9b..1beb131dd3e1 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -773,8 +773,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
773 } 773 }
774again: 774again:
775 /* Wait for the response */ 775 /* Wait for the response */
776 err = wait_event_interruptible(*req->wq, 776 err = wait_event_killable(*req->wq, req->status >= REQ_STATUS_RCVD);
777 req->status >= REQ_STATUS_RCVD);
778 777
779 /* 778 /*
780 * Make sure our req is coherent with regard to updates in other 779 * Make sure our req is coherent with regard to updates in other
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index f24b25c25106..f3a4efcf1456 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -286,8 +286,8 @@ req_retry:
286 if (err == -ENOSPC) { 286 if (err == -ENOSPC) {
287 chan->ring_bufs_avail = 0; 287 chan->ring_bufs_avail = 0;
288 spin_unlock_irqrestore(&chan->lock, flags); 288 spin_unlock_irqrestore(&chan->lock, flags);
289 err = wait_event_interruptible(*chan->vc_wq, 289 err = wait_event_killable(*chan->vc_wq,
290 chan->ring_bufs_avail); 290 chan->ring_bufs_avail);
291 if (err == -ERESTARTSYS) 291 if (err == -ERESTARTSYS)
292 return err; 292 return err;
293 293
@@ -327,7 +327,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
327 * Other zc request to finish here 327 * Other zc request to finish here
328 */ 328 */
329 if (atomic_read(&vp_pinned) >= chan->p9_max_pages) { 329 if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
330 err = wait_event_interruptible(vp_wq, 330 err = wait_event_killable(vp_wq,
331 (atomic_read(&vp_pinned) < chan->p9_max_pages)); 331 (atomic_read(&vp_pinned) < chan->p9_max_pages));
332 if (err == -ERESTARTSYS) 332 if (err == -ERESTARTSYS)
333 return err; 333 return err;
@@ -471,8 +471,8 @@ req_retry_pinned:
471 if (err == -ENOSPC) { 471 if (err == -ENOSPC) {
472 chan->ring_bufs_avail = 0; 472 chan->ring_bufs_avail = 0;
473 spin_unlock_irqrestore(&chan->lock, flags); 473 spin_unlock_irqrestore(&chan->lock, flags);
474 err = wait_event_interruptible(*chan->vc_wq, 474 err = wait_event_killable(*chan->vc_wq,
475 chan->ring_bufs_avail); 475 chan->ring_bufs_avail);
476 if (err == -ERESTARTSYS) 476 if (err == -ERESTARTSYS)
477 goto err_out; 477 goto err_out;
478 478
@@ -489,8 +489,7 @@ req_retry_pinned:
489 virtqueue_kick(chan->vq); 489 virtqueue_kick(chan->vq);
490 spin_unlock_irqrestore(&chan->lock, flags); 490 spin_unlock_irqrestore(&chan->lock, flags);
491 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); 491 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
492 err = wait_event_interruptible(*req->wq, 492 err = wait_event_killable(*req->wq, req->status >= REQ_STATUS_RCVD);
493 req->status >= REQ_STATUS_RCVD);
494 /* 493 /*
495 * Non kernel buffers are pinned, unpin them 494 * Non kernel buffers are pinned, unpin them
496 */ 495 */
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index 6ad3e043c617..325c56043007 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -156,8 +156,8 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
156 ring = &priv->rings[num]; 156 ring = &priv->rings[num];
157 157
158again: 158again:
159 while (wait_event_interruptible(ring->wq, 159 while (wait_event_killable(ring->wq,
160 p9_xen_write_todo(ring, size)) != 0) 160 p9_xen_write_todo(ring, size)) != 0)
161 ; 161 ;
162 162
163 spin_lock_irqsave(&ring->lock, flags); 163 spin_lock_irqsave(&ring->lock, flags);