xfs: direct calls in the direct I/O path
authorChristoph Hellwig <hch@lst.de>
Wed, 20 Jul 2016 01:38:01 +0000 (11:38 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 20 Jul 2016 01:38:01 +0000 (11:38 +1000)
We control both the callers and callees of ->direct_IO, so remove the
indirect calls.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_aops.c
fs/xfs/xfs_aops.h
fs/xfs/xfs_file.c

index 4c463b99fe574341043cb1f6ab612a59df881d31..3ba0809e0be8a6f2f396def2d2d6419cc1a7c699 100644 (file)
@@ -1336,7 +1336,7 @@ xfs_get_blocks_dax_fault(
  * whereas if we have flags set we will always be called in task context
  * (i.e. from a workqueue).
  */
-STATIC int
+int
 xfs_end_io_direct_write(
        struct kiocb            *iocb,
        loff_t                  offset,
@@ -1407,24 +1407,10 @@ xfs_vm_direct_IO(
        struct kiocb            *iocb,
        struct iov_iter         *iter)
 {
-       struct inode            *inode = iocb->ki_filp->f_mapping->host;
-       dio_iodone_t            *endio = NULL;
-       int                     flags = 0;
-       struct block_device     *bdev;
-
-       if (iov_iter_rw(iter) == WRITE) {
-               endio = xfs_end_io_direct_write;
-               flags = DIO_ASYNC_EXTEND;
-       }
-
-       if (IS_DAX(inode)) {
-               return dax_do_io(iocb, inode, iter,
-                                xfs_get_blocks_direct, endio, 0);
-       }
-
-       bdev = xfs_find_bdev_for_inode(inode);
-       return  __blockdev_direct_IO(iocb, inode, bdev, iter,
-                       xfs_get_blocks_direct, endio, NULL, flags);
+       /*
+        * We just need the method present so that open/fcntl allow direct I/O.
+        */
+       return -EINVAL;
 }
 
 /*
index 814aab7907134e14cbc3ccb7f72d14001a7834d1..bf2d9a141a734bc8b33fde55e9a3d51e30f37e64 100644 (file)
@@ -60,6 +60,9 @@ int   xfs_get_blocks_direct(struct inode *inode, sector_t offset,
 int    xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset,
                                 struct buffer_head *map_bh, int create);
 
+int    xfs_end_io_direct_write(struct kiocb *iocb, loff_t offset,
+               ssize_t size, void *private);
+
 extern void xfs_count_page_state(struct page *, int *, int *);
 extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
 
index 440bb8b5c64d834317449633fd9a7afb383ff797..dd5185dafc9fcb7b9c1533cfd48dd9f897337ed8 100644 (file)
@@ -360,7 +360,13 @@ xfs_file_dio_aio_read(
        }
 
        data = *to;
-       ret = mapping->a_ops->direct_IO(iocb, &data);
+       if (IS_DAX(inode)) {
+               ret = dax_do_io(iocb, inode, &data, xfs_get_blocks_direct,
+                               NULL, 0);
+       } else {
+               ret = __blockdev_direct_IO(iocb, inode, target->bt_bdev, &data,
+                               xfs_get_blocks_direct, NULL, NULL, 0);
+       }
        if (ret > 0) {
                iocb->ki_pos += ret;
                iov_iter_advance(to, ret);
@@ -819,7 +825,14 @@ xfs_file_dio_aio_write(
        trace_xfs_file_direct_write(ip, count, iocb->ki_pos);
 
        data = *from;
-       ret = mapping->a_ops->direct_IO(iocb, &data);
+       if (IS_DAX(inode)) {
+               ret = dax_do_io(iocb, inode, &data, xfs_get_blocks_direct,
+                               xfs_end_io_direct_write, 0);
+       } else {
+               ret = __blockdev_direct_IO(iocb, inode, target->bt_bdev, &data,
+                               xfs_get_blocks_direct, xfs_end_io_direct_write,
+                               NULL, DIO_ASYNC_EXTEND);
+       }
 
        /* see generic_file_direct_write() for why this is necessary */
        if (mapping->nrpages) {