Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christoph Hellwig and committed by
Al Viro
599bd19b 9d5722b7

+12 -57
+1 -23
fs/aio.c
··· 778 778 return 0; 779 779 } 780 780 781 - /* wait_on_sync_kiocb: 782 - * Waits on the given sync kiocb to complete. 783 - */ 784 - ssize_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 - } 795 - EXPORT_SYMBOL(wait_on_sync_kiocb); 796 - 797 781 /* 798 782 * exit_aio: called when the last user of mm goes away. At this point, there is 799 783 * no way for any new requests to be submited or any of the io_* syscalls to be ··· 1009 1025 * ref, no other paths have a way to get another ref 1010 1026 * - the sync task helpfully left a reference to itself in the iocb 1011 1027 */ 1012 - if (is_sync_kiocb(iocb)) { 1013 - iocb->ki_user_data = res; 1014 - smp_wmb(); 1015 - iocb->ki_ctx = ERR_PTR(-EXDEV); 1016 - wake_up_process(iocb->ki_obj.tsk); 1017 - return; 1018 - } 1028 + BUG_ON(is_sync_kiocb(iocb)); 1019 1029 1020 1030 if (iocb->ki_list.next) { 1021 1031 unsigned long flags;
-6
fs/ecryptfs/file.c
··· 52 52 struct file *file = iocb->ki_filp; 53 53 54 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 55 if (rc >= 0) { 62 56 path = ecryptfs_dentry_to_lower_path(file->f_path.dentry); 63 57 touch_atime(path);
+8 -18
fs/read_write.c
··· 346 346 347 347 iter->type |= READ; 348 348 ret = file->f_op->read_iter(&kiocb, iter); 349 - if (ret == -EIOCBQUEUED) 350 - ret = wait_on_sync_kiocb(&kiocb); 351 - 349 + BUG_ON(ret == -EIOCBQUEUED); 352 350 if (ret > 0) 353 351 *ppos = kiocb.ki_pos; 354 352 return ret; ··· 366 368 367 369 iter->type |= WRITE; 368 370 ret = file->f_op->write_iter(&kiocb, iter); 369 - if (ret == -EIOCBQUEUED) 370 - ret = wait_on_sync_kiocb(&kiocb); 371 - 371 + BUG_ON(ret == -EIOCBQUEUED); 372 372 if (ret > 0) 373 373 *ppos = kiocb.ki_pos; 374 374 return ret; ··· 422 426 kiocb.ki_pos = *ppos; 423 427 424 428 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); 425 - if (-EIOCBQUEUED == ret) 426 - ret = wait_on_sync_kiocb(&kiocb); 429 + BUG_ON(ret == -EIOCBQUEUED); 427 430 *ppos = kiocb.ki_pos; 428 431 return ret; 429 432 } ··· 441 446 iov_iter_init(&iter, READ, &iov, 1, len); 442 447 443 448 ret = filp->f_op->read_iter(&kiocb, &iter); 444 - if (-EIOCBQUEUED == ret) 445 - ret = wait_on_sync_kiocb(&kiocb); 449 + BUG_ON(ret == -EIOCBQUEUED); 446 450 *ppos = kiocb.ki_pos; 447 451 return ret; 448 452 } ··· 502 508 kiocb.ki_pos = *ppos; 503 509 504 510 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); 505 - if (-EIOCBQUEUED == ret) 506 - ret = wait_on_sync_kiocb(&kiocb); 511 + BUG_ON(ret == -EIOCBQUEUED); 507 512 *ppos = kiocb.ki_pos; 508 513 return ret; 509 514 } ··· 521 528 iov_iter_init(&iter, WRITE, &iov, 1, len); 522 529 523 530 ret = filp->f_op->write_iter(&kiocb, &iter); 524 - if (-EIOCBQUEUED == ret) 525 - ret = wait_on_sync_kiocb(&kiocb); 531 + BUG_ON(ret == -EIOCBQUEUED); 526 532 *ppos = kiocb.ki_pos; 527 533 return ret; 528 534 } ··· 708 716 709 717 iov_iter_init(&iter, rw, iov, nr_segs, len); 710 718 ret = fn(&kiocb, &iter); 711 - if (ret == -EIOCBQUEUED) 712 - ret = wait_on_sync_kiocb(&kiocb); 719 + BUG_ON(ret == -EIOCBQUEUED); 713 720 *ppos = kiocb.ki_pos; 714 721 return ret; 715 722 } ··· 723 732 kiocb.ki_pos = *ppos; 724 733 725 734 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); 726 - if (ret == -EIOCBQUEUED) 727 - ret = wait_on_sync_kiocb(&kiocb); 735 + BUG_ON(ret == -EIOCBQUEUED); 728 736 *ppos = kiocb.ki_pos; 729 737 return ret; 730 738 }
-4
include/linux/aio.h
··· 37 37 38 38 union { 39 39 void __user *user; 40 - struct task_struct *tsk; 41 40 } ki_obj; 42 41 43 42 __u64 ki_user_data; /* user's data for completion */ ··· 62 63 *kiocb = (struct kiocb) { 63 64 .ki_ctx = NULL, 64 65 .ki_filp = filp, 65 - .ki_obj.tsk = current, 66 66 }; 67 67 } 68 68 69 69 /* prototypes */ 70 70 #ifdef CONFIG_AIO 71 - extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb); 72 71 extern void aio_complete(struct kiocb *iocb, long res, long res2); 73 72 struct mm_struct; 74 73 extern void exit_aio(struct mm_struct *mm); ··· 74 77 struct iocb __user *__user *iocbpp, bool compat); 75 78 void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); 76 79 #else 77 - static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; } 78 80 static inline void aio_complete(struct kiocb *iocb, long res, long res2) { } 79 81 struct mm_struct; 80 82 static inline void exit_aio(struct mm_struct *mm) { }
+3 -6
net/socket.c
··· 633 633 init_sync_kiocb(&iocb, NULL); 634 634 ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : 635 635 __sock_sendmsg(&iocb, sock, msg, size); 636 - if (-EIOCBQUEUED == ret) 637 - ret = wait_on_sync_kiocb(&iocb); 636 + BUG_ON(ret == -EIOCBQUEUED); 638 637 return ret; 639 638 } 640 639 ··· 765 766 766 767 init_sync_kiocb(&iocb, NULL); 767 768 ret = __sock_recvmsg(&iocb, sock, msg, size, flags); 768 - if (-EIOCBQUEUED == ret) 769 - ret = wait_on_sync_kiocb(&iocb); 769 + BUG_ON(ret == -EIOCBQUEUED); 770 770 return ret; 771 771 } 772 772 EXPORT_SYMBOL(sock_recvmsg); ··· 778 780 779 781 init_sync_kiocb(&iocb, NULL); 780 782 ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); 781 - if (-EIOCBQUEUED == ret) 782 - ret = wait_on_sync_kiocb(&iocb); 783 + BUG_ON(ret == -EIOCBQUEUED); 783 784 return ret; 784 785 } 785 786