android_kernel_google_msm/fs/sdcardfs/mmap.c
Daniel Rosenberg c3da3c511e 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>
2017-09-22 19:12:29 +03:00

90 lines
2.2 KiB
C

/*
* fs/sdcardfs/mmap.c
*
* Copyright (c) 2013 Samsung Electronics Co. Ltd
* Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
* Sunghwan Yun, Sungjong Seo
*
* This program has been developed as a stackable file system based on
* the WrapFS which written by
*
* Copyright (c) 1998-2011 Erez Zadok
* Copyright (c) 2009 Shrikar Archak
* Copyright (c) 2003-2011 Stony Brook University
* Copyright (c) 2003-2011 The Research Foundation of SUNY
*
* This file is dual licensed. It may be redistributed and/or modified
* under the terms of the Apache 2.0 License OR version 2 of the GNU
* General Public License.
*/
#include "sdcardfs.h"
static int sdcardfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
int err;
struct file *file;
const struct vm_operations_struct *lower_vm_ops;
file = (struct file *)vma->vm_private_data;
lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops;
BUG_ON(!lower_vm_ops);
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;
const struct vm_operations_struct *lower_vm_ops;
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;
err = lower_vm_ops->page_mkwrite(vma, vmf);
out:
return err;
}
static ssize_t sdcardfs_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset,
unsigned long nr_segs)
{
/*
* This function should never be called directly. We need it
* to exist, to get past a check in open_check_o_direct(),
* which is called from do_last().
*/
return -EINVAL;
}
const struct address_space_operations sdcardfs_aops = {
.direct_IO = sdcardfs_direct_IO,
};
const struct vm_operations_struct sdcardfs_vm_ops = {
.fault = sdcardfs_fault,
.page_mkwrite = sdcardfs_page_mkwrite,
.open = sdcardfs_vm_open,
.close = sdcardfs_vm_close,
};