From 27f4903658bb5cbcaa32f350f53f1655bfc3262e Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Mon, 4 Jan 2010 20:45:06 -0500 Subject: [PATCH] Wrapfs: vm_ops operations Includes necessary address_space workaround ops. Signed-off-by: Erez Zadok --- fs/wrapfs/mmap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 fs/wrapfs/mmap.c diff --git a/fs/wrapfs/mmap.c b/fs/wrapfs/mmap.c new file mode 100644 index 000000000000..0c72ef4c8914 --- /dev/null +++ b/fs/wrapfs/mmap.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1998-2010 Erez Zadok + * Copyright (c) 2009 Shrikar Archak + * Copyright (c) 2003-2010 Stony Brook University + * Copyright (c) 2003-2010 The Research Foundation of SUNY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "wrapfs.h" + +static int wrapfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + int err; + 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 = WRAPFS_F(file)->lower_vm_ops; + BUG_ON(!lower_vm_ops); + + lower_file = wrapfs_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 wrapfs_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); + return err; +} + +/* + * XXX: the default address_space_ops for wrapfs is empty. We cannot set + * our inode->i_mapping->a_ops to NULL because too many code paths expect + * the a_ops vector to be non-NULL. + */ +const struct address_space_operations wrapfs_aops = { + /* empty on purpose */ +}; + +const struct vm_operations_struct wrapfs_vm_ops = { + .fault = wrapfs_fault, +}; -- 2.34.1