diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-04-19 16:23:28 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-04-19 16:23:28 +0400 |
commit | d5aeee8cb28317ef608ecac421abc4d986d585d2 (patch) | |
tree | 70ec8ed8891f26e5c58152ffca9924ea1c58fe3a /fs/aio.c | |
parent | 32898a145404acbebe3256709e012c2830a2043b (diff) | |
parent | e816b57a337ea3b755de72bec38c10c864f23015 (diff) | |
download | linux-d5aeee8cb28317ef608ecac421abc4d986d585d2.tar.xz |
Merge tag 'v3.4-rc3' into staging/for_v3.5
* tag 'v3.4-rc3': (3755 commits)
Linux 3.4-rc3
x86-32: fix up strncpy_from_user() sign error
ARM: 7386/1: jump_label: fixup for rename to static_key
ARM: 7384/1: ThumbEE: Disable userspace TEEHBR access for !CONFIG_ARM_THUMBEE
ARM: 7382/1: mm: truncate memory banks to fit in 4GB space for classic MMU
ARM: 7359/2: smp_twd: Only wait for reprogramming on active cpus
PCI: Fix regression in pci_restore_state(), v3
SCSI: Fix error handling when no ULD is attached
ARM: OMAP: clock: cleanup CPUfreq leftovers, fix build errors
ARM: dts: remove blank interrupt-parent properties
ARM: EXYNOS: Fix Kconfig dependencies for device tree enabled machine files
do not export kernel's NULL #define to userspace
ARM: EXYNOS: Remove broken config values for touchscren for NURI board
ARM: EXYNOS: set fix xusbxti clock for NURI and Universal210 boards
ARM: EXYNOS: fix regulator name for NURI board
ARM: SAMSUNG: make SAMSUNG_PM_DEBUG select DEBUG_LL
cpufreq: OMAP: fix build errors: depends on ARCH_OMAP2PLUS
sparc64: Eliminate obsolete __handle_softirq() function
sparc64: Fix bootup crash on sun4v.
ARM: msm: Fix section mismatches in proc_comm.c
...
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 34 |
1 files changed, 12 insertions, 22 deletions
@@ -13,7 +13,7 @@ #include <linux/errno.h> #include <linux/time.h> #include <linux/aio_abi.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/syscalls.h> #include <linux/backing-dev.h> #include <linux/uio.h> @@ -305,15 +305,18 @@ out_freectx: return ERR_PTR(err); } -/* aio_cancel_all +/* kill_ctx * Cancels all outstanding aio requests on an aio context. Used * when the processes owning a context have all exited to encourage * the rapid destruction of the kioctx. */ -static void aio_cancel_all(struct kioctx *ctx) +static void kill_ctx(struct kioctx *ctx) { int (*cancel)(struct kiocb *, struct io_event *); + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); struct io_event res; + spin_lock_irq(&ctx->ctx_lock); ctx->dead = 1; while (!list_empty(&ctx->active_reqs)) { @@ -329,15 +332,7 @@ static void aio_cancel_all(struct kioctx *ctx) spin_lock_irq(&ctx->ctx_lock); } } - spin_unlock_irq(&ctx->ctx_lock); -} - -static void wait_for_all_aios(struct kioctx *ctx) -{ - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - spin_lock_irq(&ctx->ctx_lock); if (!ctx->reqs_active) goto out; @@ -387,9 +382,7 @@ void exit_aio(struct mm_struct *mm) ctx = hlist_entry(mm->ioctx_list.first, struct kioctx, list); hlist_del_rcu(&ctx->list); - aio_cancel_all(ctx); - - wait_for_all_aios(ctx); + kill_ctx(ctx); if (1 != atomic_read(&ctx->users)) printk(KERN_DEBUG @@ -1269,8 +1262,7 @@ static void io_destroy(struct kioctx *ioctx) if (likely(!was_dead)) put_ioctx(ioctx); /* twice for the list */ - aio_cancel_all(ioctx); - wait_for_all_aios(ioctx); + kill_ctx(ioctx); /* * Wake up any waiters. The setting of ctx->dead must be seen @@ -1278,7 +1270,6 @@ static void io_destroy(struct kioctx *ioctx) * locking done by the above calls to ensure this consistency. */ wake_up_all(&ioctx->wait); - put_ioctx(ioctx); /* once for the lookup */ } /* sys_io_setup: @@ -1315,11 +1306,9 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) ret = PTR_ERR(ioctx); if (!IS_ERR(ioctx)) { ret = put_user(ioctx->user_id, ctxp); - if (!ret) { - put_ioctx(ioctx); - return 0; - } - io_destroy(ioctx); + if (ret) + io_destroy(ioctx); + put_ioctx(ioctx); } out: @@ -1337,6 +1326,7 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { io_destroy(ioctx); + put_ioctx(ioctx); return 0; } pr_debug("EINVAL: io_destroy: invalid context id\n"); |