diff options
author | Christoph Hellwig <hch@lst.de> | 2016-02-08 06:40:51 +0300 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-02-08 06:40:51 +0300 |
commit | 187372a3b9faff68ed61c291d0135e6739e0dbdf (patch) | |
tree | 7eeed8ee2944dbdcc60ec49cf08f1b1604400b3e /fs/xfs/xfs_aops.c | |
parent | 36f90b0a2ddd60823fe193a85e60ff1906c2a9b3 (diff) | |
download | linux-187372a3b9faff68ed61c291d0135e6739e0dbdf.tar.xz |
direct-io: always call ->end_io if non-NULL
This way we can pass back errors to the file system, and allow for
cleanup required for all direct I/O invocations.
Also allow the ->end_io handlers to return errors on their own, so that
I/O completion errors can be passed on to the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_aops.c')
-rw-r--r-- | fs/xfs/xfs_aops.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 379c089fb051..295aaffea78e 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1645,7 +1645,7 @@ out_end_io: * case the completion can be called in interrupt context, whereas if we have an * ioend we will always be called in task context (i.e. from a workqueue). */ -STATIC void +STATIC int xfs_end_io_direct_write( struct kiocb *iocb, loff_t offset, @@ -1655,15 +1655,19 @@ xfs_end_io_direct_write( struct inode *inode = file_inode(iocb->ki_filp); struct xfs_ioend *ioend = private; + if (size <= 0) + return 0; + trace_xfs_gbmap_direct_endio(XFS_I(inode), offset, size, ioend ? ioend->io_type : 0, NULL); if (!ioend) { ASSERT(offset + size <= i_size_read(inode)); - return; + return 0; } __xfs_end_io_direct_write(inode, ioend, offset, size); + return 0; } static inline ssize_t @@ -1672,10 +1676,7 @@ xfs_vm_do_dio( struct kiocb *iocb, struct iov_iter *iter, loff_t offset, - void (*endio)(struct kiocb *iocb, - loff_t offset, - ssize_t size, - void *private), + dio_iodone_t endio, int flags) { struct block_device *bdev; |