aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-02-11 13:59:44 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-03-13 12:10:22 -0400
commit599bd19bdc4c6b20fd91d50f2f79dececbaf80c1 (patch)
tree782dec7d04dd789c841e3798ee4c920c9493fe2c
parent9d5722b7777e64de2d932f46cfee7765fdcc60d6 (diff)
fs: don't allow to complete sync iocbs through aio_complete
The AIO interface is fairly complex because it tries to allow filesystems to always work async and then wakeup a synchronous caller through aio_complete. It turns out that basically no one was doing this to avoid the complexity and context switches, and we've already fixed up the remaining users and can now get rid of this case. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/aio.c24
-rw-r--r--fs/ecryptfs/file.c6
-rw-r--r--fs/read_write.c26
-rw-r--r--include/linux/aio.h4
-rw-r--r--net/socket.c9
5 files changed, 12 insertions, 57 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 667054c7c067..8ca8df1c3550 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -778,22 +778,6 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
778 return 0; 778 return 0;
779} 779}
780 780
781/* wait_on_sync_kiocb:
782 * Waits on the given sync kiocb to complete.
783 */
784ssize_t wait_on_sync_kiocb(struct kiocb *req)
785{
786 while (!req->ki_ctx) {
787 set_current_state(TASK_UNINTERRUPTIBLE);
788 if (req->ki_ctx)
789 break;
790 io_schedule();
791 }
792 __set_current_state(TASK_RUNNING);
793 return req->ki_user_data;
794}
795EXPORT_SYMBOL(wait_on_sync_kiocb);
796
797/* 781/*
798 * exit_aio: called when the last user of mm goes away. At this point, there is 782 * exit_aio: called when the last user of mm goes away. At this point, there is
799 * no way for any new requests to be submited or any of the io_* syscalls to be 783 * no way for any new requests to be submited or any of the io_* syscalls to be
@@ -1025,13 +1009,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
1025 * ref, no other paths have a way to get another ref 1009 * ref, no other paths have a way to get another ref
1026 * - the sync task helpfully left a reference to itself in the iocb 1010 * - the sync task helpfully left a reference to itself in the iocb
1027 */ 1011 */
1028 if (is_sync_kiocb(iocb)) { 1012 BUG_ON(is_sync_kiocb(iocb));
1029 iocb->ki_user_data = res;
1030 smp_wmb();
1031 iocb->ki_ctx = ERR_PTR(-EXDEV);
1032 wake_up_process(iocb->ki_obj.tsk);
1033 return;
1034 }
1035 1013
1036 if (iocb->ki_list.next) { 1014 if (iocb->ki_list.next) {
1037 unsigned long flags; 1015 unsigned long flags;
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 6f4e659f508f..a36da8841e0c 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -52,12 +52,6 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
52 struct file *file = iocb->ki_filp; 52 struct file *file = iocb->ki_filp;
53 53
54 rc = generic_file_read_iter(iocb, to); 54 rc = generic_file_read_iter(iocb, to);
55 /*
56 * Even though this is a async interface, we need to wait
57 * for IO to finish to update atime
58 */
59 if (-EIOCBQUEUED == rc)
60 rc = wait_on_sync_kiocb(iocb);
61 if (rc >= 0) { 55 if (rc >= 0) {
62 path = ecryptfs_dentry_to_lower_path(file->f_path.dentry); 56 path = ecryptfs_dentry_to_lower_path(file->f_path.dentry);
63 touch_atime(path); 57 touch_atime(path);
diff --git a/fs/read_write.c b/fs/read_write.c
index f8b8fc1316ab..76e324e8ce8d 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -346,9 +346,7 @@ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos)
346 346
347 iter->type |= READ; 347 iter->type |= READ;
348 ret = file->f_op->read_iter(&kiocb, iter); 348 ret = file->f_op->read_iter(&kiocb, iter);
349 if (ret == -EIOCBQUEUED) 349 BUG_ON(ret == -EIOCBQUEUED);
350 ret = wait_on_sync_kiocb(&kiocb);
351
352 if (ret > 0) 350 if (ret > 0)
353 *ppos = kiocb.ki_pos; 351 *ppos = kiocb.ki_pos;
354 return ret; 352 return ret;
@@ -368,9 +366,7 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
368 366
369 iter->type |= WRITE; 367 iter->type |= WRITE;
370 ret = file->f_op->write_iter(&kiocb, iter); 368 ret = file->f_op->write_iter(&kiocb, iter);
371 if (ret == -EIOCBQUEUED) 369 BUG_ON(ret == -EIOCBQUEUED);
372 ret = wait_on_sync_kiocb(&kiocb);
373
374 if (ret > 0) 370 if (ret > 0)
375 *ppos = kiocb.ki_pos; 371 *ppos = kiocb.ki_pos;
376 return ret; 372 return ret;
@@ -426,8 +422,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
426 kiocb.ki_pos = *ppos; 422 kiocb.ki_pos = *ppos;
427 423
428 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); 424 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
429 if (-EIOCBQUEUED == ret) 425 BUG_ON(ret == -EIOCBQUEUED);
430 ret = wait_on_sync_kiocb(&kiocb);
431 *ppos = kiocb.ki_pos; 426 *ppos = kiocb.ki_pos;
432 return ret; 427 return ret;
433} 428}
@@ -446,8 +441,7 @@ ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *p
446 iov_iter_init(&iter, READ, &iov, 1, len); 441 iov_iter_init(&iter, READ, &iov, 1, len);
447 442
448 ret = filp->f_op->read_iter(&kiocb, &iter); 443 ret = filp->f_op->read_iter(&kiocb, &iter);
449 if (-EIOCBQUEUED == ret) 444 BUG_ON(ret == -EIOCBQUEUED);
450 ret = wait_on_sync_kiocb(&kiocb);
451 *ppos = kiocb.ki_pos; 445 *ppos = kiocb.ki_pos;
452 return ret; 446 return ret;
453} 447}
@@ -508,8 +502,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
508 kiocb.ki_pos = *ppos; 502 kiocb.ki_pos = *ppos;
509 503
510 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); 504 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
511 if (-EIOCBQUEUED == ret) 505 BUG_ON(ret == -EIOCBQUEUED);
512 ret = wait_on_sync_kiocb(&kiocb);
513 *ppos = kiocb.ki_pos; 506 *ppos = kiocb.ki_pos;
514 return ret; 507 return ret;
515} 508}
@@ -528,8 +521,7 @@ ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, lo
528 iov_iter_init(&iter, WRITE, &iov, 1, len); 521 iov_iter_init(&iter, WRITE, &iov, 1, len);
529 522
530 ret = filp->f_op->write_iter(&kiocb, &iter); 523 ret = filp->f_op->write_iter(&kiocb, &iter);
531 if (-EIOCBQUEUED == ret) 524 BUG_ON(ret == -EIOCBQUEUED);
532 ret = wait_on_sync_kiocb(&kiocb);
533 *ppos = kiocb.ki_pos; 525 *ppos = kiocb.ki_pos;
534 return ret; 526 return ret;
535} 527}
@@ -716,8 +708,7 @@ static ssize_t do_iter_readv_writev(struct file *filp, int rw, const struct iove
716 708
717 iov_iter_init(&iter, rw, iov, nr_segs, len); 709 iov_iter_init(&iter, rw, iov, nr_segs, len);
718 ret = fn(&kiocb, &iter); 710 ret = fn(&kiocb, &iter);
719 if (ret == -EIOCBQUEUED) 711 BUG_ON(ret == -EIOCBQUEUED);
720 ret = wait_on_sync_kiocb(&kiocb);
721 *ppos = kiocb.ki_pos; 712 *ppos = kiocb.ki_pos;
722 return ret; 713 return ret;
723} 714}
@@ -732,8 +723,7 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
732 kiocb.ki_pos = *ppos; 723 kiocb.ki_pos = *ppos;
733 724
734 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); 725 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
735 if (ret == -EIOCBQUEUED) 726 BUG_ON(ret == -EIOCBQUEUED);
736 ret = wait_on_sync_kiocb(&kiocb);
737 *ppos = kiocb.ki_pos; 727 *ppos = kiocb.ki_pos;
738 return ret; 728 return ret;
739} 729}
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 132d1ecba435..f8516430490d 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -37,7 +37,6 @@ struct kiocb {
37 37
38 union { 38 union {
39 void __user *user; 39 void __user *user;
40 struct task_struct *tsk;
41 } ki_obj; 40 } ki_obj;
42 41
43 __u64 ki_user_data; /* user's data for completion */ 42 __u64 ki_user_data; /* user's data for completion */
@@ -63,13 +62,11 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
63 *kiocb = (struct kiocb) { 62 *kiocb = (struct kiocb) {
64 .ki_ctx = NULL, 63 .ki_ctx = NULL,
65 .ki_filp = filp, 64 .ki_filp = filp,
66 .ki_obj.tsk = current,
67 }; 65 };
68} 66}
69 67
70/* prototypes */ 68/* prototypes */
71#ifdef CONFIG_AIO 69#ifdef CONFIG_AIO
72extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb);
73extern void aio_complete(struct kiocb *iocb, long res, long res2); 70extern void aio_complete(struct kiocb *iocb, long res, long res2);
74struct mm_struct; 71struct mm_struct;
75extern void exit_aio(struct mm_struct *mm); 72extern void exit_aio(struct mm_struct *mm);
@@ -77,7 +74,6 @@ extern long do_io_submit(aio_context_t ctx_id, long nr,
77 struct iocb __user *__user *iocbpp, bool compat); 74 struct iocb __user *__user *iocbpp, bool compat);
78void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); 75void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn