]> git.pld-linux.org Git - packages/kernel.git/blobdiff - kernel-aufs4.patch
- up to 4.4.159
[packages/kernel.git] / kernel-aufs4.patch
index 8ab7d27424099d6988261d343e4beb14f2f0ad5a..31d98cdae1c16b9485c1aab63940b0a2232b45ee 100644 (file)
@@ -1,10 +1,10 @@
-aufs4.x-rcN kbuild patch
+aufs4.4 kbuild patch
 
 diff --git a/fs/Kconfig b/fs/Kconfig
-index 011f433..b1083f6 100644
+index 6ce72d8..4aa31ea 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -218,6 +218,7 @@ source "fs/pstore/Kconfig"
+@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig"
  source "fs/sysv/Kconfig"
  source "fs/ufs/Kconfig"
  source "fs/exofs/Kconfig"
@@ -13,7 +13,7 @@ index 011f433..b1083f6 100644
  endif # MISC_FILESYSTEMS
  
 diff --git a/fs/Makefile b/fs/Makefile
-index cb20e4b..dd81418 100644
+index 79f5225..a7c7f16 100644
 --- a/fs/Makefile
 +++ b/fs/Makefile
 @@ -126,3 +126,4 @@ obj-y                              += exofs/ # Multiple modules
@@ -22,7 +22,7 @@ index cb20e4b..dd81418 100644
  obj-$(CONFIG_EFIVAR_FS)               += efivarfs/
 +obj-$(CONFIG_AUFS_FS)           += aufs/
 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index 1ff9942..31efc0a 100644
+index c2e5d6c..d736c11 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
 @@ -59,6 +59,7 @@ header-y += atmsvc.h
@@ -33,13 +33,13 @@ index 1ff9942..31efc0a 100644
  header-y += auto_fs4.h
  header-y += auto_fs.h
  header-y += auxvec.h
-aufs4.x-rcN base patch
+aufs4.4 base patch
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 8133cef..04beb19 100644
+index 233f834..c250892 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -1939,6 +1939,19 @@ F:      include/linux/audit.h
+@@ -2029,6 +2029,19 @@ F:      include/linux/audit.h
  F:    include/uapi/linux/audit.h
  F:    kernel/audit*
  
@@ -60,10 +60,10 @@ index 8133cef..04beb19 100644
  M:    Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
  W:    http://miguelojeda.es/auxdisplay.htm
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index f7a4c9d..23103ad 100644
+index 423f4ca..abfdd2b 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
-@@ -560,6 +560,24 @@ static inline int is_loop_device(struct file *file)
+@@ -706,6 +706,24 @@ static inline int is_loop_device(struct file *file)
        return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
  }
  
@@ -89,10 +89,10 @@ index f7a4c9d..23103ad 100644
  
  static ssize_t loop_attr_show(struct device *dev, char *page,
 diff --git a/fs/dcache.c b/fs/dcache.c
-index 7a3f3e5..0b40298 100644
+index 5c33aeb..8aa7f26 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1164,7 +1164,7 @@ enum d_walk_ret {
+@@ -1167,7 +1167,7 @@ enum d_walk_ret {
   *
   * The @enter() and @finish() callbacks are called with d_lock held.
   */
@@ -135,10 +135,10 @@ index 819ef3f..fd0414e 100644
  {
        mm_segment_t old_fs;
 diff --git a/fs/splice.c b/fs/splice.c
-index 5fc1e50..5f8385a 100644
+index 4cf700d..30a091d 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1102,8 +1102,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1110,8 +1110,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -149,7 +149,7 @@ index 5fc1e50..5f8385a 100644
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
-@@ -1119,9 +1119,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1127,9 +1127,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  /*
   * Attempt to initiate a splice from a file to a pipe.
   */
@@ -175,10 +175,10 @@ index f87d308..9a290b3 100644
  static inline void fput_light(struct file *file, int fput_needed)
  {
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index a0653e5..86080ea 100644
+index 3aa5142..8d48506 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1661,6 +1661,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+@@ -1672,6 +1672,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
                              struct iovec *fast_pointer,
                              struct iovec **ret_pointer);
  
@@ -206,26 +206,13 @@ index da2751d..2e0fca6 100644
 +                       struct pipe_inode_info *pipe, size_t len,
 +                       unsigned int flags);
  #endif
-aufs4.x-rcN mmap patch
+aufs4.4 mmap patch
 
-diff --git a/fs/buffer.c b/fs/buffer.c
-index 1cf7a53..076aff86 100644
---- a/fs/buffer.c
-+++ b/fs/buffer.c
-@@ -2473,7 +2473,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/base.c b/fs/proc/base.c
-index 87782e8..b287e64 100644
+index 4bd5d31..aa41f2a 100644
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
-@@ -1934,7 +1934,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
+@@ -1921,7 +1921,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
        down_read(&mm->mmap_sem);
        vma = find_exact_vma(mm, vm_start, vm_end);
        if (vma && vma->vm_file) {
@@ -251,10 +238,10 @@ index f8595e8..cb8eda0 100644
                ino = inode->i_ino;
        }
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index ca1e091..8940e47 100644
+index 187b3b5..e03793e 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
-@@ -279,7 +279,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+@@ -281,7 +281,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
        const char *name = NULL;
  
        if (file) {
@@ -266,7 +253,7 @@ index ca1e091..8940e47 100644
                dev = inode->i_sb->s_dev;
                ino = inode->i_ino;
                pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1479,7 +1482,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+@@ -1505,7 +1508,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
        struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
        struct vm_area_struct *vma = v;
        struct numa_maps *md = &numa_priv->md;
@@ -292,10 +279,10 @@ index e0d64c9..7aa92db 100644
                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 2e872f9..2494ed2 100644
+index 00bad77..cc616b0 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
-@@ -1173,6 +1173,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1183,6 +1183,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
  }
  #endif
  
@@ -325,10 +312,10 @@ index 2e872f9..2494ed2 100644
  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 0038ac7..409940d 100644
+index f8d1492..c3a3760 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -259,6 +259,7 @@ struct vm_region {
+@@ -272,6 +272,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 */
@@ -336,7 +323,7 @@ index 0038ac7..409940d 100644
  
        int             vm_usage;       /* region usage count (access under nommu_region_sem) */
        bool            vm_icache_flushed : 1; /* true if the icache has been flushed for
-@@ -323,6 +324,7 @@ struct vm_area_struct {
+@@ -346,6 +347,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). */
@@ -345,10 +332,10 @@ index 0038ac7..409940d 100644
  
  #ifndef CONFIG_MMU
 diff --git a/kernel/fork.c b/kernel/fork.c
-index 1bfefc6..a86bd7f 100644
+index 1155eac..c001ea4 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -456,7 +456,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -465,7 +465,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;
  
@@ -358,7 +345,7 @@ index 1bfefc6..a86bd7f 100644
                                atomic_dec(&inode->i_writecount);
                        i_mmap_lock_write(mapping);
 diff --git a/mm/Makefile b/mm/Makefile
-index 98c4eae..3f0c9b9 100644
+index 2ed4319..e3a53f5 100644
 --- a/mm/Makefile
 +++ b/mm/Makefile
 @@ -21,7 +21,7 @@ obj-y                        := filemap.o mempool.o oom_kill.o \
@@ -371,10 +358,10 @@ index 98c4eae..3f0c9b9 100644
  obj-y += init-mm.o
  
 diff --git a/mm/filemap.c b/mm/filemap.c
-index 1283fc8..128f18f 100644
+index 1bb0076..8eaece8 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
-@@ -2089,7 +2089,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+@@ -2128,7 +2128,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);
@@ -384,10 +371,10 @@ index 1283fc8..128f18f 100644
        if (page->mapping != inode->i_mapping) {
                unlock_page(page);
 diff --git a/mm/memory.c b/mm/memory.c
-index a84fbb7..13973d2 100644
+index c387430..d434404 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
+@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
                }
  
                if (!page_mkwrite)
@@ -397,10 +384,10 @@ index a84fbb7..13973d2 100644
  
        return VM_FAULT_WRITE;
 diff --git a/mm/mmap.c b/mm/mmap.c
-index aa632ad..3ff75d3 100644
+index 2ce04a6..f555c0a 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
-@@ -274,7 +274,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+@@ -275,7 +275,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)
@@ -409,7 +396,7 @@ index aa632ad..3ff75d3 100644
        mpol_put(vma_policy(vma));
        kmem_cache_free(vm_area_cachep, vma);
        return next;
-@@ -886,7 +886,7 @@ again:                     remove_next = 1 + (end > next->vm_end);
+@@ -887,7 +887,7 @@ again:                     remove_next = 1 + (end > next->vm_end);
        if (remove_next) {
                if (file) {
                        uprobe_munmap(next, next->vm_start, next->vm_end);
@@ -418,7 +405,7 @@ index aa632ad..3ff75d3 100644
                }
                if (next->anon_vma)
                        anon_vma_merge(vma, next);
-@@ -1671,8 +1671,8 @@ out:
+@@ -1681,8 +1681,8 @@ out:
        return addr;
  
  unmap_and_free_vma:
@@ -428,7 +415,7 @@ index aa632ad..3ff75d3 100644
  
        /* Undo any partial mapping done by a device driver. */
        unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
-@@ -2473,7 +2473,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2488,7 +2488,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
                goto out_free_mpol;
  
        if (new->vm_file)
@@ -437,7 +424,7 @@ index aa632ad..3ff75d3 100644
  
        if (new->vm_ops && new->vm_ops->open)
                new->vm_ops->open(new);
-@@ -2492,7 +2492,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2507,7 +2507,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)
@@ -446,7 +433,7 @@ index aa632ad..3ff75d3 100644
        unlink_anon_vmas(new);
   out_free_mpol:
        mpol_put(vma_policy(new));
-@@ -2635,7 +2635,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+@@ -2649,7 +2649,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        struct vm_area_struct *vma;
        unsigned long populate = 0;
        unsigned long ret = -EINVAL;
@@ -454,7 +441,7 @@ index aa632ad..3ff75d3 100644
  
        pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
                        "See Documentation/vm/remap_file_pages.txt.\n",
-@@ -2679,10 +2678,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+@@ -2693,10 +2692,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
                munlock_vma_pages_range(vma, start, start + size);
        }
  
@@ -467,17 +454,17 @@ index aa632ad..3ff75d3 100644
  out:
        up_write(&mm->mmap_sem);
        if (populate)
-@@ -2949,7 +2948,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);
+@@ -2966,7 +2965,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/nommu.c b/mm/nommu.c
-index 58ea364..f937b7e 100644
+index 92be862..29179f7 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
 @@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm_region *region)
@@ -498,7 +485,7 @@ index 58ea364..f937b7e 100644
        put_nommu_region(vma->vm_region);
        kmem_cache_free(vm_area_cachep, vma);
  }
-@@ -1354,7 +1354,7 @@ unsigned long do_mmap_pgoff(struct file *file,
+@@ -1355,7 +1355,7 @@ unsigned long do_mmap(struct file *file,
                                        goto error_just_free;
                                }
                        }
@@ -507,7 +494,7 @@ index 58ea364..f937b7e 100644
                        kmem_cache_free(vm_region_jar, region);
                        region = pregion;
                        result = start;
-@@ -1429,10 +1429,10 @@ error_just_free:
+@@ -1430,10 +1430,10 @@ error_just_free:
        up_write(&nommu_region_sem);
  error:
        if (region->vm_file)
@@ -612,13 +599,13 @@ index 0000000..b323b8a
 +              fput(pr);
 +}
 +#endif /* !CONFIG_MMU */
-aufs4.x-rcN standalone patch
+aufs4.4 standalone patch
 
 diff --git a/fs/dcache.c b/fs/dcache.c
-index 0b40298..4844e61 100644
+index 8aa7f26..f997345 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1269,6 +1269,7 @@ rename_retry:
+@@ -1272,6 +1272,7 @@ rename_retry:
        seq = 1;
        goto again;
  }
@@ -626,11 +613,23 @@ index 0b40298..4844e61 100644
  
  /*
   * Search for at least 1 mount point in the dentry's subdirs.
+diff --git a/fs/exec.c b/fs/exec.c
+index b06623a..b9206c5 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -103,6 +103,7 @@ bool path_noexec(const struct path *path)
+       return (path->mnt->mnt_flags & MNT_NOEXEC) ||
+              (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
+ }
++EXPORT_SYMBOL(path_noexec);
+ #ifdef CONFIG_USELIB
+ /*
 diff --git a/fs/file_table.c b/fs/file_table.c
-index 7f9d407..8c9ec1d 100644
+index ad17e05..38e046a 100644
 --- a/fs/file_table.c
 +++ b/fs/file_table.c
-@@ -146,6 +146,7 @@ over:
+@@ -147,6 +147,7 @@ over:
        }
        return ERR_PTR(-ENFILE);
  }
@@ -638,28 +637,32 @@ index 7f9d407..8c9ec1d 100644
  
  /**
   * alloc_file - allocate and initialize a 'struct file'
-@@ -307,6 +308,7 @@ void put_filp(struct file *file)
+@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
+ {
+       delayed_fput(NULL);
+ }
++EXPORT_SYMBOL(flush_delayed_fput);
+ static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
+@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
+ }
+ EXPORT_SYMBOL(fput);
++EXPORT_SYMBOL(__fput_sync);
+ void put_filp(struct file *file)
+ {
+@@ -308,6 +311,7 @@ void put_filp(struct file *file)
                file_free(file);
        }
  }
 +EXPORT_SYMBOL(put_filp);
  
- void __init files_init(unsigned long mempages)
+ void __init files_init(void)
  { 
-diff --git a/fs/inode.c b/fs/inode.c
-index d30640f..1ecc715 100644
---- a/fs/inode.c
-+++ b/fs/inode.c
-@@ -58,6 +58,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
- static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
-+EXPORT_SYMBOL(inode_sb_list_lock);
- /*
-  * Empty aops. Can be used for the cases where the user does not
 diff --git a/fs/namespace.c b/fs/namespace.c
-index c7cb8a5..08723de 100644
+index 0570729..ec560d8 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
@@ -670,7 +673,7 @@ index c7cb8a5..08723de 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1779,6 +1780,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -1803,6 +1804,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
        }
        return 0;
  }
@@ -715,7 +718,7 @@ index d16b62c..06ca6bc 100644
  int fsnotify_fasync(int fd, struct file *file, int on)
  {
 diff --git a/fs/notify/mark.c b/fs/notify/mark.c
-index 92e48c7..d2c4b68 100644
+index fc0df44..325b5c6 100644
 --- a/fs/notify/mark.c
 +++ b/fs/notify/mark.c
 @@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
@@ -726,15 +729,15 @@ index 92e48c7..d2c4b68 100644
  
  /* Calculate mask of events for a list of marks */
  u32 fsnotify_recalc_mask(struct hlist_head *head)
-@@ -202,6 +203,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
-       fsnotify_destroy_mark_locked(mark, group);
+@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
        mutex_unlock(&group->mark_mutex);
+       fsnotify_free_mark(mark);
  }
 +EXPORT_SYMBOL(fsnotify_destroy_mark);
  
- /*
-  * Destroy all marks in the given list. The marks must be already detached from
-@@ -376,6 +378,7 @@ err:
+ void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
+ {
+@@ -392,6 +394,7 @@ err:
  
        return ret;
  }
@@ -742,7 +745,7 @@ index 92e48c7..d2c4b68 100644
  
  int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
                      struct inode *inode, struct vfsmount *mnt, int allow_dups)
-@@ -455,6 +458,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
+@@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
        atomic_set(&mark->refcnt, 1);
        mark->free_mark = free_mark;
  }
@@ -751,7 +754,7 @@ index 92e48c7..d2c4b68 100644
  static int fsnotify_mark_destroy(void *ignored)
  {
 diff --git a/fs/open.c b/fs/open.c
-index e33dab2..b84b828 100644
+index b6f1e96..4ab0d4e 100644
 --- a/fs/open.c
 +++ b/fs/open.c
 @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
@@ -791,10 +794,10 @@ index fd0414e..8ace6ec 100644
  ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
  {
 diff --git a/fs/splice.c b/fs/splice.c
-index 5f8385a..f76067e 100644
+index 30a091d..c37c311 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1115,6 +1115,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1123,6 +1123,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
        return splice_write(pipe, out, ppos, len, flags);
  }
@@ -802,7 +805,7 @@ index 5f8385a..f76067e 100644
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
-@@ -1141,6 +1142,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1149,6 +1150,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
  
        return splice_read(in, ppos, pipe, len, flags);
  }
@@ -811,7 +814,7 @@ index 5f8385a..f76067e 100644
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
 diff --git a/fs/xattr.c b/fs/xattr.c
-index 072fee1..a7677af 100644
+index 9b932b9..44c457a 100644
 --- a/fs/xattr.c
 +++ b/fs/xattr.c
 @@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
@@ -822,11 +825,20 @@ index 072fee1..a7677af 100644
  
  /* Compare an extended attribute value with the given value */
  int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
+diff --git a/kernel/task_work.c b/kernel/task_work.c
+index 53fa971..f80d564 100644
+--- a/kernel/task_work.c
++++ b/kernel/task_work.c
+@@ -118,3 +118,4 @@ void task_work_run(void)
+               } while (work);
+       }
+ }
++EXPORT_SYMBOL(task_work_run);
 diff --git a/security/commoncap.c b/security/commoncap.c
-index d103f5a4..393654e 100644
+index 1832cf7..987ff5f 100644
 --- a/security/commoncap.c
 +++ b/security/commoncap.c
-@@ -970,12 +970,14 @@ int cap_mmap_addr(unsigned long addr)
+@@ -1053,12 +1053,14 @@ int cap_mmap_addr(unsigned long addr)
        }
        return ret;
  }
@@ -842,7 +854,7 @@ index d103f5a4..393654e 100644
  #ifdef CONFIG_SECURITY
  
 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
-index 188c1d2..426d9af 100644
+index 03c1652..b00aa76 100644
 --- a/security/device_cgroup.c
 +++ b/security/device_cgroup.c
 @@ -7,6 +7,7 @@
@@ -862,10 +874,10 @@ index 188c1d2..426d9af 100644
  int devcgroup_inode_mknod(int mode, dev_t dev)
  {
 diff --git a/security/security.c b/security/security.c
-index 595fffa..346bad6 100644
+index 46f405c..54488b0 100644
 --- a/security/security.c
 +++ b/security/security.c
-@@ -438,6 +438,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
+@@ -433,6 +433,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
                return 0;
        return call_int_hook(path_rmdir, 0, dir, dentry);
  }
@@ -873,7 +885,7 @@ index 595fffa..346bad6 100644
  
  int security_path_unlink(struct path *dir, struct dentry *dentry)
  {
-@@ -454,6 +455,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
+@@ -449,6 +450,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
                return 0;
        return call_int_hook(path_symlink, 0, dir, dentry, old_name);
  }
@@ -881,7 +893,7 @@ index 595fffa..346bad6 100644
  
  int security_path_link(struct dentry *old_dentry, struct path *new_dir,
                       struct dentry *new_dentry)
-@@ -462,6 +464,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
+@@ -457,6 +459,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
                return 0;
        return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
  }
@@ -889,7 +901,7 @@ index 595fffa..346bad6 100644
  
  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
                         struct path *new_dir, struct dentry *new_dentry,
-@@ -489,6 +492,7 @@ int security_path_truncate(struct path *path)
+@@ -484,6 +487,7 @@ int security_path_truncate(struct path *path)
                return 0;
        return call_int_hook(path_truncate, 0, path);
  }
@@ -897,7 +909,7 @@ index 595fffa..346bad6 100644
  
  int security_path_chmod(struct path *path, umode_t mode)
  {
-@@ -496,6 +500,7 @@ int security_path_chmod(struct path *path, umode_t mode)
+@@ -491,6 +495,7 @@ int security_path_chmod(struct path *path, umode_t mode)
                return 0;
        return call_int_hook(path_chmod, 0, path, mode);
  }
@@ -905,7 +917,7 @@ index 595fffa..346bad6 100644
  
  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
  {
-@@ -503,6 +508,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
+@@ -498,6 +503,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
                return 0;
        return call_int_hook(path_chown, 0, path, uid, gid);
  }
@@ -913,7 +925,7 @@ index 595fffa..346bad6 100644
  
  int security_path_chroot(struct path *path)
  {
-@@ -588,6 +594,7 @@ int security_inode_readlink(struct dentry *dentry)
+@@ -583,6 +589,7 @@ int security_inode_readlink(struct dentry *dentry)
                return 0;
        return call_int_hook(inode_readlink, 0, dentry);
  }
@@ -921,7 +933,7 @@ index 595fffa..346bad6 100644
  
  int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
                               bool rcu)
-@@ -603,6 +610,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -598,6 +605,7 @@ int security_inode_permission(struct inode *inode, int mask)
                return 0;
        return call_int_hook(inode_permission, 0, inode, mask);
  }
@@ -929,7 +941,7 @@ index 595fffa..346bad6 100644
  
  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  {
-@@ -741,6 +749,7 @@ int security_file_permission(struct file *file, int mask)
+@@ -736,6 +744,7 @@ int security_file_permission(struct file *file, int mask)
  
        return fsnotify_perm(file, mask);
  }
@@ -937,7 +949,7 @@ index 595fffa..346bad6 100644
  
  int security_file_alloc(struct file *file)
  {
-@@ -800,6 +809,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
+@@ -795,6 +804,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
                return ret;
        return ima_file_mmap(file, prot);
  }
@@ -947,7 +959,7 @@ index 595fffa..346bad6 100644
  {
 diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
 --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs    1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/ABI/testing/debugfs-aufs       2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/ABI/testing/debugfs-aufs       2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,50 @@
 +What:         /debug/aufs/si_<id>/
 +Date:         March 2009
@@ -1001,7 +1013,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Document
 +              will be empty. About XINO files, see the aufs manual.
 diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
 --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs      1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/ABI/testing/sysfs-aufs 2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,31 @@
 +What:         /sys/fs/aufs/si_<id>/
 +Date:         March 2009
@@ -1036,10 +1048,10 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentat
 +              will be empty. About XINO files, see the aufs manual.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/01intro.txt    2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/01intro.txt    2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,170 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1210,10 +1222,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt lin
 +about it. But currently I have implemented it in kernel space.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/02struct.txt   2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/02struct.txt   2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,258 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1472,10 +1484,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt li
 +For this purpose, use "aumvdown" command in aufs-util.git.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt   1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt      2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,85 @@
 +
-+# Copyright (C) 2015 Junjiro R. Okajima
++# Copyright (C) 2015-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1561,10 +1573,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.t
 +       be implemented in aufs, but not all I am afraid.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/03lookup.txt   2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/03lookup.txt   2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,113 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1678,10 +1690,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt li
 +   by over-mounting something (or another method).
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/04branch.txt   2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/04branch.txt   2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,74 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1756,10 +1768,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt li
 +    same named entry on the upper branch.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt    1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt       2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt       2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,64 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1824,10 +1836,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx
 +  copyup policy.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt  1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt     2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,120 @@
 +
-+# Copyright (C) 2011-2015 Junjiro R. Okajima
++# Copyright (C) 2011-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -1948,10 +1960,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linu
 +should restore the original file state after an error happens.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt  1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06mmap.txt     2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/06mmap.txt     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,72 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -2024,10 +2036,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu
 +I have to give up this "looks-smater" approach.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06xattr.txt    2015-09-24 10:47:58.244719488 +0200
++++ linux/Documentation/filesystems/aufs/design/06xattr.txt    2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,96 @@
 +
-+# Copyright (C) 2014-2015 Junjiro R. Okajima
++# Copyright (C) 2014-2016 Junjiro R. Okajima
 +#
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -2124,10 +2136,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt lin
 +now, aufs implements the branch attributes to ignore the error.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/07export.txt   2015-09-24 10:47:58.248052907 +0200
++++ linux/Documentation/filesystems/aufs/design/07export.txt   2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,58 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -2186,10 +2198,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt li
 +  lookup_one_len(), vfs_getattr(), encode_fh() and others.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt  1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/08shwh.txt     2015-09-24 10:47:58.248052907 +0200
++++ linux/Documentation/filesystems/aufs/design/08shwh.txt     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,52 @@
 +
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
++# Copyright (C) 2005-2016 Junjiro R. Okajima
 +# 
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -2242,10 +2254,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linu
 +initramfs will use it to replace the old one at the next boot.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/10dynop.txt    2015-09-24 10:47:58.248052907 +0200
++++ linux/Documentation/filesystems/aufs/design/10dynop.txt    2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,47 @@
 +
-+# Copyright (C) 2010-2015 Junjiro R. Okajima
++# Copyright (C) 2010-2016 Junjiro R. Okajima
 +#
 +# This program is free software; you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
@@ -2293,8 +2305,8 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin
 +regular files only.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
 --- /usr/share/empty/Documentation/filesystems/aufs/README     1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/README        2015-09-24 10:47:58.244719488 +0200
-@@ -0,0 +1,383 @@
++++ linux/Documentation/filesystems/aufs/README        2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,391 @@
 +
 +Aufs4 -- advanced multi layered unification filesystem version 4.x
 +http://aufs.sf.net
@@ -2403,7 +2415,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
 +build aufs4 as an external kernel module.
 +Several extra patches are not included in this tree. Only
-+aufs4-standalone tree contains them. They are describe in the later
++aufs4-standalone tree contains them. They are described in the later
 +section "Configuration and Compilation."
 +
 +On the other hand, the aufs4-standalone tree has only aufs source files
@@ -2559,6 +2571,13 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +  duplication of inode number, which is important for backup tools and
 +  other utilities. When you find aufs XINO files for tmpfs branch
 +  growing too much, try this patch.
++- lockdep-debug.patch
++  Because aufs is not only an ordinary filesystem (callee of VFS), but
++  also a caller of VFS functions for branch filesystems, subclassing of
++  the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
++  feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
++  need to apply this debug patch to expand several constant values.
++  If don't know what LOCKDEP, then you don't have apply this patch.
 +
 +
 +4. Usage
@@ -2661,6 +2680,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +James B made a donation (2014/7 and 2015/7).
 +Stefano Di Biase made a donation (2014/8).
 +Daniel Epellei made a donation (2015/1).
++OmegaPhil made a donation (2016/1).
 +
 +Thank you very much.
 +Donations are always, including future donations, very important and
@@ -2680,10 +2700,10 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +# End: ;
 diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
 --- /usr/share/empty/fs/aufs/aufs.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/aufs.h       2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/aufs.h       2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,59 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -2743,10 +2763,10 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
 +#endif /* __AUFS_H__ */
 diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 --- /usr/share/empty/fs/aufs/branch.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/branch.c     2015-09-24 10:47:58.248052907 +0200
-@@ -0,0 +1,1414 @@
++++ linux/fs/aufs/branch.c     2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,1407 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -2877,7 +2897,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +      err = -ENOMEM;
 +      root = sb->s_root;
-+      add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
++      add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
 +      if (unlikely(!add_branch))
 +              goto out;
 +
@@ -2885,16 +2905,14 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      if (unlikely(err))
 +              goto out_br;
 +
-+      add_branch->br_wbr = NULL;
 +      if (au_br_writable(perm)) {
 +              /* may be freed separately at changing the branch permission */
-+              add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
++              add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
 +                                           GFP_NOFS);
 +              if (unlikely(!add_branch->br_wbr))
 +                      goto out_hnotify;
 +      }
 +
-+      add_branch->br_fhsm = NULL;
 +      if (au_br_fhsm(perm)) {
 +              err = au_fhsm_br_alloc(add_branch);
 +              if (unlikely(err))
@@ -3099,9 +3117,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +      wbr = br->br_wbr;
 +      au_rw_init(&wbr->wbr_wh_rwsem);
-+      memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
 +      atomic_set(&wbr->wbr_wh_running, 0);
-+      wbr->wbr_bytes = 0;
 +
 +      /*
 +       * a limit for rmdir/rename a dir
@@ -3130,12 +3146,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      struct inode *h_inode;
 +
 +      err = 0;
-+      memset(&br->br_xino, 0, sizeof(br->br_xino));
 +      mutex_init(&br->br_xino.xi_nondir_mtx);
 +      br->br_perm = add->perm;
 +      br->br_path = add->path; /* set first, path_get() later */
 +      spin_lock_init(&br->br_dykey_lock);
-+      memset(br->br_dykey, 0, sizeof(br->br_dykey));
 +      atomic_set(&br->br_count, 0);
 +      atomic_set(&br->br_xino_running, 0);
 +      br->br_id = au_new_br_id(sb);
@@ -3301,7 +3315,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+static unsigned long long au_farray_cb(void *a,
++static unsigned long long au_farray_cb(struct super_block *sb, void *a,
 +                                     unsigned long long max __maybe_unused,
 +                                     void *arg)
 +{
@@ -3309,7 +3323,6 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      struct file **p, *f;
 +      struct au_sphlhead *files;
 +      struct au_finfo *finfo;
-+      struct super_block *sb = arg;
 +
 +      n = 0;
 +      p = a;
@@ -3334,7 +3347,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +                                   unsigned long long *max)
 +{
 +      *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
-+      return au_array_alloc(max, au_farray_cb, sb);
++      return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
 +}
 +
 +static void au_farray_free(struct file **a, unsigned long long max)
@@ -3344,7 +3357,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      for (ull = 0; ull < max; ull++)
 +              if (a[ull])
 +                      fput(a[ull]);
-+      au_array_free(a);
++      kvfree(a);
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -3732,8 +3745,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      au_br_do_free(br);
 +}
 +
-+static unsigned long long empty_cb(void *array, unsigned long long max,
-+                                 void *arg)
++static unsigned long long empty_cb(struct super_block *sb, void *array,
++                                 unsigned long long max, void *arg)
 +{
 +      return max;
 +}
@@ -3778,7 +3791,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      br_id = br->br_id;
 +      opened = atomic_read(&br->br_count);
 +      if (unlikely(opened)) {
-+              to_free = au_array_alloc(&opened, empty_cb, NULL);
++              to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
 +              err = PTR_ERR(to_free);
 +              if (IS_ERR(to_free))
 +                      goto out;
@@ -4094,7 +4107,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +                      if (unlikely(err)) {
 +                              rerr = -ENOMEM;
-+                              br->br_wbr = kmalloc(sizeof(*br->br_wbr),
++                              br->br_wbr = kzalloc(sizeof(*br->br_wbr),
 +                                                   GFP_NOFS);
 +                              if (br->br_wbr)
 +                                      rerr = au_wbr_init(br, sb, br->br_perm);
@@ -4108,7 +4121,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      } else if (au_br_writable(mod->perm)) {
 +              /* ro --> rw */
 +              err = -ENOMEM;
-+              br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
++              br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
 +              if (br->br_wbr) {
 +                      err = au_wbr_init(br, sb, mod->perm);
 +                      if (unlikely(err)) {
@@ -4161,10 +4174,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +}
 diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 --- /usr/share/empty/fs/aufs/branch.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/branch.h     2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/branch.h     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,279 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -4321,7 +4334,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +
 +      err = 0;
 +      exec_flag = oflag & __FMODE_EXEC;
-+      if (unlikely(exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC)))
++      if (unlikely(exec_flag && path_noexec(&br->br_path)))
 +              err = -EACCES;
 +
 +      return err;
@@ -4444,7 +4457,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +#endif /* __AUFS_BRANCH_H__ */
 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 --- /usr/share/empty/fs/aufs/conf.mk   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/conf.mk      2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/conf.mk      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,38 @@
 +
 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
@@ -4486,10 +4499,10 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 +-include ${srctree}/${src}/conf_priv.mk
 diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 --- /usr/share/empty/fs/aufs/cpup.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/cpup.c       2015-09-24 10:47:58.248052907 +0200
-@@ -0,0 +1,1319 @@
++++ linux/fs/aufs/cpup.c       2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,1379 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -4511,6 +4524,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +
 +#include <linux/fs_stack.h>
 +#include <linux/mm.h>
++#include <linux/task_work.h>
 +#include "aufs.h"
 +
 +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
@@ -4883,6 +4897,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              }
 +      };
 +      struct super_block *sb;
++      struct task_struct *tsk = current;
 +
 +      /* bsrc branch can be ro/rw. */
 +      sb = cpg->dentry->d_sb;
@@ -4900,7 +4915,21 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      IMustLock(d_inode(file[SRC].dentry));
 +      err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
 +
-+      fput(file[DST].file);
++      /* i wonder if we had O_NO_DELAY_FPUT flag */
++      if (tsk->flags & PF_KTHREAD)
++              __fput_sync(file[DST].file);
++      else {
++              WARN(1, "%pD\nPlease report this warning to aufs-users ML",
++                   file[DST].file);
++              fput(file[DST].file);
++              /*
++               * too bad.
++               * we have to call both since we don't know which place the file
++               * was added to.
++               */
++              task_work_run();
++              flush_delayed_fput();
++      }
 +      au_sbr_put(sb, file[DST].bindex);
 +
 +out_src:
@@ -4999,6 +5028,57 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      return err;
 +}
 +
++/*
++ * regardless 'acl' option, reset all ACL.
++ * All ACL will be copied up later from the original entry on the lower branch.
++ */
++static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
++{
++      int err;
++      struct dentry *h_dentry;
++      struct inode *h_inode;
++
++      h_dentry = h_path->dentry;
++      h_inode = d_inode(h_dentry);
++      /* forget_all_cached_acls(h_inode)); */
++      err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
++      AuTraceErr(err);
++      if (err == -EOPNOTSUPP)
++              err = 0;
++      if (!err)
++              err = vfsub_acl_chmod(h_inode, mode);
++
++      AuTraceErr(err);
++      return err;
++}
++
++static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
++                        struct inode *h_dir, struct path *h_path)
++{
++      int err;
++      struct inode *dir, *inode;
++
++      err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
++      AuTraceErr(err);
++      if (err == -EOPNOTSUPP)
++              err = 0;
++      if (unlikely(err))
++              goto out;
++
++      /*
++       * strange behaviour from the users view,
++       * particularry setattr case
++       */
++      dir = d_inode(dst_parent);
++      if (au_ibstart(dir) == cpg->bdst)
++              au_cpup_attr_nlink(dir, /*force*/1);
++      inode = d_inode(cpg->dentry);
++      au_cpup_attr_nlink(inode, /*force*/1);
++
++out:
++      return err;
++}
++
 +static noinline_for_stack
 +int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
 +             struct au_cpup_reg_attr *h_src_attr)
@@ -5011,7 +5091,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct au_dtime dt;
 +      struct path h_path;
 +      struct dentry *h_src, *h_dst, *h_parent;
-+      struct inode *h_inode, *h_dir, *dir, *inode;
++      struct inode *h_inode, *h_dir;
 +      struct super_block *sb;
 +
 +      /* bsrc branch can be ro/rw. */
@@ -5043,7 +5123,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      switch (mode & S_IFMT) {
 +      case S_IFREG:
 +              isreg = 1;
-+              err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
++              err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR,
 +                                 /*want_excl*/true);
 +              if (!err)
 +                      err = au_do_cpup_regular(cpg, h_src_attr);
@@ -5051,17 +5131,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      case S_IFDIR:
 +              isdir = 1;
 +              err = vfsub_mkdir(h_dir, &h_path, mode);
-+              if (!err) {
-+                      /*
-+                       * strange behaviour from the users view,
-+                       * particularry setattr case
-+                       */
-+                      dir = d_inode(dst_parent);
-+                      if (au_ibstart(dir) == cpg->bdst)
-+                              au_cpup_attr_nlink(dir, /*force*/1);
-+                      inode = d_inode(cpg->dentry);
-+                      au_cpup_attr_nlink(inode, /*force*/1);
-+              }
++              if (!err)
++                      err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
 +              break;
 +      case S_IFLNK:
 +              err = au_do_cpup_symlink(&h_path, h_src, h_dir);
@@ -5078,6 +5149,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              AuIOErr("Unknown inode type 0%o\n", mode);
 +              err = -EIO;
 +      }
++      if (!err)
++              err = au_reset_acl(h_dir, &h_path, mode);
 +
 +      mnt_flags = au_mntflags(sb);
 +      if (!au_opt_test(mnt_flags, UDBA_NONE)
@@ -5213,9 +5286,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +                              goto out_parent;
 +                      if (unlikely(d_is_negative(h_src))) {
 +                              err = -EIO;
-+                              AuIOErr("i%lu exists on a upper branch "
++                              AuIOErr("i%lu exists on b%d "
 +                                      "but not pseudo-linked\n",
-+                                      inode->i_ino);
++                                      inode->i_ino, cpg->bdst);
 +                              dput(h_src);
 +                              goto out_parent;
 +                      }
@@ -5809,10 +5882,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +}
 diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
 --- /usr/share/empty/fs/aufs/cpup.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/cpup.h       2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/cpup.h       2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,94 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -5907,10 +5980,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
 +#endif /* __AUFS_CPUP_H__ */
 diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 --- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dbgaufs.c    2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/dbgaufs.c    2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,432 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -6343,10 +6416,10 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +}
 diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
 --- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dbgaufs.h    2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/dbgaufs.h    2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,48 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -6395,10 +6468,10 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
 +#endif /* __DBGAUFS_H__ */
 diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
 --- /usr/share/empty/fs/aufs/dcsub.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dcsub.c      2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/dcsub.c      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,224 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -6623,10 +6696,10 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
 +}
 diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 --- /usr/share/empty/fs/aufs/dcsub.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dcsub.h      2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/dcsub.h      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,136 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -6763,10 +6836,10 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +#endif /* __AUFS_DCSUB_H__ */
 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 --- /usr/share/empty/fs/aufs/debug.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.c      2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,440 @@
++++ linux/fs/aufs/debug.c      2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,438 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -7097,9 +7170,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +      }
 +
 +      a->mnt.mnt_sb = sb;
-+      a->fake.br_perm = 0;
 +      a->fake.br_path.mnt = &a->mnt;
-+      a->fake.br_xino.xi_file = NULL;
 +      atomic_set(&a->fake.br_count, 0);
 +      smp_mb(); /* atomic_set */
 +      err = do_pri_br(-1, &a->fake);
@@ -7207,10 +7278,10 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +}
 diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
 --- /usr/share/empty/fs/aufs/debug.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.h      2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/debug.h      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,225 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -7436,10 +7507,10 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
 +#endif /* __AUFS_DEBUG_H__ */
 diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 --- /usr/share/empty/fs/aufs/dentry.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dentry.c     2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,1105 @@
++++ linux/fs/aufs/dentry.c     2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,1136 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -7632,7 +7703,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              if (dirperm1)
 +                      au_fset_lkup(args.flags, IGNORE_PERM);
 +
-+              if (au_dbwh(dentry) >= 0)
++              if (au_dbwh(dentry) == bindex)
 +                      break;
 +              if (!h_dentry)
 +                      continue;
@@ -8007,7 +8078,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              struct dentry *dentry;
 +              struct inode *inode;
 +              mode_t mode;
-+      } orig_h, tmp_h;
++      } orig_h, tmp_h = {
++              .dentry = NULL
++      };
 +      struct au_hdentry *hd;
 +      struct inode *inode, *h_inode;
 +      struct dentry *h_dentry;
@@ -8021,10 +8094,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              orig_h.inode = d_inode(orig_h.dentry);
 +              orig_h.mode = orig_h.inode->i_mode & S_IFMT;
 +      }
-+      memset(&tmp_h, 0, sizeof(tmp_h));
 +      if (tmp->di_bstart >= 0) {
 +              tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
-+              tmp_h.inode = NULL;
 +              if (d_is_positive(tmp_h.dentry)) {
 +                      tmp_h.inode = d_inode(tmp_h.dentry);
 +                      tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
@@ -8138,6 +8209,28 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      return err;
 +}
 +
++void au_refresh_dop(struct dentry *dentry, int force_reval)
++{
++      const struct dentry_operations *dop
++              = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
++      static const unsigned int mask
++              = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
++
++      BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
++
++      if (dentry->d_op == dop)
++              return;
++
++      AuDbg("%pd\n", dentry);
++      spin_lock(&dentry->d_lock);
++      if (dop == &aufs_dop)
++              dentry->d_flags |= mask;
++      else
++              dentry->d_flags &= ~mask;
++      dentry->d_op = dop;
++      spin_unlock(&dentry->d_lock);
++}
++
 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
 +{
 +      int err, ebrange;
@@ -8493,8 +8586,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
 +          && inode
 +          && !(inode->i_state && I_LINKABLE)
-+          && (IS_DEADDIR(inode) || !inode->i_nlink))
++          && (IS_DEADDIR(inode) || !inode->i_nlink)) {
++              AuTraceErr(err);
 +              goto out_inval;
++      }
 +
 +      do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
 +      if (do_udba && inode) {
@@ -8503,8 +8598,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +              if (bstart >= 0) {
 +                      h_inode = au_h_iptr(inode, bstart);
-+                      if (h_inode && au_test_higen(inode, h_inode))
++                      if (h_inode && au_test_higen(inode, h_inode)) {
++                              AuTraceErr(err);
 +                              goto out_inval;
++                      }
 +              }
 +      }
 +
@@ -8543,12 +8640,17 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      .d_weak_revalidate      = aufs_d_revalidate,
 +      .d_release              = aufs_d_release
 +};
++
++/* aufs_dop without d_revalidate */
++const struct dentry_operations aufs_dop_noreval = {
++      .d_release              = aufs_d_release
++};
 diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 --- /usr/share/empty/fs/aufs/dentry.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dentry.h     2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,233 @@
++++ linux/fs/aufs/dentry.h     2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,234 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -8593,7 +8695,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 +/* ---------------------------------------------------------------------- */
 +
 +/* dentry.c */
-+extern const struct dentry_operations aufs_dop;
++extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
 +struct au_branch;
 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
@@ -8603,6 +8705,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
++void au_refresh_dop(struct dentry *dentry, int force_reval);
 +
 +/* dinfo.c */
 +void au_di_init_once(void *_di);
@@ -8782,10 +8885,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 +#endif /* __AUFS_DENTRY_H__ */
 diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 --- /usr/share/empty/fs/aufs/dinfo.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dinfo.c      2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/dinfo.c      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,550 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -9336,10 +9439,10 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 --- /usr/share/empty/fs/aufs/dir.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dir.c        2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,753 @@
++++ linux/fs/aufs/dir.c        2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,758 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -9455,9 +9558,9 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      sb = a->dentry->d_sb;
 +      if (d_really_is_negative(a->dentry))
 +              goto out;
-+      aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */
-+
 +      /* no dir->i_mutex lock */
++      aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
++
 +      dir = d_inode(a->dentry);
 +      bstart = au_ibstart(dir);
 +      bindex = au_br_index(sb, a->brid);
@@ -9590,11 +9693,13 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      int err;
 +      aufs_bindex_t bindex, btail;
 +      struct dentry *dentry, *h_dentry;
++      struct vfsmount *mnt;
 +
 +      FiMustWriteLock(file);
 +      AuDebugOn(h_file);
 +
 +      err = 0;
++      mnt = file->f_path.mnt;
 +      dentry = file->f_path.dentry;
 +      file->f_version = d_inode(dentry)->i_version;
 +      bindex = au_dbstart(dentry);
@@ -9606,6 +9711,9 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +              if (!h_dentry)
 +                      continue;
 +
++              err = vfsub_test_mntns(mnt, h_dentry->d_sb);
++              if (unlikely(err))
++                      break;
 +              h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
 +              if (IS_ERR(h_file)) {
 +                      err = PTR_ERR(h_file);
@@ -10093,10 +10201,10 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +};
 diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
 --- /usr/share/empty/fs/aufs/dir.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dir.h        2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/dir.h        2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,131 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -10228,10 +10336,10 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
 +#endif /* __AUFS_DIR_H__ */
 diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 --- /usr/share/empty/fs/aufs/dynop.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dynop.c      2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/dynop.c      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,369 @@
 +/*
-+ * Copyright (C) 2010-2015 Junjiro R. Okajima
++ * Copyright (C) 2010-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -10601,10 +10709,10 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +}
 diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
 --- /usr/share/empty/fs/aufs/dynop.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dynop.h      2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/dynop.h      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,74 @@
 +/*
-+ * Copyright (C) 2010-2015 Junjiro R. Okajima
++ * Copyright (C) 2010-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -10679,10 +10787,10 @@ diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
 +#endif /* __AUFS_DYNOP_H__ */
 diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 --- /usr/share/empty/fs/aufs/export.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/export.c     2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/export.c     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,832 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -11293,7 +11401,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +      ino = decode_ino(fh + Fh_ino);
 +      /* it should never happen */
 +      if (unlikely(ino == AUFS_ROOT_INO))
-+              goto out;
++              goto out_unlock;
 +
 +      dir_ino = decode_ino(fh + Fh_dir_ino);
 +      dentry = decode_by_ino(sb, ino, dir_ino);
@@ -11515,10 +11623,10 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +}
 diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
 --- /usr/share/empty/fs/aufs/fhsm.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/fhsm.c       2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/fhsm.c       2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,426 @@
 +/*
-+ * Copyright (C) 2011-2015 Junjiro R. Okajima
++ * Copyright (C) 2011-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -11945,10 +12053,10 @@ diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
 +}
 diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 --- /usr/share/empty/fs/aufs/file.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/file.c       2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,841 @@
++++ linux/fs/aufs/file.c       2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,844 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -12744,9 +12852,11 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +{ AuUnsupport(); }
 +static int aufs_releasepage(struct page *page, gfp_t gfp)
 +{ AuUnsupport(); return 0; }
++#if 0 /* called by memory compaction regardless file */
 +static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
 +                          struct page *page, enum migrate_mode mode)
 +{ AuUnsupport(); return 0; }
++#endif
 +static int aufs_launder_page(struct page *page)
 +{ AuUnsupport(); return 0; }
 +static int aufs_is_partially_uptodate(struct page *page,
@@ -12779,7 +12889,8 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      /* no bmap, no block device */
 +      .invalidatepage         = aufs_invalidatepage,
 +      .releasepage            = aufs_releasepage,
-+      .migratepage            = aufs_migratepage,
++      /* is fallback_migrate_page ok? */
++      /* .migratepage         = aufs_migratepage, */
 +      .launder_page           = aufs_launder_page,
 +      .is_partially_uptodate  = aufs_is_partially_uptodate,
 +      .is_dirty_writeback     = aufs_is_dirty_writeback,
@@ -12790,10 +12901,10 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +};
 diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 --- /usr/share/empty/fs/aufs/file.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/file.h       2015-09-24 10:47:58.251386326 +0200
++++ linux/fs/aufs/file.h       2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,291 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -13085,10 +13196,10 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +#endif /* __AUFS_FILE_H__ */
 diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 --- /usr/share/empty/fs/aufs/finfo.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/finfo.c      2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,157 @@
++++ linux/fs/aufs/finfo.c      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,156 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -13164,7 +13275,6 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +      if (fidir) {
 +              fidir->fd_bbot = -1;
 +              fidir->fd_nent = nbr;
-+              fidir->fd_vdir_cache = NULL;
 +      }
 +
 +      return fidir;
@@ -13246,10 +13356,10 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 --- /usr/share/empty/fs/aufs/f_op.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/f_op.c       2015-09-24 10:47:58.251386326 +0200
-@@ -0,0 +1,738 @@
++++ linux/fs/aufs/f_op.c       2016-02-28 11:26:32.569971135 +0100
+@@ -0,0 +1,748 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -13279,7 +13389,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +{
 +      int err;
 +      aufs_bindex_t bindex;
-+      struct dentry *dentry;
++      struct dentry *dentry, *h_dentry;
 +      struct au_finfo *finfo;
 +      struct inode *h_inode;
 +
@@ -13292,10 +13402,19 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +      memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
 +      atomic_set(&finfo->fi_mmapped, 0);
 +      bindex = au_dbstart(dentry);
-+      if (!h_file)
++      if (!h_file) {
++              h_dentry = au_h_dptr(dentry, bindex);
++              err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
++              if (unlikely(err))
++                      goto out;
 +              h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
-+      else
++      } else {
++              h_dentry = h_file->f_path.dentry;
++              err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
++              if (unlikely(err))
++                      goto out;
 +              get_file(h_file);
++      }
 +      if (IS_ERR(h_file))
 +              err = PTR_ERR(h_file);
 +      else {
@@ -13313,6 +13432,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +              /* file->f_ra = h_file->f_ra; */
 +      }
 +
++out:
 +      return err;
 +}
 +
@@ -13988,10 +14108,10 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +};
 diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 --- /usr/share/empty/fs/aufs/fstype.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/fstype.h     2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/fstype.h     2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,400 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -14018,8 +14138,8 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +#include <linux/fs.h>
 +#include <linux/magic.h>
-+#include <linux/romfs_fs.h>
 +#include <linux/nfs_fs.h>
++#include <linux/romfs_fs.h>
 +
 +static inline int au_test_aufs(struct super_block *sb)
 +{
@@ -14392,10 +14512,10 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +#endif /* __AUFS_FSTYPE_H__ */
 diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
 --- /usr/share/empty/fs/aufs/hfsnotify.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/hfsnotify.c  2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/hfsnotify.c  2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,288 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -14684,10 +14804,10 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
 +};
 diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
 --- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/hfsplus.c    2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/hfsplus.c    2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,56 @@
 +/*
-+ * Copyright (C) 2010-2015 Junjiro R. Okajima
++ * Copyright (C) 2010-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -14744,10 +14864,10 @@ diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
 +}
 diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 --- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/hnotify.c    2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/hnotify.c    2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,710 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -15458,10 +15578,10 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +}
 diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 --- /usr/share/empty/fs/aufs/iinfo.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/iinfo.c      2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/iinfo.c      2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,277 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -15580,13 +15700,13 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +      sigen = au_sigen(inode->i_sb);
 +      iinfo = au_ii(inode);
 +      iigen = &iinfo->ii_generation;
-+      spin_lock(&iinfo->ii_genspin);
++      spin_lock(&iigen->ig_spin);
 +      iigen->ig_generation = sigen;
 +      if (half)
 +              au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
 +      else
 +              au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
-+      spin_unlock(&iinfo->ii_genspin);
++      spin_unlock(&iigen->ig_spin);
 +}
 +
 +/* it may be called at remount time, too */
@@ -15639,7 +15759,7 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +      struct au_iinfo *iinfo = &c->iinfo;
 +      static struct lock_class_key aufs_ii;
 +
-+      spin_lock_init(&iinfo->ii_genspin);
++      spin_lock_init(&iinfo->ii_generation.ig_spin);
 +      au_rw_init(&iinfo->ii_rwsem);
 +      au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
 +      inode_init_once(&c->vfs_inode);
@@ -15739,10 +15859,10 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 --- /usr/share/empty/fs/aufs/inode.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/inode.c      2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,500 @@
++++ linux/fs/aufs/inode.c      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,527 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -15843,6 +15963,32 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      return err;
 +}
 +
++void au_refresh_iop(struct inode *inode, int force_getattr)
++{
++      int type;
++      struct au_sbinfo *sbi = au_sbi(inode->i_sb);
++      const struct inode_operations *iop
++              = force_getattr ? aufs_iop : sbi->si_iop_array;
++
++      if (inode->i_op == iop)
++              return;
++
++      switch (inode->i_mode & S_IFMT) {
++      case S_IFDIR:
++              type = AuIop_DIR;
++              break;
++      case S_IFLNK:
++              type = AuIop_SYMLINK;
++              break;
++      default:
++              type = AuIop_OTHER;
++              break;
++      }
++
++      inode->i_op = iop + type;
++      /* unnecessary smp_wmb() */
++}
++
 +int au_refresh_hinode_self(struct inode *inode)
 +{
 +      int err, update;
@@ -15924,11 +16070,13 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      struct dentry *h_dentry;
 +      struct inode *h_inode;
 +      struct au_iinfo *iinfo;
++      struct inode_operations *iop;
 +
 +      IiMustWriteLock(inode);
 +
 +      err = 0;
 +      isdir = 0;
++      iop = au_sbi(inode->i_sb)->si_iop_array;
 +      bstart = au_dbstart(dentry);
 +      h_dentry = au_h_dptr(dentry, bstart);
 +      h_inode = d_inode(h_dentry);
@@ -15936,7 +16084,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      switch (mode & S_IFMT) {
 +      case S_IFREG:
 +              btail = au_dbtail(dentry);
-+              inode->i_op = &aufs_iop;
++              inode->i_op = iop + AuIop_OTHER;
 +              inode->i_fop = &aufs_file_fop;
 +              err = au_dy_iaop(inode, bstart, h_inode);
 +              if (unlikely(err))
@@ -15945,19 +16093,19 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      case S_IFDIR:
 +              isdir = 1;
 +              btail = au_dbtaildir(dentry);
-+              inode->i_op = &aufs_dir_iop;
++              inode->i_op = iop + AuIop_DIR;
 +              inode->i_fop = &aufs_dir_fop;
 +              break;
 +      case S_IFLNK:
 +              btail = au_dbtail(dentry);
-+              inode->i_op = &aufs_symlink_iop;
++              inode->i_op = iop + AuIop_SYMLINK;
 +              break;
 +      case S_IFBLK:
 +      case S_IFCHR:
 +      case S_IFIFO:
 +      case S_IFSOCK:
 +              btail = au_dbtail(dentry);
-+              inode->i_op = &aufs_iop;
++              inode->i_op = iop + AuIop_OTHER;
 +              init_special_inode(inode, mode, h_inode->i_rdev);
 +              break;
 +      default:
@@ -16001,8 +16149,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +static int reval_inode(struct inode *inode, struct dentry *dentry)
 +{
 +      int err;
-+      unsigned int gen;
-+      struct au_iigen iigen;
++      unsigned int gen, igflags;
 +      aufs_bindex_t bindex, bend;
 +      struct inode *h_inode, *h_dinode;
 +      struct dentry *h_dentry;
@@ -16027,9 +16174,9 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +                      continue;
 +
 +              err = 0;
-+              gen = au_iigen(inode, &iigen);
++              gen = au_iigen(inode, &igflags);
 +              if (gen == au_digen(dentry)
-+                  && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
++                  && !au_ig_ftest(igflags, HALF_REFRESHED))
 +                      break;
 +
 +              /* fully refresh inode using dentry */
@@ -16243,10 +16390,10 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +}
 diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 --- /usr/share/empty/fs/aufs/inode.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/inode.h      2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,673 @@
++++ linux/fs/aufs/inode.h      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,685 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -16306,12 +16453,12 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +      do { (flags) &= ~AuIG_##name; } while (0)
 +
 +struct au_iigen {
++      spinlock_t      ig_spin;
 +      __u32           ig_generation, ig_flags;
 +};
 +
 +struct au_vdir;
 +struct au_iinfo {
-+      spinlock_t              ii_genspin;
 +      struct au_iigen         ii_generation;
 +      struct super_block      *ii_hsb1;       /* no get/put */
 +
@@ -16377,6 +16524,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +
 +/* inode.c */
 +struct inode *au_igrab(struct inode *inode);
++void au_refresh_iop(struct inode *inode, int force_getattr);
 +int au_refresh_hinode_self(struct inode *inode);
 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
@@ -16398,7 +16546,14 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +}
 +
 +/* i_op.c */
-+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
++enum {
++      AuIop_SYMLINK,
++      AuIop_DIR,
++      AuIop_OTHER,
++      AuIop_Last
++};
++extern struct inode_operations aufs_iop[AuIop_Last],
++      aufs_iop_nogetattr[AuIop_Last];
 +
 +/* au_wr_dir flags */
 +#define AuWrDir_ADD_ENTRY     1
@@ -16661,17 +16816,19 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +#endif
 +}
 +
-+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
++static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
 +{
 +      unsigned int gen;
 +      struct au_iinfo *iinfo;
++      struct au_iigen *iigen;
 +
 +      iinfo = au_ii(inode);
-+      spin_lock(&iinfo->ii_genspin);
-+      if (iigen)
-+              *iigen = iinfo->ii_generation;
-+      gen = iinfo->ii_generation.ig_generation;
-+      spin_unlock(&iinfo->ii_genspin);
++      iigen = &iinfo->ii_generation;
++      spin_lock(&iigen->ig_spin);
++      if (igflags)
++              *igflags = iigen->ig_flags;
++      gen = iigen->ig_generation;
++      spin_unlock(&iigen->ig_spin);
 +
 +      return gen;
 +}
@@ -16691,11 +16848,13 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +static inline void au_iigen_dec(struct inode *inode)
 +{
 +      struct au_iinfo *iinfo;
++      struct au_iigen *iigen;
 +
 +      iinfo = au_ii(inode);
-+      spin_lock(&iinfo->ii_genspin);
-+      iinfo->ii_generation.ig_generation--;
-+      spin_unlock(&iinfo->ii_genspin);
++      iigen = &iinfo->ii_generation;
++      spin_lock(&iigen->ig_spin);
++      iigen->ig_generation--;
++      spin_unlock(&iigen->ig_spin);
 +}
 +
 +static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
@@ -16920,10 +17079,10 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +#endif /* __AUFS_INODE_H__ */
 diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
 --- /usr/share/empty/fs/aufs/ioctl.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/ioctl.c      2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/ioctl.c      2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,219 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -17143,10 +17302,10 @@ diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
 +#endif
 diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 --- /usr/share/empty/fs/aufs/i_op_add.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op_add.c   2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/i_op_add.c   2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,932 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -18079,10 +18238,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +}
 diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 --- /usr/share/empty/fs/aufs/i_op.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op.c       2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,1483 @@
++++ linux/fs/aufs/i_op.c       2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,1490 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -18104,13 +18263,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +
 +#include <linux/device_cgroup.h>
 +#include <linux/fs_stack.h>
-+#include <linux/mm.h>
 +#include <linux/namei.h>
 +#include <linux/security.h>
 +#include "aufs.h"
 +
 +static int h_permission(struct inode *h_inode, int mask,
-+                      struct vfsmount *h_mnt, int brperm)
++                      struct path *h_path, int brperm)
 +{
 +      int err;
 +      const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
@@ -18119,7 +18277,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      if ((write_mask && IS_IMMUTABLE(h_inode))
 +          || ((mask & MAY_EXEC)
 +              && S_ISREG(h_inode->i_mode)
-+              && ((h_mnt->mnt_flags & MNT_NOEXEC)
++              && (path_noexec(h_path)
 +                  || !(h_inode->i_mode & S_IXUGO))))
 +              goto out;
 +
@@ -18204,7 +18362,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              err = 0;
 +              bindex = au_ibstart(inode);
 +              br = au_sbr(sb, bindex);
-+              err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
++              err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
 +              if (write_mask
 +                  && !err
 +                  && !special_file(h_inode->i_mode)) {
@@ -18230,7 +18388,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +                              break;
 +
 +                      br = au_sbr(sb, bindex);
-+                      err = h_permission(h_inode, mask, au_br_mnt(br),
++                      err = h_permission(h_inode, mask, &br->br_path,
 +                                         br->br_perm);
 +              }
 +      }
@@ -19060,6 +19218,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +                      break;
 +              }
 +      }
++      /*
++       * regardless aufs 'acl' option setting.
++       * why don't all acl-aware fs call this func from their ->setattr()?
++       */
++      if (!err && (ia->ia_valid & ATTR_MODE))
++              err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
 +      if (!err)
 +              au_cpup_attr_changeable(inode);
 +
@@ -19380,7 +19544,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      int err;
 +      aufs_bindex_t bindex;
 +
-+      ret = NULL; /* supress a warning */
++      ret = NULL; /* suppress a warning */
 +      err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
 +      if (unlikely(err))
 +              goto out;
@@ -19489,87 +19653,89 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+struct inode_operations aufs_symlink_iop = {
-+      .permission     = aufs_permission,
++/* no getattr version will be set by module.c:aufs_init() */
++struct inode_operations aufs_iop_nogetattr[AuIop_Last],
++      aufs_iop[] = {
++      [AuIop_SYMLINK] = {
++              .permission     = aufs_permission,
 +#ifdef CONFIG_FS_POSIX_ACL
-+      .get_acl        = aufs_get_acl,
-+      .set_acl        = aufs_set_acl, /* unsupport for symlink? */
++              .get_acl        = aufs_get_acl,
++              .set_acl        = aufs_set_acl, /* unsupport for symlink? */
 +#endif
 +
-+      .setattr        = aufs_setattr,
-+      .getattr        = aufs_getattr,
++              .setattr        = aufs_setattr,
++              .getattr        = aufs_getattr,
 +
 +#ifdef CONFIG_AUFS_XATTR
-+      .setxattr       = aufs_setxattr,
-+      .getxattr       = aufs_getxattr,
-+      .listxattr      = aufs_listxattr,
-+      .removexattr    = aufs_removexattr,
++              .setxattr       = aufs_setxattr,
++              .getxattr       = aufs_getxattr,
++              .listxattr      = aufs_listxattr,
++              .removexattr    = aufs_removexattr,
 +#endif
 +
-+      .readlink       = generic_readlink,
-+      .follow_link    = aufs_follow_link,
-+      .put_link       = aufs_put_link,
-+
-+      /* .update_time = aufs_update_time */
-+};
++              .readlink       = generic_readlink,
++              .follow_link    = aufs_follow_link,
++              .put_link       = aufs_put_link,
 +
-+struct inode_operations aufs_dir_iop = {
-+      .create         = aufs_create,
-+      .lookup         = aufs_lookup,
-+      .link           = aufs_link,
-+      .unlink         = aufs_unlink,
-+      .symlink        = aufs_symlink,
-+      .mkdir          = aufs_mkdir,
-+      .rmdir          = aufs_rmdir,
-+      .mknod          = aufs_mknod,
-+      .rename         = aufs_rename,
-+
-+      .permission     = aufs_permission,
++              /* .update_time = aufs_update_time */
++      },
++      [AuIop_DIR] = {
++              .create         = aufs_create,
++              .lookup         = aufs_lookup,
++              .link           = aufs_link,
++              .unlink         = aufs_unlink,
++              .symlink        = aufs_symlink,
++              .mkdir          = aufs_mkdir,
++              .rmdir          = aufs_rmdir,
++              .mknod          = aufs_mknod,
++              .rename         = aufs_rename,
++
++              .permission     = aufs_permission,
 +#ifdef CONFIG_FS_POSIX_ACL
-+      .get_acl        = aufs_get_acl,
-+      .set_acl        = aufs_set_acl,
++              .get_acl        = aufs_get_acl,
++              .set_acl        = aufs_set_acl,
 +#endif
 +
-+      .setattr        = aufs_setattr,
-+      .getattr        = aufs_getattr,
++              .setattr        = aufs_setattr,
++              .getattr        = aufs_getattr,
 +
 +#ifdef CONFIG_AUFS_XATTR
-+      .setxattr       = aufs_setxattr,
-+      .getxattr       = aufs_getxattr,
-+      .listxattr      = aufs_listxattr,
-+      .removexattr    = aufs_removexattr,
++              .setxattr       = aufs_setxattr,
++              .getxattr       = aufs_getxattr,
++              .listxattr      = aufs_listxattr,
++              .removexattr    = aufs_removexattr,
 +#endif
 +
-+      .update_time    = aufs_update_time,
-+      .atomic_open    = aufs_atomic_open,
-+      .tmpfile        = aufs_tmpfile
-+};
-+
-+struct inode_operations aufs_iop = {
-+      .permission     = aufs_permission,
++              .update_time    = aufs_update_time,
++              .atomic_open    = aufs_atomic_open,
++              .tmpfile        = aufs_tmpfile
++      },
++      [AuIop_OTHER] = {
++              .permission     = aufs_permission,
 +#ifdef CONFIG_FS_POSIX_ACL
-+      .get_acl        = aufs_get_acl,
-+      .set_acl        = aufs_set_acl,
++              .get_acl        = aufs_get_acl,
++              .set_acl        = aufs_set_acl,
 +#endif
 +
-+      .setattr        = aufs_setattr,
-+      .getattr        = aufs_getattr,
++              .setattr        = aufs_setattr,
++              .getattr        = aufs_getattr,
 +
 +#ifdef CONFIG_AUFS_XATTR
-+      .setxattr       = aufs_setxattr,
-+      .getxattr       = aufs_getxattr,
-+      .listxattr      = aufs_listxattr,
-+      .removexattr    = aufs_removexattr,
++              .setxattr       = aufs_setxattr,
++              .getxattr       = aufs_getxattr,
++              .listxattr      = aufs_listxattr,
++              .removexattr    = aufs_removexattr,
 +#endif
 +
-+      .update_time    = aufs_update_time
++              .update_time    = aufs_update_time
++      }
 +};
 diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 --- /usr/share/empty/fs/aufs/i_op_del.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op_del.c   2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/i_op_del.c   2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,510 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -20080,10 +20246,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +}
 diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 --- /usr/share/empty/fs/aufs/i_op_ren.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op_ren.c   2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,1017 @@
++++ linux/fs/aufs/i_op_ren.c   2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,1015 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -20174,7 +20340,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +/*
 + * functions for reverting.
 + * when an error happened in a single rename systemcall, we should revert
-+ * everything as if nothing happend.
++ * everything as if nothing happened.
 + * we don't need to revert the copied-up/down the parent dir since they are
 + * harmless.
 + */
@@ -20926,11 +21092,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +              if (unlikely(d_really_is_positive(a->dst_dentry)
 +                           && !d_is_dir(a->dst_dentry)))
 +                      goto out_free;
-+              err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
-+                                              AuLock_DIR | flags);
-+      } else
-+              err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
-+                                              flags);
++              flags |= AuLock_DIRS;
++      }
++      err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, flags);
 +      if (unlikely(err))
 +              goto out_free;
 +
@@ -20956,7 +21120,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +      /*
 +       * is it possible?
-+       * yes, it happend (in linux-3.3-rcN) but I don't know why.
++       * yes, it happened (in linux-3.3-rcN) but I don't know why.
 +       * there may exist a problem somewhere else.
 +       */
 +      err = -EINVAL;
@@ -21101,7 +21265,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +}
 diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
 --- /usr/share/empty/fs/aufs/Kconfig   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/Kconfig      2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/Kconfig      2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,185 @@
 +config AUFS_FS
 +      tristate "Aufs (Advanced multi layered unification filesystem) support"
@@ -21290,10 +21454,10 @@ diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
 +endif
 diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
 --- /usr/share/empty/fs/aufs/loop.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/loop.c       2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,145 @@
++++ linux/fs/aufs/loop.c       2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,146 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -21421,7 +21585,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
 +      int err;
 +      struct super_block *sb __maybe_unused;
 +
-+      AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
++      BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
 +
 +      err = 0;
 +      au_warn_loopback_array = kcalloc(au_warn_loopback_step,
@@ -21434,15 +21598,16 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
 +
 +void au_loopback_fin(void)
 +{
-+      symbol_put(loop_backing_file);
++      if (backing_file_func)
++              symbol_put(loop_backing_file);
 +      kfree(au_warn_loopback_array);
 +}
 diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
 --- /usr/share/empty/fs/aufs/loop.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/loop.h       2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/loop.h       2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,52 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -21495,7 +21660,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
 +#endif /* __AUFS_LOOP_H__ */
 diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
 --- /usr/share/empty/fs/aufs/magic.mk  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/magic.mk     2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/magic.mk     2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,30 @@
 +
 +# defined in ${srctree}/fs/fuse/inode.c
@@ -21529,7 +21694,7 @@ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
 +endif
 diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
 --- /usr/share/empty/fs/aufs/Makefile  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/Makefile     2015-09-24 10:47:58.248052907 +0200
++++ linux/fs/aufs/Makefile     2016-02-28 11:26:32.569971135 +0100
 @@ -0,0 +1,44 @@
 +
 +include ${src}/magic.mk
@@ -21577,10 +21742,10 @@ diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
 diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 --- /usr/share/empty/fs/aufs/module.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/module.c     2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,210 @@
++++ linux/fs/aufs/module.c     2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,221 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -21653,11 +21818,10 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +
 +      /* excluding AuCache_HNOTIFY */
 +      BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
-+      for (i = 0; i < AuCache_HNOTIFY; i++)
-+              if (au_cachep[i]) {
-+                      kmem_cache_destroy(au_cachep[i]);
-+                      au_cachep[i] = NULL;
-+              }
++      for (i = 0; i < AuCache_HNOTIFY; i++) {
++              kmem_cache_destroy(au_cachep[i]);
++              au_cachep[i] = NULL;
++      }
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -21691,7 +21855,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
 +
 +/* this module parameter has no meaning when USER_NS is disabled */
-+static bool au_userns;
++bool au_userns;
 +MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
 +module_param_named(allow_userns, au_userns, bool, S_IRUGO);
 +
@@ -21701,7 +21865,15 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +
 +int au_seq_path(struct seq_file *seq, struct path *path)
 +{
-+      return seq_path(seq, path, au_esc_chars);
++      int err;
++
++      err = seq_path(seq, path, au_esc_chars);
++      if (err > 0)
++              err = 0;
++      else if (err < 0)
++              err = -ENOMEM;
++
++      return err;
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -21720,6 +21892,10 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +
 +      au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
 +
++      memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
++      for (i = 0; i < AuIop_Last; i++)
++              aufs_iop_nogetattr[i].getattr = NULL;
++
 +      au_sbilist_init();
 +      sysaufs_brs_init();
 +      au_debug_init();
@@ -21791,10 +21967,10 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +module_exit(aufs_exit);
 diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 --- /usr/share/empty/fs/aufs/module.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/module.h     2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,104 @@
++++ linux/fs/aufs/module.h     2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,105 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -21826,6 +22002,7 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +
 +/* module parameters */
 +extern int sysaufs_brs;
++extern bool au_userns;
 +
 +/* ---------------------------------------------------------------------- */
 +
@@ -21899,10 +22076,10 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +#endif /* __AUFS_MODULE_H__ */
 diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 --- /usr/share/empty/fs/aufs/mvdown.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/mvdown.c     2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,694 @@
++++ linux/fs/aufs/mvdown.c     2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,703 @@
 +/*
-+ * Copyright (C) 2011-2015 Junjiro R. Okajima
++ * Copyright (C) 2011-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -22269,6 +22446,12 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +              au_set_dbstart(a->dentry, a->mvd_bdst);
 +              au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
 +              au_set_ibstart(a->inode, a->mvd_bdst);
++      } else {
++              /* hide the lower */
++              au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
++              au_set_dbend(a->dentry, a->mvd_bsrc);
++              au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
++              au_set_ibend(a->inode, a->mvd_bsrc);
 +      }
 +      if (au_dbend(a->dentry) < a->mvd_bdst)
 +              au_set_dbend(a->dentry, a->mvd_bdst);
@@ -22524,7 +22707,9 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +      int err, e;
 +      unsigned char dmsg;
 +      struct au_mvd_args *args;
++      struct inode *inode;
 +
++      inode = d_inode(dentry);
 +      err = -EPERM;
 +      if (unlikely(!capable(CAP_SYS_ADMIN)))
 +              goto out;
@@ -22546,7 +22731,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +      args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
 +      args->mvdown.au_errno = 0;
 +      args->dentry = dentry;
-+      args->inode = d_inode(dentry);
++      args->inode = inode;
 +      args->sb = dentry->d_sb;
 +
 +      err = -ENOENT;
@@ -22560,8 +22745,8 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +              goto out_dir;
 +      }
 +
-+      mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
-+      err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
++      mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
++      err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
 +      if (unlikely(err))
 +              goto out_inode;
 +
@@ -22575,15 +22760,16 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +              goto out_parent;
 +
 +      au_cpup_attr_timesizes(args->dir);
-+      au_cpup_attr_timesizes(args->inode);
-+      au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
++      au_cpup_attr_timesizes(inode);
++      if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
++              au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
 +      /* au_digen_dec(dentry); */
 +
 +out_parent:
 +      di_write_unlock(args->parent);
 +      aufs_read_unlock(dentry, AuLock_DW);
 +out_inode:
-+      mutex_unlock(&args->inode->i_mutex);
++      mutex_unlock(&inode->i_mutex);
 +out_dir:
 +      mutex_unlock(&args->dir->i_mutex);
 +out_free:
@@ -22597,10 +22783,10 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +}
 diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 --- /usr/share/empty/fs/aufs/opts.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/opts.c       2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,1835 @@
++++ linux/fs/aufs/opts.c       2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,1859 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -24169,10 +24355,10 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +{
 +      int err, fhsm;
 +      aufs_bindex_t bindex, bend;
-+      unsigned char do_plink, skip, do_free;
++      unsigned char do_plink, skip, do_free, can_no_dreval;
 +      struct au_branch *br;
 +      struct au_wbr *wbr;
-+      struct dentry *root;
++      struct dentry *root, *dentry;
 +      struct inode *dir, *h_dir;
 +      struct au_sbinfo *sbinfo;
 +      struct au_hinode *hdir;
@@ -24202,6 +24388,8 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +      root = sb->s_root;
 +      dir = d_inode(root);
 +      do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
++      can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
++                                    UDBA_NONE);
 +      bend = au_sbend(sb);
 +      for (bindex = 0; !err && bindex <= bend; bindex++) {
 +              skip = 0;
@@ -24250,6 +24438,15 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              if (wbr)
 +                      wbr_wh_read_unlock(wbr);
 +
++              if (can_no_dreval) {
++                      dentry = br->br_path.dentry;
++                      spin_lock(&dentry->d_lock);
++                      if (dentry->d_flags &
++                          (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
++                              can_no_dreval = 0;
++                      spin_unlock(&dentry->d_lock);
++              }
++
 +              if (au_br_fhsm(br->br_perm)) {
 +                      fhsm++;
 +                      AuDebugOn(!br->br_fhsm);
@@ -24273,6 +24470,11 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              }
 +      }
 +
++      if (can_no_dreval)
++              au_fset_si(sbinfo, NO_DREVAL);
++      else
++              au_fclr_si(sbinfo, NO_DREVAL);
++
 +      if (fhsm >= 2) {
 +              au_fset_si(sbinfo, FHSM);
 +              for (bindex = bend; bindex >= 0; bindex--) {
@@ -24384,6 +24586,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
 +{
 +      int err, rerr;
++      unsigned char no_dreval;
 +      struct inode *dir;
 +      struct au_opt_xino *opt_xino;
 +      struct au_opt *opt;
@@ -24391,9 +24594,9 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +
 +      SiMustWriteLock(sb);
 +
++      err = 0;
 +      dir = d_inode(sb->s_root);
 +      sbinfo = au_sbi(sb);
-+      err = 0;
 +      opt_xino = NULL;
 +      opt = opts->opt;
 +      while (err >= 0 && opt->type != Opt_tail) {
@@ -24409,10 +24612,14 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +      AuTraceErr(err);
 +      /* go on even err */
 +
++      no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
 +      rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
 +      if (unlikely(rerr && !err))
 +              err = rerr;
 +
++      if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
++              au_fset_opts(opts->flags, REFRESH_IDOP);
++
 +      if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
 +              rerr = au_xib_trunc(sb);
 +              if (unlikely(rerr && !err))
@@ -24421,7 +24628,10 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +
 +      /* will be handled by the caller */
 +      if (!au_ftest_opts(opts->flags, REFRESH)
-+          && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
++          && (opts->given_udba
++              || au_opt_test(sbinfo->si_mntflags, XINO)
++              || au_ftest_opts(opts->flags, REFRESH_IDOP)
++                  ))
 +              au_fset_opts(opts->flags, REFRESH);
 +
 +      AuDbg("status 0x%x\n", opts->flags);
@@ -24436,10 +24646,10 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +}
 diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 --- /usr/share/empty/fs/aufs/opts.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/opts.h       2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,210 @@
++++ linux/fs/aufs/opts.h       2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,211 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -24614,6 +24824,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 +#define AuOpts_REFRESH                (1 << 1)
 +#define AuOpts_TRUNC_XIB      (1 << 2)
 +#define AuOpts_REFRESH_DYAOP  (1 << 3)
++#define AuOpts_REFRESH_IDOP   (1 << 4)
 +#define au_ftest_opts(flags, name)    ((flags) & AuOpts_##name)
 +#define au_fset_opts(flags, name) \
 +      do { (flags) |= AuOpts_##name; } while (0)
@@ -24650,10 +24861,10 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 +#endif /* __AUFS_OPTS_H__ */
 diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 --- /usr/share/empty/fs/aufs/plink.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/plink.c      2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/plink.c      2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,528 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -25182,10 +25393,10 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +}
 diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
 --- /usr/share/empty/fs/aufs/poll.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/poll.c       2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/poll.c       2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,52 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -25238,10 +25449,10 @@ diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
 +}
 diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 --- /usr/share/empty/fs/aufs/posix_acl.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/posix_acl.c  2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,99 @@
++++ linux/fs/aufs/posix_acl.c  2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,98 @@
 +/*
-+ * Copyright (C) 2014-2015 Junjiro R. Okajima
++ * Copyright (C) 2014-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -25262,7 +25473,6 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 + */
 +
 +#include <linux/fs.h>
-+#include <linux/posix_acl.h>
 +#include "aufs.h"
 +
 +struct posix_acl *aufs_get_acl(struct inode *inode, int type)
@@ -25341,10 +25551,10 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 +}
 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
 --- /usr/share/empty/fs/aufs/procfs.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/procfs.c     2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/procfs.c     2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,169 @@
 +/*
-+ * Copyright (C) 2010-2015 Junjiro R. Okajima
++ * Copyright (C) 2010-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -25514,10 +25724,10 @@ diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
 +}
 diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
 --- /usr/share/empty/fs/aufs/rdu.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/rdu.c        2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/rdu.c        2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,388 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -25906,10 +26116,10 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
 +#endif
 diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
 --- /usr/share/empty/fs/aufs/rwsem.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/rwsem.h      2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/rwsem.h      2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,191 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -26101,10 +26311,10 @@ diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
 +#endif /* __AUFS_RWSEM_H__ */
 diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 --- /usr/share/empty/fs/aufs/sbinfo.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sbinfo.c     2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,360 @@
++++ linux/fs/aufs/sbinfo.c     2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,366 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -26231,6 +26441,9 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +
 +      au_sphl_init(&sbinfo->si_files);
 +
++      /* with getattr by default */
++      sbinfo->si_iop_array = aufs_iop;
++
 +      /* leave other members for sysaufs and si_mnt. */
 +      sbinfo->si_sb = sb;
 +      sb->s_fs_info = sbinfo;
@@ -26355,7 +26568,10 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +
 +      if (au_ftest_lock(flags, GEN)) {
 +              err = au_digen_test(dentry, au_sigen(sb));
-+              AuDebugOn(!err && au_dbrange_test(dentry));
++              if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
++                      AuDebugOn(!err && au_dbrange_test(dentry));
++              else if (!err)
++                      err = au_dbrange_test(dentry);
 +              if (unlikely(err))
 +                      aufs_read_unlock(dentry, flags);
 +      }
@@ -26396,7 +26612,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +      if (unlikely(err))
 +              goto out;
 +
-+      di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
++      di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
 +
 +      if (au_ftest_lock(flags, GEN)) {
 +              sigen = au_sigen(sb);
@@ -26465,10 +26681,10 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 --- /usr/share/empty/fs/aufs/spl.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/spl.h        2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/spl.h        2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,111 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -26580,10 +26796,10 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 +#endif /* __AUFS_SPL_H__ */
 diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 --- /usr/share/empty/fs/aufs/super.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/super.c      2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,1004 @@
++++ linux/fs/aufs/super.c      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,1039 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -26688,15 +26904,15 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              path.mnt = au_br_mnt(br);
 +              path.dentry = hdp[bindex].hd_dentry;
 +              err = au_seq_path(seq, &path);
-+              if (err > 0) {
++              if (!err) {
 +                      au_optstr_br_perm(&perm, br->br_perm);
-+                      err = seq_printf(seq, "=%s", perm.a);
-+                      if (err == -1)
-+                              err = -E2BIG;
++                      seq_printf(seq, "=%s", perm.a);
++                      if (bindex != bend)
++                              seq_putc(seq, ':');
 +              }
-+              if (!err && bindex != bend)
-+                      err = seq_putc(seq, ':');
 +      }
++      if (unlikely(err || seq_has_overflowed(seq)))
++              err = -E2BIG;
 +
 +      return err;
 +}
@@ -27053,17 +27269,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+void au_array_free(void *array)
-+{
-+      if (array) {
-+              if (!is_vmalloc_addr(array))
-+                      kfree(array);
-+              else
-+                      vfree(array);
-+      }
-+}
-+
-+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
++void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
++                   struct super_block *sb, void *arg)
 +{
 +      void *array;
 +      unsigned long long n, sz;
@@ -27088,7 +27295,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              goto out;
 +      }
 +
-+      n = cb(array, *hint, arg);
++      n = cb(sb, array, *hint, arg);
 +      AuDebugOn(n > *hint);
 +
 +out:
@@ -27096,7 +27303,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      return array;
 +}
 +
-+static unsigned long long au_iarray_cb(void *a,
++static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
 +                                     unsigned long long max __maybe_unused,
 +                                     void *arg)
 +{
@@ -27107,7 +27314,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      n = 0;
 +      p = a;
 +      head = arg;
-+      spin_lock(&inode_sb_list_lock);
++      spin_lock(&sb->s_inode_list_lock);
 +      list_for_each_entry(inode, head, i_sb_list) {
 +              if (!is_bad_inode(inode)
 +                  && au_ii(inode)->ii_bstart >= 0) {
@@ -27121,7 +27328,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +                      spin_unlock(&inode->i_lock);
 +              }
 +      }
-+      spin_unlock(&inode_sb_list_lock);
++      spin_unlock(&sb->s_inode_list_lock);
 +
 +      return n;
 +}
@@ -27129,7 +27336,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
 +{
 +      *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
-+      return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
++      return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
 +}
 +
 +void au_iarray_free(struct inode **a, unsigned long long max)
@@ -27138,7 +27345,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +
 +      for (ull = 0; ull < max; ull++)
 +              iput(a[ull]);
-+      au_array_free(a);
++      kvfree(a);
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -27165,7 +27372,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +
 +static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
 +                         struct au_sbinfo *sbinfo,
-+                         const unsigned int dir_flags)
++                         const unsigned int dir_flags, unsigned int do_idop)
 +{
 +      int err;
 +      struct dentry *parent;
@@ -27188,11 +27395,17 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      }
 +      dput(parent);
 +
++      if (!err) {
++              if (do_idop)
++                      au_refresh_dop(dentry, /*force_reval*/0);
++      } else
++              au_refresh_dop(dentry, /*force_reval*/1);
++
 +      AuTraceErr(err);
 +      return err;
 +}
 +
-+static int au_refresh_d(struct super_block *sb)
++static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
 +{
 +      int err, i, j, ndentry, e;
 +      unsigned int sigen;
@@ -27203,6 +27416,9 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      struct dentry *root = sb->s_root;
 +      const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
 +
++      if (do_idop)
++              au_refresh_dop(root, /*force_reval*/0);
++
 +      err = au_dpages_init(&dpages, GFP_NOFS);
 +      if (unlikely(err))
 +              goto out;
@@ -27218,7 +27434,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              ndentry = dpage->ndentry;
 +              for (j = 0; j < ndentry; j++) {
 +                      d = dentries[j];
-+                      e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
++                      e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
++                                          do_idop);
 +                      if (unlikely(e && !err))
 +                              err = e;
 +                      /* go on even err */
@@ -27231,7 +27448,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      return err;
 +}
 +
-+static int au_refresh_i(struct super_block *sb)
++static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
 +{
 +      int err, e;
 +      unsigned int sigen;
@@ -27249,17 +27466,22 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              inode = array[ull];
 +              if (unlikely(!inode))
 +                      break;
++
++              e = 0;
++              ii_write_lock_child(inode);
 +              if (au_iigen(inode, NULL) != sigen) {
-+                      ii_write_lock_child(inode);
 +                      e = au_refresh_hinode_self(inode);
-+                      ii_write_unlock(inode);
 +                      if (unlikely(e)) {
++                              au_refresh_iop(inode, /*force_getattr*/1);
 +                              pr_err("error %d, i%lu\n", e, inode->i_ino);
 +                              if (!err)
 +                                      err = e;
 +                              /* go on even if err */
 +                      }
 +              }
++              if (!e && do_idop)
++                      au_refresh_iop(inode, /*force_getattr*/0);
++              ii_write_unlock(inode);
 +      }
 +
 +      au_iarray_free(array, max);
@@ -27268,7 +27490,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      return err;
 +}
 +
-+static void au_remount_refresh(struct super_block *sb)
++static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
 +{
 +      int err, e;
 +      unsigned int udba;
@@ -27276,9 +27498,11 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      struct dentry *root;
 +      struct inode *inode;
 +      struct au_branch *br;
++      struct au_sbinfo *sbi;
 +
 +      au_sigen_inc(sb);
-+      au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
++      sbi = au_sbi(sb);
++      au_fclr_si(sbi, FAILED_REFRESH_DIR);
 +
 +      root = sb->s_root;
 +      DiMustNoWaiters(root);
@@ -27297,9 +27521,25 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      }
 +      au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
 +
++      if (do_idop) {
++              if (au_ftest_si(sbi, NO_DREVAL)) {
++                      AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
++                      sb->s_d_op = &aufs_dop_noreval;
++                      AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
++                      sbi->si_iop_array = aufs_iop_nogetattr;
++              } else {
++                      AuDebugOn(sb->s_d_op == &aufs_dop);
++                      sb->s_d_op = &aufs_dop;
++                      AuDebugOn(sbi->si_iop_array == aufs_iop);
++                      sbi->si_iop_array = aufs_iop;
++              }
++              pr_info("reset to %pf and %pf\n",
++                      sb->s_d_op, sbi->si_iop_array);
++      }
++
 +      di_write_unlock(root);
-+      err = au_refresh_d(sb);
-+      e = au_refresh_i(sb);
++      err = au_refresh_d(sb, do_idop);
++      e = au_refresh_i(sb, do_idop);
 +      if (unlikely(e && !err))
 +              err = e;
 +      /* aufs_write_lock() calls ..._child() */
@@ -27330,7 +27570,9 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +{
 +      int err, do_dx;
 +      unsigned int mntflags;
-+      struct au_opts opts;
++      struct au_opts opts = {
++              .opt = NULL
++      };
 +      struct dentry *root;
 +      struct inode *inode;
 +      struct au_sbinfo *sbinfo;
@@ -27348,7 +27590,6 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      }
 +
 +      err = -ENOMEM;
-+      memset(&opts, 0, sizeof(opts));
 +      opts.opt = (void *)__get_free_page(GFP_NOFS);
 +      if (unlikely(!opts.opt))
 +              goto out;
@@ -27374,7 +27615,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      au_opts_free(&opts);
 +
 +      if (au_ftest_opts(opts.flags, REFRESH))
-+              au_remount_refresh(sb);
++              au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
 +
 +      if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
 +              mntflags = au_mntflags(sb);
@@ -27421,7 +27662,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      if (IS_ERR(inode))
 +              goto out;
 +
-+      inode->i_op = &aufs_dir_iop;
++      inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
 +      inode->i_fop = &aufs_dir_fop;
 +      inode->i_mode = S_IFDIR;
 +      set_nlink(inode, 2);
@@ -27449,7 +27690,10 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +                         int silent __maybe_unused)
 +{
 +      int err;
-+      struct au_opts opts;
++      struct au_opts opts = {
++              .opt = NULL
++      };
++      struct au_sbinfo *sbinfo;
 +      struct dentry *root;
 +      struct inode *inode;
 +      char *arg = raw_data;
@@ -27461,7 +27705,6 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      }
 +
 +      err = -ENOMEM;
-+      memset(&opts, 0, sizeof(opts));
 +      opts.opt = (void *)__get_free_page(GFP_NOFS);
 +      if (unlikely(!opts.opt))
 +              goto out;
@@ -27471,6 +27714,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      err = au_si_alloc(sb);
 +      if (unlikely(err))
 +              goto out_opts;
++      sbinfo = au_sbi(sb);
 +
 +      /* all timestamps always follow the ones on the branch */
 +      sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
@@ -27506,6 +27750,13 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      aufs_write_lock(root);
 +      err = au_opts_mount(sb, &opts);
 +      au_opts_free(&opts);
++      if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
++              sb->s_d_op = &aufs_dop_noreval;
++              pr_info("%pf\n", sb->s_d_op);
++              au_refresh_dop(root, /*force_reval*/0);
++              sbinfo->si_iop_array = aufs_iop_nogetattr;
++              au_refresh_iop(inode, /*force_getattr*/0);
++      }
 +      aufs_write_unlock(root);
 +      mutex_unlock(&inode->i_mutex);
 +      if (!err)
@@ -27515,8 +27766,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      dput(root);
 +      sb->s_root = NULL;
 +out_info:
-+      dbgaufs_si_fin(au_sbi(sb));
-+      kobject_put(&au_sbi(sb)->si_kobj);
++      dbgaufs_si_fin(sbinfo);
++      kobject_put(&sbinfo->si_kobj);
 +      sb->s_fs_info = NULL;
 +out_opts:
 +      free_page((unsigned long)opts.opt);
@@ -27565,7 +27816,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +                      sbinfo->si_wbr_create_ops->fin(sb);
 +              if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
 +                      au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
-+                      au_remount_refresh(sb);
++                      au_remount_refresh(sb, /*do_idop*/0);
 +              }
 +              if (au_opt_test(sbinfo->si_mntflags, PLINK))
 +                      au_plink_put(sb, /*verbose*/1);
@@ -27588,10 +27839,10 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +};
 diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 --- /usr/share/empty/fs/aufs/super.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/super.h      2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,638 @@
++++ linux/fs/aufs/super.h      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,641 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -27783,6 +28034,9 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +      /* file list */
 +      struct au_sphlhead      si_files;
 +
++      /* with/without getattr, brother of sb->s_d_op */
++      struct inode_operations *si_iop_array;
++
 +      /*
 +       * sysfs and lifetime management.
 +       * this is not a small structure and it may be a waste of memory in case
@@ -27814,8 +28068,8 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 + * if it is false, refreshing dirs at access time is unnecesary
 + */
 +#define AuSi_FAILED_REFRESH_DIR       1
-+
 +#define AuSi_FHSM             (1 << 1)        /* fhsm is active now */
++#define AuSi_NO_DREVAL                (1 << 2)        /* disable all d_revalidate */
 +
 +#ifndef CONFIG_AUFS_FHSM
 +#undef AuSi_FHSM
@@ -27851,7 +28105,7 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +#define AuLock_IR             (1 << 1)        /* read-lock inode */
 +#define AuLock_IW             (1 << 2)        /* write-lock inode */
 +#define AuLock_FLUSH          (1 << 3)        /* wait for 'nowait' tasks */
-+#define AuLock_DIR            (1 << 4)        /* target is a dir */
++#define AuLock_DIRS           (1 << 4)        /* target is a pair of dirs */
 +#define AuLock_NOPLM          (1 << 5)        /* return err in plm mode */
 +#define AuLock_NOPLMW         (1 << 6)        /* wait for plm mode ends */
 +#define AuLock_GEN            (1 << 7)        /* test digen/iigen */
@@ -27866,10 +28120,10 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +/* super.c */
 +extern struct file_system_type aufs_fs_type;
 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
-+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
-+                                         void *arg);
-+void au_array_free(void *array);
-+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
++typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
++                                         unsigned long long max, void *arg);
++void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
++                   struct super_block *sb, void *arg);
 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
 +void au_iarray_free(struct inode **a, unsigned long long max);
 +
@@ -28230,10 +28484,10 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +#endif /* __AUFS_SUPER_H__ */
 diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
 --- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sysaufs.c    2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/sysaufs.c    2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,104 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -28338,10 +28592,10 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
 +}
 diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
 --- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sysaufs.h    2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/sysaufs.h    2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,101 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -28443,10 +28697,10 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
 +#endif /* __SYSAUFS_H__ */
 diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
 --- /usr/share/empty/fs/aufs/sysfs.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sysfs.c      2015-09-24 10:47:58.254719746 +0200
-@@ -0,0 +1,372 @@
++++ linux/fs/aufs/sysfs.c      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,376 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -28544,16 +28798,18 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
 +      case AuBrSysfs_BR:
 +              path.mnt = au_br_mnt(br);
 +              path.dentry = au_h_dptr(root, bindex);
-+              au_seq_path(seq, &path);
-+              au_optstr_br_perm(&perm, br->br_perm);
-+              err = seq_printf(seq, "=%s\n", perm.a);
++              err = au_seq_path(seq, &path);
++              if (!err) {
++                      au_optstr_br_perm(&perm, br->br_perm);
++                      seq_printf(seq, "=%s\n", perm.a);
++              }
 +              break;
 +      case AuBrSysfs_BRID:
-+              err = seq_printf(seq, "%d\n", br->br_id);
++              seq_printf(seq, "%d\n", br->br_id);
 +              break;
 +      }
 +      di_read_unlock(root, !AuLock_IR);
-+      if (err == -1)
++      if (unlikely(err || seq_has_overflowed(seq)))
 +              err = -E2BIG;
 +
 +      return err;
@@ -28707,9 +28963,11 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
 +              if (unlikely(err))
 +                      break;
 +
-+              au_seq_path(seq, &br->br_path);
-+              err = seq_putc(seq, '\0');
-+              if (!err && seq->count <= sz) {
++              err = au_seq_path(seq, &br->br_path);
++              if (unlikely(err))
++                      break;
++              seq_putc(seq, '\0');
++              if (!seq_has_overflowed(seq)) {
 +                      err = copy_to_user(arg->path, seq->buf, seq->count);
 +                      seq->count = 0;
 +                      if (unlikely(err))
@@ -28819,10 +29077,10 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
 +}
 diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
 --- /usr/share/empty/fs/aufs/sysrq.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sysrq.c      2015-09-24 10:47:58.254719746 +0200
++++ linux/fs/aufs/sysrq.c      2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,157 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -28900,14 +29158,14 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
 +              struct inode *i;
 +
 +              pr("isolated inode\n");
-+              spin_lock(&inode_sb_list_lock);
++              spin_lock(&sb->s_inode_list_lock);
 +              list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
 +                      spin_lock(&i->i_lock);
 +                      if (1 || hlist_empty(&i->i_dentry))
 +                              au_dpri_inode(i);
 +                      spin_unlock(&i->i_lock);
 +              }
-+              spin_unlock(&inode_sb_list_lock);
++              spin_unlock(&sb->s_inode_list_lock);
 +      }
 +#endif
 +      pr("files\n");
@@ -28980,10 +29238,10 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
 +}
 diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 --- /usr/share/empty/fs/aufs/vdir.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/vdir.c       2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/vdir.c       2016-02-28 11:26:32.573304539 +0100
 @@ -0,0 +1,888 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -29037,7 +29295,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+/* estimate the apropriate size for name hash table */
++/* estimate the appropriate size for name hash table */
 +unsigned int au_rdhash_est(loff_t sz)
 +{
 +      unsigned int n;
@@ -29363,7 +29621,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +
 +      vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
 +      if (!vdir->vd_deblk_sz) {
-+              /* estimate the apropriate size for deblk */
++              /* estimate the appropriate size for deblk */
 +              vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
 +              /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
 +      }
@@ -29872,10 +30130,10 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +}
 diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 --- /usr/share/empty/fs/aufs/vfsub.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/vfsub.c      2015-09-24 10:47:58.258053165 +0200
-@@ -0,0 +1,848 @@
++++ linux/fs/aufs/vfsub.c      2016-02-28 11:26:32.573304539 +0100
+@@ -0,0 +1,866 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -29896,10 +30154,28 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 + */
 +
 +#include <linux/namei.h>
++#include <linux/nsproxy.h>
 +#include <linux/security.h>
 +#include <linux/splice.h>
++#include "../fs/mount.h"
 +#include "aufs.h"
 +
++#ifdef CONFIG_AUFS_BR_FUSE
++int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
++{
++      struct nsproxy *ns;
++
++      if (!au_test_fuse(h_sb) || !au_userns)
++              return 0;
++
++      ns = current->nsproxy;
++      /* no {get,put}_nsproxy(ns) */
++      return real_mount(mnt)->mnt_ns == ns->mnt_ns ? 0 : -EACCES;
++}
++#endif
++
++/* ---------------------------------------------------------------------- */
++
 +int vfsub_update_h_iattr(struct path *h_path, int *did)
 +{
 +      int err;
@@ -30724,10 +31000,10 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +}
 diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 --- /usr/share/empty/fs/aufs/vfsub.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/vfsub.h      2015-09-24 10:47:58.258053165 +0200
-@@ -0,0 +1,286 @@
++++ linux/fs/aufs/vfsub.h      2016-02-28 11:26:32.576637942 +0100
+@@ -0,0 +1,308 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -30754,13 +31030,13 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +
 +#include <linux/fs.h>
 +#include <linux/mount.h>
++#include <linux/posix_acl.h>
 +#include <linux/xattr.h>
 +#include "debug.h"
 +
 +/* copied from linux/fs/internal.h */
 +/* todo: BAD approach!! */
 +extern void __mnt_drop_write(struct vfsmount *);
-+extern spinlock_t inode_sb_list_lock;
 +extern int open_check_o_direct(struct file *f);
 +
 +/* ---------------------------------------------------------------------- */
@@ -30805,6 +31081,12 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +              || IS_IMMUTABLE(inode);
 +}
 +
++#ifdef CONFIG_AUFS_BR_FUSE
++int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
++#else
++AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
++#endif
++
 +/* ---------------------------------------------------------------------- */
 +
 +int vfsub_update_h_iattr(struct path *h_path, int *did);
@@ -30924,6 +31206,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +}
 +#endif
 +
++#if 0 /* reserved */
 +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
 +                                   struct dentry *h_dentry)
 +{
@@ -30934,6 +31217,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +      touch_atime(&h_path);
 +      vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
 +}
++#endif
 +
 +static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
 +                                  int flags)
@@ -30942,6 +31226,20 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +      /* no vfsub_update_h_iattr() since we don't have struct path */
 +}
 +
++#ifdef CONFIG_FS_POSIX_ACL
++static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
++{
++      int err;
++
++      err = posix_acl_chmod(h_inode, h_mode);
++      if (err == -EOPNOTSUPP)
++              err = 0;
++      return err;
++}
++#else
++AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
++#endif
++
 +long vfsub_splice_to(struct file *in, loff_t *ppos,
 +                   struct pipe_inode_info *pipe, size_t len,
 +                   unsigned int flags);
@@ -31014,10 +31312,10 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +#endif /* __AUFS_VFSUB_H__ */
 diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 --- /usr/share/empty/fs/aufs/wbr_policy.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/wbr_policy.c 2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/wbr_policy.c 2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,765 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -31783,10 +32081,10 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +};
 diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 --- /usr/share/empty/fs/aufs/whout.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/whout.c      2015-09-24 10:47:58.258053165 +0200
-@@ -0,0 +1,1063 @@
++++ linux/fs/aufs/whout.c      2016-02-28 11:26:32.576637942 +0100
+@@ -0,0 +1,1060 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -32681,15 +32979,12 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +      SiMustAnyLock(sb);
 +
-+      whtmp = kmalloc(sizeof(*whtmp), gfp);
++      whtmp = kzalloc(sizeof(*whtmp), gfp);
 +      if (unlikely(!whtmp)) {
 +              whtmp = ERR_PTR(-ENOMEM);
 +              goto out;
 +      }
 +
-+      whtmp->dir = NULL;
-+      whtmp->br = NULL;
-+      whtmp->wh_dentry = NULL;
 +      /* no estimation for dir size */
 +      rdhash = au_sbi(sb)->si_rdhash;
 +      if (!rdhash)
@@ -32850,10 +33145,10 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +}
 diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
 --- /usr/share/empty/fs/aufs/whout.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/whout.h      2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/whout.h      2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,85 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -32939,10 +33234,10 @@ diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
 +#endif /* __AUFS_WHOUT_H__ */
 diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 --- /usr/share/empty/fs/aufs/wkq.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/wkq.c        2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/wkq.c        2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,213 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -33156,10 +33451,10 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 +}
 diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 --- /usr/share/empty/fs/aufs/wkq.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/wkq.h        2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/wkq.h        2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,91 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -33251,10 +33546,10 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 +#endif /* __AUFS_WKQ_H__ */
 diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 --- /usr/share/empty/fs/aufs/xattr.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/xattr.c      2015-09-24 10:47:58.258053165 +0200
++++ linux/fs/aufs/xattr.c      2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,344 @@
 +/*
-+ * Copyright (C) 2014-2015 Junjiro R. Okajima
++ * Copyright (C) 2014-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -33599,10 +33894,10 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +#endif
 diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 --- /usr/share/empty/fs/aufs/xino.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/xino.c       2015-09-24 10:47:58.258053165 +0200
-@@ -0,0 +1,1297 @@
++++ linux/fs/aufs/xino.c       2016-02-28 11:26:32.576637942 +0100
+@@ -0,0 +1,1318 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -33656,6 +33951,9 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +/* ---------------------------------------------------------------------- */
 +
++static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
++                             size_t size, loff_t *pos);
++
 +static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
 +                            size_t size, loff_t *pos)
 +{
@@ -33665,14 +33963,26 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +              void *k;
 +              const char __user *u;
 +      } buf;
++      int i;
++      const int prevent_endless = 10;
 +
++      i = 0;
 +      buf.k = kbuf;
 +      oldfs = get_fs();
 +      set_fs(KERNEL_DS);
 +      do {
-+              /* todo: signal_pending? */
 +              err = func(file, buf.u, size, pos);
-+      } while (err == -EAGAIN || err == -EINTR);
++              if (err == -EINTR
++                  && !au_wkq_test()
++                  && fatal_signal_pending(current)) {
++                      set_fs(oldfs);
++                      err = xino_fwrite_wkq(func, file, kbuf, size, pos);
++                      BUG_ON(err == -EINTR);
++                      oldfs = get_fs();
++                      set_fs(KERNEL_DS);
++              }
++      } while (i++ < prevent_endless
++               && (err == -EAGAIN || err == -EINTR));
 +      set_fs(oldfs);
 +
 +#if 0 /* reserved for future use */
@@ -33698,35 +34008,42 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
 +}
 +
++static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
++                             size_t size, loff_t *pos)
++{
++      ssize_t err;
++      int wkq_err;
++      struct do_xino_fwrite_args args = {
++              .errp   = &err,
++              .func   = func,
++              .file   = file,
++              .buf    = buf,
++              .size   = size,
++              .pos    = pos
++      };
++
++      /*
++       * it breaks RLIMIT_FSIZE and normal user's limit,
++       * users should care about quota and real 'filesystem full.'
++       */
++      wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
++      if (unlikely(wkq_err))
++              err = wkq_err;
++
++      return err;
++}
++
 +ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
 +                  size_t size, loff_t *pos)
 +{
 +      ssize_t err;
 +
-+      /* todo: signal block and no wkq? */
 +      if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
 +              lockdep_off();
 +              err = do_xino_fwrite(func, file, buf, size, pos);
 +              lockdep_on();
-+      } else {
-+              /*
-+               * it breaks RLIMIT_FSIZE and normal user's limit,
-+               * users should care about quota and real 'filesystem full.'
-+               */
-+              int wkq_err;
-+              struct do_xino_fwrite_args args = {
-+                      .errp   = &err,
-+                      .func   = func,
-+                      .file   = file,
-+                      .buf    = buf,
-+                      .size   = size,
-+                      .pos    = pos
-+              };
-+
-+              wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
-+              if (unlikely(wkq_err))
-+                      err = wkq_err;
-+      }
++      } else
++              err = xino_fwrite_wkq(func, file, buf, size, pos);
 +
 +      return err;
 +}
@@ -33861,7 +34178,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      struct au_xino_lock_dir ldir;
 +
 +      err = -ENOMEM;
-+      st = kzalloc(sizeof(*st), GFP_NOFS);
++      st = kmalloc(sizeof(*st), GFP_NOFS);
 +      if (unlikely(!st))
 +              goto out;
 +
@@ -34885,10 +35202,9 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      int err;
 +
 +      err = au_seq_path(seq, &file->f_path);
-+      if (unlikely(err < 0))
++      if (unlikely(err))
 +              goto out;
 +
-+      err = 0;
 +#define Deleted "\\040(deleted)"
 +      seq->count -= sizeof(Deleted) - 1;
 +      AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
@@ -34900,10 +35216,10 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +}
 diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
 --- /usr/share/empty/include/uapi/linux/aufs_type.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/uapi/linux/aufs_type.h       2015-09-24 10:47:58.258053165 +0200
++++ linux/include/uapi/linux/aufs_type.h       2016-02-28 11:26:32.576637942 +0100
 @@ -0,0 +1,419 @@
 +/*
-+ * Copyright (C) 2005-2015 Junjiro R. Okajima
++ * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
 + * This program, aufs is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
@@ -34943,7 +35259,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +
 +#include <linux/limits.h>
 +
-+#define AUFS_VERSION  "4.x-rcN-20150921"
++#define AUFS_VERSION  "4.4-20160223"
 +
 +/* todo? move this to linux-2.6.19/include/magic.h */
 +#define AUFS_SUPER_MAGIC      ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -35321,13 +35637,13 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +#define AUFS_CTL_FHSM_FD      _IOW(AuCtlType, AuCtl_FHSM_FD, int)
 +
 +#endif /* __AUFS_TYPE_H__ */
-aufs4.x-rcN loopback patch
+aufs4.4 loopback patch
 
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index 23103ad..5c3263f 100644
+index abfdd2b..a2e3c43 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
-@@ -417,7 +417,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
+@@ -556,7 +556,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
  }
  
  struct switch_request {
@@ -35336,7 +35652,7 @@ index 23103ad..5c3263f 100644
        struct completion wait;
  };
  
-@@ -437,6 +437,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
+@@ -582,6 +582,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
        mapping = file->f_mapping;
        mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
        lo->lo_backing_file = file;
@@ -35344,7 +35660,7 @@ index 23103ad..5c3263f 100644
        lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
                mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
        lo->old_gfp_mask = mapping_gfp_mask(mapping);
-@@ -448,11 +449,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
+@@ -594,11 +595,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
   * First it needs to flush existing IO, it does this by sending a magic
   * BIO down the pipe. The completion of this BIO does the actual switch.
   */
@@ -35359,10 +35675,10 @@ index 23103ad..5c3263f 100644
  
        /* freeze queue and wait for completion of scheduled requests */
        blk_mq_freeze_queue(lo->lo_queue);
-@@ -471,7 +474,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
-  */
static int loop_flush(struct loop_device *lo)
- {
+@@ -617,7 +620,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
+       /* loop not yet configured, no running thread, nothing to flush */
      if (lo->lo_state != Lo_bound)
+               return 0;
 -      return loop_switch(lo, NULL);
 +      return loop_switch(lo, NULL, NULL);
 +}
@@ -35377,7 +35693,7 @@ index 23103ad..5c3263f 100644
  }
  
  static void loop_reread_partitions(struct loop_device *lo,
-@@ -508,6 +520,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+@@ -654,6 +666,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
                          unsigned int arg)
  {
        struct file     *file, *old_file;
@@ -35385,7 +35701,7 @@ index 23103ad..5c3263f 100644
        struct inode    *inode;
        int             error;
  
-@@ -524,9 +537,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+@@ -670,13 +683,20 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
        file = fget(arg);
        if (!file)
                goto out;
@@ -35396,13 +35712,17 @@ index 23103ad..5c3263f 100644
 +              get_file(file);
 +      }
  
+       error = loop_validate_file(file, bdev);
+       if (error)
+               goto out_putf;
        inode = file->f_mapping->host;
        old_file = lo->lo_backing_file;
 +      old_virt_file = lo->lo_backing_virt_file;
  
        error = -EINVAL;
  
-@@ -538,17 +558,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+@@ -684,17 +704,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
                goto out_putf;
  
        /* and ... switch */
@@ -35425,16 +35745,16 @@ index 23103ad..5c3263f 100644
   out:
        return error;
  }
-@@ -709,7 +733,7 @@ static void loop_config_discard(struct loop_device *lo)
+@@ -881,7 +905,7 @@ static int loop_prepare_queue(struct loop_device *lo)
  static int loop_set_fd(struct loop_device *lo, fmode_t mode,
                       struct block_device *bdev, unsigned int arg)
  {
--      struct file     *file, *f;
+-      struct file     *file;
 +      struct file     *file, *f, *virt_file = NULL;
        struct inode    *inode;
        struct address_space *mapping;
        unsigned lo_blocksize;
-@@ -724,6 +748,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+@@ -896,6 +920,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
        file = fget(arg);
        if (!file)
                goto out;
@@ -35447,7 +35767,7 @@ index 23103ad..5c3263f 100644
  
        error = -EBUSY;
        if (lo->lo_state != Lo_unbound)
-@@ -778,6 +808,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+@@ -948,6 +978,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
        lo->lo_device = bdev;
        lo->lo_flags = lo_flags;
        lo->lo_backing_file = file;
@@ -35455,7 +35775,7 @@ index 23103ad..5c3263f 100644
        lo->transfer = NULL;
        lo->ioctl = NULL;
        lo->lo_sizelimit = 0;
-@@ -809,6 +840,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+@@ -980,6 +1011,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
  
   out_putf:
        fput(file);
@@ -35464,7 +35784,7 @@ index 23103ad..5c3263f 100644
   out:
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
-@@ -855,6 +888,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
+@@ -1026,6 +1059,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
  static int loop_clr_fd(struct loop_device *lo)
  {
        struct file *filp = lo->lo_backing_file;
@@ -35472,7 +35792,7 @@ index 23103ad..5c3263f 100644
        gfp_t gfp = lo->old_gfp_mask;
        struct block_device *bdev = lo->lo_device;
  
-@@ -886,6 +920,7 @@ static int loop_clr_fd(struct loop_device *lo)
+@@ -1057,6 +1091,7 @@ static int loop_clr_fd(struct loop_device *lo)
        spin_lock_irq(&lo->lo_lock);
        lo->lo_state = Lo_rundown;
        lo->lo_backing_file = NULL;
@@ -35480,7 +35800,7 @@ index 23103ad..5c3263f 100644
        spin_unlock_irq(&lo->lo_lock);
  
        loop_release_xfer(lo);
-@@ -931,6 +966,8 @@ static int loop_clr_fd(struct loop_device *lo)
+@@ -1101,6 +1136,8 @@ static int loop_clr_fd(struct loop_device *lo)
         * bd_mutex which is usually taken before lo_ctl_mutex.
         */
        fput(filp);
@@ -35490,7 +35810,7 @@ index 23103ad..5c3263f 100644
  }
  
 diff --git a/drivers/block/loop.h b/drivers/block/loop.h
-index 25e8997..93b6fce 100644
+index fb2237c..c3888c5 100644
 --- a/drivers/block/loop.h
 +++ b/drivers/block/loop.h
 @@ -46,7 +46,7 @@ struct loop_device {
@@ -35503,10 +35823,10 @@ index 25e8997..93b6fce 100644
        unsigned        lo_blocksize;
        void            *key_data; 
 diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
-index 91c2ce7..d4ee5a7 100644
+index 2baacd7..22bcb89 100644
 --- a/fs/aufs/f_op.c
 +++ b/fs/aufs/f_op.c
-@@ -389,7 +389,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
+@@ -399,7 +399,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
        if (IS_ERR(h_file))
                goto out;
  
@@ -35516,11 +35836,11 @@ index 91c2ce7..d4ee5a7 100644
                if (file->f_mapping != h_file->f_mapping) {
                        file->f_mapping = h_file->f_mapping;
 diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
-index 69f7e96..7941063 100644
+index 5711e7a..9df5d16 100644
 --- a/fs/aufs/loop.c
 +++ b/fs/aufs/loop.c
-@@ -130,3 +130,19 @@ void au_loopback_fin(void)
-       symbol_put(loop_backing_file);
+@@ -131,3 +131,19 @@ void au_loopback_fin(void)
+               symbol_put(loop_backing_file);
        kfree(au_warn_loopback_array);
  }
 +
@@ -35540,7 +35860,7 @@ index 69f7e96..7941063 100644
 +      return f;
 +}
 diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
-index 6d9864d..3322557 100644
+index 48bf070..66afec7 100644
 --- a/fs/aufs/loop.h
 +++ b/fs/aufs/loop.h
 @@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
@@ -35565,10 +35885,10 @@ index 6d9864d..3322557 100644
  
  #endif /* __KERNEL__ */
 diff --git a/fs/aufs/super.c b/fs/aufs/super.c
-index ee5780d..da35759 100644
+index b41d789..51d2fb9 100644
 --- a/fs/aufs/super.c
 +++ b/fs/aufs/super.c
-@@ -807,7 +807,10 @@ static const struct super_operations aufs_sop = {
+@@ -832,7 +832,10 @@ static const struct super_operations aufs_sop = {
        .statfs         = aufs_statfs,
        .put_super      = aufs_put_super,
        .sync_fs        = aufs_sync_fs,
@@ -35581,10 +35901,10 @@ index ee5780d..da35759 100644
  
  /* ---------------------------------------------------------------------- */
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 86080ea..5f8e0f2 100644
+index 8d48506..5246785 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1708,6 +1708,10 @@ struct super_operations {
+@@ -1719,6 +1719,10 @@ struct super_operations {
                                  struct shrink_control *);
        long (*free_cached_objects)(struct super_block *,
                                    struct shrink_control *);
This page took 0.356103 seconds and 4 git commands to generate.