]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/xfs/xfs_aops.c
xfs: defer AIO/DIO completions
[mv-sheeva.git] / fs / xfs / xfs_aops.c
index d91564404abfa945a9d223f3b683ad9c5e626ced..10660c3641058ac9c5fee41c83814e2c06954e53 100644 (file)
@@ -122,6 +122,11 @@ xfs_destroy_ioend(
                bh->b_end_io(bh, !ioend->io_error);
        }
 
+       if (ioend->io_iocb) {
+               if (ioend->io_isasync)
+                       aio_complete(ioend->io_iocb, ioend->io_result, 0);
+               inode_dio_done(ioend->io_inode);
+       }
        xfs_ioend_wake(ip);
        mempool_free(ioend, xfs_ioend_pool);
 }
@@ -236,8 +241,6 @@ xfs_end_io(
                /* ensure we don't spin on blocked ioends */
                delay(1);
        } else {
-               if (ioend->io_iocb)
-                       aio_complete(ioend->io_iocb, ioend->io_result, 0);
                xfs_destroy_ioend(ioend);
        }
 }
@@ -274,6 +277,7 @@ xfs_alloc_ioend(
         * all the I/O from calling the completion routine too early.
         */
        atomic_set(&ioend->io_remaining, 1);
+       ioend->io_isasync = 0;
        ioend->io_error = 0;
        ioend->io_list = NULL;
        ioend->io_type = type;
@@ -1289,7 +1293,6 @@ xfs_end_io_direct_write(
        bool                    is_async)
 {
        struct xfs_ioend        *ioend = iocb->private;
-       struct inode            *inode = ioend->io_inode;
 
        /*
         * blockdev_direct_IO can return an error even after the I/O
@@ -1300,28 +1303,17 @@ xfs_end_io_direct_write(
 
        ioend->io_offset = offset;
        ioend->io_size = size;
+       ioend->io_iocb = iocb;
+       ioend->io_result = ret;
        if (private && size > 0)
                ioend->io_type = IO_UNWRITTEN;
 
        if (is_async) {
-               /*
-                * If we are converting an unwritten extent we need to delay
-                * the AIO completion until after the unwrittent extent
-                * conversion has completed, otherwise do it ASAP.
-                */
-               if (ioend->io_type == IO_UNWRITTEN) {
-                       ioend->io_iocb = iocb;
-                       ioend->io_result = ret;
-               } else {
-                       aio_complete(iocb, ret, 0);
-               }
+               ioend->io_isasync = 1;
                xfs_finish_ioend(ioend);
        } else {
                xfs_finish_ioend_sync(ioend);
        }
-
-       /* XXX: probably should move into the real I/O completion handler */
-       inode_dio_done(inode);
 }
 
 STATIC ssize_t