summaryrefslogtreecommitdiffstats
path: root/linux-drd/aufs3-mmap.patch
diff options
context:
space:
mode:
Diffstat (limited to 'linux-drd/aufs3-mmap.patch')
-rw-r--r--linux-drd/aufs3-mmap.patch396
1 files changed, 396 insertions, 0 deletions
diff --git a/linux-drd/aufs3-mmap.patch b/linux-drd/aufs3-mmap.patch
new file mode 100644
index 0000000..579a8d3
--- /dev/null
+++ b/linux-drd/aufs3-mmap.patch
@@ -0,0 +1,396 @@
+aufs3.11 mmap patch
+
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 4d74335..3b1db7d 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -2436,7 +2436,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
+ * Update file times before taking page lock. We may end up failing the
+ * fault so this update may be superfluous but who really cares...
+ */
+- file_update_time(vma->vm_file);
++ vma_file_update_time(vma);
+
+ ret = __block_page_mkwrite(vma, vmf, get_block);
+ sb_end_pagefault(sb);
+diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
+index ccfd99b..bca7789 100644
+--- a/fs/proc/nommu.c
++++ b/fs/proc/nommu.c
+@@ -45,7 +45,9 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
+ file = region->vm_file;
+
+ if (file) {
+- struct inode *inode = file_inode(region->vm_file);
++ struct inode *inode;
++ file = vmr_pr_or_file(region);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ }
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 107d026..9942e5f 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -272,7 +272,9 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+ const char *name = NULL;
+
+ if (file) {
+- struct inode *inode = file_inode(vma->vm_file);
++ struct inode *inode;
++ file = vma_pr_or_file(vma);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
+@@ -1382,6 +1384,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+ seq_printf(m, "%08lx %s", vma->vm_start, buffer);
+
+ if (file) {
++ file = vma_pr_or_file(vma);
+ seq_printf(m, " file=");
+ seq_path(m, &file->f_path, "\n\t= ");
+ } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index 56123a6..d19737f 100644
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -149,7 +149,9 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
+ file = vma->vm_file;
+
+ if (file) {
+- struct inode *inode = file_inode(vma->vm_file);
++ struct inode *inode;
++ file = vma_pr_or_file(file);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index f022460..4f3e9ca 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -17,6 +17,9 @@
+ #include <linux/pfn.h>
+ #include <linux/bit_spinlock.h>
+ #include <linux/shrinker.h>
++#include <linux/dcache.h>
++#include <linux/file.h>
++#include <linux/fs.h>
+
+ struct mempolicy;
+ struct anon_vma;
+@@ -1023,6 +1026,87 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+ }
+ #endif
+
++/*
++ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
++ * in /proc/PID/maps.
++ */
++/* #define AUFS_DEBUG_MMAP */
++static inline void aufs_trace(struct file *f, struct file *pr,
++ const char func[], int line, const char func2[])
++{
++#ifdef AUFS_DEBUG_MMAP
++ if (pr)
++ pr_info("%s:%d: %s, %p\n", func, line, func2,
++ f ? (char *)f->f_dentry->d_name.name : "(null)");
++#endif
++}
++
++static inline struct file *vmr_do_pr_or_file(struct vm_region *region,
++ const char func[], int line)
++{
++ struct file *f = region->vm_file, *pr = region->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ return (f && pr) ? pr : f;
++}
++
++static inline void vmr_do_fput(struct vm_region *region,
++ const char func[], int line)
++{
++ struct file *f = region->vm_file, *pr = region->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ fput(f);
++ if (f && pr)
++ fput(pr);
++}
++
++static inline void vma_do_file_update_time(struct vm_area_struct *vma,
++ const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ file_update_time(f);
++ if (f && pr)
++ file_update_time(pr);
++}
++
++static inline struct file *vma_do_pr_or_file(struct vm_area_struct *vma,
++ const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ return (f && pr) ? pr : f;
++}
++
++static inline void vma_do_get_file(struct vm_area_struct *vma,
++ const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ get_file(f);
++ if (f && pr)
++ get_file(pr);
++}
++
++static inline void vma_do_fput(struct vm_area_struct *vma,
++ const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++ aufs_trace(f, pr, func, line, __func__);
++ fput(f);
++ if (f && pr)
++ fput(pr);
++}
++
++#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
++ __LINE__)
++#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
++#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
++ __LINE__)
++#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
++ __LINE__)
++#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
++#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
++
+ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+ void *buf, int len, int write);
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index faf4b7c..cd750ff 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -213,6 +213,7 @@ struct vm_region {
+ unsigned long vm_top; /* region allocated to here */
+ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
+ struct file *vm_file; /* the backing file or NULL */
++ struct file *vm_prfile; /* the virtual backing file or NULL */
+
+ int vm_usage; /* region usage count (access under nommu_region_sem) */
+ bool vm_icache_flushed : 1; /* true if the icache has been flushed for
+@@ -281,6 +282,7 @@ struct vm_area_struct {
+ unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
+ units, *not* PAGE_CACHE_SIZE */
+ struct file * vm_file; /* File we map to (can be NULL). */
++ struct file *vm_prfile; /* shadow of vm_file */
+ void * vm_private_data; /* was vm_pte (shared mem) */
+
+ #ifndef CONFIG_MMU
+diff --git a/kernel/fork.c b/kernel/fork.c
+index bf46287..947c36d 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -415,7 +415,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+ struct inode *inode = file_inode(file);
+ struct address_space *mapping = file->f_mapping;
+
+- get_file(file);
++ vma_get_file(tmp);
+ if (tmp->vm_flags & VM_DENYWRITE)
+ atomic_dec(&inode->i_writecount);
+ mutex_lock(&mapping->i_mmap_mutex);
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 4b51ac1..cc2fd08 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1733,7 +1733,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+ int ret = VM_FAULT_LOCKED;
+
+ sb_start_pagefault(inode->i_sb);
+- file_update_time(vma->vm_file);
++ vma_file_update_time(vma);
+ lock_page(page);
+ if (page->mapping != inode->i_mapping) {
+ unlock_page(page);
+diff --git a/mm/fremap.c b/mm/fremap.c
+index 5bff081..246a9c7 100644
+--- a/mm/fremap.c
++++ b/mm/fremap.c
+@@ -207,11 +207,12 @@ get_write_lock:
+ */
+ if (mapping_cap_account_dirty(mapping)) {
+ unsigned long addr;
+- struct file *file = get_file(vma->vm_file);
++ struct file *file = vma->vm_file;
+
++ vma_get_file(vma);
+ addr = mmap_region(file, start, size,
+ vma->vm_flags, pgoff);
+- fput(file);
++ vma_fput(vma);
+ if (IS_ERR_VALUE(addr)) {
+ err = addr;
+ } else {
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 7055883..e6b768d 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -327,12 +327,12 @@ static long madvise_remove(struct vm_area_struct *vma,
+ * vma's reference to the file) can go away as soon as we drop
+ * mmap_sem.
+ */
+- get_file(f);
++ vma_get_file(vma);
+ up_read(&current->mm->mmap_sem);
+ error = do_fallocate(f,
+ FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+ offset, end - start);
+- fput(f);
++ vma_fput(vma);
+ down_read(&current->mm->mmap_sem);
+ return error;
+ }
+diff --git a/mm/memory.c b/mm/memory.c
+index af84bc0..95a666b 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2754,7 +2754,7 @@ reuse:
+ set_page_dirty_balance(dirty_page, page_mkwrite);
+ /* file_update_time outside page_lock */
+ if (vma->vm_file)
+- file_update_time(vma->vm_file);
++ vma_file_update_time(vma);
+ }
+ put_page(dirty_page);
+ if (page_mkwrite) {
+@@ -3465,7 +3465,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+
+ /* file_update_time outside page_lock */
+ if (vma->vm_file && !page_mkwrite)
+- file_update_time(vma->vm_file);
++ vma_file_update_time(vma);
+ } else {
+ unlock_page(vmf.page);
+ if (anon)
+diff --git a/mm/mmap.c b/mm/mmap.c
+index f9c97d1..dbd8dd2 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -250,7 +250,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ mpol_put(vma_policy(vma));
+ kmem_cache_free(vm_area_cachep, vma);
+ return next;
+@@ -860,7 +860,7 @@ again: remove_next = 1 + (end > next->vm_end);
+ if (remove_next) {
+ if (file) {
+ uprobe_munmap(next, next->vm_start, next->vm_end);
+- fput(file);
++ vma_fput(vma);
+ }
+ if (next->anon_vma)
+ anon_vma_merge(vma, next);
+@@ -1621,8 +1621,8 @@ out:
+ unmap_and_free_vma:
+ if (vm_flags & VM_DENYWRITE)
+ allow_write_access(file);
++ vma_fput(vma);
+ vma->vm_file = NULL;
+- fput(file);
+
+ /* Undo any partial mapping done by a device driver. */
+ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
+@@ -2415,7 +2415,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+ goto out_free_mpol;
+
+ if (new->vm_file)
+- get_file(new->vm_file);
++ vma_get_file(new);
+
+ if (new->vm_ops && new->vm_ops->open)
+ new->vm_ops->open(new);
+@@ -2434,7 +2434,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+ if (new->vm_ops && new->vm_ops->close)
+ new->vm_ops->close(new);
+ if (new->vm_file)
+- fput(new->vm_file);
++ vma_fput(new);
+ unlink_anon_vmas(new);
+ out_free_mpol:
+ mpol_put(pol);
+@@ -2833,7 +2833,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+ if (anon_vma_clone(new_vma, vma))
+ goto out_free_mempol;
+ if (new_vma->vm_file)
+- get_file(new_vma->vm_file);
++ vma_get_file(new_vma);
+ if (new_vma->vm_ops && new_vma->vm_ops->open)
+ new_vma->vm_ops->open(new_vma);
+ vma_link(mm, new_vma, prev, rb_link, rb_parent);
+diff --git a/mm/msync.c b/mm/msync.c
+index 632df45..02d770e 100644
+--- a/mm/msync.c
++++ b/mm/msync.c
+@@ -80,10 +80,10 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
+ start = vma->vm_end;
+ if ((flags & MS_SYNC) && file &&
+ (vma->vm_flags & VM_SHARED)) {
+- get_file(file);
++ vma_get_file(vma);
+ up_read(&mm->mmap_sem);
+ error = vfs_fsync(file, 0);
+- fput(file);
++ vma_fput(vma);
+ if (error || start >= end)
+ goto out;
+ down_read(&mm->mmap_sem);
+diff --git a/mm/nommu.c b/mm/nommu.c
+index ecd1f15..d4306cd 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -652,7 +652,7 @@ static void __put_nommu_region(struct vm_region *region)
+ up_write(&nommu_region_sem);
+
+ if (region->vm_file)
+- fput(region->vm_file);
++ vmr_fput(region);
+
+ /* IO memory and memory shared directly out of the pagecache
+ * from ramfs/tmpfs mustn't be released here */
+@@ -810,7 +810,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ put_nommu_region(vma->vm_region);
+ kmem_cache_free(vm_area_cachep, vma);
+ }
+@@ -1376,7 +1376,7 @@ unsigned long do_mmap_pgoff(struct file *file,
+ goto error_just_free;
+ }
+ }
+- fput(region->vm_file);
++ vmr_fput(region);
+ kmem_cache_free(vm_region_jar, region);
+ region = pregion;
+ result = start;
+@@ -1452,10 +1452,10 @@ error_just_free:
+ up_write(&nommu_region_sem);
+ error:
+ if (region->vm_file)
+- fput(region->vm_file);
++ vmr_fput(region);
+ kmem_cache_free(vm_region_jar, region);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ kmem_cache_free(vm_area_cachep, vma);
+ kleave(" = %d", ret);
+ return ret;