fuse: Switch to using async direct IO for FOPEN_DIRECT_IO
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. Signed-off-by: Martin Raiber <martin@urbackup.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
75126f5504
commit
23c94e1cdc
|
@ -1436,10 +1436,26 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter);
|
||||||
|
|
||||||
static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
{
|
{
|
||||||
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
|
ssize_t res;
|
||||||
return __fuse_direct_read(&io, to, &iocb->ki_pos);
|
|
||||||
|
if (!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) {
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
|
|
||||||
|
if (is_bad_inode(file_inode(file)))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
res = fuse_direct_IO(iocb, to);
|
||||||
|
} else {
|
||||||
|
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
|
||||||
|
|
||||||
|
res = __fuse_direct_read(&io, to, &iocb->ki_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
|
@ -1454,8 +1470,14 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
/* Don't allow parallel writes to the same file */
|
/* Don't allow parallel writes to the same file */
|
||||||
inode_lock(inode);
|
inode_lock(inode);
|
||||||
res = generic_write_checks(iocb, from);
|
res = generic_write_checks(iocb, from);
|
||||||
if (res > 0)
|
if (res > 0) {
|
||||||
res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE);
|
if (!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) {
|
||||||
|
res = fuse_direct_IO(iocb, from);
|
||||||
|
} else {
|
||||||
|
res = fuse_direct_io(&io, from, &iocb->ki_pos,
|
||||||
|
FUSE_DIO_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
fuse_invalidate_attr(inode);
|
fuse_invalidate_attr(inode);
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
fuse_write_update_size(inode, iocb->ki_pos);
|
fuse_write_update_size(inode, iocb->ki_pos);
|
||||||
|
|
Loading…
Reference in New Issue