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>
This commit is contained in:

committed by
Miklos Szeredi

parent
fe38d7df23
commit
ea8cd33390
@@ -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,
|
||||
|
Reference in New Issue
Block a user