btrfs: Update existing btrfs_device for renaming device
[safe/jmp/linux-2.6] / fs / aio.c
index d6f89d3..02a2c93 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -24,6 +24,7 @@
 #include <linux/file.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/mmu_context.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/aio.h>
@@ -34,7 +35,6 @@
 
 #include <asm/kmap_types.h>
 #include <asm/uaccess.h>
-#include <asm/mmu_context.h>
 
 #if DEBUG > 1
 #define dprintk                printk
@@ -78,6 +78,7 @@ static int __init aio_setup(void)
 
        return 0;
 }
+__initcall(aio_setup);
 
 static void aio_free_ring(struct kioctx *ctx)
 {
@@ -380,6 +381,7 @@ ssize_t wait_on_sync_kiocb(struct kiocb *iocb)
        __set_current_state(TASK_RUNNING);
        return iocb->ki_user_data;
 }
+EXPORT_SYMBOL(wait_on_sync_kiocb);
 
 /* exit_aio: called when the last user of mm goes away.  At this point, 
  * there is no way for any new requests to be submited or any of the 
@@ -443,7 +445,7 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx)
        req->private = NULL;
        req->ki_iovec = NULL;
        INIT_LIST_HEAD(&req->ki_run_list);
-       req->ki_eventfd = ERR_PTR(-EINVAL);
+       req->ki_eventfd = NULL;
 
        /* Check if the completion queue has enough free space to
         * accept an event from this io.
@@ -485,8 +487,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
 {
        assert_spin_locked(&ctx->ctx_lock);
 
-       if (!IS_ERR(req->ki_eventfd))
-               fput(req->ki_eventfd);
+       if (req->ki_eventfd != NULL)
+               eventfd_ctx_put(req->ki_eventfd);
        if (req->ki_dtor)
                req->ki_dtor(req);
        if (req->ki_iovec != &req->ki_inline_vec)
@@ -508,8 +510,9 @@ static void aio_fput_routine(struct work_struct *data)
                list_del(&req->ki_list);
                spin_unlock_irq(&fput_lock);
 
-               /* Complete the fput */
-               __fput(req->ki_filp);
+               /* Complete the fput(s) */
+               if (req->ki_filp != NULL)
+                       __fput(req->ki_filp);
 
                /* Link the iocb into the context's free list */
                spin_lock_irq(&ctx->ctx_lock);
@@ -532,7 +535,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
 
        assert_spin_locked(&ctx->ctx_lock);
 
-       req->ki_users --;
+       req->ki_users--;
        BUG_ON(req->ki_users < 0);
        if (likely(req->ki_users))
                return 0;
@@ -540,8 +543,11 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
        req->ki_cancel = NULL;
        req->ki_retry = NULL;
 
-       /* Must be done under the lock to serialise against cancellation.
-        * Call this aio_fput as it duplicates fput via the fput_work.
+       /*
+        * Try to optimize the aio and eventfd file* puts, by avoiding to
+        * schedule work in case it is not __fput() time. In normal cases,
+        * we would not be holding the last reference to the file*, so
+        * this function will be executed w/out any aio kthread wakeup.
         */
        if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) {
                get_ioctx(ctx);
@@ -549,8 +555,10 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
                list_add(&req->ki_list, &fput_head);
                spin_unlock(&fput_lock);
                queue_work(aio_wq, &fput_work);
-       } else
+       } else {
+               req->ki_filp = NULL;
                really_put_req(ctx, req);
+       }
        return 1;
 }
 
@@ -567,11 +575,12 @@ int aio_put_req(struct kiocb *req)
        spin_unlock_irq(&ctx->ctx_lock);
        return ret;
 }
+EXPORT_SYMBOL(aio_put_req);
 
 static struct kioctx *lookup_ioctx(unsigned long ctx_id)
 {
        struct mm_struct *mm = current->mm;
-       struct kioctx *ctx = NULL;
+       struct kioctx *ctx, *ret = NULL;
        struct hlist_node *n;
 
        rcu_read_lock();
@@ -579,57 +588,13 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
        hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) {
                if (ctx->user_id == ctx_id && !ctx->dead) {
                        get_ioctx(ctx);
+                       ret = ctx;
                        break;
                }
        }
 
        rcu_read_unlock();
-       return ctx;
-}
-
-/*
- * use_mm
- *     Makes the calling kernel thread take on the specified
- *     mm context.
- *     Called by the retry thread execute retries within the
- *     iocb issuer's mm context, so that copy_from/to_user
- *     operations work seamlessly for aio.
- *     (Note: this routine is intended to be called only
- *     from a kernel thread context)
- */
-static void use_mm(struct mm_struct *mm)
-{
-       struct mm_struct *active_mm;
-       struct task_struct *tsk = current;
-
-       task_lock(tsk);
-       active_mm = tsk->active_mm;
-       atomic_inc(&mm->mm_count);
-       tsk->mm = mm;
-       tsk->active_mm = mm;
-       switch_mm(active_mm, mm, tsk);
-       task_unlock(tsk);
-
-       mmdrop(active_mm);
-}
-
-/*
- * unuse_mm
- *     Reverses the effect of use_mm, i.e. releases the
- *     specified mm context which was earlier taken on
- *     by the calling kernel thread
- *     (Note: this routine is intended to be called only
- *     from a kernel thread context)
- */
-static void unuse_mm(struct mm_struct *mm)
-{
-       struct task_struct *tsk = current;
-
-       task_lock(tsk);
-       tsk->mm = NULL;
-       /* active_mm is still 'mm' */
-       enter_lazy_tlb(mm, tsk);
-       task_unlock(tsk);
+       return ret;
 }
 
 /*
@@ -1009,7 +974,7 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
         * eventfd. The eventfd_signal() function is safe to be called
         * from IRQ context.
         */
-       if (!IS_ERR(iocb->ki_eventfd))
+       if (iocb->ki_eventfd != NULL)
                eventfd_signal(iocb->ki_eventfd, 1);
 
 put_rq:
@@ -1030,6 +995,7 @@ put_rq:
        spin_unlock_irqrestore(&ctx->ctx_lock, flags);
        return ret;
 }
+EXPORT_SYMBOL(aio_complete);
 
 /* aio_read_evt
  *     Pull an event off of the ioctx's event ring.  Returns the number of 
@@ -1270,7 +1236,7 @@ static void io_destroy(struct kioctx *ioctx)
  *     pointer is passed for ctxp.  Will fail with -ENOSYS if not
  *     implemented.
  */
-asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
+SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp)
 {
        struct kioctx *ioctx = NULL;
        unsigned long ctx;
@@ -1308,7 +1274,7 @@ out:
  *     implemented.  May fail with -EFAULT if the context pointed to
  *     is invalid.
  */
-asmlinkage long sys_io_destroy(aio_context_t ctx)
+SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
 {
        struct kioctx *ioctx = lookup_ioctx(ctx);
        if (likely(NULL != ioctx)) {
@@ -1605,9 +1571,10 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                 * an eventfd() fd, and will be signaled for each completed
                 * event using the eventfd_signal() function.
                 */
-               req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd);
+               req->ki_eventfd = eventfd_ctx_fdget((int) iocb->aio_resfd);
                if (IS_ERR(req->ki_eventfd)) {
                        ret = PTR_ERR(req->ki_eventfd);
+                       req->ki_eventfd = NULL;
                        goto out_put_req;
                }
        }
@@ -1662,8 +1629,8 @@ out_put_req:
  *     are available to queue any iocbs.  Will return 0 if nr is 0.  Will
  *     fail with -ENOSYS if not implemented.
  */
-asmlinkage long sys_io_submit(aio_context_t ctx_id, long nr,
-                             struct iocb __user * __user *iocbpp)
+SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
+               struct iocb __user * __user *, iocbpp)
 {
        struct kioctx *ctx;
        long ret = 0;
@@ -1737,8 +1704,8 @@ static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb,
  *     invalid.  May fail with -EAGAIN if the iocb specified was not
  *     cancelled.  Will fail with -ENOSYS if not implemented.
  */
-asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
-                             struct io_event __user *result)
+SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
+               struct io_event __user *, result)
 {
        int (*cancel)(struct kiocb *iocb, struct io_event *res);
        struct kioctx *ctx;
@@ -1799,11 +1766,11 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
  *     will be updated if not NULL and the operation blocks.  Will fail
  *     with -ENOSYS if not implemented.
  */
-asmlinkage long sys_io_getevents(aio_context_t ctx_id,
-                                long min_nr,
-                                long nr,
-                                struct io_event __user *events,
-                                struct timespec __user *timeout)
+SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
+               long, min_nr,
+               long, nr,
+               struct io_event __user *, events,
+               struct timespec __user *, timeout)
 {
        struct kioctx *ioctx = lookup_ioctx(ctx_id);
        long ret = -EINVAL;
@@ -1817,9 +1784,3 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id,
        asmlinkage_protect(5, ret, ctx_id, min_nr, nr, events, timeout);
        return ret;
 }
-
-__initcall(aio_setup);
-
-EXPORT_SYMBOL(aio_complete);
-EXPORT_SYMBOL(aio_put_req);
-EXPORT_SYMBOL(wait_on_sync_kiocb);