From: Daniel Rosenberg Date: Fri, 24 Feb 2017 23:41:48 +0000 (-0800) Subject: ANDROID: sdcardfs: implement vm_ops->page_mkwrite X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4a4cb11d4f3f847fbbc770a0ae012091695bd341;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git ANDROID: sdcardfs: implement vm_ops->page_mkwrite This comes from wrapfs commit 3dfec0ffe5e2 ("Wrapfs: implement vm_ops->page_mkwrite") Some file systems (e.g., ext4) require it. Reported by Ted Ts'o. Signed-off-by: Erez Zadok Signed-off-by: Daniel Rosenberg Bug: 34133558 Change-Id: I1a389b2422c654a6d3046bb8ec3e20511aebfa8e --- diff --git a/fs/sdcardfs/mmap.c b/fs/sdcardfs/mmap.c index ac5f3deae088..28db1d11c99e 100644 --- a/fs/sdcardfs/mmap.c +++ b/fs/sdcardfs/mmap.c @@ -48,6 +48,39 @@ static int sdcardfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return err; } +static int sdcardfs_page_mkwrite(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + int err = 0; + struct file *file, *lower_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; + 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); +out: + return err; +} + static ssize_t sdcardfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) { /* @@ -77,4 +110,5 @@ const struct address_space_operations sdcardfs_aops = { const struct vm_operations_struct sdcardfs_vm_ops = { .fault = sdcardfs_fault, + .page_mkwrite = sdcardfs_page_mkwrite, };