aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDaniel Rosenberg <drosen@google.com>2017-04-10 20:54:30 -0700
committerAmit Pundir <amit.pundir@linaro.org>2017-05-01 15:02:43 +0530
commited966e3649596cbb488a5dbf178bacf965a26e4c (patch)
treeaf521bc5835f5f8a62731bfd9c3e1eb087f4eb42 /fs
parent8bbc8d5787cabafc0b782304882f5a7f2c80fbbb (diff)
ANDROID: sdcardfs: Directly pass lower file for mmap
Instead of relying on a copy hack, pass the lower file as private data. This lets the kernel find the vma mapping for pages used by the file, allowing pages used by mapping to be reclaimed. This is adapted from following esdfs patches commit 0647e638d: ("esdfs: store lower file in vm_file for mmap") commit 064850866: ("esdfs: keep a counter for mmaped file") Change-Id: I75b74d1e5061db1b8c13be38d184e118c0851a1a Signed-off-by: Daniel Rosenberg <drosen@google.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/sdcardfs/file.c3
-rw-r--r--fs/sdcardfs/mmap.c57
2 files changed, 25 insertions, 35 deletions
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c
index c0146e03fa2e..1f6921e2ffbf 100644
--- a/fs/sdcardfs/file.c
+++ b/fs/sdcardfs/file.c
@@ -192,6 +192,9 @@ static int sdcardfs_mmap(struct file *file, struct vm_area_struct *vma)
file->f_mapping->a_ops = &sdcardfs_aops; /* set our aops */
if (!SDCARDFS_F(file)->lower_vm_ops) /* save for our ->fault */
SDCARDFS_F(file)->lower_vm_ops = saved_vm_ops;
+ vma->vm_private_data = file;
+ get_file(lower_file);
+ vma->vm_file = lower_file;
out:
return err;
diff --git a/fs/sdcardfs/mmap.c b/fs/sdcardfs/mmap.c
index 0d4089c62c3a..b61f82275e7d 100644
--- a/fs/sdcardfs/mmap.c
+++ b/fs/sdcardfs/mmap.c
@@ -23,60 +23,45 @@
static int sdcardfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
int err;
- struct file *file, *lower_file;
+ struct file *file;
const struct vm_operations_struct *lower_vm_ops;
- struct vm_area_struct lower_vma;
- memcpy(&lower_vma, vma, sizeof(struct vm_area_struct));
- file = lower_vma.vm_file;
+ file = (struct file *)vma->vm_private_data;
lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops;
BUG_ON(!lower_vm_ops);
- lower_file = sdcardfs_lower_file(file);
- /*
- * XXX: vm_ops->fault may be called in parallel. Because we have to
- * resort to temporarily changing the vma->vm_file to point to the
- * lower file, a concurrent invocation of sdcardfs_fault could see a
- * different value. In this workaround, we keep a different copy of
- * the vma structure in our stack, so we never expose a different
- * value of the vma->vm_file called to us, even temporarily. A
- * better fix would be to change the calling semantics of ->fault to
- * take an explicit file pointer.
- */
- lower_vma.vm_file = lower_file;
- err = lower_vm_ops->fault(&lower_vma, vmf);
+ err = lower_vm_ops->fault(vma, vmf);
return err;
}
+static void sdcardfs_vm_open(struct vm_area_struct *vma)
+{
+ struct file *file = (struct file *)vma->vm_private_data;
+
+ get_file(file);
+}
+
+static void sdcardfs_vm_close(struct vm_area_struct *vma)
+{
+ struct file *file = (struct file *)vma->vm_private_data;
+
+ fput(file);
+}
+
static int sdcardfs_page_mkwrite(struct vm_area_struct *vma,
struct vm_fault *vmf)
{
int err = 0;
- struct file *file, *lower_file;
+ struct file *file;
const struct vm_operations_struct *lower_vm_ops;
- struct vm_area_struct lower_vma;
- memcpy(&lower_vma, vma, sizeof(struct vm_area_struct));
- file = lower_vma.vm_file;
+ file = (struct file *)vma->vm_private_data;
lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops;
BUG_ON(!lower_vm_ops);
if (!lower_vm_ops->page_mkwrite)
goto out;
- lower_file = sdcardfs_lower_file(file);
- /*
- * XXX: vm_ops->page_mkwrite may be called in parallel.
- * Because we have to resort to temporarily changing the
- * vma->vm_file to point to the lower file, a concurrent
- * invocation of sdcardfs_page_mkwrite could see a different
- * value. In this workaround, we keep a different copy of the
- * vma structure in our stack, so we never expose a different
- * value of the vma->vm_file called to us, even temporarily.
- * A better fix would be to change the calling semantics of
- * ->page_mkwrite to take an explicit file pointer.
- */
- lower_vma.vm_file = lower_file;
- err = lower_vm_ops->page_mkwrite(&lower_vma, vmf);
+ err = lower_vm_ops->page_mkwrite(vma, vmf);
out:
return err;
}
@@ -99,4 +84,6 @@ const struct address_space_operations sdcardfs_aops = {
const struct vm_operations_struct sdcardfs_vm_ops = {
.fault = sdcardfs_fault,
.page_mkwrite = sdcardfs_page_mkwrite,
+ .open = sdcardfs_vm_open,
+ .close = sdcardfs_vm_close,
};