[packages/kernel] - updated aufs3 patch to 3.15 branch

baggins baggins at pld-linux.org
Tue Jun 24 01:12:43 CEST 2014


commit 38d290e651dace09d9da8a962d6032042783d2f2
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Tue Jun 24 00:20:03 2014 +0200

    - updated aufs3 patch to 3.15 branch

 kernel-aufs3.patch | 1196 +++++++++++++++++++++++-----------------------------
 kernel.spec        |    2 +-
 2 files changed, 522 insertions(+), 676 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 0cf9d6a..0230d17 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -207,7 +207,7 @@ Patch118:	ovl09-fs-limit-filesystem-stacking-depth.patch
 # Patch creation:
 # git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git
 # cd aufs3-standalone
-# git checkout -b aufs3.14 origin/aufs3.14
+# git checkout -b aufs3.15 origin/aufs3.15
 # cat aufs3-kbuild.patch aufs3-base.patch aufs3-mmap.patch aufs3-standalone.patch > ~/rpm/packages/kernel/kernel-aufs3.patch
 # mkdir linux
 # cp -a Documentation fs include linux
diff --git a/kernel-aufs3.patch b/kernel-aufs3.patch
index 1295576..0a5f5a3 100644
--- a/kernel-aufs3.patch
+++ b/kernel-aufs3.patch
@@ -1,10 +1,10 @@
-aufs3.14 kbuild patch
+aufs3.15 kbuild patch
 
 diff --git a/fs/Kconfig b/fs/Kconfig
-index 7385e54..d5c769c 100644
+index 312393f..78632ed 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -208,6 +208,7 @@ source "fs/ufs/Kconfig"
+@@ -209,6 +209,7 @@ source "fs/ufs/Kconfig"
  source "fs/exofs/Kconfig"
  source "fs/f2fs/Kconfig"
  source "fs/efivarfs/Kconfig"
@@ -13,16 +13,16 @@ index 7385e54..d5c769c 100644
  endif # MISC_FILESYSTEMS
  
 diff --git a/fs/Makefile b/fs/Makefile
-index 47ac07b..0c6a294 100644
+index f9cb987..a0c580f 100644
 --- a/fs/Makefile
 +++ b/fs/Makefile
-@@ -125,3 +125,4 @@ obj-y				+= exofs/ # Multiple modules
+@@ -126,3 +126,4 @@ obj-y				+= exofs/ # Multiple modules
  obj-$(CONFIG_CEPH_FS)		+= ceph/
  obj-$(CONFIG_PSTORE)		+= pstore/
  obj-$(CONFIG_EFIVAR_FS)		+= efivarfs/
 +obj-$(CONFIG_AUFS_FS)           += aufs/
 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index 3ce25b5..9faebdc 100644
+index 6929571..351ca48 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
 @@ -56,6 +56,7 @@ header-y += atmppp.h
@@ -33,10 +33,10 @@ index 3ce25b5..9faebdc 100644
  header-y += auto_fs.h
  header-y += auto_fs4.h
  header-y += auxvec.h
-aufs3.14 base patch
+aufs3.15 base patch
 
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index 66e8c3b..ec278ac 100644
+index f70a230..138104b 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
 @@ -692,6 +692,24 @@ static inline int is_loop_device(struct file *file)
@@ -65,10 +65,10 @@ index 66e8c3b..ec278ac 100644
  
  static ssize_t loop_attr_show(struct device *dev, char *page,
 diff --git a/fs/inode.c b/fs/inode.c
-index 4bcdad3..bc83168 100644
+index f96d2a6..2d72083 100644
 --- a/fs/inode.c
 +++ b/fs/inode.c
-@@ -1497,7 +1497,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
+@@ -1496,7 +1496,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
   * This does the actual work of updating an inodes time or version.  Must have
   * had called mnt_want_write() before calling this.
   */
@@ -78,10 +78,10 @@ index 4bcdad3..bc83168 100644
  	if (inode->i_op->update_time)
  		return inode->i_op->update_time(inode, time, flags);
 diff --git a/fs/splice.c b/fs/splice.c
-index 12028fa..f26cbaf 100644
+index e246954..4797013 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1111,8 +1111,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1103,8 +1103,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -92,7 +92,7 @@ index 12028fa..f26cbaf 100644
  {
  	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  				loff_t *, size_t, unsigned int);
-@@ -1128,9 +1128,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1120,9 +1120,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.
   */
@@ -106,10 +106,10 @@ index 12028fa..f26cbaf 100644
  	ssize_t (*splice_read)(struct file *, loff_t *,
  			       struct pipe_inode_info *, size_t, unsigned int);
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 23b2a35..f3f635c 100644
+index 8780312..3ff3e89 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -2669,6 +2669,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
+@@ -2606,6 +2606,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
  extern int inode_newsize_ok(const struct inode *, loff_t offset);
  extern void setattr_copy(struct inode *inode, const struct iattr *attr);
  
@@ -132,10 +132,10 @@ index 0e43906..304169e 100644
 +			 struct pipe_inode_info *pipe, size_t len,
 +			 unsigned int flags);
  #endif
-aufs3.14 mmap patch
+aufs3.15 mmap patch
 
 diff --git a/fs/buffer.c b/fs/buffer.c
-index 27265a8..75427a6 100644
+index 9ddb9fc..1059a0b 100644
 --- a/fs/buffer.c
 +++ b/fs/buffer.c
 @@ -2448,7 +2448,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
@@ -163,10 +163,10 @@ index d4a3574..e44a744 100644
  		ino = inode->i_ino;
  	}
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index fb52b54..1aca72e 100644
+index c4b2646..dc3c0dc 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
-@@ -264,7 +264,9 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+@@ -265,7 +265,9 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
  	const char *name = NULL;
  
  	if (file) {
@@ -177,7 +177,7 @@ index fb52b54..1aca72e 100644
  		dev = inode->i_sb->s_dev;
  		ino = inode->i_ino;
  		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1407,6 +1409,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+@@ -1408,6 +1410,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
  	seq_printf(m, "%08lx %s", vma->vm_start, buffer);
  
  	if (file) {
@@ -201,7 +201,7 @@ index 678455d..ad0ce45 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 c1b7414..02036e0 100644
+index d677706..192e7ac4 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
 @@ -18,6 +18,9 @@
@@ -214,7 +214,7 @@ index c1b7414..02036e0 100644
  
  struct mempolicy;
  struct anon_vma;
-@@ -1152,6 +1155,87 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1173,6 +1176,87 @@ static inline int fixup_user_fault(struct task_struct *tsk,
  }
  #endif
  
@@ -303,10 +303,10 @@ index c1b7414..02036e0 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 290901a..c21588b 100644
+index 8967e20..a57b589 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -231,6 +231,7 @@ struct vm_region {
+@@ -232,6 +232,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 */
@@ -314,7 +314,7 @@ index 290901a..c21588b 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
-@@ -299,6 +300,7 @@ struct vm_area_struct {
+@@ -300,6 +301,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). */
@@ -323,10 +323,10 @@ index 290901a..c21588b 100644
  
  #ifndef CONFIG_MMU
 diff --git a/kernel/fork.c b/kernel/fork.c
-index a17621c..40d9f6a 100644
+index 54a8d26..dcf08b6 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -412,7 +412,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -416,7 +416,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;
  
@@ -336,10 +336,10 @@ index a17621c..40d9f6a 100644
  				atomic_dec(&inode->i_writecount);
  			mutex_lock(&mapping->i_mmap_mutex);
 diff --git a/mm/filemap.c b/mm/filemap.c
-index 7a13f6a..f1805df 100644
+index 088358c..138a88c 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
-@@ -1733,7 +1733,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+@@ -2091,7 +2091,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);
@@ -349,21 +349,41 @@ index 7a13f6a..f1805df 100644
  	if (page->mapping != inode->i_mapping) {
  		unlock_page(page);
 diff --git a/mm/fremap.c b/mm/fremap.c
-index 34feba6..d857364 100644
+index 34feba6..8d6c451 100644
 --- a/mm/fremap.c
 +++ b/mm/fremap.c
-@@ -227,7 +227,9 @@ get_write_lock:
+@@ -223,16 +223,27 @@ get_write_lock:
+ 		 */
+ 		if (mapping_cap_account_dirty(mapping)) {
+ 			unsigned long addr;
+-			struct file *file = get_file(vma->vm_file);
++			struct file *file = vma->vm_file,
++				*prfile = vma->vm_prfile;
++
  			/* mmap_region may free vma; grab the info now */
  			vm_flags = vma->vm_flags;
  
 +			vma_get_file(vma);
  			addr = mmap_region(file, start, size, vm_flags, pgoff);
+-			fput(file);
 +			vma_fput(vma);
- 			fput(file);
  			if (IS_ERR_VALUE(addr)) {
  				err = addr;
+ 			} else {
+ 				BUG_ON(addr != start);
++				if (prfile) {
++					struct vm_area_struct *new_vma;
++					new_vma = find_vma(mm, addr);
++					if (!new_vma->vm_prfile)
++						new_vma->vm_prfile = prfile;
++					if (new_vma != vma)
++						get_file(prfile);
++				}
+ 				err = 0;
+ 			}
+ 			goto out_freed;
 diff --git a/mm/madvise.c b/mm/madvise.c
-index 539eeb9..5e700b1 100644
+index a402f8f..134e15d 100644
 --- a/mm/madvise.c
 +++ b/mm/madvise.c
 @@ -327,12 +327,12 @@ static long madvise_remove(struct vm_area_struct *vma,
@@ -382,11 +402,11 @@ index 539eeb9..5e700b1 100644
  	return error;
  }
 diff --git a/mm/memory.c b/mm/memory.c
-index 22dfa61..81813d9 100644
+index 037b812..6e7d241 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -2755,7 +2755,7 @@ reuse:
- 			set_page_dirty_balance(dirty_page, page_mkwrite);
+@@ -2805,7 +2805,7 @@ reuse:
+ 			set_page_dirty_balance(dirty_page);
  			/* file_update_time outside page_lock */
  			if (vma->vm_file)
 -				file_update_time(vma->vm_file);
@@ -394,20 +414,11 @@ index 22dfa61..81813d9 100644
  		}
  		put_page(dirty_page);
  		if (page_mkwrite) {
-@@ -3467,7 +3467,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
- 
- 		/* file_update_time outside page_lock */
- 		if (vma->vm_file && !page_mkwrite)
--			file_update_time(vma->vm_file);
-+			vma_file_update_time(vma);
- 	} else {
- 		unlock_page(vmf.page);
- 		if (anon)
 diff --git a/mm/mmap.c b/mm/mmap.c
-index 20ff0c3..f743033 100644
+index b1202cf..40dd067 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
-@@ -249,7 +249,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+@@ -250,7 +250,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
  	if (vma->vm_ops && vma->vm_ops->close)
  		vma->vm_ops->close(vma);
  	if (vma->vm_file)
@@ -416,7 +427,7 @@ index 20ff0c3..f743033 100644
  	mpol_put(vma_policy(vma));
  	kmem_cache_free(vm_area_cachep, vma);
  	return next;
-@@ -859,7 +859,7 @@ again:			remove_next = 1 + (end > next->vm_end);
+@@ -861,7 +861,7 @@ again:			remove_next = 1 + (end > next->vm_end);
  	if (remove_next) {
  		if (file) {
  			uprobe_munmap(next, next->vm_start, next->vm_end);
@@ -425,7 +436,7 @@ index 20ff0c3..f743033 100644
  		}
  		if (next->anon_vma)
  			anon_vma_merge(vma, next);
-@@ -1639,8 +1639,8 @@ out:
+@@ -1641,8 +1641,8 @@ out:
  unmap_and_free_vma:
  	if (vm_flags & VM_DENYWRITE)
  		allow_write_access(file);
@@ -435,7 +446,7 @@ index 20ff0c3..f743033 100644
  
  	/* Undo any partial mapping done by a device driver. */
  	unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
-@@ -2429,7 +2429,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2432,7 +2432,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
  		goto out_free_mpol;
  
  	if (new->vm_file)
@@ -444,7 +455,7 @@ index 20ff0c3..f743033 100644
  
  	if (new->vm_ops && new->vm_ops->open)
  		new->vm_ops->open(new);
-@@ -2448,7 +2448,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2451,7 +2451,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)
@@ -453,7 +464,7 @@ index 20ff0c3..f743033 100644
  	unlink_anon_vmas(new);
   out_free_mpol:
  	mpol_put(vma_policy(new));
-@@ -2837,7 +2837,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2840,7 +2840,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)
@@ -480,10 +491,10 @@ index 632df45..02d770e 100644
  				goto out;
  			down_read(&mm->mmap_sem);
 diff --git a/mm/nommu.c b/mm/nommu.c
-index 8740213..ea7e336 100644
+index 85f8d66..9f471fa 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
-@@ -653,7 +653,7 @@ static void __put_nommu_region(struct vm_region *region)
+@@ -655,7 +655,7 @@ static void __put_nommu_region(struct vm_region *region)
  		up_write(&nommu_region_sem);
  
  		if (region->vm_file)
@@ -492,7 +503,7 @@ index 8740213..ea7e336 100644
  
  		/* IO memory and memory shared directly out of the pagecache
  		 * from ramfs/tmpfs mustn't be released here */
-@@ -811,7 +811,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -820,7 +820,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
  	if (vma->vm_ops && vma->vm_ops->close)
  		vma->vm_ops->close(vma);
  	if (vma->vm_file)
@@ -501,7 +512,7 @@ index 8740213..ea7e336 100644
  	put_nommu_region(vma->vm_region);
  	kmem_cache_free(vm_area_cachep, vma);
  }
-@@ -1377,7 +1377,7 @@ unsigned long do_mmap_pgoff(struct file *file,
+@@ -1382,7 +1382,7 @@ unsigned long do_mmap_pgoff(struct file *file,
  					goto error_just_free;
  				}
  			}
@@ -510,7 +521,7 @@ index 8740213..ea7e336 100644
  			kmem_cache_free(vm_region_jar, region);
  			region = pregion;
  			result = start;
-@@ -1453,10 +1453,10 @@ error_just_free:
+@@ -1458,10 +1458,10 @@ error_just_free:
  	up_write(&nommu_region_sem);
  error:
  	if (region->vm_file)
@@ -523,10 +534,10 @@ index 8740213..ea7e336 100644
  	kmem_cache_free(vm_area_cachep, vma);
  	kleave(" = %d", ret);
  	return ret;
-aufs3.14 standalone patch
+aufs3.15 standalone patch
 
 diff --git a/fs/inode.c b/fs/inode.c
-index bc83168..6dd1207 100644
+index 2d72083..30b69da 100644
 --- a/fs/inode.c
 +++ b/fs/inode.c
 @@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
@@ -537,7 +548,7 @@ index bc83168..6dd1207 100644
  
  /*
   * Empty aops. Can be used for the cases where the user does not
-@@ -1513,6 +1514,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
+@@ -1512,6 +1513,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
  	mark_inode_dirty_sync(inode);
  	return 0;
  }
@@ -546,10 +557,10 @@ index bc83168..6dd1207 100644
  /**
   *	touch_atime	-	update the access time
 diff --git a/fs/namespace.c b/fs/namespace.c
-index 2ffc5a2..785a51f 100644
+index 182bc41..c88e101 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
-@@ -455,6 +455,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
+@@ -453,6 +453,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
  	mnt_dec_writers(real_mount(mnt));
  	preempt_enable();
  }
@@ -557,7 +568,7 @@ index 2ffc5a2..785a51f 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1555,6 +1556,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -1564,6 +1565,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
  	}
  	return 0;
  }
@@ -638,7 +649,7 @@ index 923fe4a..176b435 100644
  static int fsnotify_mark_destroy(void *ignored)
  {
 diff --git a/fs/open.c b/fs/open.c
-index b9ed8b2..3ea66972 100644
+index 9d64679..1aa876a 100644
 --- a/fs/open.c
 +++ b/fs/open.c
 @@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
@@ -649,11 +660,19 @@ index b9ed8b2..3ea66972 100644
  
  long vfs_truncate(struct path *path, loff_t length)
  {
+@@ -299,6 +300,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
+ 	sb_end_write(inode->i_sb);
+ 	return ret;
+ }
++EXPORT_SYMBOL(do_fallocate);
+ 
+ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
+ {
 diff --git a/fs/splice.c b/fs/splice.c
-index f26cbaf..ac02366 100644
+index 4797013..44b603a 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1124,6 +1124,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1116,6 +1116,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
  	return splice_write(pipe, out, ppos, len, flags);
  }
@@ -661,7 +680,7 @@ index f26cbaf..ac02366 100644
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
-@@ -1150,6 +1151,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1142,6 +1143,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
  
  	return splice_read(in, ppos, pipe, len, flags);
  }
@@ -686,7 +705,7 @@ index b9d613e..ba3b618 100644
  }
 +EXPORT_SYMBOL(cap_mmap_file);
 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
-index d3b6d2c..5076912 100644
+index 9134dbf..4d4217a 100644
 --- a/security/device_cgroup.c
 +++ b/security/device_cgroup.c
 @@ -7,6 +7,7 @@
@@ -697,7 +716,7 @@ index d3b6d2c..5076912 100644
  #include <linux/list.h>
  #include <linux/uaccess.h>
  #include <linux/seq_file.h>
-@@ -744,6 +745,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
+@@ -856,6 +857,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
  	return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
  			access);
  }
@@ -706,7 +725,7 @@ index d3b6d2c..5076912 100644
  int devcgroup_inode_mknod(int mode, dev_t dev)
  {
 diff --git a/security/security.c b/security/security.c
-index 919cad9..f9e9e17 100644
+index 8b774f3..e3190b9 100644
 --- a/security/security.c
 +++ b/security/security.c
 @@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
@@ -732,8 +751,8 @@ index 919cad9..f9e9e17 100644
 +EXPORT_SYMBOL(security_path_link);
  
  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
- 			 struct path *new_dir, struct dentry *new_dentry)
-@@ -449,6 +452,7 @@ int security_path_truncate(struct path *path)
+ 			 struct path *new_dir, struct dentry *new_dentry,
+@@ -458,6 +461,7 @@ int security_path_truncate(struct path *path)
  		return 0;
  	return security_ops->path_truncate(path);
  }
@@ -741,7 +760,7 @@ index 919cad9..f9e9e17 100644
  
  int security_path_chmod(struct path *path, umode_t mode)
  {
-@@ -456,6 +460,7 @@ int security_path_chmod(struct path *path, umode_t mode)
+@@ -465,6 +469,7 @@ int security_path_chmod(struct path *path, umode_t mode)
  		return 0;
  	return security_ops->path_chmod(path, mode);
  }
@@ -749,7 +768,7 @@ index 919cad9..f9e9e17 100644
  
  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
  {
-@@ -463,6 +468,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
+@@ -472,6 +477,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
  		return 0;
  	return security_ops->path_chown(path, uid, gid);
  }
@@ -757,7 +776,7 @@ index 919cad9..f9e9e17 100644
  
  int security_path_chroot(struct path *path)
  {
-@@ -539,6 +545,7 @@ int security_inode_readlink(struct dentry *dentry)
+@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentry *dentry)
  		return 0;
  	return security_ops->inode_readlink(dentry);
  }
@@ -765,7 +784,7 @@ index 919cad9..f9e9e17 100644
  
  int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  {
-@@ -553,6 +560,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -571,6 +578,7 @@ int security_inode_permission(struct inode *inode, int mask)
  		return 0;
  	return security_ops->inode_permission(inode, mask);
  }
@@ -773,7 +792,7 @@ index 919cad9..f9e9e17 100644
  
  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  {
-@@ -675,6 +683,7 @@ int security_file_permission(struct file *file, int mask)
+@@ -693,6 +701,7 @@ int security_file_permission(struct file *file, int mask)
  
  	return fsnotify_perm(file, mask);
  }
@@ -781,7 +800,7 @@ index 919cad9..f9e9e17 100644
  
  int security_file_alloc(struct file *file)
  {
-@@ -735,6 +744,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
+@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
  		return ret;
  	return ima_file_mmap(file, prot);
  }
@@ -791,7 +810,7 @@ index 919cad9..f9e9e17 100644
  {
 diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
 --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs	1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/ABI/testing/debugfs-aufs	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/ABI/testing/debugfs-aufs	2014-06-24 00:14:06.769385243 +0200
 @@ -0,0 +1,50 @@
 +What:		/debug/aufs/si_<id>/
 +Date:		March 2009
@@ -845,7 +864,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/ABI/testing/sysfs-aufs	2014-06-24 00:14:06.769385243 +0200
 @@ -0,0 +1,31 @@
 +What:		/sys/fs/aufs/si_<id>/
 +Date:		March 2009
@@ -880,7 +899,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/01intro.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,161 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1045,7 +1064,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/02struct.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,242 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1291,7 +1310,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/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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/03lookup.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,105 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1400,7 +1419,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/04branch.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,75 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1479,7 +1498,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,64 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1547,7 +1566,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx
 +  copyup policy.
 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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/06mmap.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,46 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1597,7 +1616,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu
 +switching the approach.
 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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/07export.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,58 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1659,7 +1678,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/08shwh.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,52 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1715,7 +1734,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	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/10dynop.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,46 @@
 +
 +# Copyright (C) 2010-2014 Junjiro R. Okajima
@@ -1765,7 +1784,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin
 +vm_operations_struct for regular files only.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt	1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/99plan.txt	2014-04-24 22:11:10.471931783 +0200
++++ linux/Documentation/filesystems/aufs/design/99plan.txt	2014-06-24 00:14:06.772718759 +0200
 @@ -0,0 +1,95 @@
 +
 +# Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -1864,8 +1883,8 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linu
 +Otherwise from /new.
 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	2014-04-24 22:11:10.471931783 +0200
-@@ -0,0 +1,344 @@
++++ linux/Documentation/filesystems/aufs/README	2014-06-24 00:14:06.769385243 +0200
+@@ -0,0 +1,368 @@
 +
 +Aufs3 -- advanced multi layered unification filesystem version 3.x
 +http://aufs.sf.net
@@ -1888,10 +1907,16 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
 +
 +Note: it becomes clear that "Aufs was rejected. Let's give it up."
-+According to Christoph Hellwig, linux rejects all union-type filesystems
-+but UnionMount.
++      According to Christoph Hellwig, linux rejects all union-type
++      filesystems but UnionMount.
 +<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
 +
++PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
++    UnionMount, and he pointed out an issue around a directory mutex
++    lock and aufs addressed it. But it is still unsure whether aufs will
++    be merged (or any other union solution).
++<http://lkml.org/lkml/2013/3/12/637>
++
 +
 +1. Features
 +----------------------------------------
@@ -2096,6 +2121,23 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +  then run "make install_ulib" too. And refer to the aufs manual in
 +  detail.
 +
++There several other patches in aufs3-standalone.git. They are all
++optional. When you meet some problems, they will help you.
++- aufs3-loopback.patch
++  Supports a nested loopback mount in a branch-fs. This patch is
++  unnecessary until aufs produces a message like "you may want to try
++  another patch for loopback file".
++- vfs-ino.patch
++  Modifies a system global kernel internal function get_next_ino() in
++  order to stop assigning 0 for an inode-number. Not directly related to
++  aufs, but recommended generally.
++- tmpfs-idr.patch
++  Keeps the tmpfs inode number as the lowest value. Effective to reduce
++  the size of aufs XINO files for tmpfs branch. Also it prevents the
++  duplication of inode number, which is important for backup tools and
++  other utilities. When you find aufs XINO files for tmpfs branch
++  growing too much, try this patch.
++
 +
 +4. Usage
 +----------------------------------------
@@ -2193,6 +2235,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +"pemasu from Finland" made a donation (2013/7).
 +The Parted Magic Project made a donation (2013/9 and 11).
 +Pavel Barta made a donation (2013/10).
++Nikolay Pertsev made a donation (2014/5).
 +
 +Thank you very much.
 +Donations are always, including future donations, very important and
@@ -2212,7 +2255,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/aufs.h	2014-06-24 00:14:06.776052275 +0200
 @@ -0,0 +1,59 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -2275,8 +2318,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,1219 @@
++++ linux/fs/aufs/branch.c	2014-06-24 00:14:06.776052275 +0200
+@@ -0,0 +1,1220 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -3328,7 +3371,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	unsigned int mnt_flags;
 +	unsigned long long ull, max;
 +	aufs_bindex_t br_id;
-+	unsigned char verbose;
++	unsigned char verbose, writer;
 +	struct file *file, *hf, **array;
 +	struct inode *inode;
 +	struct au_hfile *hfile;
@@ -3397,11 +3440,12 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +		hf = hfile->hf_file;
 +		/* fi_read_unlock(file); */
 +		spin_lock(&hf->f_lock);
-+		hf->f_mode &= ~FMODE_WRITE;
++		writer = !!(hf->f_mode & FMODE_WRITER);
++		hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
 +		spin_unlock(&hf->f_lock);
-+		if (!file_check_writeable(hf)) {
++		if (writer) {
++			put_write_access(file_inode(hf));
 +			__mnt_drop_write(hf->f_path.mnt);
-+			file_release_write(hf);
 +		}
 +	}
 +
@@ -3498,7 +3542,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/branch.h	2014-06-24 00:14:06.776052275 +0200
 @@ -0,0 +1,264 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -3766,8 +3810,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,37 @@
++++ linux/fs/aufs/conf.mk	2014-06-24 00:14:06.776052275 +0200
+@@ -0,0 +1,36 @@
 +
 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
 +
@@ -3782,7 +3826,6 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 +	HNOTIFY HFSNOTIFY \
 +	EXPORT INO_T_64 \
 +	RDU \
-+	SP_IATTR \
 +	SHWH \
 +	BR_RAMFS \
 +	BR_FUSE POLL \
@@ -3807,8 +3850,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,1277 @@
++++ linux/fs/aufs/cpup.c	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,1289 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -3872,8 +3915,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +
 +	/*
 +	 * 0 can happen in revalidating.
-+	 * h_inode->i_mutex is not held, but it is harmless since once i_nlink
-+	 * reaches 0, it will never become positive.
++	 * h_inode->i_mutex may not be held here, but it is harmless since once
++	 * i_nlink reaches 0, it will never become positive except O_TMPFILE
++	 * case.
++	 * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
++	 *	 the incorrect link count.
 +	 */
 +	set_nlink(inode, h_inode->i_nlink);
 +
@@ -4223,7 +4269,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	int err, rerr;
 +	loff_t l;
 +	struct path h_path;
-+	struct inode *h_src_inode;
++	struct inode *h_src_inode, *h_dst_inode;
 +
 +	err = 0;
 +	h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
@@ -4250,6 +4296,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		if (!err && rerr)
 +			err = rerr;
 +	}
++	if (!err && (h_src_inode->i_state & I_LINKABLE)) {
++		h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
++		h_dst_inode = h_path.dentry->d_inode;
++		spin_lock(&h_dst_inode->i_lock);
++		h_dst_inode->i_state |= I_LINKABLE;
++		spin_unlock(&h_dst_inode->i_lock);
++	}
 +
 +out:
 +	return err;
@@ -4372,7 +4425,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +	if (!au_opt_test(mnt_flags, UDBA_NONE)
 +	    && !isdir
 +	    && au_opt_test(mnt_flags, XINO)
-+	    && h_inode->i_nlink == 1
++	    && (h_inode->i_nlink == 1
++		|| (h_inode->i_state & I_LINKABLE))
 +	    /* todo: unnecessary? */
 +	    /* && cpg->dentry->d_inode->i_nlink == 1 */
 +	    && cpg->bdst < cpg->bsrc
@@ -4564,7 +4618,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		goto out_rev;
 +
 +	if (!isdir
-+	    && h_src->d_inode->i_nlink > 1
++	    && (h_src->d_inode->i_nlink > 1
++		|| h_src->d_inode->i_state & I_LINKABLE)
 +	    && plink)
 +		au_plink_append(inode, cpg->bdst, h_dst);
 +
@@ -5088,7 +5143,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/cpup.h	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,94 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -5186,7 +5241,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/dbgaufs.c	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,432 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -5622,7 +5677,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/dbgaufs.h	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,48 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -5674,7 +5729,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/dcsub.c	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,243 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -5921,8 +5976,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,98 @@
++++ linux/fs/aufs/dcsub.h	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,116 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -5995,6 +6050,18 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +	return err;
 +}
 +
++static inline int au_d_linkable(struct dentry *d)
++{
++	int err;
++	struct inode *inode = d->d_inode;
++	err = au_d_hashed_positive(d);
++	if (err
++	    && inode
++	    && (inode->i_state & I_LINKABLE))
++		err = 0;
++	return err;
++}
++
 +static inline int au_d_alive(struct dentry *d)
 +{
 +	int err;
@@ -6019,12 +6086,18 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +	return err;
 +}
 +
++static inline int au_qstreq(struct qstr *a, struct qstr *b)
++{
++	return a->len == b->len
++		&& !memcmp(a->name, b->name, a->len);
++}
++
 +#endif /* __KERNEL__ */
 +#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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,517 @@
++++ linux/fs/aufs/debug.c	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,518 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -6242,9 +6315,10 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +	dinfo = au_di(dentry);
 +	if (!dinfo)
 +		return;
-+	dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
++	dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
 +	     dinfo->di_bstart, dinfo->di_bend,
-+	     dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
++	     dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
++	     dinfo->di_tmpfile);
 +	if (dinfo->di_bstart < 0)
 +		return;
 +	hdp = dinfo->di_hdentry;
@@ -6544,7 +6618,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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/debug.h	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,247 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -6795,8 +6869,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,1081 @@
++++ linux/fs/aufs/dentry.c	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,1084 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -7508,7 +7582,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	if (!ebrange)
 +		ebrange = au_do_refresh_hdentry(dentry, parent);
 +
-+	if (d_unhashed(dentry) || ebrange) {
++	if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
 +		AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
 +		if (inode)
 +			err = au_refresh_hinode_self(inode);
@@ -7594,7 +7668,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	int err;
 +	umode_t mode, h_mode;
 +	aufs_bindex_t bindex, btail, bstart, ibs, ibe;
-+	unsigned char plus, unhashed, is_root, h_plus, h_nfs;
++	unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
 +	struct inode *h_inode, *h_cached_inode;
 +	struct dentry *h_dentry;
 +	struct qstr *name, *h_name;
@@ -7607,13 +7681,13 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	unhashed = !!d_unhashed(dentry);
 +	is_root = !!IS_ROOT(dentry);
 +	name = &dentry->d_name;
++	tmpfile = au_di(dentry)->di_tmpfile;
 +
 +	/*
 +	 * Theoretically, REVAL test should be unnecessary in case of
 +	 * {FS,I}NOTIFY.
 +	 * But {fs,i}notify doesn't fire some necessary events,
 +	 *	IN_ATTRIB for atime/nlink/pageio
-+	 *	IN_DELETE for NFS dentry
 +	 * Let's do REVAL test too.
 +	 */
 +	if (do_udba && inode) {
@@ -7640,18 +7714,20 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +			     && !is_root
 +			     && ((!h_nfs
 +				  && (unhashed != !!d_unhashed(h_dentry)
-+				      || name->len != h_name->len
-+				      || memcmp(name->name, h_name->name,
-+						name->len)))
++				      || (!tmpfile
++					  && !au_qstreq(name, h_name))
++					  ))
 +				 || (h_nfs
 +				     && !(flags & LOOKUP_OPEN)
 +				     && (h_dentry->d_flags
 +					 & DCACHE_NFSFS_RENAMED)))
 +			    )) {
-+			AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
-+			      unhashed, d_unhashed(h_dentry),
-+			      dentry, h_dentry);
++			int h_unhashed;
++
++			h_unhashed = d_unhashed(h_dentry);
 +			spin_unlock(&h_dentry->d_lock);
++			AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
++			      unhashed, h_unhashed, dentry, h_dentry);
 +			goto err;
 +		}
 +		spin_unlock(&h_dentry->d_lock);
@@ -7681,7 +7757,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +			h_cached_inode = au_h_iptr(inode, bindex);
 +
 +		if (!h_nfs) {
-+			if (unlikely(plus != h_plus))
++			if (unlikely(plus != h_plus && !tmpfile))
 +				goto err;
 +		} else {
 +			if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
@@ -7828,6 +7904,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	err = -EINVAL;
 +	if (!(flags & LOOKUP_OPEN)
 +	    && inode
++	    && !(inode->i_state && I_LINKABLE)
 +	    && (IS_DEADDIR(inode) || !inode->i_nlink))
 +		goto out_inval;
 +
@@ -7880,8 +7957,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,233 @@
++++ linux/fs/aufs/dentry.h	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,234 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -7921,6 +7998,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 +
 +	struct au_rwsem		di_rwsem;
 +	aufs_bindex_t		di_bstart, di_bend, di_bwh, di_bdiropq;
++	unsigned char		di_tmpfile; /* to allow the different name */
 +	struct au_hdentry	*di_hdentry;
 +} ____cacheline_aligned_in_smp;
 +
@@ -8117,8 +8195,8 @@ 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	2014-04-24 22:11:10.848602379 +0200
-@@ -0,0 +1,542 @@
++++ linux/fs/aufs/dinfo.c	2014-06-24 00:14:06.779385790 +0200
+@@ -0,0 +1,544 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -8170,6 +8248,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +		dinfo->di_bend = -1;
 +		dinfo->di_bwh = -1;
 +		dinfo->di_bdiropq = -1;
++		dinfo->di_tmpfile = 0;
 +		for (i = 0; i < nbr; i++)
 +			dinfo->di_hdentry[i].hd_id = -1;
 +		goto out;
@@ -8444,7 +8523,8 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +
 +/*
 + * extended version of au_h_dptr().
-+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
++ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
++ * error.
 + */
 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
 +{
@@ -8458,7 +8538,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +	if (au_dbstart(dentry) <= bindex
 +	    && bindex <= au_dbend(dentry))
 +		h_dentry = au_h_dptr(dentry, bindex);
-+	if (h_dentry && !au_d_hashed_positive(h_dentry)) {
++	if (h_dentry && !au_d_linkable(h_dentry)) {
 +		dget(h_dentry);
 +		goto out; /* success */
 +	}
@@ -8469,7 +8549,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +	h_dentry = d_find_alias(h_inode);
 +	if (h_dentry) {
 +		if (!IS_ERR(h_dentry)) {
-+			if (!au_d_hashed_positive(h_dentry))
++			if (!au_d_linkable(h_dentry))
 +				goto out; /* success */
 +			dput(h_dentry);
 +		} else
@@ -8663,7 +8743,7 @@ 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	2014-04-24 22:11:10.848602379 +0200
++++ linux/fs/aufs/dir.c	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,639 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -9306,7 +9386,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/dir.h	2014-06-24 00:14:06.779385790 +0200
 @@ -0,0 +1,136 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -9446,7 +9526,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/dynop.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,379 @@
 +/*
 + * Copyright (C) 2010-2014 Junjiro R. Okajima
@@ -9829,7 +9909,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/dynop.h	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,75 @@
 +/*
 + * Copyright (C) 2010-2014 Junjiro R. Okajima
@@ -9908,7 +9988,7 @@ 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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/export.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,831 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -10743,8 +10823,8 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,724 @@
++++ linux/fs/aufs/file.c	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,711 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -10835,18 +10915,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +	atomic_inc(&br->br_count);
 +	h_path.dentry = h_dentry;
 +	h_path.mnt = au_br_mnt(br);
-+	if (!au_special_file(h_inode->i_mode))
-+		h_file = vfsub_dentry_open(&h_path, flags);
-+	else {
-+		/* this block depends upon the configuration */
-+		di_read_unlock(dentry, AuLock_IR);
-+		fi_write_unlock(file);
-+		si_read_unlock(sb);
-+		h_file = vfsub_dentry_open(&h_path, flags);
-+		si_noflush_read_lock(sb);
-+		fi_write_lock(file);
-+		di_read_lock_child(dentry, AuLock_IR);
-+	}
++	h_file = vfsub_dentry_open(&h_path, flags);
 +	if (IS_ERR(h_file))
 +		goto out_br;
 +
@@ -10900,7 +10969,6 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +	struct file *h_file, *h_file_tmp;
 +
 +	dentry = file->f_dentry;
-+	AuDebugOn(au_special_file(dentry->d_inode->i_mode));
 +	bstart = au_dbstart(dentry);
 +	h_file_tmp = NULL;
 +	if (au_fbstart(file) == bstart) {
@@ -11006,7 +11074,8 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +		err = au_reopen_wh(file, bcpup, hi_wh);
 +
 +	if (!err
-+	    && inode->i_nlink > 1
++	    && (inode->i_nlink > 1
++		|| (inode->i_state & I_LINKABLE))
 +	    && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
 +		au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
 +
@@ -11035,7 +11104,6 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +
 +	sb = cpg.dentry->d_sb;
 +	inode = cpg.dentry->d_inode;
-+	AuDebugOn(au_special_file(inode->i_mode));
 +	cpg.bsrc = au_fbstart(file);
 +	err = au_test_ro(sb, cpg.bsrc, inode);
 +	if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
@@ -11343,7 +11411,6 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +	err = 0;
 +	dentry = file->f_dentry;
 +	inode = dentry->d_inode;
-+	AuDebugOn(au_special_file(inode->i_mode));
 +	sigen = au_sigen(dentry->d_sb);
 +	fi_write_lock(file);
 +	figen = au_figen(file);
@@ -11430,8 +11497,8 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +static int aufs_launder_page(struct page *page)
 +{ AuUnsupport(); return 0; }
 +static int aufs_is_partially_uptodate(struct page *page,
-+				      read_descriptor_t *desc,
-+				      unsigned long from)
++				      unsigned long from,
++				      unsigned long count)
 +{ AuUnsupport(); return 0; }
 +static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
 +				    bool *writeback)
@@ -11471,8 +11538,8 @@ 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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,312 @@
++++ linux/fs/aufs/file.h	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,289 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -11586,24 +11653,6 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +int au_do_open_nondir(struct file *file, int flags);
 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
 +
-+#ifdef CONFIG_AUFS_SP_IATTR
-+/* f_op_sp.c */
-+struct au_finfo *au_fi_sp(struct file *file);
-+int au_special_file(umode_t mode);
-+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
-+#else
-+static inline struct au_finfo *au_fi_sp(struct file *file)
-+{
-+	return NULL;
-+}
-+AuStubInt0(au_special_file, umode_t mode)
-+static inline void au_init_special_fop(struct inode *inode, umode_t mode,
-+				       dev_t rdev)
-+{
-+	init_special_inode(inode, mode, rdev);
-+}
-+#endif
-+
 +/* finfo.c */
 +void au_hfput(struct au_hfile *hf, struct file *file);
 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
@@ -11630,12 +11679,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +
 +static inline struct au_finfo *au_fi(struct file *file)
 +{
-+	struct au_finfo *finfo;
-+
-+	finfo = au_fi_sp(file);
-+	if (!finfo)
-+		finfo = file->private_data;
-+	return finfo;
++	return file->private_data;
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -11787,7 +11831,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/finfo.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,156 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -11947,8 +11991,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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,718 @@
++++ linux/fs/aufs/f_op.c	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,782 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -11983,6 +12027,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	struct file *h_file;
 +	struct dentry *dentry;
 +	struct au_finfo *finfo;
++	struct inode *h_inode;
 +
 +	FiMustWriteLock(file);
 +
@@ -11996,6 +12041,13 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	if (IS_ERR(h_file))
 +		err = PTR_ERR(h_file);
 +	else {
++		if ((flags & __O_TMPFILE)
++		    && !(flags & O_EXCL)) {
++			h_inode = file_inode(h_file);
++			spin_lock(&h_inode->i_lock);
++			h_inode->i_state |= I_LINKABLE;
++			spin_unlock(&h_inode->i_lock);
++		}
 +		au_set_fbstart(file, bindex);
 +		au_set_h_fptr(file, bindex, h_file);
 +		au_update_figen(file);
@@ -12370,6 +12422,54 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	return err;
 +}
 +
++static long aufs_fallocate(struct file *file, int mode, loff_t offset,
++			   loff_t len)
++{
++	long err;
++	struct au_pin pin;
++	struct dentry *dentry;
++	struct super_block *sb;
++	struct inode *inode;
++	struct file *h_file;
++
++	dentry = file->f_dentry;
++	sb = dentry->d_sb;
++	inode = dentry->d_inode;
++	au_mtx_and_read_lock(inode);
++
++	err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
++	if (unlikely(err))
++		goto out;
++
++	err = au_ready_to_write(file, -1, &pin);
++	di_downgrade_lock(dentry, AuLock_IR);
++	if (unlikely(err)) {
++		di_read_unlock(dentry, AuLock_IR);
++		fi_write_unlock(file);
++		goto out;
++	}
++
++	h_file = au_hf_top(file);
++	get_file(h_file);
++	au_unpin(&pin);
++	di_read_unlock(dentry, AuLock_IR);
++	fi_write_unlock(file);
++
++	lockdep_off();
++	err = do_fallocate(h_file, mode, offset, len);
++	lockdep_on();
++	ii_write_lock_child(inode);
++	au_cpup_attr_timesizes(inode);
++	inode->i_mode = file_inode(h_file)->i_mode;
++	ii_write_unlock(inode);
++	fput(h_file);
++
++out:
++	si_read_unlock(sb);
++	mutex_unlock(&inode->i_mutex);
++	return err;
++}
++
 +/* ---------------------------------------------------------------------- */
 +
 +/*
@@ -12391,6 +12491,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 + * The similar scenario is applied to aufs_readlink() too.
 + */
 +
++#if 0 /* stop calling security_file_mmap() */
 +/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
 +#define AuConv_VM_PROT(f, b)	_calc_vm_trans(f, VM_##b, PROT_##b)
 +
@@ -12424,6 +12525,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +		| AuConv_VM_MAP(flags, DENYWRITE)
 +		| AuConv_VM_MAP(flags, LOCKED);
 +}
++#endif
 +
 +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
 +{
@@ -12467,8 +12569,13 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	lockdep_on();
 +
 +	au_vm_file_reset(vma, h_file);
-+	err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
-+				 au_flag_conv(vma->vm_flags));
++	/*
++	 * we cannot call security_mmap_file() here since it may acquire
++	 * mmap_sem or i_mutex.
++	 *
++	 * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
++	 *			 au_flag_conv(vma->vm_flags));
++	 */
 +	if (!err)
 +		err = h_file->f_op->mmap(h_file, vma);
 +	if (unlikely(err))
@@ -12664,398 +12771,13 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +	.splice_read	= aufs_splice_read,
 +#if 0
 +	.aio_splice_write = aufs_aio_splice_write,
-+	.aio_splice_read  = aufs_aio_splice_read
++	.aio_splice_read  = aufs_aio_splice_read,
 +#endif
++	.fallocate	= aufs_fallocate
 +};
-diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
---- /usr/share/empty/fs/aufs/f_op_sp.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/f_op_sp.c	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,382 @@
-+/*
-+ * Copyright (C) 2005-2014 Junjiro R. Okajima
-+ *
-+ * This program, aufs is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+/*
-+ * file operations for special files.
-+ * while they exist in aufs virtually,
-+ * their file I/O is handled out of aufs.
-+ */
-+
-+#include <linux/aio.h>
-+#include "aufs.h"
-+
-+/*
-+ * I don't think the size of this list grows much.
-+ * so here is a very simple list implemented in order to find finfo matching a
-+ * given file.
-+ */
-+static struct au_sphlhead au_finfo_sp = {
-+	.spin	= __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
-+	.head	= HLIST_HEAD_INIT
-+};
-+
-+struct au_finfo_sp {
-+	struct hlist_node	hlist;
-+	struct file		*file;
-+	struct au_finfo		*finfo;
-+};
-+
-+struct au_finfo *au_fi_sp(struct file *file)
-+{
-+	struct au_finfo *finfo;
-+	struct au_finfo_sp *sp;
-+
-+	finfo = NULL;
-+	spin_lock(&au_finfo_sp.spin);
-+	hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
-+		if (sp->file != file)
-+			continue;
-+		finfo = sp->finfo;
-+		break;
-+	}
-+	spin_unlock(&au_finfo_sp.spin);
-+
-+	return finfo;
-+}
-+
-+static int au_fi_sp_add(struct file *file)
-+{
-+	int err;
-+	struct au_finfo_sp *sp;
-+
-+	err = -ENOMEM;
-+	sp = kmalloc(sizeof(*sp), GFP_NOFS);
-+	if (sp) {
-+		err = 0;
-+		sp->file = file;
-+		sp->finfo = file->private_data;
-+		spin_lock(&au_finfo_sp.spin);
-+		hlist_add_head(&sp->hlist, &au_finfo_sp.head);
-+		spin_unlock(&au_finfo_sp.spin);
-+	}
-+	return err;
-+}
-+
-+static void au_fi_sp_del(struct file *file)
-+{
-+	struct au_finfo_sp *sp, *do_free;
-+
-+	do_free = NULL;
-+	spin_lock(&au_finfo_sp.spin);
-+	hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
-+		if (sp->file != file)
-+			continue;
-+		hlist_del(&sp->hlist);
-+		do_free = sp;
-+		break;
-+	}
-+	spin_unlock(&au_finfo_sp.spin);
-+	kfree(do_free);
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
-+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
-+				unsigned long nv, loff_t pos)
-+{
-+	ssize_t err;
-+	aufs_bindex_t bstart;
-+	unsigned char wbr;
-+	struct file *file, *h_file;
-+	struct super_block *sb;
-+
-+	file = kio->ki_filp;
-+	sb = file->f_dentry->d_sb;
-+	si_read_lock(sb, AuLock_FLUSH);
-+	fi_read_lock(file);
-+	bstart = au_fbstart(file);
-+	h_file = au_hf_top(file);
-+	fi_read_unlock(file);
-+	wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
-+	si_read_unlock(sb);
-+
-+	/* do not change the file in kio */
-+	AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
-+	err = h_file->f_op->aio_read(kio, iov, nv, pos);
-+	if (err > 0 && wbr)
-+		file_accessed(h_file);
-+
-+	return err;
-+}
-+
-+static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
-+				 unsigned long nv, loff_t pos)
-+{
-+	ssize_t err;
-+	aufs_bindex_t bstart;
-+	unsigned char wbr;
-+	struct super_block *sb;
-+	struct file *file, *h_file;
-+
-+	file = kio->ki_filp;
-+	sb = file->f_dentry->d_sb;
-+	si_read_lock(sb, AuLock_FLUSH);
-+	fi_read_lock(file);
-+	bstart = au_fbstart(file);
-+	h_file = au_hf_top(file);
-+	fi_read_unlock(file);
-+	wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
-+	si_read_unlock(sb);
-+
-+	/* do not change the file in kio */
-+	AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
-+	err = h_file->f_op->aio_write(kio, iov, nv, pos);
-+	return err;
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
-+static int aufs_release_sp(struct inode *inode, struct file *file)
-+{
-+	int err;
-+	struct file *h_file;
-+
-+	fi_read_lock(file);
-+	h_file = au_hf_top(file);
-+	fi_read_unlock(file);
-+	/* close this fifo in aufs */
-+	err = h_file->f_op->release(inode, file); /* ignore */
-+	aufs_release_nondir(inode, file); /* ignore */
-+	au_fi_sp_del(file);
-+	return err;
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
-+/* currently, support only FIFO */
-+enum {
-+	AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
-+	/* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
-+	AuSp_Last
-+};
-+static int aufs_open_sp(struct inode *inode, struct file *file);
-+static struct au_sp_fop {
-+	int			done;
-+	struct file_operations	fop;	/* not 'const' */
-+	spinlock_t		spin;
-+} au_sp_fop[AuSp_Last] = {
-+	[AuSp_FIFO] = {
-+		.fop	= {
-+			.owner	= THIS_MODULE,
-+			.open	= aufs_open_sp
-+		}
-+	}
-+};
-+
-+static void au_init_fop_sp(struct file *file)
-+{
-+	struct au_sp_fop *p;
-+	int i;
-+	struct file *h_file;
-+
-+	p = au_sp_fop;
-+	if (unlikely(!p->done)) {
-+		/* initialize first time only */
-+		static DEFINE_SPINLOCK(spin);
-+
-+		spin_lock(&spin);
-+		if (!p->done) {
-+			BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
-+				     != AuSp_Last);
-+			for (i = 0; i < AuSp_Last; i++)
-+				spin_lock_init(&p[i].spin);
-+			p->done = 1;
-+		}
-+		spin_unlock(&spin);
-+	}
-+
-+	switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
-+	case FMODE_READ:
-+		i = AuSp_FIFO_R;
-+		break;
-+	case FMODE_WRITE:
-+		i = AuSp_FIFO_W;
-+		break;
-+	case FMODE_READ | FMODE_WRITE:
-+		i = AuSp_FIFO_RW;
-+		break;
-+	default:
-+		BUG();
-+	}
-+
-+	p += i;
-+	if (unlikely(!p->done)) {
-+		/* initialize first time only */
-+		h_file = au_hf_top(file);
-+		spin_lock(&p->spin);
-+		if (!p->done) {
-+			p->fop = *h_file->f_op;
-+			p->fop.owner = THIS_MODULE;
-+			if (p->fop.aio_read)
-+				p->fop.aio_read = aufs_aio_read_sp;
-+			if (p->fop.aio_write)
-+				p->fop.aio_write = aufs_aio_write_sp;
-+			p->fop.release = aufs_release_sp;
-+			p->done = 1;
-+		}
-+		spin_unlock(&p->spin);
-+	}
-+	file->f_op = &p->fop;
-+}
-+
-+static int au_cpup_sp(struct dentry *dentry)
-+{
-+	int err;
-+	struct au_pin pin;
-+	struct au_wr_dir_args wr_dir_args = {
-+		.force_btgt	= -1,
-+		.flags		= 0
-+	};
-+	struct au_cp_generic cpg = {
-+		.dentry	= dentry,
-+		.bdst	= -1,
-+		.bsrc	= -1,
-+		.len	= -1,
-+		.pin	= &pin,
-+		.flags	= AuCpup_DTIME
-+	};
-+
-+	AuDbg("%pd\n", dentry);
-+
-+	di_read_unlock(dentry, AuLock_IR);
-+	di_write_lock_child(dentry);
-+	err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
-+	if (unlikely(err < 0))
-+		goto out;
-+	cpg.bdst = err;
-+	err = 0;
-+	if (cpg.bdst == au_dbstart(dentry))
-+		goto out; /* success */
-+
-+	err = au_pin(&pin, dentry, cpg.bdst, au_opt_udba(dentry->d_sb),
-+		     AuPin_MNT_WRITE);
-+	if (!err) {
-+		err = au_sio_cpup_simple(&cpg);
-+		au_unpin(&pin);
-+	}
-+
-+out:
-+	di_downgrade_lock(dentry, AuLock_IR);
-+	return err;
-+}
-+
-+static int au_do_open_sp(struct file *file, int flags)
-+{
-+	int err;
-+	struct dentry *dentry;
-+	struct super_block *sb;
-+	struct file *h_file;
-+	struct inode *h_inode;
-+
-+	err = au_fi_sp_add(file);
-+	if (unlikely(err))
-+		goto out;
-+
-+	dentry = file->f_dentry;
-+	AuDbg("%pd\n", dentry);
-+
-+	/*
-+	 * try copying-up.
-+	 * operate on the ro branch is not an error.
-+	 */
-+	au_cpup_sp(dentry); /* ignore */
-+
-+	/* prepare h_file */
-+	err = au_do_open_nondir(file, vfsub_file_flags(file));
-+	if (unlikely(err))
-+		goto out_del;
-+
-+	sb = dentry->d_sb;
-+	h_file = au_hf_top(file);
-+	h_inode = file_inode(h_file);
-+	di_read_unlock(dentry, AuLock_IR);
-+	fi_write_unlock(file);
-+	si_read_unlock(sb);
-+	/* open this fifo in aufs */
-+	err = h_inode->i_fop->open(file_inode(file), file);
-+	si_noflush_read_lock(sb);
-+	fi_write_lock(file);
-+	di_read_lock_child(dentry, AuLock_IR);
-+	if (!err) {
-+		au_init_fop_sp(file);
-+		goto out; /* success */
-+	}
-+
-+out_del:
-+	au_fi_sp_del(file);
-+out:
-+	return err;
-+}
-+
-+static int aufs_open_sp(struct inode *inode, struct file *file)
-+{
-+	int err;
-+	struct super_block *sb;
-+
-+	sb = file->f_dentry->d_sb;
-+	si_read_lock(sb, AuLock_FLUSH);
-+	err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
-+	si_read_unlock(sb);
-+	return err;
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
-+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
-+{
-+	init_special_inode(inode, mode, rdev);
-+
-+	switch (mode & S_IFMT) {
-+	case S_IFIFO:
-+		inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
-+		/*FALLTHROUGH*/
-+	case S_IFCHR:
-+	case S_IFBLK:
-+	case S_IFSOCK:
-+		break;
-+	default:
-+		AuDebugOn(1);
-+	}
-+}
-+
-+int au_special_file(umode_t mode)
-+{
-+	int ret;
-+
-+	ret = 0;
-+	switch (mode & S_IFMT) {
-+	case S_IFIFO:
-+#if 0
-+	case S_IFCHR:
-+	case S_IFBLK:
-+	case S_IFSOCK:
-+#endif
-+		ret = 1;
-+	}
-+
-+	return ret;
-+}
 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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/fstype.h	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,469 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -13528,7 +13250,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/hfsnotify.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,281 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -13813,7 +13535,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	2014-04-24 22:11:10.851935747 +0200
++++ linux/fs/aufs/hfsplus.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,56 @@
 +/*
 + * Copyright (C) 2010-2014 Junjiro R. Okajima
@@ -13873,8 +13595,8 @@ 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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,710 @@
++++ linux/fs/aufs/hnotify.c	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,713 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -14203,7 +13925,8 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +	    && a->inode
 +	    && a->h_inode) {
 +		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
-+		if (!a->h_inode->i_nlink)
++		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);
 +	}
@@ -14506,8 +14229,10 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +		p[len] = 0;
 +	}
 +
++	/* NFS fires the event for silly-renamed one from kworker */
 +	f = 0;
-+	if (!dir->i_nlink)
++	if (!dir->i_nlink
++	    || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
 +		f = AuWkq_NEST;
 +	err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
 +	if (unlikely(err)) {
@@ -14587,8 +14312,8 @@ 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	2014-04-24 22:11:10.855269116 +0200
-@@ -0,0 +1,275 @@
++++ linux/fs/aufs/iinfo.c	2014-06-24 00:14:06.786052822 +0200
+@@ -0,0 +1,277 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -14736,7 +14461,9 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +			struct inode *h_i;
 +
 +			h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
-+			if (h_i && !h_i->i_nlink)
++			if (h_i
++			    && !h_i->i_nlink
++			    && !(h_i->i_state & I_LINKABLE))
 +				au_set_h_iptr(inode, bindex, NULL, 0);
 +		}
 +	}
@@ -14866,7 +14593,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/inode.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,491 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -15083,7 +14810,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +	case S_IFSOCK:
 +		btail = au_dbtail(dentry);
 +		inode->i_op = &aufs_iop;
-+		au_init_special_fop(inode, mode, h_inode->i_rdev);
++		init_special_inode(inode, mode, h_inode->i_rdev);
 +		break;
 +	default:
 +		AuIOErr("Unknown file type 0%o\n", mode);
@@ -15361,8 +15088,8 @@ 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	2014-04-24 22:11:10.855269116 +0200
-@@ -0,0 +1,599 @@
++++ linux/fs/aufs/inode.h	2014-06-24 00:14:06.786052822 +0200
+@@ -0,0 +1,601 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -15521,6 +15248,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +#define AuWrDir_ADD_ENTRY	1
 +#define AuWrDir_TMP_WHENTRY	(1 << 1)
 +#define AuWrDir_ISDIR		(1 << 2)
++#define AuWrDir_TMPFILE		(1 << 3)
 +#define au_ftest_wrdir(flags, name)	((flags) & AuWrDir_##name)
 +#define au_fset_wrdir(flags, name) \
 +	do { (flags) |= AuWrDir_##name; } while (0)
@@ -15551,6 +15279,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 +		bool want_excl);
++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
 +	      struct dentry *dentry);
 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
@@ -15964,7 +15693,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +#endif /* __AUFS_INODE_H__ */
 diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
 --- /usr/share/empty/fs/aufs/ioctl.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/ioctl.c	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/ioctl.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,201 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -16169,8 +15898,8 @@ 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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,762 @@
++++ linux/fs/aufs/i_op_add.c	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,881 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -16529,6 +16258,121 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +	return add_simple(dir, dentry, &arg);
 +}
 +
++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
++{
++	int err;
++	aufs_bindex_t bindex;
++	struct super_block *sb;
++	struct dentry *parent, *h_parent, *h_dentry;
++	struct inode *h_dir, *inode;
++	struct vfsmount *h_mnt;
++	struct au_wr_dir_args wr_dir_args = {
++		.force_btgt	= -1,
++		.flags		= AuWrDir_TMPFILE
++	};
++
++	/* copy-up may happen */
++	mutex_lock(&dir->i_mutex);
++
++	sb = dir->i_sb;
++	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
++	if (unlikely(err))
++		goto out;
++
++	err = au_di_init(dentry);
++	if (unlikely(err))
++		goto out_si;
++
++	err = -EBUSY;
++	parent = d_find_any_alias(dir);
++	AuDebugOn(!parent);
++	di_write_lock_parent(parent);
++	if (unlikely(parent->d_inode != dir))
++		goto out_parent;
++
++	err = au_digen_test(parent, au_sigen(sb));
++	if (unlikely(err))
++		goto out_parent;
++
++	bindex = au_dbstart(parent);
++	au_set_dbstart(dentry, bindex);
++	au_set_dbend(dentry, bindex);
++	err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
++	bindex = err;
++	if (unlikely(err < 0))
++		goto out_parent;
++
++	err = -EOPNOTSUPP;
++	h_dir = au_h_iptr(dir, bindex);
++	if (unlikely(!h_dir->i_op->tmpfile))
++		goto out_parent;
++
++	h_mnt = au_sbr_mnt(sb, bindex);
++	err = vfsub_mnt_want_write(h_mnt);
++	if (unlikely(err))
++		goto out_parent;
++
++	h_parent = au_h_dptr(parent, bindex);
++	err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
++	if (unlikely(err))
++		goto out_mnt;
++
++	err = -ENOMEM;
++	h_dentry = d_alloc(h_parent, &dentry->d_name);
++	if (unlikely(!h_dentry))
++		goto out_mnt;
++
++	err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
++	if (unlikely(err))
++		goto out_dentry;
++
++	au_set_dbstart(dentry, bindex);
++	au_set_dbend(dentry, bindex);
++	au_set_h_dptr(dentry, bindex, dget(h_dentry));
++	inode = au_new_inode(dentry, /*must_new*/1);
++	if (IS_ERR(inode)) {
++		err = PTR_ERR(inode);
++		au_set_h_dptr(dentry, bindex, NULL);
++		au_set_dbstart(dentry, -1);
++		au_set_dbend(dentry, -1);
++	} else {
++		if (!inode->i_nlink)
++			set_nlink(inode, 1);
++		d_tmpfile(dentry, inode);
++		au_di(dentry)->di_tmpfile = 1;
++
++		/* update without i_mutex */
++		if (au_ibstart(dir) == au_dbstart(dentry))
++			au_cpup_attr_timesizes(dir);
++	}
++
++out_dentry:
++	dput(h_dentry);
++out_mnt:
++	vfsub_mnt_drop_write(h_mnt);
++out_parent:
++	di_write_unlock(parent);
++	dput(parent);
++	di_write_unlock(dentry);
++	if (!err)
++#if 0
++		/* verbose coding for lock class name */
++		au_rw_class(&au_di(dentry)->di_rwsem,
++			    au_lc_key + AuLcNonDir_DIINFO);
++#else
++		;
++#endif
++	else {
++		au_di_fin(dentry);
++		dentry->d_fsdata = NULL;
++	}
++out_si:
++	si_read_unlock(sb);
++out:
++	mutex_unlock(&dir->i_mutex);
++	return err;
++}
++
 +/* ---------------------------------------------------------------------- */
 +
 +struct au_link_args {
@@ -16692,7 +16536,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +					AuLock_NOPLM | AuLock_GEN);
 +	if (unlikely(err))
 +		goto out_kfree;
-+	err = au_d_hashed_positive(src_dentry);
++	err = au_d_linkable(src_dentry);
 +	if (unlikely(err))
 +		goto out_unlock;
 +	err = au_d_may_add(dentry);
@@ -16717,12 +16561,16 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +	a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
 +	a->bsrc = au_ibstart(inode);
 +	h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
++	if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
++		h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
 +	if (!h_src_dentry) {
 +		a->bsrc = au_dbstart(src_dentry);
 +		h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
 +		AuDebugOn(!h_src_dentry);
-+	} else if (IS_ERR(h_src_dentry))
++	} else if (IS_ERR(h_src_dentry)) {
++		err = PTR_ERR(h_src_dentry);
 +		goto out_parent;
++	}
 +
 +	if (au_opt_test(au_mntflags(sb), PLINK)) {
 +		if (a->bdst < a->bsrc
@@ -16935,8 +16783,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	2014-04-24 22:11:10.851935747 +0200
-@@ -0,0 +1,1127 @@
++++ linux/fs/aufs/i_op.c	2014-06-24 00:14:06.782719306 +0200
+@@ -0,0 +1,1138 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -17205,7 +17053,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +		else
 +			BUG();
 +	}
-+	if (!err && add_entry) {
++	if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
 +		h_parent = au_h_dptr(parent, bcpup);
 +		h_dir = h_parent->d_inode;
 +		mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
@@ -17244,7 +17092,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	aufs_bindex_t bcpup, bstart, src_bstart;
 +	const unsigned char add_entry
 +		= au_ftest_wrdir(args->flags, ADD_ENTRY)
-+		| au_ftest_wrdir(args->flags, TMP_WHENTRY);
++		| au_ftest_wrdir(args->flags, TMP_WHENTRY)
++		| au_ftest_wrdir(args->flags, TMPFILE);
 +	struct super_block *sb;
 +	struct dentry *parent;
 +	struct au_sbinfo *sbinfo;
@@ -17300,7 +17149,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +			au_set_dbstart(dentry, bcpup);
 +			au_set_dbend(dentry, bcpup);
 +		}
-+		AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
++		AuDebugOn(add_entry
++			  && !au_ftest_wrdir(args->flags, TMPFILE)
++			  && !au_h_dptr(dentry, bcpup));
 +	}
 +
 +out:
@@ -18018,9 +17869,15 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	h_inode = au_h_iptr(inode, au_ibstart(inode));
 +	err = vfsub_update_time(h_inode, ts, flags);
 +	lockdep_off();
++	if (!err)
++		au_cpup_attr_timesizes(inode);
 +	ii_write_unlock(inode);
 +	si_read_unlock(sb);
 +	lockdep_on();
++
++	if (!err && (flags & S_VERSION))
++		inode_inc_iversion(inode);
++
 +	return err;
 +}
 +
@@ -18053,8 +17910,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +	.setattr	= aufs_setattr,
 +	.getattr	= aufs_getattr,
 +
-+	.update_time	= aufs_update_time
++	.update_time	= aufs_update_time,
 +	/* no support for atomic_open() */
++
++	.tmpfile	= aufs_tmpfile
 +};
 +
 +struct inode_operations aufs_iop = {
@@ -18066,7 +17925,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/i_op_del.c	2014-06-24 00:14:06.782719306 +0200
 @@ -0,0 +1,506 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -18576,7 +18435,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/i_op_ren.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,1032 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -19612,8 +19471,8 @@ 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	2014-04-24 22:11:10.835268907 +0200
-@@ -0,0 +1,179 @@
++++ linux/fs/aufs/Kconfig	2014-06-24 00:14:06.776052275 +0200
+@@ -0,0 +1,168 @@
 +config AUFS_FS
 +	tristate "Aufs (Advanced multi layered unification filesystem) support"
 +	help
@@ -19715,17 +19574,6 @@ diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
 +	shows better performance in most cases.
 +	See detail in aufs.5.
 +
-+config AUFS_SP_IATTR
-+	bool "Respect the attributes (mtime/ctime mainly) of special files"
-+	help
-+	When you write something to a special file, some attributes of it
-+	(mtime/ctime mainly) may be updated. Generally such updates are
-+	less important (actually some device drivers and NFS ignore
-+	it). But some applications (such like test program) requires
-+	such updates. If you need these updates, then enable this
-+	configuration which introduces some overhead.
-+	Currently this configuration handles FIFO only.
-+
 +config AUFS_SHWH
 +	bool "Show whiteouts"
 +	help
@@ -19795,7 +19643,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/loop.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,145 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -19944,7 +19792,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/loop.h	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,52 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -20000,7 +19848,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	2012-10-05 20:40:23.980965955 +0200
++++ linux/fs/aufs/magic.mk	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,54 @@
 +
 +# defined in ${srctree}/fs/fuse/inode.c
@@ -20058,8 +19906,8 @@ 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	2014-04-24 22:11:10.845269011 +0200
-@@ -0,0 +1,42 @@
++++ linux/fs/aufs/Makefile	2014-06-24 00:14:06.776052275 +0200
+@@ -0,0 +1,41 @@
 +
 +include ${src}/magic.mk
 +ifeq (${CONFIG_AUFS_FS},m)
@@ -20098,13 +19946,12 @@ diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
 +aufs-$(CONFIG_AUFS_EXPORT) += export.o
 +aufs-$(CONFIG_AUFS_POLL) += poll.o
 +aufs-$(CONFIG_AUFS_RDU) += rdu.o
-+aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
 +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
 +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
 +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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/module.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,202 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -20310,7 +20157,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/module.h	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,104 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -20418,7 +20265,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/mvdown.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,627 @@
 +/*
 + * Copyright (C) 2011-2014 Junjiro R. Okajima
@@ -21049,7 +20896,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/opts.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,1701 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -22754,7 +22601,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/opts.h	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,210 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -22968,7 +22815,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/plink.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,532 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -23504,7 +23351,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	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/poll.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,55 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -23563,7 +23410,7 @@ diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
 +}
 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
 --- /usr/share/empty/fs/aufs/procfs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/procfs.c	2014-04-24 22:11:10.855269116 +0200
++++ linux/fs/aufs/procfs.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,169 @@
 +/*
 + * Copyright (C) 2010-2014 Junjiro R. Okajima
@@ -23736,7 +23583,7 @@ 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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/rdu.c	2014-06-24 00:14:06.786052822 +0200
 @@ -0,0 +1,388 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -24128,7 +23975,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/rwsem.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,187 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -24319,7 +24166,7 @@ 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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/sbinfo.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,351 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -24674,7 +24521,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 --- /usr/share/empty/fs/aufs/spl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/spl.h	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/spl.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,111 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -24789,7 +24636,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/super.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,1001 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -25794,7 +25641,7 @@ 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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/super.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,571 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -26369,7 +26216,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/sysaufs.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,104 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -26477,7 +26324,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/sysaufs.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,103 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -26584,7 +26431,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/sysfs.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,296 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -26884,7 +26731,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/sysrq.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,154 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -26981,7 +26828,7 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
 +		umode_t mode;
 +		file = finfo->fi_file;
 +		mode = file_inode(file)->i_mode;
-+		if (!special_file(mode) || au_special_file(mode))
++		if (!special_file(mode))
 +			au_dpri_file(file);
 +	}
 +	spin_unlock(&files->spin);
@@ -27042,7 +26889,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	2014-04-24 22:11:10.858602483 +0200
++++ linux/fs/aufs/vdir.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,887 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -27933,7 +27780,7 @@ 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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/vfsub.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,782 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -28242,14 +28089,14 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +	d = path->dentry;
 +	path->dentry = d->d_parent;
 +	tmp.dentry = src_dentry->d_parent;
-+	err = security_path_rename(&tmp, src_dentry, path, d);
++	err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
 +	path->dentry = d;
 +	if (unlikely(err))
 +		goto out;
 +
 +	lockdep_off();
 +	err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
-+			 delegated_inode);
++			 delegated_inode, /*flags*/0);
 +	lockdep_on();
 +	if (!err) {
 +		int did;
@@ -28719,7 +28566,7 @@ 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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/vfsub.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,282 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -29005,7 +28852,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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/wbr_policy.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,756 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -29765,7 +29612,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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/whout.c	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,1052 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -30821,7 +30668,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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/whout.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,86 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -30911,8 +30758,8 @@ 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	2014-04-24 22:11:10.861935852 +0200
-@@ -0,0 +1,212 @@
++++ linux/fs/aufs/wkq.c	2014-06-24 00:14:06.789386337 +0200
+@@ -0,0 +1,213 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -31018,7 +30865,8 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 +{
 +	if (au_ftest_wkq(wkinfo->flags, NEST)) {
 +		if (au_wkq_test()) {
-+			AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
++			AuWarn1("wkq from wkq, unless silly-rename on NFS,"
++				" due to a dead dir by UDBA?\n");
 +			AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
 +		}
 +	} else
@@ -31127,7 +30975,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	2014-04-24 22:11:10.861935852 +0200
++++ linux/fs/aufs/wkq.h	2014-06-24 00:14:06.789386337 +0200
 @@ -0,0 +1,91 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -31222,8 +31070,8 @@ 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/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	2014-04-24 22:11:10.861935852 +0200
-@@ -0,0 +1,1314 @@
++++ linux/fs/aufs/xino.c	2014-06-24 00:14:06.792719853 +0200
+@@ -0,0 +1,1312 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
 + *
@@ -32426,9 +32274,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +			cur_parent = dget_parent(cur_xino->f_dentry);
 +			cur_name = &cur_xino->f_dentry->d_name;
 +			skip = (cur_parent == parent
-+				&& dname->len == cur_name->len
-+				&& !memcmp(dname->name, cur_name->name,
-+					   dname->len));
++				&& au_qstreq(dname, cur_name));
 +			dput(cur_parent);
 +		}
 +		if (skip)
@@ -32540,7 +32386,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	2014-04-24 22:11:10.935269950 +0200
++++ linux/include/uapi/linux/aufs_type.h	2014-06-24 00:14:06.792719853 +0200
 @@ -0,0 +1,281 @@
 +/*
 + * Copyright (C) 2005-2014 Junjiro R. Okajima
@@ -32583,7 +32429,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +
 +#include <linux/limits.h>
 +
-+#define AUFS_VERSION	"3.14-20140407"
++#define AUFS_VERSION	"3.15-20140623"
 +
 +/* todo? move this to linux-2.6.19/include/magic.h */
 +#define AUFS_SUPER_MAGIC	('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -32823,10 +32669,10 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +				      struct aufs_mvdown)
 +
 +#endif /* __AUFS_TYPE_H__ */
-aufs3.14 loopback patch
+aufs3.15 loopback patch
 
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index ec278ac..1894990 100644
+index 138104b..227f7fa 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
 @@ -514,7 +514,7 @@ out:
@@ -33021,10 +32867,10 @@ index 90df5d6..cb91822 100644
  	unsigned	lo_blocksize;
  	void		*key_data; 
 diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
-index 2e0302d..b35af58 100644
+index 510919e..f9317c9 100644
 --- a/fs/aufs/f_op.c
 +++ b/fs/aufs/f_op.c
-@@ -337,7 +337,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
+@@ -345,7 +345,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
  	err = -EINVAL;
  	h_file = au_hf_top(file);
  	get_file(h_file);
@@ -33099,10 +32945,10 @@ index b609e5a..e3909ed 100644
  
  /* ---------------------------------------------------------------------- */
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index f3f635c..c4308ca 100644
+index 3ff3e89..13017e6 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1626,6 +1626,10 @@ struct super_operations {
+@@ -1554,6 +1554,10 @@ struct super_operations {
  	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
  	long (*nr_cached_objects)(struct super_block *, int);
  	long (*free_cached_objects)(struct super_block *, long, int);
================================================================

---- gitweb:

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



More information about the pld-cvs-commit mailing list