diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-31 13:42:57 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-31 13:42:57 -0700 |
commit | 8bb1f229527dee95644e0f8496980bb767c6f620 (patch) | |
tree | 511551e9772f11f855bd5b759b6d449da47e8820 /fs/aio.c | |
parent | f22e08a79f3765fecf060b225a46931c94fb0a92 (diff) | |
parent | c0d0259481cc6ec2a38cad810055e455de35c733 (diff) | |
download | op-kernel-dev-8bb1f229527dee95644e0f8496980bb767c6f620.zip op-kernel-dev-8bb1f229527dee95644e0f8496980bb767c6f620.tar.gz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second try at vfs part d#2 from Al Viro:
"Miklos' first series (with do_lookup() rewrite split into edible
chunks) + assorted bits and pieces.
The 'untangling of do_lookup()' series is is a splitup of what used to
be a monolithic patch from Miklos, so this series is basically "how do
I convince myself that his patch is correct (or find a hole in it)".
No holes found and I like the resulting cleanup, so in it went..."
Changes from try 1: Fix a boot problem with selinux, and commit messages
prettied up a bit.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (24 commits)
vfs: fix out-of-date dentry_unhash() comment
vfs: split __lookup_hash
untangling do_lookup() - take __lookup_hash()-calling case out of line.
untangling do_lookup() - switch to calling __lookup_hash()
untangling do_lookup() - merge d_alloc_and_lookup() callers
untangling do_lookup() - merge failure exits in !dentry case
untangling do_lookup() - massage !dentry case towards __lookup_hash()
untangling do_lookup() - get rid of need_reval in !dentry case
untangling do_lookup() - eliminate a loop.
untangling do_lookup() - expand the area under ->i_mutex
untangling do_lookup() - isolate !dentry stuff from the rest of it.
vfs: move MAY_EXEC check from __lookup_hash()
vfs: don't revalidate just looked up dentry
vfs: fix d_need_lookup/d_revalidate order in do_lookup
ext3: move headers to fs/ext3/
migrate ext2_fs.h guts to fs/ext2/ext2.h
new helper: ext2_image_size()
get rid of pointless includes of ext2_fs.h
ext2: No longer export ext2_fs.h to user space
mtdchar: kill persistently held vfsmount
...
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 32 |
1 files changed, 11 insertions, 21 deletions
@@ -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"); |