aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c27
1 files changed, 9 insertions, 18 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 20bb919eb195..e7cd40b626b7 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -937,28 +937,19 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
937 unsigned long tail; 937 unsigned long tail;
938 int ret; 938 int ret;
939 939
940 /* Special case handling for sync iocbs: events go directly 940 /*
941 * into the iocb for fast handling. Note that this will not 941 * Special case handling for sync iocbs:
942 * work if we allow sync kiocbs to be cancelled. in which 942 * - events go directly into the iocb for fast handling
943 * case the usage count checks will have to move under ctx_lock 943 * - the sync task with the iocb in its stack holds the single iocb
944 * for all cases. 944 * ref, no other paths have a way to get another ref
945 * - the sync task helpfully left a reference to itself in the iocb
945 */ 946 */
946 if (is_sync_kiocb(iocb)) { 947 if (is_sync_kiocb(iocb)) {
947 int ret; 948 BUG_ON(iocb->ki_users != 1);
948
949 iocb->ki_user_data = res; 949 iocb->ki_user_data = res;
950 if (iocb->ki_users == 1) { 950 iocb->ki_users = 0;
951 iocb->ki_users = 0;
952 ret = 1;
953 } else {
954 spin_lock_irq(&ctx->ctx_lock);
955 iocb->ki_users--;
956 ret = (0 == iocb->ki_users);
957 spin_unlock_irq(&ctx->ctx_lock);
958 }
959 /* sync iocbs put the task here for us */
960 wake_up_process(iocb->ki_obj.tsk); 951 wake_up_process(iocb->ki_obj.tsk);
961 return ret; 952 return 1;
962 } 953 }
963 954
964 info = &ctx->ring_info; 955 info = &ctx->ring_info;