Message ID | 01020166b66d99e7-59bda620-1b46-42f8-a2fa-81e5a3937454-000000@eu-west-1.amazonses.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fs: fuse: Switch to using async direct IO in fuse_direct_read/write_iter | expand |
On Sat, Oct 27, 2018 at 6:48 PM Martin Raiber <martin@urbackup.org> wrote: > > 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 Missing Signed-off-by tag. Can I add it for you? Thanks, Miklos
On 24.01.2019 09:52 Miklos Szeredi wrote: > On Sat, Oct 27, 2018 at 6:48 PM Martin Raiber <martin@urbackup.org> wrote: >> 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 > Missing Signed-off-by tag. Can I add it for you? > > Thanks, > Miklos Sure, thanks!
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);