summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhilesh Reddy <reddyn@codeaurora.org>2016-06-20 15:33:46 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-21 15:11:43 -0700
commitddd6e3c8304fb419dd8ec513577f99ef30fa7f72 (patch)
treea00a54c5b3567dd8063380b23f4a8578bbcaa442
parent38d03cd71e0be00ec4d1479b7274b0513b80a160 (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.c13
-rw-r--r--fs/fuse/fuse_i.h1
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 */