[packages/kernel] - updated aufs patch

baggins baggins at pld-linux.org
Sun Apr 24 19:41:52 CEST 2016


commit febd17d6c05fa4f2ce04ec0aa2818133296e19e0
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Sun Apr 24 18:34:45 2016 +0200

    - updated aufs patch

 kernel-aufs4.patch | 1037 ++++++++++++++++++++++++++--------------------------
 1 file changed, 515 insertions(+), 522 deletions(-)
---
diff --git a/kernel-aufs4.patch b/kernel-aufs4.patch
index e9aae06..4b72052 100644
--- a/kernel-aufs4.patch
+++ b/kernel-aufs4.patch
@@ -1,10 +1,10 @@
-aufs4.4 kbuild patch
+aufs4.5 kbuild patch
 
 diff --git a/fs/Kconfig b/fs/Kconfig
-index 6ce72d8..4aa31ea 100644
+index 9adee0d..5e9cfb2 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig"
+@@ -232,6 +232,7 @@ source "fs/pstore/Kconfig"
  source "fs/sysv/Kconfig"
  source "fs/ufs/Kconfig"
  source "fs/exofs/Kconfig"
@@ -22,7 +22,7 @@ index 79f5225..a7c7f16 100644
  obj-$(CONFIG_EFIVAR_FS)		+= efivarfs/
 +obj-$(CONFIG_AUFS_FS)           += aufs/
 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index c2e5d6c..d736c11 100644
+index ebd10e6..32152e7 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
 @@ -59,6 +59,7 @@ header-y += atmsvc.h
@@ -33,13 +33,13 @@ index c2e5d6c..d736c11 100644
  header-y += auto_fs4.h
  header-y += auto_fs.h
  header-y += auxvec.h
-aufs4.4 base patch
+aufs4.5 base patch
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 233f834..c250892 100644
+index 6ee06ea..3147250 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -2029,6 +2029,19 @@ F:	include/linux/audit.h
+@@ -2082,6 +2082,19 @@ F:	include/linux/audit.h
  F:	include/uapi/linux/audit.h
  F:	kernel/audit*
  
@@ -60,7 +60,7 @@ index 233f834..c250892 100644
  M:	Miguel Ojeda Sandonis <miguel.ojeda.sandonis at gmail.com>
  W:	http://miguelojeda.es/auxdisplay.htm
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index 423f4ca..abfdd2b 100644
+index 423f4ca..0b816b2 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
 @@ -706,6 +706,24 @@ static inline int is_loop_device(struct file *file)
@@ -83,16 +83,16 @@ index 423f4ca..abfdd2b 100644
 +	}
 +	return ret;
 +}
-+EXPORT_SYMBOL(loop_backing_file);
++EXPORT_SYMBOL_GPL(loop_backing_file);
 +
  /* loop sysfs attributes */
  
  static ssize_t loop_attr_show(struct device *dev, char *page,
 diff --git a/fs/dcache.c b/fs/dcache.c
-index 5c33aeb..8aa7f26 100644
+index 2398f9f9..318c329 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1167,7 +1167,7 @@ enum d_walk_ret {
+@@ -1156,7 +1156,7 @@ enum d_walk_ret {
   *
   * The @enter() and @finish() callbacks are called with d_lock held.
   */
@@ -101,11 +101,33 @@ index 5c33aeb..8aa7f26 100644
  		   enum d_walk_ret (*enter)(void *, struct dentry *),
  		   void (*finish)(void *))
  {
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 350a2c8..6f42279 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -29,7 +29,7 @@
+ 
+ #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
+ 
+-static int setfl(int fd, struct file * filp, unsigned long arg)
++int setfl(int fd, struct file * filp, unsigned long arg)
+ {
+ 	struct inode * inode = file_inode(filp);
+ 	int error = 0;
+@@ -60,6 +60,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
+ 
+ 	if (filp->f_op->check_flags)
+ 		error = filp->f_op->check_flags(arg);
++	if (!error && filp->f_op->setfl)
++		error = filp->f_op->setfl(filp, arg);
+ 	if (error)
+ 		return error;
+ 
 diff --git a/fs/read_write.c b/fs/read_write.c
-index 819ef3f..fd0414e 100644
+index dadf24e..c8b5b7a 100644
 --- a/fs/read_write.c
 +++ b/fs/read_write.c
-@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+@@ -534,6 +534,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
  }
  EXPORT_SYMBOL(__vfs_write);
  
@@ -135,10 +157,10 @@ index 819ef3f..fd0414e 100644
  {
  	mm_segment_t old_fs;
 diff --git a/fs/splice.c b/fs/splice.c
-index 4cf700d..30a091d 100644
+index 82bc0d6..93aee51 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1110,8 +1110,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1108,8 +1108,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -149,7 +171,7 @@ index 4cf700d..30a091d 100644
  {
  	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  				loff_t *, size_t, unsigned int);
-@@ -1127,9 +1127,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1125,9 +1125,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 +197,26 @@ 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 3aa5142..8d48506 100644
+index ae68100..99fc2bd 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1672,6 +1672,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+@@ -1260,6 +1260,7 @@ extern void fasync_free(struct fasync_struct *);
+ /* can be called from interrupts */
+ extern void kill_fasync(struct fasync_struct **, int, int);
+ 
++extern int setfl(int fd, struct file * filp, unsigned long arg);
+ extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
+ extern void f_setown(struct file *filp, unsigned long arg, int force);
+ extern void f_delown(struct file *filp);
+@@ -1646,6 +1647,7 @@ struct file_operations {
+ 	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
+ 	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ 	int (*check_flags)(int);
++	int (*setfl)(struct file *, unsigned long);
+ 	int (*flock) (struct file *, int, struct file_lock *);
+ 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
+ 	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
+@@ -1704,6 +1706,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
  			      struct iovec *fast_pointer,
  			      struct iovec **ret_pointer);
  
@@ -206,13 +244,13 @@ index da2751d..2e0fca6 100644
 +			 struct pipe_inode_info *pipe, size_t len,
 +			 unsigned int flags);
  #endif
-aufs4.4 mmap patch
+aufs4.5 mmap patch
 
 diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 4bd5d31..aa41f2a 100644
+index 4f764c2..229de5e 100644
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
-@@ -1921,7 +1921,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
+@@ -1933,7 +1933,7 @@ static int 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) {
@@ -238,10 +276,10 @@ index f8595e8..cb8eda0 100644
  		ino = inode->i_ino;
  	}
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 187b3b5..e03793e 100644
+index fa95ab2..d440354 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
-@@ -281,7 +281,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+@@ -298,7 +298,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
  	const char *name = NULL;
  
  	if (file) {
@@ -253,7 +291,7 @@ index 187b3b5..e03793e 100644
  		dev = inode->i_sb->s_dev;
  		ino = inode->i_ino;
  		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1505,7 +1508,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+@@ -1576,7 +1579,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;
@@ -263,10 +301,10 @@ index 187b3b5..e03793e 100644
  	struct mm_walk walk = {
  		.hugetlb_entry = gather_hugetlb_stats,
 diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
-index e0d64c9..7aa92db 100644
+index faacb0c..17b43be 100644
 --- a/fs/proc/task_nommu.c
 +++ b/fs/proc/task_nommu.c
-@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
+@@ -163,7 +163,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
  	file = vma->vm_file;
  
  	if (file) {
@@ -279,10 +317,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 00bad77..cc616b0 100644
+index 516e149..ddd5454 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
-@@ -1183,6 +1183,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1217,6 +1217,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
  }
  #endif
  
@@ -312,10 +350,10 @@ index 00bad77..cc616b0 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 f8d1492..c3a3760 100644
+index 624b78b..1be91c5 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -272,6 +272,7 @@ struct vm_region {
+@@ -269,6 +269,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 */
@@ -323,7 +361,7 @@ index f8d1492..c3a3760 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
-@@ -346,6 +347,7 @@ struct vm_area_struct {
+@@ -343,6 +344,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). */
@@ -332,10 +370,10 @@ index f8d1492..c3a3760 100644
  
  #ifndef CONFIG_MMU
 diff --git a/kernel/fork.c b/kernel/fork.c
-index 1155eac..c001ea4 100644
+index 2e391c7..6c4215c 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -465,7 +465,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -464,7 +464,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,10 +396,10 @@ index 2ed4319..e3a53f5 100644
  obj-y += init-mm.o
  
 diff --git a/mm/filemap.c b/mm/filemap.c
-index 1bb0076..8eaece8 100644
+index da7a35d..f800f87 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
-@@ -2128,7 +2128,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+@@ -2229,7 +2229,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);
@@ -371,10 +409,10 @@ index 1bb0076..8eaece8 100644
  	if (page->mapping != inode->i_mapping) {
  		unlock_page(page);
 diff --git a/mm/memory.c b/mm/memory.c
-index c387430..d434404 100644
+index 8132787..3f7de66 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
+@@ -2042,7 +2042,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
  		}
  
  		if (!page_mkwrite)
@@ -384,10 +422,10 @@ index c387430..d434404 100644
  
  	return VM_FAULT_WRITE;
 diff --git a/mm/mmap.c b/mm/mmap.c
-index 2ce04a6..f555c0a 100644
+index 76d1ec2..fdd163e 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
-@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+@@ -290,7 +290,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)
@@ -396,7 +434,7 @@ index 2ce04a6..f555c0a 100644
  	mpol_put(vma_policy(vma));
  	kmem_cache_free(vm_area_cachep, vma);
  	return next;
-@@ -887,7 +887,7 @@ again:			remove_next = 1 + (end > next->vm_end);
+@@ -909,7 +909,7 @@ again:			remove_next = 1 + (end > next->vm_end);
  	if (remove_next) {
  		if (file) {
  			uprobe_munmap(next, next->vm_start, next->vm_end);
@@ -405,7 +443,7 @@ index 2ce04a6..f555c0a 100644
  		}
  		if (next->anon_vma)
  			anon_vma_merge(vma, next);
-@@ -1681,8 +1681,8 @@ out:
+@@ -1683,8 +1683,8 @@ out:
  	return addr;
  
  unmap_and_free_vma:
@@ -415,7 +453,7 @@ index 2ce04a6..f555c0a 100644
  
  	/* Undo any partial mapping done by a device driver. */
  	unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
-@@ -2488,7 +2488,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2479,7 +2479,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
  		goto out_free_mpol;
  
  	if (new->vm_file)
@@ -424,7 +462,7 @@ index 2ce04a6..f555c0a 100644
  
  	if (new->vm_ops && new->vm_ops->open)
  		new->vm_ops->open(new);
-@@ -2507,7 +2507,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2498,7 +2498,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)
@@ -433,7 +471,7 @@ index 2ce04a6..f555c0a 100644
  	unlink_anon_vmas(new);
   out_free_mpol:
  	mpol_put(vma_policy(new));
-@@ -2649,7 +2649,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+@@ -2640,7 +2640,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;
@@ -441,8 +479,8 @@ index 2ce04a6..f555c0a 100644
  
  	pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
  			"See Documentation/vm/remap_file_pages.txt.\n",
-@@ -2693,10 +2692,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
- 		munlock_vma_pages_range(vma, start, start + size);
+@@ -2708,10 +2707,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ 		}
  	}
  
 -	file = get_file(vma->vm_file);
@@ -454,7 +492,7 @@ index 2ce04a6..f555c0a 100644
  out:
  	up_write(&mm->mmap_sem);
  	if (populate)
-@@ -2966,7 +2965,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2982,7 +2981,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)
@@ -464,7 +502,7 @@ index 2ce04a6..f555c0a 100644
  			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 92be862..29179f7 100644
+index fbf6f0f1..1a4a06d 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
 @@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm_region *region)
@@ -599,41 +637,53 @@ index 0000000..b323b8a
 +		fput(pr);
 +}
 +#endif /* !CONFIG_MMU */
-aufs4.4 standalone patch
+aufs4.5 standalone patch
 
 diff --git a/fs/dcache.c b/fs/dcache.c
-index 8aa7f26..f997345 100644
+index 318c329..72d3cc8 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1272,6 +1272,7 @@ rename_retry:
+@@ -1261,6 +1261,7 @@ rename_retry:
  	seq = 1;
  	goto again;
  }
-+EXPORT_SYMBOL(d_walk);
++EXPORT_SYMBOL_GPL(d_walk);
  
  /*
   * 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
+index dcd4ac7..09a7818 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);
++EXPORT_SYMBOL_GPL(path_noexec);
  
  #ifdef CONFIG_USELIB
  /*
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 6f42279..04fd33c 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
+  out:
+ 	return error;
+ }
++EXPORT_SYMBOL_GPL(setfl);
+ 
+ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
+                      int force)
 diff --git a/fs/file_table.c b/fs/file_table.c
-index ad17e05..38e046a 100644
+index ad17e05..ae9f267 100644
 --- a/fs/file_table.c
 +++ b/fs/file_table.c
 @@ -147,6 +147,7 @@ over:
  	}
  	return ERR_PTR(-ENFILE);
  }
-+EXPORT_SYMBOL(get_empty_filp);
++EXPORT_SYMBOL_GPL(get_empty_filp);
  
  /**
   * alloc_file - allocate and initialize a 'struct file'
@@ -641,7 +691,7 @@ index ad17e05..38e046a 100644
  {
  	delayed_fput(NULL);
  }
-+EXPORT_SYMBOL(flush_delayed_fput);
++EXPORT_SYMBOL_GPL(flush_delayed_fput);
  
  static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
  
@@ -649,7 +699,7 @@ index ad17e05..38e046a 100644
  }
  
  EXPORT_SYMBOL(fput);
-+EXPORT_SYMBOL(__fput_sync);
++EXPORT_SYMBOL_GPL(__fput_sync);
  
  void put_filp(struct file *file)
  {
@@ -657,12 +707,12 @@ index ad17e05..38e046a 100644
  		file_free(file);
  	}
  }
-+EXPORT_SYMBOL(put_filp);
++EXPORT_SYMBOL_GPL(put_filp);
  
  void __init files_init(void)
  { 
 diff --git a/fs/namespace.c b/fs/namespace.c
-index 0570729..ec560d8 100644
+index 4fb1691..97654d2 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
@@ -673,16 +723,16 @@ index 0570729..ec560d8 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1803,6 +1804,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -1811,6 +1812,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
  	}
  	return 0;
  }
-+EXPORT_SYMBOL(iterate_mounts);
++EXPORT_SYMBOL_GPL(iterate_mounts);
  
  static void cleanup_group_ids(struct mount *mnt, struct mount *end)
  {
 diff --git a/fs/notify/group.c b/fs/notify/group.c
-index d16b62c..06ca6bc 100644
+index d16b62c..53e45b6 100644
 --- a/fs/notify/group.c
 +++ b/fs/notify/group.c
 @@ -22,6 +22,7 @@
@@ -697,7 +747,7 @@ index d16b62c..06ca6bc 100644
  {
  	atomic_inc(&group->refcnt);
  }
-+EXPORT_SYMBOL(fsnotify_get_group);
++EXPORT_SYMBOL_GPL(fsnotify_get_group);
  
  /*
   * Drop a reference to a group.  Free it if it's through.
@@ -705,7 +755,7 @@ index d16b62c..06ca6bc 100644
  	if (atomic_dec_and_test(&group->refcnt))
  		fsnotify_final_destroy_group(group);
  }
-+EXPORT_SYMBOL(fsnotify_put_group);
++EXPORT_SYMBOL_GPL(fsnotify_put_group);
  
  /*
   * Create a new fsnotify_group and hold a reference for the group returned.
@@ -713,55 +763,55 @@ index d16b62c..06ca6bc 100644
  
  	return group;
  }
-+EXPORT_SYMBOL(fsnotify_alloc_group);
++EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
  
  int fsnotify_fasync(int fd, struct file *file, int on)
  {
 diff --git a/fs/notify/mark.c b/fs/notify/mark.c
-index fc0df44..325b5c6 100644
+index 7115c5d..ac2bd69 100644
 --- a/fs/notify/mark.c
 +++ b/fs/notify/mark.c
-@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
+@@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
  		mark->free_mark(mark);
  	}
  }
-+EXPORT_SYMBOL(fsnotify_put_mark);
++EXPORT_SYMBOL_GPL(fsnotify_put_mark);
  
  /* Calculate mask of events for a list of marks */
  u32 fsnotify_recalc_mask(struct hlist_head *head)
-@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
+@@ -213,6 +214,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
  	mutex_unlock(&group->mark_mutex);
  	fsnotify_free_mark(mark);
  }
-+EXPORT_SYMBOL(fsnotify_destroy_mark);
++EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
  
  void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
  {
-@@ -392,6 +394,7 @@ err:
+@@ -398,6 +400,7 @@ err:
  
  	return ret;
  }
-+EXPORT_SYMBOL(fsnotify_add_mark);
++EXPORT_SYMBOL_GPL(fsnotify_add_mark);
  
  int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
  		      struct inode *inode, struct vfsmount *mnt, int allow_dups)
-@@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
+@@ -498,6 +501,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
  	atomic_set(&mark->refcnt, 1);
  	mark->free_mark = free_mark;
  }
-+EXPORT_SYMBOL(fsnotify_init_mark);
++EXPORT_SYMBOL_GPL(fsnotify_init_mark);
  
- static int fsnotify_mark_destroy(void *ignored)
+ static void fsnotify_mark_destroy(struct work_struct *work)
  {
 diff --git a/fs/open.c b/fs/open.c
-index b6f1e96..4ab0d4e 100644
+index 55bdc75..fd1df73 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,
- 	mutex_unlock(&dentry->d_inode->i_mutex);
+ 	inode_unlock(dentry->d_inode);
  	return ret;
  }
-+EXPORT_SYMBOL(do_truncate);
++EXPORT_SYMBOL_GPL(do_truncate);
  
  long vfs_truncate(struct path *path, loff_t length)
  {
@@ -769,92 +819,92 @@ index b6f1e96..4ab0d4e 100644
  	}
  	return 0;
  }
-+EXPORT_SYMBOL(open_check_o_direct);
++EXPORT_SYMBOL_GPL(open_check_o_direct);
  
  static int do_dentry_open(struct file *f,
  			  struct inode *inode,
 diff --git a/fs/read_write.c b/fs/read_write.c
-index fd0414e..8ace6ec 100644
+index c8b5b7a..9461d12 100644
 --- a/fs/read_write.c
 +++ b/fs/read_write.c
-@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file)
+@@ -544,6 +544,7 @@ vfs_readf_t vfs_readf(struct file *file)
  		return new_sync_read;
  	return ERR_PTR(-ENOSYS);
  }
-+EXPORT_SYMBOL(vfs_readf);
++EXPORT_SYMBOL_GPL(vfs_readf);
  
  vfs_writef_t vfs_writef(struct file *file)
  {
-@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *file)
+@@ -555,6 +556,7 @@ vfs_writef_t vfs_writef(struct file *file)
  		return new_sync_write;
  	return ERR_PTR(-ENOSYS);
  }
-+EXPORT_SYMBOL(vfs_writef);
++EXPORT_SYMBOL_GPL(vfs_writef);
  
  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 30a091d..c37c311 100644
+index 93aee51..52d2f5b 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1123,6 +1123,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1121,6 +1121,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
  	return splice_write(pipe, out, ppos, len, flags);
  }
-+EXPORT_SYMBOL(do_splice_from);
++EXPORT_SYMBOL_GPL(do_splice_from);
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
-@@ -1149,6 +1150,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1147,6 +1148,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
  
  	return splice_read(in, ppos, pipe, len, flags);
  }
-+EXPORT_SYMBOL(do_splice_to);
++EXPORT_SYMBOL_GPL(do_splice_to);
  
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
 diff --git a/fs/xattr.c b/fs/xattr.c
-index 9b932b9..44c457a 100644
+index 4861322..c4bb039 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,
  	*xattr_value = value;
  	return error;
  }
-+EXPORT_SYMBOL(vfs_getxattr_alloc);
++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
  
- /* Compare an extended attribute value with the given value */
- int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
+ ssize_t
+ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 diff --git a/kernel/task_work.c b/kernel/task_work.c
-index 53fa971..f80d564 100644
+index 53fa971..bce3211 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);
++EXPORT_SYMBOL_GPL(task_work_run);
 diff --git a/security/commoncap.c b/security/commoncap.c
-index 1832cf7..987ff5f 100644
+index 48071ed..50a1a40 100644
 --- a/security/commoncap.c
 +++ b/security/commoncap.c
-@@ -1053,12 +1053,14 @@ int cap_mmap_addr(unsigned long addr)
+@@ -1058,12 +1058,14 @@ int cap_mmap_addr(unsigned long addr)
  	}
  	return ret;
  }
-+EXPORT_SYMBOL(cap_mmap_addr);
++EXPORT_SYMBOL_GPL(cap_mmap_addr);
  
  int cap_mmap_file(struct file *file, unsigned long reqprot,
  		  unsigned long prot, unsigned long flags)
  {
  	return 0;
  }
-+EXPORT_SYMBOL(cap_mmap_file);
++EXPORT_SYMBOL_GPL(cap_mmap_file);
  
  #ifdef CONFIG_SECURITY
  
 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
-index 03c1652..b00aa76 100644
+index 03c1652..f88c84b 100644
 --- a/security/device_cgroup.c
 +++ b/security/device_cgroup.c
 @@ -7,6 +7,7 @@
@@ -869,19 +919,19 @@ index 03c1652..b00aa76 100644
  	return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
  			access);
  }
-+EXPORT_SYMBOL(__devcgroup_inode_permission);
++EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);
  
  int devcgroup_inode_mknod(int mode, dev_t dev)
  {
 diff --git a/security/security.c b/security/security.c
-index 46f405c..54488b0 100644
+index e8ffd92..51fa026 100644
 --- a/security/security.c
 +++ b/security/security.c
 @@ -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);
  }
-+EXPORT_SYMBOL(security_path_rmdir);
++EXPORT_SYMBOL_GPL(security_path_rmdir);
  
  int security_path_unlink(struct path *dir, struct dentry *dentry)
  {
@@ -889,7 +939,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(path_symlink, 0, dir, dentry, old_name);
  }
-+EXPORT_SYMBOL(security_path_symlink);
++EXPORT_SYMBOL_GPL(security_path_symlink);
  
  int security_path_link(struct dentry *old_dentry, struct path *new_dir,
  		       struct dentry *new_dentry)
@@ -897,7 +947,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
  }
-+EXPORT_SYMBOL(security_path_link);
++EXPORT_SYMBOL_GPL(security_path_link);
  
  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  			 struct path *new_dir, struct dentry *new_dentry,
@@ -905,7 +955,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(path_truncate, 0, path);
  }
-+EXPORT_SYMBOL(security_path_truncate);
++EXPORT_SYMBOL_GPL(security_path_truncate);
  
  int security_path_chmod(struct path *path, umode_t mode)
  {
@@ -913,7 +963,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(path_chmod, 0, path, mode);
  }
-+EXPORT_SYMBOL(security_path_chmod);
++EXPORT_SYMBOL_GPL(security_path_chmod);
  
  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
  {
@@ -921,7 +971,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(path_chown, 0, path, uid, gid);
  }
-+EXPORT_SYMBOL(security_path_chown);
++EXPORT_SYMBOL_GPL(security_path_chown);
  
  int security_path_chroot(struct path *path)
  {
@@ -929,7 +979,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(inode_readlink, 0, dentry);
  }
-+EXPORT_SYMBOL(security_inode_readlink);
++EXPORT_SYMBOL_GPL(security_inode_readlink);
  
  int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
  			       bool rcu)
@@ -937,7 +987,7 @@ index 46f405c..54488b0 100644
  		return 0;
  	return call_int_hook(inode_permission, 0, inode, mask);
  }
-+EXPORT_SYMBOL(security_inode_permission);
++EXPORT_SYMBOL_GPL(security_inode_permission);
  
  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  {
@@ -945,7 +995,7 @@ index 46f405c..54488b0 100644
  
  	return fsnotify_perm(file, mask);
  }
-+EXPORT_SYMBOL(security_file_permission);
++EXPORT_SYMBOL_GPL(security_file_permission);
  
  int security_file_alloc(struct file *file)
  {
@@ -953,13 +1003,13 @@ index 46f405c..54488b0 100644
  		return ret;
  	return ima_file_mmap(file, prot);
  }
-+EXPORT_SYMBOL(security_mmap_file);
++EXPORT_SYMBOL_GPL(security_mmap_file);
  
  int security_mmap_addr(unsigned long addr)
  {
 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/ABI/testing/debugfs-aufs	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,50 @@
 +What:		/debug/aufs/si_<id>/
 +Date:		March 2009
@@ -1013,7 +1063,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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/ABI/testing/sysfs-aufs	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,31 @@
 +What:		/sys/fs/aufs/si_<id>/
 +Date:		March 2009
@@ -1048,7 +1098,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/01intro.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,170 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -1222,7 +1272,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/02struct.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,258 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -1484,7 +1534,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,85 @@
 +
 +# Copyright (C) 2015-2016 Junjiro R. Okajima
@@ -1573,7 +1623,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/03lookup.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,113 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -1690,7 +1740,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/04branch.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,74 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -1768,7 +1818,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,64 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -1836,7 +1886,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,120 @@
 +
 +# Copyright (C) 2011-2016 Junjiro R. Okajima
@@ -1960,7 +2010,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/06mmap.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,72 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -2036,7 +2086,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/06xattr.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,96 @@
 +
 +# Copyright (C) 2014-2016 Junjiro R. Okajima
@@ -2136,7 +2186,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/07export.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,58 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -2198,7 +2248,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/08shwh.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,52 @@
 +
 +# Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -2254,7 +2304,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/design/10dynop.txt	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,47 @@
 +
 +# Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -2305,7 +2355,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/Documentation/filesystems/aufs/README	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,391 @@
 +
 +Aufs4 -- advanced multi layered unification filesystem version 4.x
@@ -2700,7 +2750,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/aufs.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,59 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -2763,7 +2813,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/branch.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,1407 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -3062,7 +3112,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +{
 +	int err, old_perm;
 +	aufs_bindex_t bindex;
-+	struct mutex *h_mtx;
++	struct inode *h_inode;
 +	struct au_wbr *wbr;
 +	struct au_hinode *hdir;
 +	struct dentry *h_dentry;
@@ -3075,15 +3125,15 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	old_perm = br->br_perm;
 +	br->br_perm = new_perm;
 +	hdir = NULL;
-+	h_mtx = NULL;
++	h_inode = NULL;
 +	bindex = au_br_index(sb, br->br_id);
 +	if (0 <= bindex) {
 +		hdir = au_hi(d_inode(sb->s_root), bindex);
 +		au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
 +	} else {
 +		h_dentry = au_br_dentry(br);
-+		h_mtx = &d_inode(h_dentry)->i_mutex;
-+		mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
++		h_inode = d_inode(h_dentry);
++		inode_lock_nested(h_inode, AuLsc_I_PARENT);
 +	}
 +	if (!wbr)
 +		err = au_wh_init(br, sb);
@@ -3095,7 +3145,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	if (hdir)
 +		au_hn_imtx_unlock(hdir);
 +	else
-+		mutex_unlock(h_mtx);
++		inode_unlock(h_inode);
 +	vfsub_mnt_drop_write(au_br_mnt(br));
 +	br->br_perm = old_perm;
 +
@@ -4174,7 +4224,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/branch.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,279 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -4457,7 +4507,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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/conf.mk	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,38 @@
 +
 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
@@ -4499,7 +4549,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/cpup.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,1379 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -4741,7 +4791,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	size_t sz, rbytes, wbytes;
 +	unsigned char all_zero;
 +	char *p, *zp;
-+	struct mutex *h_mtx;
++	struct inode *h_inode;
 +	/* reduce stack usage */
 +	struct iattr *ia;
 +
@@ -4821,12 +4871,12 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +			ia->ia_size = dst->f_pos;
 +			ia->ia_valid = ATTR_SIZE | ATTR_FILE;
 +			ia->ia_file = dst;
-+			h_mtx = &file_inode(dst)->i_mutex;
-+			mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
++			h_inode = file_inode(dst);
++			inode_lock_nested(h_inode, AuLsc_I_CHILD2);
 +			/* no delegation since it is just created */
 +			err = vfsub_notify_change(&dst->f_path, ia,
 +						  /*delegated*/NULL);
-+			mutex_unlock(h_mtx);
++			inode_unlock(h_inode);
 +		}
 +	}
 +
@@ -4954,7 +5004,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		cpg->len = l;
 +	if (cpg->len) {
 +		/* try stopping to update while we are referencing */
-+		mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(h_src_inode, AuLsc_I_CHILD);
 +		au_pin_hdir_unlock(cpg->pin);
 +
 +		h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
@@ -4963,17 +5013,17 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		if (!au_test_nfs(h_src_inode->i_sb))
 +			err = vfs_getattr(&h_path, &h_src_attr->st);
 +		else {
-+			mutex_unlock(&h_src_inode->i_mutex);
++			inode_unlock(h_src_inode);
 +			err = vfs_getattr(&h_path, &h_src_attr->st);
-+			mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
++			inode_lock_nested(h_src_inode, AuLsc_I_CHILD);
 +		}
 +		if (unlikely(err)) {
-+			mutex_unlock(&h_src_inode->i_mutex);
++			inode_unlock(h_src_inode);
 +			goto out;
 +		}
 +		h_src_attr->valid = 1;
 +		err = au_cp_regular(cpg);
-+		mutex_unlock(&h_src_inode->i_mutex);
++		inode_unlock(h_src_inode);
 +		rerr = au_pin_hdir_relock(cpg->pin);
 +		if (!err && rerr)
 +			err = rerr;
@@ -5324,7 +5374,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	if (unlikely(err))
 +		goto out_rev;
 +	dst_inode = d_inode(h_dst);
-+	mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
++	inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
 +	/* todo: necessary? */
 +	/* au_pin_hdir_unlock(cpg->pin); */
 +
@@ -5332,7 +5382,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	if (unlikely(err)) {
 +		/* todo: necessary? */
 +		/* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
-+		mutex_unlock(&dst_inode->i_mutex);
++		inode_unlock(dst_inode);
 +		goto out_rev;
 +	}
 +
@@ -5342,7 +5392,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +			if (unlikely(err)) {
 +				/* ignore an error */
 +				/* au_pin_hdir_relock(cpg->pin); */
-+				mutex_unlock(&dst_inode->i_mutex);
++				inode_unlock(dst_inode);
 +				goto out_rev;
 +			}
 +		}
@@ -5354,7 +5404,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +
 +	/* todo: necessary? */
 +	/* err = au_pin_hdir_relock(cpg->pin); */
-+	mutex_unlock(&dst_inode->i_mutex);
++	inode_unlock(dst_inode);
 +	if (unlikely(err))
 +		goto out_rev;
 +
@@ -5728,7 +5778,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		h_tmpdir = d_inode(h_orph);
 +		au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
 +
-+		mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
++		inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
 +		/* todo: au_h_open_pre()? */
 +
 +		pin_orig = cpg->pin;
@@ -5752,7 +5802,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	}
 +
 +	if (h_orph) {
-+		mutex_unlock(&h_tmpdir->i_mutex);
++		inode_unlock(h_tmpdir);
 +		/* todo: au_h_open_post()? */
 +		au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
 +		au_set_h_dptr(parent, bdst, h_parent);
@@ -5882,7 +5932,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/cpup.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,94 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -5980,7 +6030,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dbgaufs.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,432 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -6416,7 +6466,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dbgaufs.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,48 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -6468,7 +6518,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dcsub.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,224 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -6696,7 +6746,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dcsub.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,136 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -6836,7 +6886,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/debug.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,438 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -7278,7 +7328,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/debug.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,225 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -7507,7 +7557,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dentry.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,1136 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -7612,9 +7662,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	    || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
 +		goto out; /* success */
 +
-+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
++	inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +	opq = au_diropq_test(h_dentry);
-+	mutex_unlock(&h_inode->i_mutex);
++	inode_unlock(h_inode);
 +	if (opq > 0)
 +		au_set_dbdiropq(dentry, bindex);
 +	else if (unlikely(opq < 0)) {
@@ -7691,10 +7741,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +			continue;
 +
 +		h_dir = d_inode(h_parent);
-+		mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
++		inode_lock_nested(h_dir, AuLsc_I_PARENT);
 +		h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
 +					&args);
-+		mutex_unlock(&h_dir->i_mutex);
++		inode_unlock(h_dir);
 +		err = PTR_ERR(h_dentry);
 +		if (IS_ERR(h_dentry))
 +			goto out_parent;
@@ -8647,7 +8697,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +};
 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dentry.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,234 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -8885,7 +8935,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dinfo.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,550 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -9439,8 +9489,8 @@ 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	2016-02-28 11:26:32.569971135 +0100
-@@ -0,0 +1,758 @@
++++ linux/fs/aufs/dir.c	2016-04-24 18:32:51.390353525 +0200
+@@ -0,0 +1,756 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -9884,13 +9934,11 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +	struct dentry *dentry;
 +	struct inode *inode;
 +	struct super_block *sb;
-+	struct mutex *mtx;
 +
 +	err = 0;
 +	dentry = file->f_path.dentry;
 +	inode = d_inode(dentry);
-+	mtx = &inode->i_mutex;
-+	mutex_lock(mtx);
++	inode_lock(inode);
 +	sb = dentry->d_sb;
 +	si_noflush_read_lock(sb);
 +	if (file)
@@ -9905,7 +9953,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +		fi_write_unlock(file);
 +
 +	si_read_unlock(sb);
-+	mutex_unlock(mtx);
++	inode_unlock(inode);
 +	return err;
 +}
 +
@@ -10079,9 +10127,9 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +	h_dentry = au_h_dptr(dentry, arg->bindex);
 +	h_inode = d_inode(h_dentry);
 +	/* todo: i_mode changes anytime? */
-+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
++	inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +	err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
-+	mutex_unlock(&h_inode->i_mutex);
++	inode_unlock(h_inode);
 +	if (!err)
 +		err = do_test_empty(dentry, arg);
 +	else {
@@ -10201,7 +10249,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dir.h	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,131 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -10336,7 +10384,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dynop.c	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,369 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -10709,7 +10757,7 @@ 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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/dynop.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,74 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -10787,8 +10835,8 @@ 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	2016-02-28 11:26:32.569971135 +0100
-@@ -0,0 +1,832 @@
++++ linux/fs/aufs/export.c	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,830 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -11197,9 +11245,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +
 +	/* do not call vfsub_lkup_one() */
 +	dir = d_inode(parent);
-+	mutex_lock(&dir->i_mutex);
-+	dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
-+	mutex_unlock(&dir->i_mutex);
++	dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
 +	AuTraceErrPtr(dentry);
 +	if (IS_ERR(dentry))
 +		goto out_name;
@@ -11623,7 +11669,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/fhsm.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,426 @@
 +/*
 + * Copyright (C) 2011-2016 Junjiro R. Okajima
@@ -12053,7 +12099,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/file.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,844 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -12901,7 +12947,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/file.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,291 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -13196,7 +13242,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/finfo.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,156 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -13356,8 +13402,8 @@ 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	2016-02-28 11:26:32.569971135 +0100
-@@ -0,0 +1,748 @@
++++ linux/fs/aufs/f_op.c	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,770 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -13633,11 +13679,11 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	struct super_block *sb = inode->i_sb;
 +
 +	while (1) {
-+		mutex_lock(&inode->i_mutex);
++		inode_lock(inode);
 +		err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
 +		if (!err)
 +			break;
-+		mutex_unlock(&inode->i_mutex);
++		inode_unlock(inode);
 +		si_read_lock(sb, AuLock_NOPLMW);
 +		si_read_unlock(sb);
 +	}
@@ -13665,7 +13711,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +out:
 +	si_read_unlock(inode->i_sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	return err;
 +}
 +
@@ -13750,7 +13796,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +out:
 +	si_read_unlock(inode->i_sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	return err;
 +}
 +
@@ -13813,7 +13859,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +out:
 +	si_read_unlock(inode->i_sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	return err;
 +}
 +
@@ -13840,7 +13886,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +out:
 +	si_read_unlock(inode->i_sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	return err;
 +}
 +
@@ -13983,7 +14029,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +out_unlock:
 +	si_read_unlock(inode->i_sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +out:
 +	return err;
 +}
@@ -13994,7 +14040,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +{
 +	int err;
 +	struct au_write_pre wpre;
-+	struct inode *inode;
++	struct inode *inode, *h_inode;
 +	struct file *file, *h_file;
 +
 +	err = 0; /* -EBADF; */ /* posix? */
@@ -14013,26 +14059,24 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	err = -ENOSYS;
 +	h_file = au_hf_top(file);
 +	if (h_file->f_op->aio_fsync) {
-+		struct mutex *h_mtx;
-+
-+		h_mtx = &file_inode(h_file)->i_mutex;
++		h_inode = file_inode(h_file);
 +		if (!is_sync_kiocb(kio)) {
 +			get_file(h_file);
 +			fput(file);
 +		}
 +		kio->ki_filp = h_file;
 +		err = h_file->f_op->aio_fsync(kio, datasync);
-+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
++		inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +		if (!err)
 +			vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
 +		/*ignore*/
-+		mutex_unlock(h_mtx);
++		inode_unlock(h_inode);
 +	}
 +	au_write_post(inode, h_file, &wpre, /*written*/0);
 +
 +out_unlock:
 +	si_read_unlock(inode->sb);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +out:
 +	return err;
 +}
@@ -14061,6 +14105,29 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	return err;
 +}
 +
++static int aufs_setfl(struct file *file, unsigned long arg)
++{
++	int err;
++	struct file *h_file;
++	struct super_block *sb;
++
++	sb = file->f_path.dentry->d_sb;
++	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
++
++	h_file = au_read_pre(file, /*keep_fi*/0);
++	err = PTR_ERR(h_file);
++	if (IS_ERR(h_file))
++		goto out;
++
++	arg |= vfsub_file_flags(file) & FASYNC; /* stop calling h_file->fasync */
++	err = setfl(/*unused fd*/-1, h_file, arg);
++	fput(h_file); /* instead of au_read_post() */
++
++out:
++	si_read_unlock(sb);
++	return err;
++}
++
 +/* ---------------------------------------------------------------------- */
 +
 +/* no one supports this operation, currently */
@@ -14098,6 +14165,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	/* .aio_fsync	= aufs_aio_fsync_nondir, */
 +	.fasync		= aufs_fasync,
 +	/* .sendpage	= aufs_sendpage, */
++	.setfl		= aufs_setfl,
 +	.splice_write	= aufs_splice_write,
 +	.splice_read	= aufs_splice_read,
 +#if 0
@@ -14108,7 +14176,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/fstype.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,400 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -14512,7 +14580,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/hfsnotify.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,288 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -14804,7 +14872,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/hfsplus.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,56 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -14864,7 +14932,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/hnotify.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,710 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -14951,7 +15019,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +		if (!hi)
 +			continue;
 +
-+		/* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
++		/* inode_lock_nested(hi, AuLsc_I_CHILD); */
 +		iwhdentry = au_hi_wh(inode, bindex);
 +		if (iwhdentry)
 +			dget(iwhdentry);
@@ -14961,7 +15029,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +			      flags & ~AuHi_XINO);
 +		iput(hi);
 +		dput(iwhdentry);
-+		/* mutex_unlock(&hi->i_mutex); */
++		/* inode_unlock(hi); */
 +	}
 +}
 +
@@ -15190,11 +15258,11 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +	if (au_ftest_hnjob(a->flags, TRYXINO0)
 +	    && a->inode
 +	    && a->h_inode) {
-+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
 +		if (!a->h_inode->i_nlink
 +		    && !(a->h_inode->i_state & I_LINKABLE))
 +			hn_xino(a->inode, a->h_inode); /* ignore this error */
-+		mutex_unlock(&a->h_inode->i_mutex);
++		inode_unlock(a->h_inode);
 +	}
 +
 +	/* make the generation obsolete */
@@ -15578,7 +15646,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/iinfo.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,277 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -15859,7 +15927,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/inode.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,527 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -16390,7 +16458,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/inode.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,685 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -17058,28 +17126,28 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +
 +static inline void au_hn_imtx_lock(struct au_hinode *hdir)
 +{
-+	mutex_lock(&hdir->hi_inode->i_mutex);
++	inode_lock(hdir->hi_inode);
 +	au_hn_suspend(hdir);
 +}
 +
 +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
 +					  unsigned int sc __maybe_unused)
 +{
-+	mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
++	inode_lock_nested(hdir->hi_inode, sc);
 +	au_hn_suspend(hdir);
 +}
 +
 +static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
 +{
 +	au_hn_resume(hdir);
-+	mutex_unlock(&hdir->hi_inode->i_mutex);
++	inode_unlock(hdir->hi_inode);
 +}
 +
 +#endif /* __KERNEL__ */
 +#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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/ioctl.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,219 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -17302,7 +17370,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/i_op_add.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,932 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -17720,7 +17788,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +	};
 +
 +	/* copy-up may happen */
-+	mutex_lock(&dir->i_mutex);
++	inode_lock(dir);
 +
 +	sb = dir->i_sb;
 +	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
@@ -17817,7 +17885,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +out_si:
 +	si_read_unlock(sb);
 +out:
-+	mutex_unlock(&dir->i_mutex);
++	inode_unlock(dir);
 +	return err;
 +}
 +
@@ -18136,7 +18204,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +	unsigned char diropq;
 +	struct path h_path;
 +	struct dentry *wh_dentry, *parent, *opq_dentry;
-+	struct mutex *h_mtx;
++	struct inode *h_inode;
 +	struct super_block *sb;
 +	struct {
 +		struct au_pin pin;
@@ -18179,12 +18247,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +
 +	/* make the dir opaque */
 +	diropq = 0;
-+	h_mtx = &d_inode(h_path.dentry)->i_mutex;
++	h_inode = d_inode(h_path.dentry);
 +	if (wh_dentry
 +	    || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
-+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
++		inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +		opq_dentry = au_diropq_create(dentry, bindex);
-+		mutex_unlock(h_mtx);
++		inode_unlock(h_inode);
 +		err = PTR_ERR(opq_dentry);
 +		if (IS_ERR(opq_dentry))
 +			goto out_dir;
@@ -18201,9 +18269,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +	/* revert */
 +	if (diropq) {
 +		AuLabel(revert opq);
-+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
++		inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +		rerr = au_diropq_remove(dentry, bindex);
-+		mutex_unlock(h_mtx);
++		inode_unlock(h_inode);
 +		if (rerr) {
 +			AuIOErr("%pd reverting diropq failed(%d, %d)\n",
 +				dentry, err, rerr);
@@ -18238,8 +18306,8 @@ 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	2016-02-28 11:26:32.573304539 +0100
-@@ -0,0 +1,1490 @@
++++ linux/fs/aufs/i_op.c	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,1419 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -18669,10 +18737,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
 +		h_parent = au_h_dptr(parent, bcpup);
 +		h_dir = d_inode(h_parent);
-+		mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
++		inode_lock_nested(h_dir, AuLsc_I_PARENT);
 +		err = au_lkup_neg(dentry, bcpup, /*wh*/0);
 +		/* todo: no unlock here */
-+		mutex_unlock(&h_dir->i_mutex);
++		inode_unlock(h_dir);
 +
 +		AuDbg("bcpup %d\n", bcpup);
 +		if (!err) {
@@ -19056,10 +19124,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	sz = -1;
 +	a->h_inode = d_inode(a->h_path.dentry);
 +	if (ia && (ia->ia_valid & ATTR_SIZE)) {
-+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
 +		if (ia->ia_size < i_size_read(a->h_inode))
 +			sz = ia->ia_size;
-+		mutex_unlock(&a->h_inode->i_mutex);
++		inode_unlock(a->h_inode);
 +	}
 +
 +	hi_wh = NULL;
@@ -19119,7 +19187,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	}
 +out:
 +	if (!err)
-+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
 +	return err;
 +}
 +
@@ -19203,9 +19271,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +		f = NULL;
 +		if (ia->ia_valid & ATTR_FILE)
 +			f = ia->ia_file;
-+		mutex_unlock(&a->h_inode->i_mutex);
++		inode_unlock(a->h_inode);
 +		err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
-+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
 +	} else {
 +		delegated = NULL;
 +		while (1) {
@@ -19228,7 +19296,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +		au_cpup_attr_changeable(inode);
 +
 +out_unlock:
-+	mutex_unlock(&a->h_inode->i_mutex);
++	inode_unlock(a->h_inode);
 +	au_unpin(&a->pin);
 +	if (unlikely(err))
 +		au_update_dbstart(dentry);
@@ -19304,7 +19372,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	if (unlikely(err))
 +		goto out_di;
 +
-+	mutex_unlock(&a->h_inode->i_mutex);
++	inode_unlock(a->h_inode);
 +	switch (arg->type) {
 +	case AU_XATTR_SET:
 +		err = vfsub_setxattr(h_path.dentry,
@@ -19489,62 +19557,20 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+/*
-+ * Assumption:
-+ * - the number of symlinks is not so many.
-+ *
-+ * Structure:
-+ * - sbinfo (instead of iinfo) contains an hlist of struct au_symlink.
-+ *   If iinfo contained the hlist, then it would be rather large waste of memory
-+ *   I am afraid.
-+ * - struct au_symlink contains the necessary info for h_inode follow_link() and
-+ *   put_link().
-+ */
-+
-+struct au_symlink {
-+	union {
-+		struct hlist_node hlist;
-+		struct rcu_head rcu;
-+	};
-+
-+	struct inode *h_inode;
-+	void *h_cookie;
-+};
-+
-+static void au_symlink_add(struct super_block *sb, struct au_symlink *slink,
-+			   struct inode *h_inode, void *cookie)
-+{
-+	struct au_sbinfo *sbinfo;
-+
-+	ihold(h_inode);
-+	slink->h_inode = h_inode;
-+	slink->h_cookie = cookie;
-+	sbinfo = au_sbi(sb);
-+	au_sphl_add(&slink->hlist, &sbinfo->si_symlink);
-+}
-+
-+static void au_symlink_del(struct super_block *sb, struct au_symlink *slink)
-+{
-+	struct au_sbinfo *sbinfo;
-+
-+	/* do not iput() within rcu */
-+	iput(slink->h_inode);
-+	slink->h_inode = NULL;
-+	sbinfo = au_sbi(sb);
-+	au_sphl_del_rcu(&slink->hlist, &sbinfo->si_symlink);
-+	kfree_rcu(slink, rcu);
-+}
-+
-+static const char *aufs_follow_link(struct dentry *dentry, void **cookie)
++static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
++				 struct delayed_call *done)
 +{
 +	const char *ret;
-+	struct inode *inode, *h_inode;
 +	struct dentry *h_dentry;
-+	struct au_symlink *slink;
++	struct inode *h_inode;
 +	int err;
 +	aufs_bindex_t bindex;
 +
 +	ret = NULL; /* suppress a warning */
++	err = -ECHILD;
++	if (!dentry)
++		goto out;
++
 +	err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
 +	if (unlikely(err))
 +		goto out;
@@ -19557,12 +19583,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	inode = d_inode(dentry);
 +	bindex = au_ibstart(inode);
 +	h_inode = au_h_iptr(inode, bindex);
-+	if (unlikely(!h_inode->i_op->follow_link))
-+		goto out_unlock;
-+
-+	err = -ENOMEM;
-+	slink = kmalloc(sizeof(*slink), GFP_NOFS);
-+	if (unlikely(!slink))
++	if (unlikely(!h_inode->i_op->get_link))
 +		goto out_unlock;
 +
 +	err = -EBUSY;
@@ -19576,28 +19597,20 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +		h_dentry = d_find_any_alias(h_inode);
 +		if (IS_ERR(h_dentry)) {
 +			err = PTR_ERR(h_dentry);
-+			goto out_free;
++			goto out_unlock;
 +		}
 +	}
 +	if (unlikely(!h_dentry))
-+		goto out_free;
++		goto out_unlock;
 +
 +	err = 0;
-+	AuDbg("%pf\n", h_inode->i_op->follow_link);
++	AuDbg("%pf\n", h_inode->i_op->get_link);
 +	AuDbgDentry(h_dentry);
-+	ret = h_inode->i_op->follow_link(h_dentry, cookie);
++	ret = h_inode->i_op->get_link(h_dentry, h_inode, done);
 +	dput(h_dentry);
++	if (IS_ERR(ret))
++		err = PTR_ERR(ret);
 +
-+	if (!IS_ERR_OR_NULL(ret)) {
-+		au_symlink_add(inode->i_sb, slink, h_inode, *cookie);
-+		*cookie = slink;
-+		AuDbg("slink %p\n", slink);
-+		goto out_unlock; /* success */
-+	}
-+
-+out_free:
-+	slink->h_inode = NULL;
-+	kfree_rcu(slink, rcu);
 +out_unlock:
 +	aufs_read_unlock(dentry, AuLock_IR);
 +out:
@@ -19607,21 +19620,6 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	return ret;
 +}
 +
-+static void aufs_put_link(struct inode *inode, void *cookie)
-+{
-+	struct au_symlink *slink;
-+	struct inode *h_inode;
-+
-+	slink = cookie;
-+	AuDbg("slink %p\n", slink);
-+	h_inode = slink->h_inode;
-+	AuDbg("%pf\n", h_inode->i_op->put_link);
-+	AuDbgInode(h_inode);
-+	if (h_inode->i_op->put_link)
-+		h_inode->i_op->put_link(h_inode, slink->h_cookie);
-+	au_symlink_del(inode->i_sb, slink);
-+}
-+
 +/* ---------------------------------------------------------------------- */
 +
 +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
@@ -19674,8 +19672,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +#endif
 +
 +		.readlink	= generic_readlink,
-+		.follow_link	= aufs_follow_link,
-+		.put_link	= aufs_put_link,
++		.get_link	= aufs_get_link,
 +
 +		/* .update_time	= aufs_update_time */
 +	},
@@ -19732,7 +19729,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +};
 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/i_op_del.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,510 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -20246,7 +20243,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/i_op_ren.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,1015 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21026,7 +21023,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +static void au_ren_rev_dt(int err, struct au_ren_args *a)
 +{
 +	struct dentry *h_d;
-+	struct mutex *h_mtx;
++	struct inode *h_inode;
 +
 +	au_dtime_revert(a->src_dt + AuPARENT);
 +	if (!au_ftest_ren(a->flags, ISSAMEDIR))
@@ -21034,17 +21031,17 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +	if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
 +		h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
-+		h_mtx = &d_inode(h_d)->i_mutex;
-+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
++		h_inode = d_inode(h_d);
++		inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +		au_dtime_revert(a->src_dt + AuCHILD);
-+		mutex_unlock(h_mtx);
++		inode_unlock(h_inode);
 +
 +		if (au_ftest_ren(a->flags, DT_DSTDIR)) {
 +			h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
-+			h_mtx = &d_inode(h_d)->i_mutex;
-+			mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
++			h_inode = d_inode(h_d);
++			inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +			au_dtime_revert(a->dst_dt + AuCHILD);
-+			mutex_unlock(h_mtx);
++			inode_unlock(h_inode);
 +		}
 +	}
 +}
@@ -21265,7 +21262,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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/Kconfig	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,185 @@
 +config AUFS_FS
 +	tristate "Aufs (Advanced multi layered unification filesystem) support"
@@ -21454,7 +21451,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/loop.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,146 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21604,7 +21601,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
 +}
 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/loop.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,52 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21660,7 +21657,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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/magic.mk	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,30 @@
 +
 +# defined in ${srctree}/fs/fuse/inode.c
@@ -21694,7 +21691,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	2016-02-28 11:26:32.569971135 +0100
++++ linux/fs/aufs/Makefile	2016-04-24 18:32:51.390353525 +0200
 @@ -0,0 +1,44 @@
 +
 +include ${src}/magic.mk
@@ -21742,7 +21739,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/module.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,221 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21967,7 +21964,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/module.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,105 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -22076,7 +22073,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/mvdown.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,703 @@
 +/*
 + * Copyright (C) 2011-2016 Junjiro R. Okajima
@@ -22738,14 +22735,14 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +	dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
 +	args->parent = dget_parent(dentry);
 +	args->dir = d_inode(args->parent);
-+	mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
++	inode_lock_nested(args->dir, I_MUTEX_PARENT);
 +	dput(args->parent);
 +	if (unlikely(args->parent != dentry->d_parent)) {
 +		AU_MVD_PR(dmsg, "parent dir is moved\n");
 +		goto out_dir;
 +	}
 +
-+	mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
++	inode_lock_nested(inode, I_MUTEX_CHILD);
 +	err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
 +	if (unlikely(err))
 +		goto out_inode;
@@ -22769,9 +22766,9 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +	di_write_unlock(args->parent);
 +	aufs_read_unlock(dentry, AuLock_DW);
 +out_inode:
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +out_dir:
-+	mutex_unlock(&args->dir->i_mutex);
++	inode_unlock(args->dir);
 +out_free:
 +	e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
 +	if (unlikely(e))
@@ -22783,7 +22780,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/opts.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,1859 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -24372,16 +24369,16 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +		if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
 +			pr_warn("first branch should be rw\n");
 +		if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
-+			pr_warn("shwh should be used with ro\n");
++			pr_warn_once("shwh should be used with ro\n");
 +	}
 +
 +	if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
 +	    && !au_opt_test(sbinfo->si_mntflags, XINO))
-+		pr_warn("udba=*notify requires xino\n");
++		pr_warn_once("udba=*notify requires xino\n");
 +
 +	if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
-+		pr_warn("dirperm1 breaks the protection"
-+			" by the permission bits on the lower branch\n");
++		pr_warn_once("dirperm1 breaks the protection"
++			     " by the permission bits on the lower branch\n");
 +
 +	err = 0;
 +	fhsm = 0;
@@ -24646,7 +24643,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/opts.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,211 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -24861,7 +24858,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/plink.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,528 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -25065,12 +25062,12 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +				       struct au_branch *br)
 +{
 +	struct dentry *h_dentry;
-+	struct mutex *h_mtx;
++	struct inode *h_inode;
 +
-+	h_mtx = &d_inode(h_parent)->i_mutex;
-+	mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
++	h_inode = d_inode(h_parent);
++	inode_lock_nested(h_inode, AuLsc_I_CHILD2);
 +	h_dentry = vfsub_lkup_one(tgtname, h_parent);
-+	mutex_unlock(h_mtx);
++	inode_unlock(h_inode);
 +	return h_dentry;
 +}
 +
@@ -25123,7 +25120,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +	struct inode *h_dir, *delegated;
 +
 +	h_dir = d_inode(h_parent);
-+	mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
++	inode_lock_nested(h_dir, AuLsc_I_CHILD2);
 +again:
 +	h_path.dentry = vfsub_lkup_one(tgt, h_parent);
 +	err = PTR_ERR(h_path.dentry);
@@ -25159,7 +25156,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +	dput(h_path.dentry);
 +
 +out:
-+	mutex_unlock(&h_dir->i_mutex);
++	inode_unlock(h_dir);
 +	return err;
 +}
 +
@@ -25393,7 +25390,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/poll.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,52 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -25449,7 +25446,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/posix_acl.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,98 @@
 +/*
 + * Copyright (C) 2014-2016 Junjiro R. Okajima
@@ -25524,7 +25521,7 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 +		},
 +	};
 +
-+	mutex_lock(&inode->i_mutex);
++	inode_lock(inode);
 +	if (inode->i_ino == AUFS_ROOT_INO)
 +		dentry = dget(inode->i_sb->s_root);
 +	else {
@@ -25546,12 +25543,12 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 +		err = 0;
 +
 +out:
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	return err;
 +}
 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/procfs.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,169 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -25724,8 +25721,8 @@ 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	2016-02-28 11:26:32.573304539 +0100
-@@ -0,0 +1,388 @@
++++ linux/fs/aufs/rdu.c	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,389 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -25887,8 +25884,9 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
 +	dentry = file->f_path.dentry;
 +	inode = d_inode(dentry);
 +#if 1
-+	mutex_lock(&inode->i_mutex);
++	inode_lock(inode);
 +#else
++	/* todo: create a new inline func inode_lock_killable() */
 +	err = mutex_lock_killable(&inode->i_mutex);
 +	AuTraceErr(err);
 +	if (unlikely(err))
@@ -25950,7 +25948,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
 +out_si:
 +	si_read_unlock(arg.sb);
 +out_mtx:
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +out:
 +	AuTraceErr(err);
 +	return err;
@@ -26116,7 +26114,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/rwsem.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,191 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -26311,8 +26309,8 @@ 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	2016-02-28 11:26:32.573304539 +0100
-@@ -0,0 +1,366 @@
++++ linux/fs/aufs/sbinfo.c	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,350 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -26350,19 +26348,14 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +		AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
 +	AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
 +
-+	AuDebugOn(!hlist_empty(&sbinfo->si_symlink.head));
-+
 +	au_rw_write_lock(&sbinfo->si_rwsem);
 +	au_br_free(sbinfo);
 +	au_rw_write_unlock(&sbinfo->si_rwsem);
 +
-+	AuDebugOn(radix_tree_gang_lookup
-+		  (&sbinfo->au_si_pid.tree, (void **)&locked,
-+		   /*first_index*/PID_MAX_DEFAULT - 1,
-+		   /*max_items*/sizeof(locked)/sizeof(*locked)));
-+
 +	kfree(sbinfo->si_branch);
-+	kfree(sbinfo->au_si_pid.bitmap);
++	for (i = 0; i < AU_NPIDMAP; i++)
++		kfree(sbinfo->au_si_pid.pid_bitmap[i]);
++	mutex_destroy(&sbinfo->au_si_pid.pid_mtx);
 +	mutex_destroy(&sbinfo->si_xib_mtx);
 +	AuRwDestroy(&sbinfo->si_rwsem);
 +
@@ -26380,18 +26373,10 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +	if (unlikely(!sbinfo))
 +		goto out;
 +
-+	BUILD_BUG_ON(sizeof(unsigned long) !=
-+		     sizeof(*sbinfo->au_si_pid.bitmap));
-+	sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
-+					sizeof(*sbinfo->au_si_pid.bitmap),
-+					GFP_NOFS);
-+	if (unlikely(!sbinfo->au_si_pid.bitmap))
-+		goto out_sbinfo;
-+
 +	/* will be reallocated separately */
 +	sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
 +	if (unlikely(!sbinfo->si_branch))
-+		goto out_pidmap;
++		goto out_sbinfo;
 +
 +	err = sysaufs_si_init(sbinfo);
 +	if (unlikely(err))
@@ -26400,8 +26385,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +	au_nwt_init(&sbinfo->si_nowait);
 +	au_rw_init_wlock(&sbinfo->si_rwsem);
 +	au_rw_class(&sbinfo->si_rwsem, &aufs_si);
-+	spin_lock_init(&sbinfo->au_si_pid.tree_lock);
-+	INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
++	mutex_init(&sbinfo->au_si_pid.pid_mtx);
 +
 +	atomic_long_set(&sbinfo->si_ninodes, 0);
 +	atomic_long_set(&sbinfo->si_nfiles, 0);
@@ -26418,8 +26402,6 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +
 +	sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
 +
-+	au_sphl_init(&sbinfo->si_symlink);
-+
 +	sbinfo->si_xino_jiffy = jiffies;
 +	sbinfo->si_xino_expire
 +		= msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
@@ -26452,8 +26434,6 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +
 +out_br:
 +	kfree(sbinfo->si_branch);
-+out_pidmap:
-+	kfree(sbinfo->au_si_pid.bitmap);
 +out_sbinfo:
 +	kfree(sbinfo);
 +out:
@@ -26638,50 +26618,52 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+int si_pid_test_slow(struct super_block *sb)
-+{
-+	void *p;
-+
-+	rcu_read_lock();
-+	p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
-+	rcu_read_unlock();
-+
-+	return (long)!!p;
-+}
-+
-+void si_pid_set_slow(struct super_block *sb)
++static void si_pid_alloc(struct au_si_pid *au_si_pid, int idx)
 +{
-+	int err;
-+	struct au_sbinfo *sbinfo;
++	unsigned long *p;
 +
-+	AuDebugOn(si_pid_test_slow(sb));
++	BUILD_BUG_ON(sizeof(unsigned long) !=
++		     sizeof(*au_si_pid->pid_bitmap));
 +
-+	sbinfo = au_sbi(sb);
-+	err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
-+	AuDebugOn(err);
-+	spin_lock(&sbinfo->au_si_pid.tree_lock);
-+	err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
-+				/*any valid ptr*/sb);
-+	spin_unlock(&sbinfo->au_si_pid.tree_lock);
-+	AuDebugOn(err);
-+	radix_tree_preload_end();
++	mutex_lock(&au_si_pid->pid_mtx);
++	p = au_si_pid->pid_bitmap[idx];
++	while (!p) {
++		/*
++		 * bad approach.
++		 * but keeping 'si_pid_set()' void is more important.
++		 */
++		p = kcalloc(BITS_TO_LONGS(AU_PIDSTEP),
++			    sizeof(*au_si_pid->pid_bitmap),
++			    GFP_NOFS);
++		if (p)
++			break;
++		cond_resched();
++	}
++	au_si_pid->pid_bitmap[idx] = p;
++	mutex_unlock(&au_si_pid->pid_mtx);
 +}
 +
-+void si_pid_clr_slow(struct super_block *sb)
++void si_pid_set(struct super_block *sb)
 +{
-+	void *p;
-+	struct au_sbinfo *sbinfo;
-+
-+	AuDebugOn(!si_pid_test_slow(sb));
-+
-+	sbinfo = au_sbi(sb);
-+	spin_lock(&sbinfo->au_si_pid.tree_lock);
-+	p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
-+	spin_unlock(&sbinfo->au_si_pid.tree_lock);
++	pid_t bit;
++	int idx;
++	unsigned long *bitmap;
++	struct au_si_pid *au_si_pid;
++
++	si_pid_idx_bit(&idx, &bit);
++	au_si_pid = &au_sbi(sb)->au_si_pid;
++	bitmap = au_si_pid->pid_bitmap[idx];
++	if (!bitmap) {
++		si_pid_alloc(au_si_pid, idx);
++		bitmap = au_si_pid->pid_bitmap[idx];
++	}
++	AuDebugOn(test_bit(bit, bitmap));
++	set_bit(bit, bitmap);
++	/* smp_mb(); */
 +}
 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/spl.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,111 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -26796,7 +26778,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/super.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,1039 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -27604,7 +27586,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +
 +	sbinfo = au_sbi(sb);
 +	inode = d_inode(root);
-+	mutex_lock(&inode->i_mutex);
++	inode_lock(inode);
 +	err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
 +	if (unlikely(err))
 +		goto out_mtx;
@@ -27627,7 +27609,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +	aufs_write_unlock(root);
 +
 +out_mtx:
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +out_opts:
 +	free_page((unsigned long)opts.opt);
 +out:
@@ -27746,7 +27728,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +		goto out_root;
 +
 +	/* lock vfs_inode first, then aufs. */
-+	mutex_lock(&inode->i_mutex);
++	inode_lock(inode);
 +	aufs_write_lock(root);
 +	err = au_opts_mount(sb, &opts);
 +	au_opts_free(&opts);
@@ -27758,7 +27740,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +		au_refresh_iop(inode, /*force_getattr*/0);
 +	}
 +	aufs_write_unlock(root);
-+	mutex_unlock(&inode->i_mutex);
++	inode_unlock(inode);
 +	if (!err)
 +		goto out_opts; /* success */
 +
@@ -27839,8 +27821,8 @@ 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	2016-02-28 11:26:32.573304539 +0100
-@@ -0,0 +1,641 @@
++++ linux/fs/aufs/super.h	2016-04-24 18:32:51.393686895 +0200
+@@ -0,0 +1,632 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -27930,6 +27912,13 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +#endif
 +};
 +
++#define AU_PIDSTEP	(int)(BITS_TO_LONGS(PID_MAX_DEFAULT) * BITS_PER_LONG)
++#define AU_NPIDMAP	(int)DIV_ROUND_UP(PID_MAX_LIMIT, AU_PIDSTEP)
++struct au_si_pid {
++	unsigned long	*pid_bitmap[AU_NPIDMAP];
++	struct mutex	pid_mtx;
++};
++
 +struct au_branch;
 +struct au_sbinfo {
 +	/* nowait tasks in the system-wide workqueue */
@@ -27942,11 +27931,7 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +	struct au_rwsem		si_rwsem;
 +
 +	/* prevent recursive locking in deleting inode */
-+	struct {
-+		unsigned long		*bitmap;
-+		spinlock_t		tree_lock;
-+		struct radix_tree_root	tree;
-+	} au_si_pid;
++	struct au_si_pid	au_si_pid;
 +
 +	/*
 +	 * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
@@ -27986,9 +27971,6 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +	/* include/asm-ia64/siginfo.h defines a macro named si_flags */
 +	unsigned int		si_mntflags;
 +
-+	/* symlink to follow_link() and put_link() */
-+	struct au_sphlhead	si_symlink;
-+
 +	/* external inode number (bitmap and translation table) */
 +	vfs_readf_t		si_xread;
 +	vfs_writef_t		si_xwrite;
@@ -28144,10 +28126,6 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
 +
-+int si_pid_test_slow(struct super_block *sb);
-+void si_pid_set_slow(struct super_block *sb);
-+void si_pid_clr_slow(struct super_block *sb);
-+
 +/* wbr_policy.c */
 +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
 +extern struct au_wbr_create_operations au_wbr_create_ops[];
@@ -28295,48 +28273,43 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +
 +/* ---------------------------------------------------------------------- */
 +
-+static inline pid_t si_pid_bit(void)
++static inline void si_pid_idx_bit(int *idx, pid_t *bit)
 +{
 +	/* the origin of pid is 1, but the bitmap's is 0 */
-+	return current->pid - 1;
++	*bit = current->pid - 1;
++	*idx = *bit / AU_PIDSTEP;
++	*bit %= AU_PIDSTEP;
 +}
 +
 +static inline int si_pid_test(struct super_block *sb)
 +{
 +	pid_t bit;
++	int idx;
++	unsigned long *bitmap;
 +
-+	bit = si_pid_bit();
-+	if (bit < PID_MAX_DEFAULT)
-+		return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
-+	return si_pid_test_slow(sb);
-+}
-+
-+static inline void si_pid_set(struct super_block *sb)
-+{
-+	pid_t bit;
-+
-+	bit = si_pid_bit();
-+	if (bit < PID_MAX_DEFAULT) {
-+		AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
-+		set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
-+		/* smp_mb(); */
-+	} else
-+		si_pid_set_slow(sb);
++	si_pid_idx_bit(&idx, &bit);
++	bitmap = au_sbi(sb)->au_si_pid.pid_bitmap[idx];
++	if (bitmap)
++		return test_bit(bit, bitmap);
++	return 0;
 +}
 +
 +static inline void si_pid_clr(struct super_block *sb)
 +{
 +	pid_t bit;
++	int idx;
++	unsigned long *bitmap;
 +
-+	bit = si_pid_bit();
-+	if (bit < PID_MAX_DEFAULT) {
-+		AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
-+		clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
-+		/* smp_mb(); */
-+	} else
-+		si_pid_clr_slow(sb);
++	si_pid_idx_bit(&idx, &bit);
++	bitmap = au_sbi(sb)->au_si_pid.pid_bitmap[idx];
++	BUG_ON(!bitmap);
++	AuDebugOn(!test_bit(bit, bitmap));
++	clear_bit(bit, bitmap);
++	/* smp_mb(); */
 +}
 +
++void si_pid_set(struct super_block *sb);
++
 +/* ---------------------------------------------------------------------- */
 +
 +/* lock superblock. mainly for entry point functions */
@@ -28484,7 +28457,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/sysaufs.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,104 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -28592,7 +28565,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/sysaufs.h	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,101 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -28697,7 +28670,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/sysfs.c	2016-04-24 18:32:51.393686895 +0200
 @@ -0,0 +1,376 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -29077,7 +29050,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/sysrq.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,157 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -29238,7 +29211,7 @@ 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	2016-02-28 11:26:32.573304539 +0100
++++ linux/fs/aufs/vdir.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,888 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -30130,8 +30103,8 @@ 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	2016-02-28 11:26:32.573304539 +0100
-@@ -0,0 +1,866 @@
++++ linux/fs/aufs/vfsub.c	2016-04-24 18:32:51.397020264 +0200
+@@ -0,0 +1,884 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -30289,6 +30262,24 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +	return err;
 +}
 +
++struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
++					     struct dentry *parent, int len)
++{
++	struct path path = {
++		.mnt = NULL
++	};
++
++	path.dentry = lookup_one_len_unlocked(name, parent, len);
++	if (IS_ERR(path.dentry))
++		goto out;
++	if (d_is_positive(path.dentry))
++		vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
++
++out:
++	AuTraceErrPtr(path.dentry);
++	return path.dentry;
++}
++
 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
 +				    int len)
 +{
@@ -31000,8 +30991,8 @@ 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	2016-02-28 11:26:32.576637942 +0100
-@@ -0,0 +1,308 @@
++++ linux/fs/aufs/vfsub.h	2016-04-24 18:32:51.397020264 +0200
+@@ -0,0 +1,310 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -31056,7 +31047,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +
 +/* to debug easier, do not make them inlined functions */
 +#define MtxMustLock(mtx)	AuDebugOn(!mutex_is_locked(mtx))
-+#define IMustLock(i)		MtxMustLock(&(i)->i_mutex)
++#define IMustLock(i)		AuDebugOn(!inode_is_locked(i))
 +
 +/* ---------------------------------------------------------------------- */
 +
@@ -31103,6 +31094,8 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +		      struct vfsub_aopen_args *args, struct au_branch *br);
 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
 +
++struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
++					     struct dentry *parent, int len);
 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
 +				    int len);
 +
@@ -31312,7 +31305,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/wbr_policy.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,765 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -31456,17 +31449,17 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +	if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
 +		au_fset_cpdown(*flags, PARENT_OPQ);
 +	h_inode = d_inode(h_path.dentry);
-+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
++	inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +	if (au_ftest_cpdown(*flags, WHED)) {
 +		err = au_cpdown_dir_opq(dentry, bdst, flags);
 +		if (unlikely(err)) {
-+			mutex_unlock(&h_inode->i_mutex);
++			inode_unlock(h_inode);
 +			goto out_dir;
 +		}
 +	}
 +
 +	err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
-+	mutex_unlock(&h_inode->i_mutex);
++	inode_unlock(h_inode);
 +	if (unlikely(err))
 +		goto out_opq;
 +
@@ -31487,9 +31480,9 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +	/* revert */
 +out_opq:
 +	if (au_ftest_cpdown(*flags, DIROPQ)) {
-+		mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
++		inode_lock_nested(h_inode, AuLsc_I_CHILD);
 +		rerr = au_diropq_remove(dentry, bdst);
-+		mutex_unlock(&h_inode->i_mutex);
++		inode_unlock(h_inode);
 +		if (unlikely(rerr)) {
 +			AuIOErr("failed removing diropq for %pd b%d (%d)\n",
 +				dentry, bdst, rerr);
@@ -32081,7 +32074,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/whout.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,1060 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -33027,7 +33020,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +	br = au_sbr(dir->i_sb, bindex);
 +	wh_inode = d_inode(wh_dentry);
-+	mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
++	inode_lock_nested(wh_inode, AuLsc_I_CHILD);
 +
 +	/*
 +	 * someone else might change some whiteouts while we were sleeping.
@@ -33049,7 +33042,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +		if (unlikely(wkq_err))
 +			err = wkq_err;
 +	}
-+	mutex_unlock(&wh_inode->i_mutex);
++	inode_unlock(wh_inode);
 +
 +	if (!err) {
 +		h_tmp.dentry = wh_dentry;
@@ -33085,7 +33078,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +	struct au_hinode *hdir;
 +
 +	/* rmdir by nfsd may cause deadlock with this i_mutex */
-+	/* mutex_lock(&a->dir->i_mutex); */
++	/* inode_lock(a->dir); */
 +	err = -EROFS;
 +	sb = a->dir->i_sb;
 +	si_read_lock(sb, !AuLock_FLUSH);
@@ -33115,7 +33108,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +	dput(h_parent);
 +	ii_write_unlock(a->dir);
 +out:
-+	/* mutex_unlock(&a->dir->i_mutex); */
++	/* inode_unlock(a->dir); */
 +	au_whtmp_rmdir_free(a);
 +	si_read_unlock(sb);
 +	au_nwt_done(&au_sbi(sb)->si_nowait);
@@ -33145,7 +33138,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/whout.h	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,85 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -33234,7 +33227,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/wkq.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,213 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -33451,7 +33444,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/wkq.h	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,91 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -33546,7 +33539,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/xattr.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,344 @@
 +/*
 + * Copyright (C) 2014-2016 Junjiro R. Okajima
@@ -33638,9 +33631,9 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +
 +	/* unlock it temporary */
 +	h_idst = d_inode(h_dst);
-+	mutex_unlock(&h_idst->i_mutex);
++	inode_unlock(h_idst);
 +	err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
-+	mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
++	inode_lock_nested(h_idst, AuLsc_I_CHILD2);
 +	if (unlikely(err)) {
 +		if (verbose || au_debug_test())
 +			pr_err("%s, err %d\n", name, err);
@@ -33663,9 +33656,9 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +	/* there should not be the parent-child relationship between them */
 +	h_isrc = d_inode(h_src);
 +	h_idst = d_inode(h_dst);
-+	mutex_unlock(&h_idst->i_mutex);
-+	mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
-+	mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
++	inode_unlock(h_idst);
++	inode_lock_nested(h_isrc, AuLsc_I_CHILD);
++	inode_lock_nested(h_idst, AuLsc_I_CHILD2);
 +	unlocked = 0;
 +
 +	/* some filesystems don't list POSIX ACL, for example tmpfs */
@@ -33690,7 +33683,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +			goto out;
 +		err = vfs_listxattr(h_src, p, ssz);
 +	}
-+	mutex_unlock(&h_isrc->i_mutex);
++	inode_unlock(h_isrc);
 +	unlocked = 1;
 +	AuDbg("err %d, ssz %zd\n", err, ssz);
 +	if (unlikely(err < 0))
@@ -33732,7 +33725,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +	kfree(o);
 +out:
 +	if (!unlocked)
-+		mutex_unlock(&h_isrc->i_mutex);
++		inode_unlock(h_isrc);
 +	AuTraceErr(err);
 +	return err;
 +}
@@ -33894,7 +33887,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/fs/aufs/xino.c	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,1318 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -34128,7 +34121,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +struct au_xino_lock_dir {
 +	struct au_hinode *hdir;
 +	struct dentry *parent;
-+	struct mutex *mtx;
++	struct inode *dir;
 +};
 +
 +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
@@ -34146,8 +34139,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +		au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
 +	} else {
 +		ldir->parent = dget_parent(xino->f_path.dentry);
-+		ldir->mtx = &d_inode(ldir->parent)->i_mutex;
-+		mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
++		ldir->dir = d_inode(ldir->parent);
++		inode_lock_nested(ldir->dir, AuLsc_I_PARENT);
 +	}
 +}
 +
@@ -34156,7 +34149,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +	if (ldir->hdir)
 +		au_hn_imtx_unlock(ldir->hdir);
 +	else {
-+		mutex_unlock(ldir->mtx);
++		inode_unlock(ldir->dir);
 +		dput(ldir->parent);
 +	}
 +}
@@ -34671,13 +34664,13 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +	inode = file_inode(file);
 +	h_parent = dget_parent(file->f_path.dentry);
 +	h_dir = d_inode(h_parent);
-+	mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
++	inode_lock_nested(h_dir, AuLsc_I_PARENT);
 +	/* mnt_want_write() is unnecessary here */
 +	/* no delegation since it is just created */
 +	if (inode->i_nlink)
 +		err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
 +				   /*force*/0);
-+	mutex_unlock(&h_dir->i_mutex);
++	inode_unlock(h_dir);
 +	dput(h_parent);
 +	if (unlikely(err)) {
 +		if (!silent)
@@ -35112,14 +35105,14 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +	au_opt_set(sbinfo->si_mntflags, XINO);
 +	dir = d_inode(parent);
-+	mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
++	inode_lock_nested(dir, AuLsc_I_PARENT);
 +	/* mnt_want_write() is unnecessary here */
 +	err = au_xino_set_xib(sb, xino->file);
 +	if (!err)
 +		err = au_xigen_set(sb, xino->file);
 +	if (!err)
 +		err = au_xino_set_br(sb, xino->file);
-+	mutex_unlock(&dir->i_mutex);
++	inode_unlock(dir);
 +	if (!err)
 +		goto out; /* success */
 +
@@ -35216,7 +35209,7 @@ 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	2016-02-28 11:26:32.576637942 +0100
++++ linux/include/uapi/linux/aufs_type.h	2016-04-24 18:32:51.397020264 +0200
 @@ -0,0 +1,419 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -35259,7 +35252,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +
 +#include <linux/limits.h>
 +
-+#define AUFS_VERSION	"4.4-20160223"
++#define AUFS_VERSION	"4.5-20160328"
 +
 +/* todo? move this to linux-2.6.19/include/magic.h */
 +#define AUFS_SUPER_MAGIC	('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -35637,10 +35630,10 @@ 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.4 loopback patch
+aufs4.5 loopback patch
 
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index abfdd2b..a2e3c43 100644
+index 0b816b2..86dd454 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
 @@ -556,7 +556,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
@@ -35819,7 +35812,7 @@ index fb2237c..c3888c5 100644
  	unsigned	lo_blocksize;
  	void		*key_data; 
 diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
-index 2baacd7..22bcb89 100644
+index ac1304a..0cefd8a 100644
 --- a/fs/aufs/f_op.c
 +++ b/fs/aufs/f_op.c
 @@ -399,7 +399,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
@@ -35881,7 +35874,7 @@ index 48bf070..66afec7 100644
  
  #endif /* __KERNEL__ */
 diff --git a/fs/aufs/super.c b/fs/aufs/super.c
-index b41d789..51d2fb9 100644
+index 7928a50..9466cc9 100644
 --- a/fs/aufs/super.c
 +++ b/fs/aufs/super.c
 @@ -832,7 +832,10 @@ static const struct super_operations aufs_sop = {
@@ -35897,10 +35890,10 @@ index b41d789..51d2fb9 100644
  
  /* ---------------------------------------------------------------------- */
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 8d48506..5246785 100644
+index 99fc2bd..842a2e0 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1719,6 +1719,10 @@ struct super_operations {
+@@ -1759,6 +1759,10 @@ struct super_operations {
  				  struct shrink_control *);
  	long (*free_cached_objects)(struct super_block *,
  				    struct shrink_control *);
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/f9c9dc1aa2d54c91d232a2a301da7843185359ca



More information about the pld-cvs-commit mailing list