summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/aio.c27
-rw-r--r--include/linux/aio.h2
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/fork.c1
5 files changed, 10 insertions, 22 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)
unsigned long tail;
int ret;
- /* Special case handling for sync iocbs: events go directly
- * into the iocb for fast handling. Note that this will not
- * work if we allow sync kiocbs to be cancelled. in which
- * case the usage count checks will have to move under ctx_lock
- * for all cases.
+ /*
+ * Special case handling for sync iocbs:
+ * - events go directly into the iocb for fast handling
+ * - the sync task with the iocb in its stack holds the single iocb
+ * ref, no other paths have a way to get another ref
+ * - the sync task helpfully left a reference to itself in the iocb
*/
if (is_sync_kiocb(iocb)) {
- int ret;
-
+ BUG_ON(iocb->ki_users != 1);
iocb->ki_user_data = res;
- if (iocb->ki_users == 1) {
- iocb->ki_users = 0;
- ret = 1;
- } else {
- spin_lock_irq(&ctx->ctx_lock);
- iocb->ki_users--;
- ret = (0 == iocb->ki_users);
- spin_unlock_irq(&ctx->ctx_lock);
- }
- /* sync iocbs put the task here for us */
+ iocb->ki_users = 0;
wake_up_process(iocb->ki_obj.tsk);
- return ret;
+ return 1;
}
info = &ctx->ring_info;
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 403d71dcb7c8..9e0ae8711276 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -124,7 +124,7 @@ struct kiocb {
(x)->ki_users = 1; \
(x)->ki_key = KIOCB_SYNC_KEY; \
(x)->ki_filp = (filp); \
- (x)->ki_ctx = &tsk->active_mm->default_kioctx; \
+ (x)->ki_ctx = NULL; \
(x)->ki_cancel = NULL; \
(x)->ki_dtor = NULL; \
(x)->ki_obj.tsk = tsk; \
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 68ab5f2ab9cd..dcfd2ecccb5d 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -51,7 +51,6 @@
.page_table_lock = SPIN_LOCK_UNLOCKED, \
.mmlist = LIST_HEAD_INIT(name.mmlist), \
.cpu_vm_mask = CPU_MASK_ALL, \
- .default_kioctx = INIT_KIOCTX(name.default_kioctx, name), \
}
#define INIT_SIGNALS(sig) { \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 41df81395719..2038bd27b041 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -357,7 +357,6 @@ struct mm_struct {
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
- struct kioctx default_kioctx;
};
struct sighand_struct {
diff --git a/kernel/fork.c b/kernel/fork.c
index 2c70c9cdf5dc..e0d0b77343f8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -323,7 +323,6 @@ static struct mm_struct * mm_init(struct mm_struct * mm)
spin_lock_init(&mm->page_table_lock);
rwlock_init(&mm->ioctx_list_lock);
mm->ioctx_list = NULL;
- mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
mm->free_area_cache = TASK_UNMAPPED_BASE;
mm->cached_hole_size = ~0UL;