diff options
| author | Nikhilesh Reddy <reddyn@codeaurora.org> | 2016-06-20 15:33:46 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-21 15:11:43 -0700 |
| commit | ddd6e3c8304fb419dd8ec513577f99ef30fa7f72 (patch) | |
| tree | a00a54c5b3567dd8063380b23f4a8578bbcaa442 | |
| parent | 38d03cd71e0be00ec4d1479b7274b0513b80a160 (diff) | |
fs:fuse: Disable passthrough when mmap is called on a file
When some data is written to a file both mmap and regular io
there can be race conditions that can cause incorrect data
to be saved.
Disable passthrough on the specific files on which mmap is called
until we add mmap support to passthrough.
Change-Id: Ic24219ab22d3130aa7e9e998a9e6798648a7321c
Signed-off-by: Nikhilesh Reddy <reddyn@codeaurora.org>
| -rw-r--r-- | fs/fuse/file.c | 13 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 1 |
2 files changed, 12 insertions, 2 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 14b0c69f07ee..8ff09059a91d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -60,6 +60,9 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) return NULL; ff->passthrough_filp = NULL; + ff->passthrough_enabled = 0; + if (fc->passthrough) + ff->passthrough_enabled = 1; ff->fc = fc; ff->reserved_req = fuse_request_alloc(0); if (unlikely(!ff->reserved_req)) { @@ -929,7 +932,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to) return err; } - if (ff && ff->passthrough_filp) + if (ff && ff->passthrough_enabled && ff->passthrough_filp) ret_val = fuse_passthrough_read_iter(iocb, to); else ret_val = generic_file_read_iter(iocb, to); @@ -1200,7 +1203,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (err) goto out; - if (ff && ff->passthrough_filp) { + if (ff && ff->passthrough_enabled && ff->passthrough_filp) { written = fuse_passthrough_write_iter(iocb, from); goto out; } @@ -2071,6 +2074,9 @@ static const struct vm_operations_struct fuse_file_vm_ops = { static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->passthrough_enabled = 0; if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) fuse_link_write_file(file); @@ -2081,6 +2087,9 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->passthrough_enabled = 0; /* Can't provide the coherency needed for MAP_SHARED */ if (vma->vm_flags & VM_MAYSHARE) return -ENODEV; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 2f4d9866e455..8db84062741d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -160,6 +160,7 @@ struct fuse_file { /* the read write file */ struct file *passthrough_filp; + bool passthrough_enabled; }; /** One input argument of a request */ |
