Switch to using the async directo IO code path in fuse_direct_read_iter and fuse_direct_write_iter. This is especially important in connection with loop devices with direct IO enabled as loop assumes async direct io is actually async --- fs/fuse/file.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 32d0b883e74f..c2f5491aced9 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1426,6 +1426,14 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io, static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb); + if(!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) { + struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); + + if (is_bad_inode(inode)) + return -EIO; + return inode->i_data.a_ops->direct_IO(iocb, to); + } return __fuse_direct_read(&io, to, &iocb->ki_pos); } @@ -1441,6 +1449,11 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) /* Don't allow parallel writes to the same file */ inode_lock(inode); res = generic_write_checks(iocb, from); + if(res>0 && !is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) + { + inode_unlock(inode); + return inode->i_data.a_ops->direct_IO(iocb, from); + } if (res > 0) res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); fuse_invalidate_attr(inode); -- 2.11.0.windows.1