diff options
author | Dave Chinner <david@fromorbit.com> | 2016-03-07 09:29:48 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-03-07 09:29:48 +1100 |
commit | acb3e26fc3652d43cb5cf07c311ed55f3aecf40e (patch) | |
tree | fb8d84b0bcfdd194544a50ccf87caf0ab1428454 /fs/ext4/inode.c | |
parent | 1b186d25b0dca16671fe9c2c86330a609cf55802 (diff) | |
parent | 74c66bcb7eda551f3b8588659c58fe29184af903 (diff) |
Merge branch 'xfs-dio-fix-4.6' into for-next
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 83bc8bfb3bea..2b98171a9432 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3161,14 +3161,14 @@ out: } #endif -static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, +static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset, ssize_t size, void *private) { ext4_io_end_t *io_end = iocb->private; /* if not async direct IO just return */ if (!io_end) - return; + return 0; ext_debug("ext4_end_io_dio(): io_end 0x%p " "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", @@ -3176,9 +3176,19 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, size); iocb->private = NULL; + /* + * Error during AIO DIO. We cannot convert unwritten extents as the + * data was not written. Just clear the unwritten flag and drop io_end. + */ + if (size <= 0) { + ext4_clear_io_unwritten_flag(io_end); + size = 0; + } io_end->offset = offset; io_end->size = size; ext4_put_io_end(io_end); + + return 0; } /* @@ -3301,16 +3311,6 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, if (io_end) { ext4_inode_aio_set(inode, NULL); ext4_put_io_end(io_end); - /* - * When no IO was submitted ext4_end_io_dio() was not - * called so we have to put iocb's reference. - */ - if (ret <= 0 && ret != -EIOCBQUEUED && iocb->private) { - WARN_ON(iocb->private != io_end); - WARN_ON(io_end->flag & EXT4_IO_END_UNWRITTEN); - ext4_put_io_end(io_end); - iocb->private = NULL; - } } if (ret > 0 && !overwrite && ext4_test_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN)) { |