summaryrefslogtreecommitdiff
path: root/fs/fuse/fuse_i.h
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2013-10-10 17:12:05 +0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-04-02 17:38:50 +0400
commitea8cd33390fafc1eca06a26e6a9c7bf1d386526f (patch)
treeeb0b3ecdf4760b3b96bc2d0d179e4c59c33d7ade /fs/fuse/fuse_i.h
parentfe38d7df230b022e72014ef7aa799a4f2acfecf3 (diff)
downloadlinux-ea8cd33390fafc1eca06a26e6a9c7bf1d386526f.tar.xz
fuse: Fix O_DIRECT operations vs cached writeback misorder
The problem is: 1. write cached data to a file 2. read directly from the same file (via another fd) The 2nd operation may read stale data, i.e. the one that was in a file before the 1st op. Problem is in how fuse manages writeback. When direct op occurs the core kernel code calls filemap_write_and_wait to flush all the cached ops in flight. But fuse acks the writeback right after the ->writepages callback exits w/o waiting for the real write to happen. Thus the subsequent direct op proceeds while the real writeback is still in flight. This is a problem for backends that reorder operation. Fix this by making the fuse direct IO callback explicitly wait on the in-flight writeback to finish. Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/fuse_i.h')
-rw-r--r--fs/fuse/fuse_i.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 1e6ad6d43051..a257ed8ebee6 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -868,9 +868,20 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
bool isdir);
+
+/**
+ * fuse_direct_io() flags
+ */
+
+/** If set, it is WRITE; otherwise - READ */
+#define FUSE_DIO_WRITE (1 << 0)
+
+/** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */
+#define FUSE_DIO_CUSE (1 << 1)
+
ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
unsigned long nr_segs, size_t count, loff_t *ppos,
- int write);
+ int flags);
long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
unsigned int flags);
long fuse_ioctl_common(struct file *file, unsigned int cmd,