]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- updated aufs patch
authorJan Rękorajski <baggins@pld-linux.org>
Sun, 28 Jun 2015 16:38:11 +0000 (18:38 +0200)
committerJan Rękorajski <baggins@pld-linux.org>
Sun, 28 Jun 2015 16:38:11 +0000 (18:38 +0200)
kernel-aufs4+vserver.patch [moved from kernel-aufs3+vserver.patch with 100% similarity]
kernel-aufs4.patch [moved from kernel-aufs3.patch with 96% similarity]
kernel.spec

similarity index 96%
rename from kernel-aufs3.patch
rename to kernel-aufs4.patch
index 53816565ec3236e8b12f862535097122b30f099d..505b512adf81c141f1c6dab3737e6e850dcd7f66 100644 (file)
@@ -1,31 +1,31 @@
-aufs3.x-rcN kbuild patch
+aufs4.x-rcN kbuild patch
 
 diff --git a/fs/Kconfig b/fs/Kconfig
-index ec35851..a059d62 100644
+index 011f433..b1083f6 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -218,6 +218,7 @@ source "fs/sysv/Kconfig"
+@@ -218,6 +218,7 @@ source "fs/pstore/Kconfig"
+ source "fs/sysv/Kconfig"
  source "fs/ufs/Kconfig"
  source "fs/exofs/Kconfig"
- source "fs/f2fs/Kconfig"
 +source "fs/aufs/Kconfig"
  
  endif # MISC_FILESYSTEMS
  
 diff --git a/fs/Makefile b/fs/Makefile
-index a88ac48..162500e 100644
+index cb92fd4..8c2df12 100644
 --- a/fs/Makefile
 +++ b/fs/Makefile
-@@ -126,3 +126,4 @@ obj-y                              += exofs/ # Multiple modules
+@@ -127,3 +127,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 68ceb97..0352fa4 100644
+index 1a0006a..ddad01a 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
-@@ -58,6 +58,7 @@ header-y += atmsvc.h
+@@ -59,6 +59,7 @@ header-y += atmsvc.h
  header-y += atm_tcp.h
  header-y += atm_zatm.h
  header-y += audit.h
@@ -33,13 +33,13 @@ index 68ceb97..0352fa4 100644
  header-y += auto_fs4.h
  header-y += auto_fs.h
  header-y += auxvec.h
-aufs3.x-rcN base patch
+aufs4.x-rcN base patch
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index efbcb50..30a1654 100644
+index d8afd29..feac5ea 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -1864,6 +1864,20 @@ F:      include/linux/audit.h
+@@ -1880,6 +1880,19 @@ F:      include/linux/audit.h
  F:    include/uapi/linux/audit.h
  F:    kernel/audit*
  
@@ -48,8 +48,7 @@ index efbcb50..30a1654 100644
 +L:    linux-unionfs@vger.kernel.org
 +L:    aufs-users@lists.sourceforge.net (members only)
 +W:    http://aufs.sourceforge.net
-+T:    git://git.code.sf.net/p/aufs/aufs3-linux
-+T:    git://github.com/sfjro/aufs3-linux.git
++T:    git://github.com/sfjro/aufs4-linux.git
 +S:    Supported
 +F:    Documentation/filesystems/aufs/
 +F:    Documentation/ABI/testing/debugfs-aufs
@@ -61,10 +60,10 @@ index efbcb50..30a1654 100644
  M:    Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
  W:    http://miguelojeda.es/auxdisplay.htm
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index d1f168b..a0da519 100644
+index d7173cb..0160952 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
-@@ -592,6 +592,24 @@ static inline int is_loop_device(struct file *file)
+@@ -540,6 +540,24 @@ static inline int is_loop_device(struct file *file)
        return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
  }
  
@@ -90,10 +89,10 @@ index d1f168b..a0da519 100644
  
  static ssize_t loop_attr_show(struct device *dev, char *page,
 diff --git a/fs/dcache.c b/fs/dcache.c
-index c71e373..b93a9f2 100644
+index 37b5afd..bc261e2 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1130,7 +1130,7 @@ enum d_walk_ret {
+@@ -1164,7 +1164,7 @@ enum d_walk_ret {
   *
   * The @enter() and @finish() callbacks are called with d_lock held.
   */
@@ -102,11 +101,44 @@ index c71e373..b93a9f2 100644
                   enum d_walk_ret (*enter)(void *, struct dentry *),
                   void (*finish)(void *))
  {
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 819ef3f..fd0414e 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+ }
+ EXPORT_SYMBOL(__vfs_write);
++vfs_readf_t vfs_readf(struct file *file)
++{
++      const struct file_operations *fop = file->f_op;
++
++      if (fop->read)
++              return fop->read;
++      if (fop->read_iter)
++              return new_sync_read;
++      return ERR_PTR(-ENOSYS);
++}
++
++vfs_writef_t vfs_writef(struct file *file)
++{
++      const struct file_operations *fop = file->f_op;
++
++      if (fop->write)
++              return fop->write;
++      if (fop->write_iter)
++              return new_sync_write;
++      return ERR_PTR(-ENOSYS);
++}
++
+ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ {
+       mm_segment_t old_fs;
 diff --git a/fs/splice.c b/fs/splice.c
-index 7968da9..beb9993 100644
+index bfe62ae..fa5eee5 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1099,8 +1099,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1101,8 +1101,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -117,7 +149,7 @@ index 7968da9..beb9993 100644
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
-@@ -1116,9 +1116,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1118,9 +1118,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.
   */
@@ -142,6 +174,23 @@ index f87d308..9a290b3 100644
  
  static inline void fput_light(struct file *file, int fput_needed)
  {
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 35ec87e..3229f97 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1649,6 +1649,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+                             struct iovec *fast_pointer,
+                             struct iovec **ret_pointer);
++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
++                              loff_t *);
++vfs_readf_t vfs_readf(struct file *file);
++vfs_writef_t vfs_writef(struct file *file);
++
+ extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
+ extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
+ extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
 diff --git a/include/linux/splice.h b/include/linux/splice.h
 index da2751d..2e0fca6 100644
 --- a/include/linux/splice.h
@@ -157,10 +206,10 @@ index da2751d..2e0fca6 100644
 +                       struct pipe_inode_info *pipe, size_t len,
 +                       unsigned int flags);
  #endif
-aufs3.x-rcN mmap patch
+aufs4.x-rcN mmap patch
 
 diff --git a/fs/buffer.c b/fs/buffer.c
-index 20805db..363569f 100644
+index c7a5602..8c50a22 100644
 --- a/fs/buffer.c
 +++ b/fs/buffer.c
 @@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
@@ -173,10 +222,10 @@ index 20805db..363569f 100644
        ret = __block_page_mkwrite(vma, vmf, get_block);
        sb_end_pagefault(sb);
 diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 3f3d7ae..426bcc7 100644
+index 093ca14..fc1ac03 100644
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
-@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
+@@ -1744,7 +1744,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
        down_read(&mm->mmap_sem);
        vma = find_exact_vma(mm, vm_start, vm_end);
        if (vma && vma->vm_file) {
@@ -243,10 +292,10 @@ index 599ec2e..1740207 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 47a9392..c8f8b46 100644
+index 0755b9f..2ee5500 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
-@@ -1254,6 +1254,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1172,6 +1172,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
  }
  #endif
  
@@ -276,7 +325,7 @@ index 47a9392..c8f8b46 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 199a03a..ed38ea3 100644
+index 8d37e26..ce89d4c 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
 @@ -241,6 +241,7 @@ struct vm_region {
@@ -296,10 +345,10 @@ index 199a03a..ed38ea3 100644
  
  #ifndef CONFIG_MMU
 diff --git a/kernel/fork.c b/kernel/fork.c
-index cf65139..f28a048 100644
+index 03c1eaa..7e215ba 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+@@ -456,7 +456,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;
  
@@ -309,7 +358,7 @@ index cf65139..f28a048 100644
                                atomic_dec(&inode->i_writecount);
                        i_mmap_lock_write(mapping);
 diff --git a/mm/Makefile b/mm/Makefile
-index 15dbe99..88e25b5 100644
+index 98c4eae..3f0c9b9 100644
 --- a/mm/Makefile
 +++ b/mm/Makefile
 @@ -21,7 +21,7 @@ obj-y                        := filemap.o mempool.o oom_kill.o \
@@ -322,10 +371,10 @@ index 15dbe99..88e25b5 100644
  obj-y += init-mm.o
  
 diff --git a/mm/filemap.c b/mm/filemap.c
-index ad72420..8885258 100644
+index 6bf5e42..a863d0f 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
-@@ -2064,7 +2064,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+@@ -2062,7 +2062,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);
@@ -354,10 +403,10 @@ index d551475..1ebf71b 100644
        return error;
  }
 diff --git a/mm/memory.c b/mm/memory.c
-index 97839f5..5e5d491 100644
+index 22e037e..62096a2 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct m
+@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
                }
  
                if (!page_mkwrite)
@@ -367,7 +416,7 @@ index 97839f5..5e5d491 100644
  
        return VM_FAULT_WRITE;
 diff --git a/mm/mmap.c b/mm/mmap.c
-index 9ec50a3..4a6a641 100644
+index bb50cac..1ab5e596 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
 @@ -274,7 +274,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
@@ -437,7 +486,7 @@ index 9ec50a3..4a6a641 100644
  out:
        up_write(&mm->mmap_sem);
        if (populate)
-@@ -2950,7 +2949,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2949,7 +2948,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
                        if (anon_vma_clone(new_vma, vma))
                                goto out_free_mempol;
                        if (new_vma->vm_file)
@@ -464,7 +513,7 @@ index bb04d53..5c24c54 100644
                                goto out;
                        down_read(&mm->mmap_sem);
 diff --git a/mm/nommu.c b/mm/nommu.c
-index 3fba2dc..870ce96 100644
+index e544508..dd6f74a 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
 @@ -693,7 +693,7 @@ static void __put_nommu_region(struct vm_region *region)
@@ -599,13 +648,13 @@ index 0000000..6aa5ab5
 +              fput(pr);
 +}
 +#endif /* !CONFIG_MMU */
-aufs3.x-rcN standalone patch
+aufs4.x-rcN standalone patch
 
 diff --git a/fs/dcache.c b/fs/dcache.c
-index b93a9f2..5a010ee 100644
+index bc261e2..8d7951d 100644
 --- a/fs/dcache.c
 +++ b/fs/dcache.c
-@@ -1235,6 +1235,7 @@ rename_retry:
+@@ -1269,6 +1269,7 @@ rename_retry:
        seq = 1;
        goto again;
  }
@@ -614,7 +663,7 @@ index b93a9f2..5a010ee 100644
  /*
   * Search for at least 1 mount point in the dentry's subdirs.
 diff --git a/fs/file_table.c b/fs/file_table.c
-index 3f85411..00e9dcf 100644
+index 294174d..3cea027 100644
 --- a/fs/file_table.c
 +++ b/fs/file_table.c
 @@ -147,6 +147,7 @@ over:
@@ -634,7 +683,7 @@ index 3f85411..00e9dcf 100644
  void __init files_init(unsigned long mempages)
  { 
 diff --git a/fs/inode.c b/fs/inode.c
-index f00b16f..eb7b8b5 100644
+index ea37cd1..58f5f58 100644
 --- a/fs/inode.c
 +++ b/fs/inode.c
 @@ -58,6 +58,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
@@ -646,7 +695,7 @@ index f00b16f..eb7b8b5 100644
  /*
   * Empty aops. Can be used for the cases where the user does not
 diff --git a/fs/namespace.c b/fs/namespace.c
-index 82ef140..a3aa4b9 100644
+index 1b9e111..d45b81b 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
@@ -657,7 +706,7 @@ index 82ef140..a3aa4b9 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1718,6 +1719,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -1768,6 +1769,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
        }
        return 0;
  }
@@ -738,7 +787,7 @@ index 92e48c7..d2c4b68 100644
  static int fsnotify_mark_destroy(void *ignored)
  {
 diff --git a/fs/open.c b/fs/open.c
-index 33f9cbf..fcc7eb4 100644
+index 98e5a52..a94e2e7 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,
@@ -749,7 +798,7 @@ index 33f9cbf..fcc7eb4 100644
  
  long vfs_truncate(struct path *path, loff_t length)
  {
-@@ -672,6 +673,7 @@ int open_check_o_direct(struct file *f)
+@@ -676,6 +677,7 @@ int open_check_o_direct(struct file *f)
        }
        return 0;
  }
@@ -757,11 +806,31 @@ index 33f9cbf..fcc7eb4 100644
  
  static int do_dentry_open(struct file *f,
                          int (*open)(struct inode *, struct file *),
+diff --git a/fs/read_write.c b/fs/read_write.c
+index fd0414e..8ace6ec 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file)
+               return new_sync_read;
+       return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL(vfs_readf);
+ vfs_writef_t vfs_writef(struct file *file)
+ {
+@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *file)
+               return new_sync_write;
+       return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL(vfs_writef);
+ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ {
 diff --git a/fs/splice.c b/fs/splice.c
-index beb9993..813275a 100644
+index fa5eee5..bfb3324 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1112,6 +1112,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1114,6 +1114,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
        return splice_write(pipe, out, ppos, len, flags);
  }
@@ -769,7 +838,7 @@ index beb9993..813275a 100644
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
-@@ -1138,6 +1139,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1140,6 +1141,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
  
        return splice_read(in, ppos, pipe, len, flags);
  }
@@ -790,7 +859,7 @@ index 4ef6985..6bb6303 100644
  /* Compare an extended attribute value with the given value */
  int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
 diff --git a/security/commoncap.c b/security/commoncap.c
-index f66713b..fd4c4b8 100644
+index f2875cd..ebf06ec 100644
 --- a/security/commoncap.c
 +++ b/security/commoncap.c
 @@ -975,9 +975,11 @@ int cap_mmap_addr(unsigned long addr)
@@ -826,7 +895,7 @@ index 188c1d2..426d9af 100644
  int devcgroup_inode_mknod(int mode, dev_t dev)
  {
 diff --git a/security/security.c b/security/security.c
-index e81d5bb..0b7b840 100644
+index 8e9b1f4..c1c7cd1 100644
 --- a/security/security.c
 +++ b/security/security.c
 @@ -430,6 +430,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
@@ -911,7 +980,7 @@ index e81d5bb..0b7b840 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-01-30 21:10:02.794146538 +0100
++++ linux/Documentation/ABI/testing/debugfs-aufs       2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,50 @@
 +What:         /debug/aufs/si_<id>/
 +Date:         March 2009
@@ -965,7 +1034,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-01-30 21:10:02.794146538 +0100
++++ linux/Documentation/ABI/testing/sysfs-aufs 2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,31 @@
 +What:         /sys/fs/aufs/si_<id>/
 +Date:         March 2009
@@ -1000,7 +1069,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    2015-06-22 08:27:37.867501461 +0200
++++ linux/Documentation/filesystems/aufs/design/01intro.txt    2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,170 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1174,7 +1243,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   2015-06-22 08:27:37.867501461 +0200
++++ linux/Documentation/filesystems/aufs/design/02struct.txt   2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,258 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1436,7 +1505,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt li
 +For this purpose, use "aumvdown" command in aufs-util.git.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt   1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt      2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt      2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,85 @@
 +
 +# Copyright (C) 2015 Junjiro R. Okajima
@@ -1525,7 +1594,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.t
 +       be implemented in aufs, but not all I am afraid.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/03lookup.txt   2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/03lookup.txt   2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,113 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1642,7 +1711,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   2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/04branch.txt   2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,74 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1720,7 +1789,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       2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt       2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,64 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1788,7 +1857,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx
 +  copyup policy.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt  1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt     2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt     2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,120 @@
 +
 +# Copyright (C) 2011-2015 Junjiro R. Okajima
@@ -1912,7 +1981,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linu
 +should restore the original file state after an error happens.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt  1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06mmap.txt     2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/06mmap.txt     2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,72 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -1988,7 +2057,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu
 +I have to give up this "looks-smater" approach.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06xattr.txt    2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/06xattr.txt    2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,96 @@
 +
 +# Copyright (C) 2014-2015 Junjiro R. Okajima
@@ -2088,7 +2157,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt lin
 +now, aufs implements the branch attributes to ignore the error.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt        1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/07export.txt   2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/07export.txt   2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,58 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -2150,7 +2219,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     2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/08shwh.txt     2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,52 @@
 +
 +# Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -2206,7 +2275,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    2015-06-22 08:27:37.870834875 +0200
++++ linux/Documentation/filesystems/aufs/design/10dynop.txt    2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,47 @@
 +
 +# Copyright (C) 2010-2015 Junjiro R. Okajima
@@ -2255,73 +2324,12 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin
 +XIP (DAX) mainly.
 +Currently this approach is applied to address_space_operations 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     2015-06-22 08:27:37.870834875 +0200
-@@ -0,0 +1,57 @@
-+
-+# Copyright (C) 2005-2015 Junjiro R. Okajima
-+# 
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# 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/>.
-+
-+Plan
-+
-+Restoring some features which was implemented in aufs1.
-+They were dropped in aufs2 in order to make source files simpler and
-+easier to be reviewed.
-+
-+
-+Being Another Aufs's Readonly Branch (robr)
-+----------------------------------------------------------------------
-+Aufs1 allows aufs to be another aufs's readonly branch.
-+This feature was developed by a user's request. But it may not be used
-+currently.
-+
-+
-+Refresh the Opened File (refrof)
-+----------------------------------------------------------------------
-+This option is implemented in aufs1 but incomplete.
-+
-+When user reads from a file, he expects to get its latest filedata
-+generally. If the file is removed and a new same named file is created,
-+the content he gets is unchanged, ie. the unlinked filedata.
-+
-+Let's try case study again.
-+- aufs has two branches.
-+  /au = /rw + /ro
-+- "fileA" exists under /ro, but /rw.
-+- user opened "/au/fileA".
-+- he or someone else inserts a branch (/new) between /rw and /ro.
-+  /au = /rw + /new + /ro
-+- the new branch contains "fileA".
-+- user reads from the opened "fileA"
-+- which filedata should aufs return, from /ro or /new?
-+
-+Some people says it has to be "from /ro" and it is a semantics of Unix.
-+The others say it should be "from /new" because the file is not removed
-+and it is equivalent to the case of someone else modifies the file.
-+
-+Here again I don't have a best and final answer. I got an idea to
-+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
-+Opened File) is specified (by default), aufs returns the filedata from
-+/new. Otherwise from /ro.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
 --- /usr/share/empty/Documentation/filesystems/aufs/README     1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/README        2015-06-22 08:27:37.867501461 +0200
-@@ -0,0 +1,384 @@
++++ linux/Documentation/filesystems/aufs/README        2015-06-28 17:35:44.344717109 +0200
+@@ -0,0 +1,383 @@
 +
-+Aufs3 -- advanced multi layered unification filesystem version 3.x
++Aufs4 -- advanced multi layered unification filesystem version 4.x
 +http://aufs.sf.net
 +Junjiro R. Okajima
 +
@@ -2337,7 +2345,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +Unionfs is being developed by Professor Erez Zadok at Stony Brook
 +University and his team.
 +
-+Aufs3 supports linux-3.0 and later.
++Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
 +If you want older kernel version support, try aufs2-2.6.git or
 +aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
 +
@@ -2399,7 +2407,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
 +- and more...
 +
-+Currently these features are dropped temporary from aufs3.
++Currently these features are dropped temporary from aufs4.
 +See design/08plan.txt in detail.
 +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
 +  (robr)
@@ -2417,65 +2425,64 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +
 +2. Download
 +----------------------------------------
-+There were three GIT trees for aufs3, aufs3-linux.git,
-+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
++There are three GIT trees for aufs4, aufs4-linux.git,
++aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
 +"aufs-util.git."
-+While the aufs-util is always necessary, you need either of aufs3-linux
-+or aufs3-standalone.
++While the aufs-util is always necessary, you need either of aufs4-linux
++or aufs4-standalone.
 +
-+The aufs3-linux tree includes the whole linux mainline GIT tree,
++The aufs4-linux tree includes the whole linux mainline GIT tree,
 +git://git.kernel.org/.../torvalds/linux.git.
 +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
-+build aufs3 as an external kernel module.
++build aufs4 as an external kernel module.
 +Several extra patches are not included in this tree. Only
-+aufs3-standalong tree contains them. They are describe in the later
++aufs4-standalone tree contains them. They are describe in the later
 +section "Configuration and Compilation."
 +
-+On the other hand, the aufs3-standalone tree has only aufs source files
++On the other hand, the aufs4-standalone tree has only aufs source files
 +and necessary patches, and you can select CONFIG_AUFS_FS=m.
 +But you need to apply all aufs patches manually.
 +
-+You will find GIT branches whose name is in form of "aufs3.x" where "x"
-+represents the linux kernel version, "linux-3.x". For instance,
-+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
-+"aufs3.x-rcN" branch.
++You will find GIT branches whose name is in form of "aufs4.x" where "x"
++represents the linux kernel version, "linux-4.x". For instance,
++"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
++"aufs4.x-rcN" branch.
 +
-+o aufs3-linux tree
++o aufs4-linux tree
 +$ git clone --reference /your/linux/git/tree \
-+      git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git
++      git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
 +- if you don't have linux GIT tree, then remove "--reference ..."
-+$ cd aufs3-linux.git
-+$ git checkout origin/aufs3.0
++$ cd aufs4-linux.git
++$ git checkout origin/aufs4.0
 +
 +Or You may want to directly git-pull aufs into your linux GIT tree, and
 +leave the patch-work to GIT.
 +$ cd /your/linux/git/tree
-+$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git
-+- aufs3-linux.git tree also exists on github.
-+$ git fetch aufs3
-+$ git checkout -b my3.14 v3.14
-+$ (add your change...)
-+$ git pull aufs3 aufs3.14
-+- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch.
++$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
++$ git fetch aufs4
++$ git checkout -b my4.0 v4.0
++$ (add your local change...)
++$ git pull aufs4 aufs4.0
++- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
 +- you may need to solve some conflicts between your_changes and
-+  aufs3.14. in this case, git-rerere is recommended so that you can
-+  solve the similar confilicts automatically when you upgrade to 3.15 or
++  aufs4.0. in this case, git-rerere is recommended so that you can
++  solve the similar conflicts automatically when you upgrade to 4.1 or
 +  later in the future.
 +
-+o aufs3-standalone tree
-+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
-+      aufs3-standalone.git
-+$ cd aufs3-standalone.git
-+$ git checkout origin/aufs3.0
++o aufs4-standalone tree
++$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
++$ cd aufs4-standalone.git
++$ git checkout origin/aufs4.0
 +
 +o aufs-util tree
-+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
-+      aufs-util.git
++$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
++- note that the public aufs-util.git is on SourceForge instead of
++  GitHUB.
 +$ cd aufs-util.git
-+$ git checkout origin/aufs3.0
++$ git checkout origin/aufs4.0
 +
-+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
-+The minor version number, 'x' in '3.x', of aufs may not always
++Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
++The minor version number, 'x' in '4.x', of aufs may not always
 +follow the minor version number of the kernel.
 +Because changes in the kernel that cause the use of a new
 +minor version number do not always require changes to aufs-util.
@@ -2487,8 +2494,8 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +nearest lower number.
 +
 +For (an unreleased) example:
-+If you are using "linux-3.10" and the "aufs3.10" branch
-+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
++If you are using "linux-4.10" and the "aufs4.10" branch
++does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
 +or something numerically smaller is the branch for your kernel.
 +
 +Also you can view all branches by
@@ -2499,19 +2506,19 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +----------------------------------------
 +Make sure you have git-checkout'ed the correct branch.
 +
-+For aufs3-linux tree,
++For aufs4-linux tree,
 +- enable CONFIG_AUFS_FS.
 +- set other aufs configurations if necessary.
 +
-+For aufs3-standalone tree,
++For aufs4-standalone tree,
 +There are several ways to build.
 +
 +1.
-+- apply ./aufs3-kbuild.patch to your kernel source files.
-+- apply ./aufs3-base.patch too.
-+- apply ./aufs3-mmap.patch too.
-+- apply ./aufs3-standalone.patch too, if you have a plan to set
-+  CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
++- apply ./aufs4-kbuild.patch to your kernel source files.
++- apply ./aufs4-base.patch too.
++- apply ./aufs4-mmap.patch too.
++- apply ./aufs4-standalone.patch too, if you have a plan to set
++  CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
 +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
 +  kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
 +- enable CONFIG_AUFS_FS, you can select either
@@ -2528,9 +2535,9 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +
 +2.
 +- module only (CONFIG_AUFS_FS=m).
-+- apply ./aufs3-base.patch to your kernel source files.
-+- apply ./aufs3-mmap.patch too.
-+- apply ./aufs3-standalone.patch too.
++- apply ./aufs4-base.patch to your kernel source files.
++- apply ./aufs4-mmap.patch too.
++- apply ./aufs4-standalone.patch too.
 +- build your kernel, don't forget "make headers_install", and reboot.
 +- edit ./config.mk and set other aufs configurations if necessary.
 +  Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
@@ -2549,7 +2556,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +    available in aufs standalone version's Makefile only), or copy
 +    $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
 +    you like manually. By default, the target directory is $PWD/usr.
-+- no need to apply aufs3-kbuild.patch, nor copying source files to your
++- no need to apply aufs4-kbuild.patch, nor copying source files to your
 +  kernel source tree.
 +
 +Note: The header file aufs_type.h is necessary to build aufs-util
@@ -2569,9 +2576,9 @@ 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
++There several other patches in aufs4-standalone.git. They are all
 +optional. When you meet some problems, they will help you.
-+- aufs3-loopback.patch
++- aufs4-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".
@@ -2706,7 +2713,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       2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/aufs.h       2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,59 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -2769,8 +2776,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     2015-06-22 08:29:23.703424266 +0200
-@@ -0,0 +1,1406 @@
++++ linux/fs/aufs/branch.c     2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,1414 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -2898,6 +2905,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +{
 +      struct au_branch *add_branch;
 +      struct dentry *root;
++      struct inode *inode;
 +      int err;
 +
 +      err = -ENOMEM;
@@ -2929,8 +2937,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      err = au_sbr_realloc(au_sbi(sb), new_nbranch);
 +      if (!err)
 +              err = au_di_realloc(au_di(root), new_nbranch);
-+      if (!err)
-+              err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
++      if (!err) {
++              inode = d_inode(root);
++              err = au_ii_realloc(au_ii(inode), new_nbranch);
++      }
 +      if (!err)
 +              return add_branch; /* success */
 +
@@ -2972,7 +2982,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +{
 +      int err;
 +      aufs_bindex_t bend, bindex;
-+      struct dentry *root;
++      struct dentry *root, *h_dentry;
 +      struct inode *inode, *h_inode;
 +
 +      root = sb->s_root;
@@ -3000,7 +3010,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +              goto out;
 +      }
 +
-+      inode = add->path.dentry->d_inode;
++      inode = d_inode(add->path.dentry);
 +      err = -ENOENT;
 +      if (unlikely(!inode->i_nlink)) {
 +              pr_err("no existence %s\n", add->pathname);
@@ -3025,7 +3035,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +              goto out;
 +      }
 +
-+      err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
++      err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
 +      if (unlikely(err))
 +              goto out;
 +
@@ -3042,7 +3052,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +      err = 0;
 +      if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
-+              h_inode = au_h_dptr(root, 0)->d_inode;
++              h_dentry = au_h_dptr(root, 0);
++              h_inode = d_inode(h_dentry);
 +              if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
 +                  || !uid_eq(h_inode->i_uid, inode->i_uid)
 +                  || !gid_eq(h_inode->i_gid, inode->i_gid))
@@ -3069,6 +3080,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      struct mutex *h_mtx;
 +      struct au_wbr *wbr;
 +      struct au_hinode *hdir;
++      struct dentry *h_dentry;
 +
 +      err = vfsub_mnt_want_write(au_br_mnt(br));
 +      if (unlikely(err))
@@ -3081,10 +3093,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      h_mtx = NULL;
 +      bindex = au_br_index(sb, br->br_id);
 +      if (0 <= bindex) {
-+              hdir = au_hi(sb->s_root->d_inode, bindex);
++              hdir = au_hi(d_inode(sb->s_root), bindex);
 +              au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
 +      } else {
-+              h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
++              h_dentry = au_br_dentry(br);
++              h_mtx = &d_inode(h_dentry)->i_mutex;
 +              mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
 +      }
 +      if (!wbr)
@@ -3147,6 +3160,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +                    struct au_opt_add *add)
 +{
 +      int err;
++      struct inode *h_inode;
 +
 +      err = 0;
 +      memset(&br->br_xino, 0, sizeof(br->br_xino));
@@ -3167,7 +3181,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      }
 +
 +      if (au_opt_test(au_mntflags(sb), XINO)) {
-+              err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
++              h_inode = d_inode(add->path.dentry);
++              err = au_xino_br(sb, br, h_inode->i_ino,
 +                               au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
 +              if (unlikely(err)) {
 +                      AuDebugOn(br->br_xino.xi_file);
@@ -3236,11 +3251,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +                       aufs_bindex_t bindex)
 +{
 +      struct dentry *root, *h_dentry;
-+      struct inode *root_inode;
++      struct inode *root_inode, *h_inode;
 +      aufs_bindex_t bend, amount;
 +
 +      root = sb->s_root;
-+      root_inode = root->d_inode;
++      root_inode = d_inode(root);
 +      bend = au_sbend(sb);
 +      amount = bend + 1 - bindex;
 +      h_dentry = au_br_dentry(br);
@@ -3249,8 +3264,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      au_br_do_add_hdp(au_di(root), bindex, bend, amount);
 +      au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
 +      au_set_h_dptr(root, bindex, dget(h_dentry));
-+      au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
-+                    /*flags*/0);
++      h_inode = d_inode(h_dentry);
++      au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
 +      au_sbilist_unlock();
 +}
 +
@@ -3263,7 +3278,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      struct au_branch *add_branch;
 +
 +      root = sb->s_root;
-+      root_inode = root->d_inode;
++      root_inode = d_inode(root);
 +      IMustLock(root_inode);
 +      err = test_add(sb, add, remount);
 +      if (unlikely(err < 0))
@@ -3299,7 +3314,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +              au_cpup_attr_all(root_inode, /*force*/1);
 +              sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
 +      } else
-+              au_add_nlink(root_inode, h_dentry->d_inode);
++              au_add_nlink(root_inode, d_inode(h_dentry));
 +
 +      /*
 +       * this test/set prevents aufs from handling unnecesary notify events
@@ -3386,7 +3401,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
 +                       aufs_bindex_t bend)
 +{
-+      return au_test_ibusy(dentry->d_inode, bstart, bend);
++      return au_test_ibusy(d_inode(dentry), bstart, bend);
 +}
 +
 +/*
@@ -3519,7 +3534,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +
 +      sigen = au_sigen(root->d_sb);
 +      DiMustNoWaiters(root);
-+      IiMustNoWaiters(root->d_inode);
++      IiMustNoWaiters(d_inode(root));
 +      di_write_unlock(root);
 +      err = test_dentry_busy(root, bindex, sigen, verbose);
 +      if (!err)
@@ -3730,7 +3745,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      SiMustWriteLock(sb);
 +
 +      root = sb->s_root;
-+      inode = root->d_inode;
++      inode = d_inode(root);
 +      sbinfo = au_sbi(sb);
 +      bend = sbinfo->si_bend;
 +
@@ -3846,10 +3861,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      }
 +
 +      if (!bindex) {
-+              au_cpup_attr_all(root->d_inode, /*force*/1);
++              au_cpup_attr_all(d_inode(root), /*force*/1);
 +              sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
 +      } else
-+              au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
++              au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
 +      if (au_opt_test(mnt_flags, PLINK))
 +              au_plink_half_refresh(sb, br_id);
 +
@@ -4076,7 +4091,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      }
 +      AuDbg("bindex b%d\n", bindex);
 +
-+      err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
++      err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
 +      if (unlikely(err))
 +              goto out;
 +
@@ -4104,7 +4119,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +              if (!au_br_writable(mod->perm)) {
 +                      /* rw --> ro, file might be mmapped */
 +                      DiMustNoWaiters(root);
-+                      IiMustNoWaiters(root->d_inode);
++                      IiMustNoWaiters(d_inode(root));
 +                      di_write_unlock(root);
 +                      err = au_br_mod_files_ro(sb, bindex);
 +                      /* aufs_write_lock() calls ..._child() */
@@ -4179,7 +4194,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     2015-06-22 08:29:23.703424266 +0200
++++ linux/fs/aufs/branch.h     2015-06-28 17:36:09.025073697 +0200
 @@ -0,0 +1,279 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -4369,10 +4384,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +static const loff_t au_loff_max = LLONG_MAX;
 +
 +int au_xib_trunc(struct super_block *sb);
-+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
++ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
 +                 loff_t *pos);
-+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
-+                  loff_t *pos);
++ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
++                  size_t size, loff_t *pos);
 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
 +ino_t au_xino_new_ino(struct super_block *sb);
@@ -4462,7 +4477,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +#endif /* __AUFS_BRANCH_H__ */
 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 --- /usr/share/empty/fs/aufs/conf.mk   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/conf.mk      2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/conf.mk      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,38 @@
 +
 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
@@ -4504,8 +4519,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       2015-06-22 08:29:23.703424266 +0200
-@@ -0,0 +1,1308 @@
++++ linux/fs/aufs/cpup.c       2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,1319 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -4638,7 +4653,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +
 +      dt->dt_dentry = dentry;
 +      dt->dt_h_path = *h_path;
-+      h_inode = h_path->dentry->d_inode;
++      h_inode = d_inode(h_path->dentry);
 +      dt->dt_atime = h_inode->i_atime;
 +      dt->dt_mtime = h_inode->i_mtime;
 +      /* smp_mb(); */
@@ -4683,10 +4698,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct au_branch *br;
 +
 +      h_path.dentry = au_h_dptr(dst, bindex);
-+      h_idst = h_path.dentry->d_inode;
++      h_idst = d_inode(h_path.dentry);
 +      br = au_sbr(dst->d_sb, bindex);
 +      h_path.mnt = au_br_mnt(br);
-+      h_isrc = h_src->d_inode;
++      h_isrc = d_inode(h_src);
 +      ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
 +              | ATTR_ATIME | ATTR_MTIME
 +              | ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -4915,7 +4930,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      }
 +
 +      /* try stopping to update while we copyup */
-+      IMustLock(file[SRC].dentry->d_inode);
++      IMustLock(d_inode(file[SRC].dentry));
 +      err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
 +
 +      fput(file[DST].file);
@@ -4937,7 +4952,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct inode *h_src_inode, *h_dst_inode;
 +
 +      err = 0;
-+      h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
++      h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
 +      l = i_size_read(h_src_inode);
 +      if (cpg->len == -1 || l < cpg->len)
 +              cpg->len = l;
@@ -4949,7 +4964,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
 +              h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
 +              h_src_attr->iflags = h_src_inode->i_flags;
-+              err = vfs_getattr(&h_path, &h_src_attr->st);
++              if (!au_test_nfs(h_src_inode->i_sb))
++                      err = vfs_getattr(&h_path, &h_src_attr->st);
++              else {
++                      mutex_unlock(&h_src_inode->i_mutex);
++                      err = vfs_getattr(&h_path, &h_src_attr->st);
++                      mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
++              }
 +              if (unlikely(err)) {
 +                      mutex_unlock(&h_src_inode->i_mutex);
 +                      goto out;
@@ -4963,7 +4984,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      }
 +      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;
++              h_dst_inode = d_inode(h_path.dentry);
 +              spin_lock(&h_dst_inode->i_lock);
 +              h_dst_inode->i_state |= I_LINKABLE;
 +              spin_unlock(&h_dst_inode->i_lock);
@@ -4982,9 +5003,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              char *k;
 +              char __user *u;
 +      } sym;
++      struct inode *h_inode = d_inode(h_src);
++      const struct inode_operations *h_iop = h_inode->i_op;
 +
 +      err = -ENOSYS;
-+      if (unlikely(!h_src->d_inode->i_op->readlink))
++      if (unlikely(!h_iop->readlink))
 +              goto out;
 +
 +      err = -ENOMEM;
@@ -4995,7 +5018,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      /* unnecessary to support mmap_sem since symlink is not mmap-able */
 +      old_fs = get_fs();
 +      set_fs(KERNEL_DS);
-+      symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
++      symlen = h_iop->readlink(h_src, sym.u, PATH_MAX);
 +      err = symlen;
 +      set_fs(old_fs);
 +
@@ -5021,13 +5044,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct au_dtime dt;
 +      struct path h_path;
 +      struct dentry *h_src, *h_dst, *h_parent;
-+      struct inode *h_inode, *h_dir;
++      struct inode *h_inode, *h_dir, *dir, *inode;
 +      struct super_block *sb;
 +
 +      /* bsrc branch can be ro/rw. */
 +      h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
-+      h_inode = h_src->d_inode;
-+      AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
++      h_inode = d_inode(h_src);
++      AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
 +
 +      /* try stopping to be referenced while we are creating */
 +      h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
@@ -5035,7 +5058,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
 +                                AUFS_WH_PFX_LEN));
 +      h_parent = h_dst->d_parent; /* dir inode is locked */
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      IMustLock(h_dir);
 +      AuDebugOn(h_parent != h_dst->d_parent);
 +
@@ -5066,10 +5089,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +                       * strange behaviour from the users view,
 +                       * particularry setattr case
 +                       */
-+                      if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
-+                              au_cpup_attr_nlink(dst_parent->d_inode,
-+                                                 /*force*/1);
-+                      au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
++                      dir = d_inode(dst_parent);
++                      if (au_ibstart(dir) == cpg->bdst)
++                              au_cpup_attr_nlink(dir, /*force*/1);
++                      inode = d_inode(cpg->dentry);
++                      au_cpup_attr_nlink(inode, /*force*/1);
 +              }
 +              break;
 +      case S_IFLNK:
@@ -5095,7 +5119,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +          && (h_inode->i_nlink == 1
 +              || (h_inode->i_state & I_LINKABLE))
 +          /* todo: unnecessary? */
-+          /* && cpg->dentry->d_inode->i_nlink == 1 */
++          /* && d_inode(cpg->dentry)->i_nlink == 1 */
 +          && cpg->bdst < cpg->bsrc
 +          && !au_ftest_cpup(cpg->flags, KEEPLINO))
 +              au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
@@ -5146,7 +5170,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              goto out;
 +
 +      h_parent = h_dentry->d_parent; /* dir inode is locked */
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      IMustLock(h_dir);
 +      AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
 +      /* no delegation since it is just created */
@@ -5170,7 +5194,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      aufs_bindex_t old_ibstart;
 +      unsigned char isdir, plink;
 +      struct dentry *h_src, *h_dst, *h_parent;
-+      struct inode *dst_inode, *h_dir, *inode, *delegated;
++      struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
 +      struct super_block *sb;
 +      struct au_branch *br;
 +      /* to reuduce stack size */
@@ -5191,11 +5215,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      a->h_path.mnt = au_br_mnt(br);
 +      h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
 +      h_parent = h_dst->d_parent; /* dir inode is locked */
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      IMustLock(h_dir);
 +
 +      h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
-+      inode = cpg->dentry->d_inode;
++      inode = d_inode(cpg->dentry);
 +
 +      if (!dst_parent)
 +              dst_parent = dget_parent(cpg->dentry);
@@ -5220,7 +5244,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +                      err = PTR_ERR(h_src);
 +                      if (IS_ERR(h_src))
 +                              goto out_parent;
-+                      if (unlikely(!h_src->d_inode)) {
++                      if (unlikely(d_is_negative(h_src))) {
 +                              err = -EIO;
 +                              AuIOErr("i%lu exists on a upper branch "
 +                                      "but not pseudo-linked\n",
@@ -5259,7 +5283,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
 +      if (unlikely(err))
 +              goto out_rev;
-+      dst_inode = h_dst->d_inode;
++      dst_inode = d_inode(h_dst);
 +      mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
 +      /* todo: necessary? */
 +      /* au_pin_hdir_unlock(cpg->pin); */
@@ -5294,9 +5318,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      if (unlikely(err))
 +              goto out_rev;
 +
++      src_inode = d_inode(h_src);
 +      if (!isdir
-+          && (h_src->d_inode->i_nlink > 1
-+              || h_src->d_inode->i_state & I_LINKABLE)
++          && (src_inode->i_nlink > 1
++              || src_inode->i_state & I_LINKABLE)
 +          && plink)
 +              au_plink_append(inode, cpg->bdst, h_dst);
 +
@@ -5313,7 +5338,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      au_dtime_store(&a->dt, dst_parent, &a->h_path);
 +      a->h_path.dentry = h_dst;
 +      rerr = 0;
-+      if (h_dst->d_inode) {
++      if (d_is_positive(h_dst)) {
 +              if (!isdir) {
 +                      /* no delegation since it is just created */
 +                      rerr = vfsub_unlink(h_dir, &a->h_path,
@@ -5396,7 +5421,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct dentry *h_dentry;
 +
 +      h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
-+      if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
++      if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
 +              err = au_cpup_single(cpg, dst_parent);
 +      else {
 +              struct au_cpup_single_args args = {
@@ -5477,9 +5502,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      }
 +
 +      parent = dget_parent(dentry);
-+      h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
++      h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
 +      if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
-+          && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
++          && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
 +              err = au_cpup_simple(cpg);
 +      else {
 +              struct au_cpup_simple_args args = {
@@ -5510,7 +5535,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
 +                      h_dentry = au_h_dptr(dentry, bsrc);
 +                      if (h_dentry) {
-+                              AuDebugOn(!h_dentry->d_inode);
++                              AuDebugOn(d_is_negative(h_dentry));
 +                              break;
 +                      }
 +              }
@@ -5602,17 +5627,17 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      h_path.dentry = wh_dentry;
 +      if (!d_is_dir(wh_dentry)) {
 +              /* no delegation since it is just created */
-+              err = vfsub_unlink(h_parent->d_inode, &h_path,
++              err = vfsub_unlink(d_inode(h_parent), &h_path,
 +                                 /*delegated*/NULL, /*force*/0);
 +      } else
-+              err = vfsub_rmdir(h_parent->d_inode, &h_path);
++              err = vfsub_rmdir(d_inode(h_parent), &h_path);
 +      if (unlikely(err)) {
 +              AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
 +                      wh_dentry, err);
 +              err = -EIO;
 +      }
 +      au_dtime_revert(&dt);
-+      au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
++      au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
 +
 +out_wh:
 +      dput(wh_dentry);
@@ -5648,7 +5673,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      dentry = cpg->dentry;
 +      bdst = cpg->bdst;
 +      parent = dget_parent(dentry);
-+      dir = parent->d_inode;
++      dir = d_inode(parent);
 +      h_orph = NULL;
 +      h_parent = NULL;
 +      h_dir = au_igrab(au_h_iptr(dir, bdst));
@@ -5660,7 +5685,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +
 +              h_parent = dget(au_h_dptr(parent, bdst));
 +              au_set_h_dptr(parent, bdst, dget(h_orph));
-+              h_tmpdir = h_orph->d_inode;
++              h_tmpdir = d_inode(h_orph);
 +              au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
 +
 +              mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
@@ -5673,7 +5698,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      }
 +
 +      if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
-+          && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
++          && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
 +              err = au_cpup_wh(cpg, file);
 +      else {
 +              struct au_cpup_wh_args args = {
@@ -5714,7 +5739,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +{
 +      int err;
 +      struct au_pin pin;
-+      struct dentry *d, *parent, *h_parent, *real_parent;
++      struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
 +
 +      err = 0;
 +      parent = dget_parent(dentry);
@@ -5747,8 +5772,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +                      di_write_lock_child3(d);
 +
 +              /* somebody else might create while we were sleeping */
-+              if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
-+                      if (au_h_dptr(d, bdst))
++              h_dentry = au_h_dptr(d, bdst);
++              if (!h_dentry || d_is_negative(h_dentry)) {
++                      if (h_dentry)
 +                              au_update_dbstart(d);
 +
 +                      au_pin_set_dentry(&pin, d);
@@ -5798,7 +5824,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      struct inode *dir;
 +
 +      parent = dget_parent(dentry);
-+      dir = parent->d_inode;
++      dir = d_inode(parent);
 +      err = 0;
 +      if (au_h_iptr(dir, bdst))
 +              goto out;
@@ -5816,7 +5842,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       2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/cpup.h       2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,94 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -5914,7 +5940,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    2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/dbgaufs.c    2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,432 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -6350,7 +6376,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    2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/dbgaufs.h    2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,48 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -6402,7 +6428,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      2015-06-22 08:27:37.877501704 +0200
++++ linux/fs/aufs/dcsub.c      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,224 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -6630,8 +6656,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      2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,132 @@
++++ linux/fs/aufs/dcsub.h      2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,136 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -6695,10 +6721,12 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +static inline int au_d_hashed_positive(struct dentry *d)
 +{
 +      int err;
-+      struct inode *inode = d->d_inode;
++      struct inode *inode = d_inode(d);
 +
 +      err = 0;
-+      if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
++      if (unlikely(d_unhashed(d)
++                   || d_is_negative(d)
++                   || !inode->i_nlink))
 +              err = -ENOENT;
 +      return err;
 +}
@@ -6706,11 +6734,11 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +static inline int au_d_linkable(struct dentry *d)
 +{
 +      int err;
-+      struct inode *inode = d->d_inode;
++      struct inode *inode = d_inode(d);
 +
 +      err = au_d_hashed_positive(d);
 +      if (err
-+          && inode
++          && d_is_positive(d)
 +          && (inode->i_state & I_LINKABLE))
 +              err = 0;
 +      return err;
@@ -6725,8 +6753,10 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +      if (!IS_ROOT(d))
 +              err = au_d_hashed_positive(d);
 +      else {
-+              inode = d->d_inode;
-+              if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
++              inode = d_inode(d);
++              if (unlikely(d_unlinked(d)
++                           || d_is_negative(d)
++                           || !inode->i_nlink))
 +                      err = -ENOENT;
 +      }
 +      return err;
@@ -6737,7 +6767,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +      int err;
 +
 +      err = au_d_alive(d);
-+      if (unlikely(err || IS_DEADDIR(d->d_inode)))
++      if (unlikely(err || IS_DEADDIR(d_inode(d))))
 +              err = -ENOENT;
 +      return err;
 +}
@@ -6766,8 +6796,8 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +#endif /* __AUFS_DCSUB_H__ */
 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 --- /usr/share/empty/fs/aufs/debug.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.c      2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,438 @@
++++ linux/fs/aufs/debug.c      2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,440 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -6961,14 +6991,16 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +           au_dcount(dentry), dentry->d_flags,
 +           d_unhashed(dentry) ? "un" : "");
 +      hn = -1;
-+      if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
-+              iinfo = au_ii(dentry->d_inode);
++      if (bindex >= 0
++          && d_is_positive(dentry)
++          && au_test_aufs(dentry->d_sb)) {
++              iinfo = au_ii(d_inode(dentry));
 +              if (iinfo) {
 +                      hn = !!au_hn(iinfo->ii_hinode + bindex);
 +                      wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
 +              }
 +      }
-+      do_pri_inode(bindex, dentry->d_inode, hn, wh);
++      do_pri_inode(bindex, d_inode(dentry), hn, wh);
 +      return 0;
 +}
 +
@@ -7123,7 +7155,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +
 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
 +{
-+      struct inode *h_inode, *inode = dentry->d_inode;
++      struct inode *h_inode, *inode = d_inode(dentry);
 +      struct dentry *h_dentry;
 +      aufs_bindex_t bindex, bend, bi;
 +
@@ -7144,7 +7176,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +              if (!h_dentry)
 +                      continue;
 +              h_inode = au_h_iptr(inode, bindex);
-+              if (unlikely(h_inode != h_dentry->d_inode)) {
++              if (unlikely(h_inode != d_inode(h_dentry))) {
 +                      au_debug_on();
 +                      AuDbg("b%d, %s:%d\n", bindex, func, line);
 +                      AuDbgDentry(dentry);
@@ -7208,8 +7240,8 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +}
 diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
 --- /usr/share/empty/fs/aufs/debug.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.h      2015-06-22 08:27:37.877501704 +0200
-@@ -0,0 +1,228 @@
++++ linux/fs/aufs/debug.h      2015-06-28 17:35:44.348050491 +0200
+@@ -0,0 +1,225 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -7398,9 +7430,6 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
 +} while (0)
 +#else
 +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
-+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
-+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
-+         unsigned int sigen)
 +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
 +AuStubVoid(au_dbg_verify_kthread, void)
 +AuStubInt0(__init au_debug_init, void)
@@ -7440,8 +7469,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     2015-06-22 08:27:37.877501704 +0200
-@@ -0,0 +1,1097 @@
++++ linux/fs/aufs/dentry.c     2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,1105 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -7526,8 +7555,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              goto out;
 +      }
 +
-+      h_inode = h_dentry->d_inode;
-+      if (!h_inode) {
++      h_inode = d_inode(h_dentry);
++      if (d_is_negative(h_dentry)) {
 +              if (!allow_neg)
 +                      goto out_neg;
 +      } else if (wh_found
@@ -7542,7 +7571,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +      if (!d_is_dir(h_dentry)
 +          || !wh_able
-+          || (d_is_positive(dentry) && !d_is_dir(dentry)))
++          || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
 +              goto out; /* success */
 +
 +      mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
@@ -7588,7 +7617,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      };
 +      const struct qstr *name = &dentry->d_name;
 +      struct dentry *parent;
-+      struct inode *inode;
 +      struct super_block *sb;
 +
 +      sb = dentry->d_sb;
@@ -7600,7 +7628,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      if (unlikely(err))
 +              goto out;
 +
-+      inode = dentry->d_inode;
 +      isdir = !!d_is_dir(dentry);
 +      if (!type)
 +              au_fset_lkup(args.flags, ALLOW_NEG);
@@ -7615,7 +7642,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +              h_dentry = au_h_dptr(dentry, bindex);
 +              if (h_dentry) {
-+                      if (h_dentry->d_inode)
++                      if (d_is_positive(h_dentry))
 +                              npositive++;
 +                      if (type != S_IFDIR)
 +                              break;
@@ -7625,7 +7652,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              if (!h_parent || !d_is_dir(h_parent))
 +                      continue;
 +
-+              h_dir = h_parent->d_inode;
++              h_dir = d_inode(h_parent);
 +              mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
 +              h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
 +                                      &args);
@@ -7642,9 +7669,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +                      break;
 +              if (!h_dentry)
 +                      continue;
-+              h_inode = h_dentry->d_inode;
-+              if (!h_inode)
++              if (d_is_negative(h_dentry))
 +                      continue;
++              h_inode = d_inode(h_dentry);
 +              npositive++;
 +              if (!args.type)
 +                      args.type = h_inode->i_mode & S_IFMT;
@@ -7682,7 +7709,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      struct dentry *dentry;
 +      int wkq_err;
 +
-+      if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
++      if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
 +              dentry = vfsub_lkup_one(name, parent);
 +      else {
 +              struct vfsub_lkup_one_args args = {
@@ -7718,7 +7745,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      err = PTR_ERR(h_dentry);
 +      if (IS_ERR(h_dentry))
 +              goto out;
-+      if (unlikely(h_dentry->d_inode)) {
++      if (unlikely(d_is_positive(h_dentry))) {
 +              err = -EIO;
 +              AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
 +              dput(h_dentry);
@@ -7793,10 +7820,11 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      err = 0;
 +      memset(&ia, -1, sizeof(ia));
 +      h_sb = h_dentry->d_sb;
-+      h_inode = h_dentry->d_inode;
-+      if (h_inode)
++      h_inode = NULL;
++      if (d_is_positive(h_dentry)) {
++              h_inode = d_inode(h_dentry);
 +              au_iattr_save(&ia, h_inode);
-+      else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
++      else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
 +              /* nfs d_revalidate may return 0 for negative dentry */
 +              /* fuse d_revalidate always return 0 for negative dentry */
 +              goto out;
@@ -7809,7 +7837,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +      err = 0;
 +      if (unlikely(h_d != h_dentry
-+                   || h_d->d_inode != h_inode
++                   || d_inode(h_d) != h_inode
 +                   || (h_inode && au_iattr_test(&ia, h_inode))))
 +              err = au_busy_or_stale();
 +      dput(h_d);
@@ -7828,7 +7856,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +      if (udba == AuOpt_UDBA_REVAL
 +          && !au_test_fs_remote(h_dentry->d_sb)) {
 +              IMustLock(h_dir);
-+              err = (h_dentry->d_parent->d_inode != h_dir);
++              err = (d_inode(h_dentry->d_parent) != h_dir);
 +      } else if (udba != AuOpt_UDBA_NONE)
 +              err = au_h_verify_dentry(h_dentry, h_parent, br);
 +
@@ -7920,9 +7948,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +{
 +      struct inode *inode;
 +
-+      inode = dentry->d_inode;
-+      if (inode) {
-+              if (!S_ISDIR(inode->i_mode)) {
++      if (d_really_is_positive(dentry)) {
++              inode = d_inode(dentry);
++              if (!d_is_dir(dentry)) {
 +                      if (inode->i_nlink && !d_unhashed(dentry))
 +                              drop_nlink(inode);
 +              } else {
@@ -8019,20 +8047,26 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +      err = 0;
 +      AuDebugOn(dinfo->di_bstart < 0);
-+      orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
-+      orig_h.inode = orig_h.dentry->d_inode;
 +      orig_h.mode = 0;
-+      if (orig_h.inode)
++      orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
++      orig_h.inode = NULL;
++      if (d_is_positive(orig_h.dentry)) {
++              orig_h.inode = d_inode(orig_h.dentry);
 +              orig_h.mode = orig_h.inode->i_mode & S_IFMT;
++      }
 +      memset(&tmp_h, 0, sizeof(tmp_h));
 +      if (tmp->di_bstart >= 0) {
 +              tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
-+              tmp_h.inode = tmp_h.dentry->d_inode;
-+              if (tmp_h.inode)
++              tmp_h.inode = NULL;
++              if (d_is_positive(tmp_h.dentry)) {
++                      tmp_h.inode = d_inode(tmp_h.dentry);
 +                      tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
++              }
 +      }
 +
-+      inode = dentry->d_inode;
++      inode = NULL;
++      if (d_really_is_positive(dentry))
++              inode = d_inode(dentry);
 +      if (!orig_h.inode) {
 +              AuDbg("nagative originally\n");
 +              if (inode) {
@@ -8112,8 +8146,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +                                      h_dentry = hd[bindex].hd_dentry;
 +                                      if (!h_dentry)
 +                                              continue;
-+                                      h_inode = h_dentry->d_inode;
-+                                      AuDebugOn(!h_inode);
++                                      AuDebugOn(d_is_negative(h_dentry));
++                                      h_inode = d_inode(h_dentry);
 +                                      AuDebugOn(orig_h.mode
 +                                                != (h_inode->i_mode
 +                                                    & S_IFMT));
@@ -8147,10 +8181,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +      DiMustWriteLock(dentry);
 +      AuDebugOn(IS_ROOT(dentry));
-+      AuDebugOn(!parent->d_inode);
++      AuDebugOn(d_really_is_negative(parent));
 +
 +      sb = dentry->d_sb;
-+      inode = dentry->d_inode;
 +      sigen = au_sigen(sb);
 +      err = au_digen_test(parent, sigen);
 +      if (unlikely(err))
@@ -8166,8 +8199,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +      if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
 +              AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
-+              if (inode)
++              if (d_really_is_positive(dentry)) {
++                      inode = d_inode(dentry);
 +                      err = au_refresh_hinode_self(inode);
++              }
 +              au_dbg_verify_dinode(dentry);
 +              if (!err)
 +                      goto out_dgen; /* success */
@@ -8324,10 +8359,12 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +                      continue;
 +
 +              /* UDBA tests */
-+              h_inode = h_dentry->d_inode;
-+              if (unlikely(!!inode != !!h_inode))
++              if (unlikely(!!inode != d_is_positive(h_dentry)))
 +                      goto err;
 +
++              h_inode = NULL;
++              if (d_is_positive(h_dentry))
++                      h_inode = d_inode(h_dentry);
 +              h_plus = plus;
 +              h_mode = mode;
 +              h_cached_inode = h_inode;
@@ -8386,7 +8423,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +{
 +      int err;
 +      struct dentry *d, *parent;
-+      struct inode *inode;
 +
 +      if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
 +              return simple_reval_dpath(dentry, sigen);
@@ -8405,7 +8441,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +                      d = parent;
 +              }
 +
-+              inode = d->d_inode;
 +              if (d != dentry)
 +                      di_write_lock_child2(d);
 +
@@ -8462,7 +8497,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +              AuTraceErr(err);
 +              goto out;
 +      }
-+      inode = dentry->d_inode;
++      inode = NULL;
++      if (d_really_is_positive(dentry))
++              inode = d_inode(dentry);
 +      if (unlikely(inode && is_bad_inode(inode))) {
 +              err = -EINVAL;
 +              AuTraceErr(err);
@@ -8541,7 +8578,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +};
 diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 --- /usr/share/empty/fs/aufs/dentry.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dentry.h     2015-06-22 08:27:37.877501704 +0200
++++ linux/fs/aufs/dentry.h     2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,233 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -8778,8 +8815,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      2015-06-22 08:27:37.877501704 +0200
-@@ -0,0 +1,544 @@
++++ linux/fs/aufs/dinfo.c      2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,550 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -9002,24 +9039,30 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +
 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
 +{
++      struct inode *inode;
++
 +      au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
-+      if (d->d_inode) {
++      if (d_really_is_positive(d)) {
++              inode = d_inode(d);
 +              if (au_ftest_lock(flags, IW))
-+                      do_ii_write_lock(d->d_inode, lsc);
++                      do_ii_write_lock(inode, lsc);
 +              else if (au_ftest_lock(flags, IR))
-+                      do_ii_read_lock(d->d_inode, lsc);
++                      do_ii_read_lock(inode, lsc);
 +      }
 +}
 +
 +void di_read_unlock(struct dentry *d, int flags)
 +{
-+      if (d->d_inode) {
++      struct inode *inode;
++
++      if (d_really_is_positive(d)) {
++              inode = d_inode(d);
 +              if (au_ftest_lock(flags, IW)) {
 +                      au_dbg_verify_dinode(d);
-+                      ii_write_unlock(d->d_inode);
++                      ii_write_unlock(inode);
 +              } else if (au_ftest_lock(flags, IR)) {
 +                      au_dbg_verify_dinode(d);
-+                      ii_read_unlock(d->d_inode);
++                      ii_read_unlock(inode);
 +              }
 +      }
 +      au_rw_read_unlock(&au_di(d)->di_rwsem);
@@ -9027,30 +9070,30 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +
 +void di_downgrade_lock(struct dentry *d, int flags)
 +{
-+      if (d->d_inode && au_ftest_lock(flags, IR))
-+              ii_downgrade_lock(d->d_inode);
++      if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
++              ii_downgrade_lock(d_inode(d));
 +      au_rw_dgrade_lock(&au_di(d)->di_rwsem);
 +}
 +
 +void di_write_lock(struct dentry *d, unsigned int lsc)
 +{
 +      au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
-+      if (d->d_inode)
-+              do_ii_write_lock(d->d_inode, lsc);
++      if (d_really_is_positive(d))
++              do_ii_write_lock(d_inode(d), lsc);
 +}
 +
 +void di_write_unlock(struct dentry *d)
 +{
 +      au_dbg_verify_dinode(d);
-+      if (d->d_inode)
-+              ii_write_unlock(d->d_inode);
++      if (d_really_is_positive(d))
++              ii_write_unlock(d_inode(d));
 +      au_rw_write_unlock(&au_di(d)->di_rwsem);
 +}
 +
 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
 +{
 +      AuDebugOn(d1 == d2
-+                || d1->d_inode == d2->d_inode
++                || d_inode(d1) == d_inode(d2)
 +                || d1->d_sb != d2->d_sb);
 +
 +      if (isdir && au_test_subdir(d1, d2)) {
@@ -9066,7 +9109,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
 +{
 +      AuDebugOn(d1 == d2
-+                || d1->d_inode == d2->d_inode
++                || d_inode(d1) == d_inode(d2)
 +                || d1->d_sb != d2->d_sb);
 +
 +      if (isdir && au_test_subdir(d1, d2)) {
@@ -9082,7 +9125,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
 +{
 +      di_write_unlock(d1);
-+      if (d1->d_inode == d2->d_inode)
++      if (d_inode(d1) == d_inode(d2))
 +              au_rw_write_unlock(&au_di(d2)->di_rwsem);
 +      else
 +              di_write_unlock(d2);
@@ -9114,8 +9157,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +      struct dentry *h_dentry;
 +      struct inode *inode, *h_inode;
 +
-+      inode = dentry->d_inode;
-+      AuDebugOn(!inode);
++      AuDebugOn(d_really_is_negative(dentry));
 +
 +      h_dentry = NULL;
 +      if (au_dbstart(dentry) <= bindex
@@ -9126,6 +9168,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +              goto out; /* success */
 +      }
 +
++      inode = d_inode(dentry);
 +      AuDebugOn(bindex < au_ibstart(inode));
 +      AuDebugOn(au_ibend(inode) < bindex);
 +      h_inode = au_h_iptr(inode, bindex);
@@ -9225,7 +9268,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +
 +      err = 0;
 +      if (unlikely(au_digen(dentry) != sigen
-+                   || au_iigen_test(dentry->d_inode, sigen)))
++                   || au_iigen_test(d_inode(dentry), sigen)))
 +              err = -EIO;
 +
 +      return err;
@@ -9256,7 +9299,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +              bend = dinfo->di_bend;
 +              for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
 +                      h_d = hdp[0 + bindex].hd_dentry;
-+                      if (h_d && !h_d->d_inode)
++                      if (h_d && d_is_negative(h_d))
 +                              au_set_h_dptr(dentry, bindex, NULL);
 +              }
 +      }
@@ -9288,7 +9331,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +              h_dentry = au_h_dptr(dentry, bindex);
 +              if (!h_dentry)
 +                      continue;
-+              if (h_dentry->d_inode) {
++              if (d_is_positive(h_dentry)) {
 +                      au_set_dbstart(dentry, bindex);
 +                      return;
 +              }
@@ -9306,7 +9349,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +              h_dentry = au_h_dptr(dentry, bindex);
 +              if (!h_dentry)
 +                      continue;
-+              if (h_dentry->d_inode) {
++              if (d_is_positive(h_dentry)) {
 +                      au_set_dbend(dentry, bindex);
 +                      return;
 +              }
@@ -9326,8 +9369,8 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 --- /usr/share/empty/fs/aufs/dir.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dir.c        2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,751 @@
++++ linux/fs/aufs/dir.c        2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,753 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -9410,8 +9453,8 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +                   bindex <= bend && sz < KMALLOC_MAX_SIZE;
 +                   bindex++) {
 +                      h_dentry = au_h_dptr(dentry, bindex);
-+                      if (h_dentry && h_dentry->d_inode)
-+                              sz += i_size_read(h_dentry->d_inode);
++                      if (h_dentry && d_is_positive(h_dentry))
++                              sz += i_size_read(d_inode(h_dentry));
 +              }
 +      }
 +      if (sz < KMALLOC_MAX_SIZE)
@@ -9443,12 +9486,12 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      aufs_bindex_t bstart, bindex;
 +
 +      sb = a->dentry->d_sb;
-+      dir = a->dentry->d_inode;
-+      if (!dir)
++      if (d_really_is_negative(a->dentry))
 +              goto out;
-+      /* no dir->i_mutex lock */
 +      aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */
 +
++      /* no dir->i_mutex lock */
++      dir = d_inode(a->dentry);
 +      bstart = au_ibstart(dir);
 +      bindex = au_br_index(sb, a->brid);
 +      if (bindex < bstart)
@@ -9586,7 +9629,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +
 +      err = 0;
 +      dentry = file->f_path.dentry;
-+      file->f_version = dentry->d_inode->i_version;
++      file->f_version = d_inode(dentry)->i_version;
 +      bindex = au_dbstart(dentry);
 +      au_set_fbstart(file, bindex);
 +      btail = au_dbtaildir(dentry);
@@ -9710,7 +9753,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +
 +      err = 0;
 +      sb = dentry->d_sb;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +      bend = au_dbend(dentry);
 +      for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
@@ -9764,12 +9807,14 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +{
 +      int err;
 +      struct dentry *dentry;
++      struct inode *inode;
 +      struct super_block *sb;
 +      struct mutex *mtx;
 +
 +      err = 0;
 +      dentry = file->f_path.dentry;
-+      mtx = &dentry->d_inode->i_mutex;
++      inode = d_inode(dentry);
++      mtx = &inode->i_mutex;
 +      mutex_lock(mtx);
 +      sb = dentry->d_sb;
 +      si_noflush_read_lock(sb);
@@ -9779,7 +9824,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +              di_write_lock_child(dentry);
 +              err = au_do_fsync_dir_no_file(dentry, datasync);
 +      }
-+      au_cpup_attr_timesizes(dentry->d_inode);
++      au_cpup_attr_timesizes(inode);
 +      di_write_unlock(dentry);
 +      if (file)
 +              fi_write_unlock(file);
@@ -9801,7 +9846,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
 +
 +      dentry = file->f_path.dentry;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +
 +      sb = dentry->d_sb;
@@ -9957,7 +10002,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      struct inode *h_inode;
 +
 +      h_dentry = au_h_dptr(dentry, arg->bindex);
-+      h_inode = h_dentry->d_inode;
++      h_inode = d_inode(h_dentry);
 +      /* todo: i_mode changes anytime? */
 +      mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
 +      err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
@@ -10022,7 +10067,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +              struct dentry *h_dentry;
 +
 +              h_dentry = au_h_dptr(dentry, bindex);
-+              if (h_dentry && h_dentry->d_inode) {
++              if (h_dentry && d_is_positive(h_dentry)) {
 +                      arg.bindex = bindex;
 +                      err = test_empty(dentry, &arg);
 +              }
@@ -10054,7 +10099,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +              struct dentry *h_dentry;
 +
 +              h_dentry = au_h_dptr(dentry, bindex);
-+              if (h_dentry && h_dentry->d_inode) {
++              if (h_dentry && d_is_positive(h_dentry)) {
 +                      arg.bindex = bindex;
 +                      err = sio_test_empty(dentry, &arg);
 +              }
@@ -10081,7 +10126,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        2015-06-22 08:27:37.877501704 +0200
++++ linux/fs/aufs/dir.h        2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,131 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -10216,7 +10261,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      2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/dynop.c      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,369 @@
 +/*
 + * Copyright (C) 2010-2015 Junjiro R. Okajima
@@ -10589,7 +10634,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      2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/dynop.h      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,74 @@
 +/*
 + * Copyright (C) 2010-2015 Junjiro R. Okajima
@@ -10667,8 +10712,8 @@ diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
 +#endif /* __AUFS_DYNOP_H__ */
 diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 --- /usr/share/empty/fs/aufs/export.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/export.c     2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,831 @@
++++ linux/fs/aufs/export.c     2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,832 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -10917,7 +10962,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +              hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
 +                      spin_lock(&d->d_lock);
 +                      if (!au_test_anon(d)
-+                          && d->d_parent->d_inode->i_ino == dir_ino) {
++                          && d_inode(d->d_parent)->i_ino == dir_ino) {
 +                              dentry = dget_dlock(d);
 +                              spin_unlock(&d->d_lock);
 +                              break;
@@ -11076,7 +11121,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +              goto out_name;
 +
 +      /* do not call vfsub_lkup_one() */
-+      dir = parent->d_inode;
++      dir = d_inode(parent);
 +      mutex_lock(&dir->i_mutex);
 +      dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
 +      mutex_unlock(&dir->i_mutex);
@@ -11084,7 +11129,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +      if (IS_ERR(dentry))
 +              goto out_name;
 +      AuDebugOn(au_test_anon(dentry));
-+      if (unlikely(!dentry->d_inode)) {
++      if (unlikely(d_really_is_negative(dentry))) {
 +              dput(dentry);
 +              dentry = ERR_PTR(-ENOENT);
 +      }
@@ -11225,10 +11270,10 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +
 +      dentry = ERR_PTR(-ENOENT);
 +      AuDebugOn(au_test_anon(path.dentry));
-+      if (unlikely(!path.dentry->d_inode))
++      if (unlikely(d_really_is_negative(path.dentry)))
 +              goto out_path;
 +
-+      if (ino != path.dentry->d_inode->i_ino)
++      if (ino != d_inode(path.dentry)->i_ino)
 +              dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
 +      else
 +              dentry = dget(path.dentry);
@@ -11309,7 +11354,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +
 +accept:
 +      if (!au_digen_test(dentry, au_sigen(sb))
-+          && dentry->d_inode->i_generation == fh[Fh_igen])
++          && d_inode(dentry)->i_generation == fh[Fh_igen])
 +              goto out_unlock; /* success */
 +
 +      dput(dentry);
@@ -11393,7 +11438,8 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +              dput(dentry);
 +              if (unlikely(!parent))
 +                      goto out_unlock;
-+              dir = parent->d_inode;
++              if (d_really_is_positive(parent))
++                      dir = d_inode(parent);
 +      }
 +
 +      ii_read_lock_parent(dir);
@@ -11502,7 +11548,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +}
 diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
 --- /usr/share/empty/fs/aufs/fhsm.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/fhsm.c       2015-06-22 08:27:37.880835119 +0200
++++ linux/fs/aufs/fhsm.c       2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,426 @@
 +/*
 + * Copyright (C) 2011-2015 Junjiro R. Okajima
@@ -11932,8 +11978,8 @@ diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
 +}
 diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 --- /usr/share/empty/fs/aufs/file.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/file.c       2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,844 @@
++++ linux/fs/aufs/file.c       2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,841 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -11984,15 +12030,12 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      /* a race condition can happen between open and unlink/rmdir */
 +      h_file = ERR_PTR(-ENOENT);
 +      h_dentry = au_h_dptr(dentry, bindex);
-+      if (au_test_nfsd() && !h_dentry)
-+              goto out;
-+      h_inode = h_dentry->d_inode;
-+      if (au_test_nfsd() && !h_inode)
++      if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
 +              goto out;
++      h_inode = d_inode(h_dentry);
 +      spin_lock(&h_dentry->d_lock);
 +      err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
-+              || !h_inode
-+              /* || !dentry->d_inode->i_nlink */
++              /* || !d_inode(dentry)->i_nlink */
 +              ;
 +      spin_unlock(&h_dentry->d_lock);
 +      if (unlikely(err))
@@ -12006,7 +12049,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +              goto out;
 +
 +      /* drop flags for writing */
-+      if (au_test_ro(sb, bindex, dentry->d_inode)) {
++      if (au_test_ro(sb, bindex, d_inode(dentry))) {
 +              if (force_wr && !(flags & O_WRONLY))
 +                      force_wr = 0;
 +              flags = au_file_roflags(flags);
@@ -12069,7 +12112,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      struct au_hinode *hdir;
 +
 +      DiMustWriteLock(dentry);
-+      IiMustWriteLock(dentry->d_inode);
++      IiMustWriteLock(d_inode(dentry));
 +
 +      err = 0;
 +      if (IS_ROOT(dentry))
@@ -12132,7 +12175,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +
 +      h_path.mnt = au_br_mnt(br);
 +      h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
-+      hdir = au_hi(parent->d_inode, cpg.bsrc);
++      hdir = au_hi(d_inode(parent), cpg.bsrc);
 +      delegated = NULL;
 +      err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
 +      au_unpin(&pin);
@@ -12316,13 +12359,13 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      };
 +
 +      au_update_dbstart(cpg.dentry);
-+      inode = cpg.dentry->d_inode;
++      inode = d_inode(cpg.dentry);
 +      h_inode = NULL;
 +      if (au_dbstart(cpg.dentry) <= bcpup
 +          && au_dbend(cpg.dentry) >= bcpup) {
 +              h_dentry = au_h_dptr(cpg.dentry, bcpup);
-+              if (h_dentry)
-+                      h_inode = h_dentry->d_inode;
++              if (h_dentry && d_is_positive(h_dentry))
++                      h_inode = d_inode(h_dentry);
 +      }
 +      hi_wh = au_hi_wh(inode, bcpup);
 +      if (!hi_wh && !h_inode)
@@ -12361,7 +12404,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      };
 +
 +      sb = cpg.dentry->d_sb;
-+      inode = cpg.dentry->d_inode;
++      inode = d_inode(cpg.dentry);
 +      cpg.bsrc = au_fbstart(file);
 +      err = au_test_ro(sb, cpg.bsrc, inode);
 +      if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
@@ -12482,7 +12525,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      err = 0;
 +      finfo = au_fi(file);
 +      sb = cpg.dentry->d_sb;
-+      inode = cpg.dentry->d_inode;
++      inode = d_inode(cpg.dentry);
 +      cpg.bdst = au_ibstart(inode);
 +      if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
 +              goto out;
@@ -12662,7 +12705,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +
 +      err = 0;
 +      dentry = file->f_path.dentry;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      sigen = au_sigen(dentry->d_sb);
 +      fi_write_lock(file);
 +      figen = au_figen(file);
@@ -12710,8 +12753,8 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +}
 +
 +/* it will never be called, but necessary to support O_DIRECT */
-+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
-+                            struct iov_iter *iter, loff_t offset)
++static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
++                            loff_t offset)
 +{ BUG(); return 0; }
 +
 +/* they will never be called. */
@@ -12780,7 +12823,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +};
 diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 --- /usr/share/empty/fs/aufs/file.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/file.h       2015-06-22 08:27:37.880835119 +0200
++++ linux/fs/aufs/file.h       2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,291 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -13075,7 +13118,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      2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/finfo.c      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,157 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -13236,8 +13279,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       2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,748 @@
++++ linux/fs/aufs/f_op.c       2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,738 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -13545,8 +13588,6 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +      ssize_t err;
 +      struct file *file;
 +      ssize_t (*iter)(struct kiocb *, struct iov_iter *);
-+      ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
-+                     loff_t);
 +
 +      err = security_file_permission(h_file, rw);
 +      if (unlikely(err))
@@ -13554,14 +13595,10 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +
 +      err = -ENOSYS;
 +      iter = NULL;
-+      aio = NULL;
-+      if (rw == MAY_READ) {
++      if (rw == MAY_READ)
 +              iter = h_file->f_op->read_iter;
-+              aio = h_file->f_op->aio_read;
-+      } else if (rw == MAY_WRITE) {
++      else if (rw == MAY_WRITE)
 +              iter = h_file->f_op->write_iter;
-+              aio = h_file->f_op->aio_write;
-+      }
 +
 +      file = kio->ki_filp;
 +      kio->ki_filp = h_file;
@@ -13569,10 +13606,6 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +              lockdep_off();
 +              err = iter(kio, iov_iter);
 +              lockdep_on();
-+      } else if (aio) {
-+              lockdep_off();
-+              err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
-+              lockdep_on();
 +      } else
 +              /* currently there is no such fs */
 +              WARN_ON_ONCE(1);
@@ -13988,7 +14021,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +};
 diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 --- /usr/share/empty/fs/aufs/fstype.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/fstype.h     2015-06-22 08:27:37.880835119 +0200
++++ linux/fs/aufs/fstype.h     2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,400 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -14392,7 +14425,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  2015-06-22 08:27:37.880835119 +0200
++++ linux/fs/aufs/hfsnotify.c  2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,288 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -14684,7 +14717,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    2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/hfsplus.c    2015-06-28 17:36:09.025073697 +0200
 @@ -0,0 +1,56 @@
 +/*
 + * Copyright (C) 2010-2015 Junjiro R. Okajima
@@ -14723,7 +14756,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
 +
 +      h_dentry = au_h_dptr(dentry, bindex);
 +      AuDebugOn(!h_dentry);
-+      AuDebugOn(!h_dentry->d_inode);
++      AuDebugOn(d_is_negative(h_dentry));
 +
 +      h_file = NULL;
 +      if (au_test_hfsplus(h_dentry->d_sb)
@@ -14744,8 +14777,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    2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,714 @@
++++ linux/fs/aufs/hnotify.c    2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,710 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -14919,10 +14952,10 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +                              continue;
 +
 +                      au_digen_dec(d);
-+                      if (d->d_inode)
++                      if (d_really_is_positive(d))
 +                              /* todo: reset children xino?
 +                                 cached children only? */
-+                              au_iigen_dec(d->d_inode);
++                              au_iigen_dec(d_inode(d));
 +              }
 +      }
 +
@@ -15000,12 +15033,8 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
 +{
 +      int err;
-+      struct inode *inode;
 +
-+      inode = dentry->d_inode;
-+      if (IS_ROOT(dentry)
-+          /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
-+              ) {
++      if (IS_ROOT(dentry)) {
 +              pr_warn("branch root dir was changed\n");
 +              return 0;
 +      }
@@ -15013,11 +15042,11 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +      err = 0;
 +      if (!isdir) {
 +              au_digen_dec(dentry);
-+              if (inode)
-+                      au_iigen_dec(inode);
++              if (d_really_is_positive(dentry))
++                      au_iigen_dec(d_inode(dentry));
 +      } else {
 +              au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
-+              if (inode)
++              if (d_really_is_positive(dentry))
 +                      err = hn_gen_tree(dentry);
 +      }
 +
@@ -15237,8 +15266,8 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +              dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
 +                                            a->dir);
 +      try_iput = 0;
-+      if (dentry)
-+              inode = dentry->d_inode;
++      if (dentry && d_really_is_positive(dentry))
++              inode = d_inode(dentry);
 +      if (xino && !inode && h_ino
 +          && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
 +              || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
@@ -15462,7 +15491,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +}
 diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 --- /usr/share/empty/fs/aufs/iinfo.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/iinfo.c      2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/iinfo.c      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,277 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -15743,8 +15772,8 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +}
 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 --- /usr/share/empty/fs/aufs/inode.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/inode.c      2015-06-22 08:27:37.884168534 +0200
-@@ -0,0 +1,495 @@
++++ linux/fs/aufs/inode.c      2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,500 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -15881,18 +15910,19 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      flags = au_hi_flags(inode, isdir);
 +      bend = au_dbend(dentry);
 +      for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
-+              struct inode *h_i;
++              struct inode *h_i, *h_inode;
 +              struct dentry *h_d;
 +
 +              h_d = au_h_dptr(dentry, bindex);
-+              if (!h_d || !h_d->d_inode)
++              if (!h_d || d_is_negative(h_d))
 +                      continue;
 +
-+              AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
++              h_inode = d_inode(h_d);
++              AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
 +              if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
 +                      h_i = au_h_iptr(inode, bindex);
 +                      if (h_i) {
-+                              if (h_i == h_d->d_inode)
++                              if (h_i == h_inode)
 +                                      continue;
 +                              err = -EIO;
 +                              break;
@@ -15902,7 +15932,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +                      iinfo->ii_bstart = bindex;
 +              if (iinfo->ii_bend < bindex)
 +                      iinfo->ii_bend = bindex;
-+              au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
++              au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
 +              update = 1;
 +      }
 +      au_update_ibrange(inode, /*do_put_zero*/0);
@@ -15933,7 +15963,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      err = 0;
 +      isdir = 0;
 +      bstart = au_dbstart(dentry);
-+      h_inode = au_h_dptr(dentry, bstart)->d_inode;
++      h_dentry = au_h_dptr(dentry, bstart);
++      h_inode = d_inode(h_dentry);
 +      mode = h_inode->i_mode;
 +      switch (mode & S_IFMT) {
 +      case S_IFREG:
@@ -15982,7 +16013,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +              h_dentry = au_h_dptr(dentry, bindex);
 +              if (h_dentry)
 +                      au_set_h_iptr(inode, bindex,
-+                                    au_igrab(h_dentry->d_inode), flags);
++                                    au_igrab(d_inode(h_dentry)), flags);
 +      }
 +      au_cpup_attr_all(inode, /*force*/1);
 +      /*
@@ -16007,6 +16038,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      struct au_iigen iigen;
 +      aufs_bindex_t bindex, bend;
 +      struct inode *h_inode, *h_dinode;
++      struct dentry *h_dentry;
 +
 +      /*
 +       * before this function, if aufs got any iinfo lock, it must be only
@@ -16019,7 +16051,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +
 +      err = 1;
 +      ii_write_lock_new_child(inode);
-+      h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
++      h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
++      h_dinode = d_inode(h_dentry);
 +      bend = au_ibend(inode);
 +      for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
 +              h_inode = au_h_iptr(inode, bindex);
@@ -16081,7 +16114,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +/* todo: return with unlocked? */
 +struct inode *au_new_inode(struct dentry *dentry, int must_new)
 +{
-+      struct inode *inode;
++      struct inode *inode, *h_inode;
 +      struct dentry *h_dentry;
 +      struct super_block *sb;
 +      struct mutex *mtx;
@@ -16092,7 +16125,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +      sb = dentry->d_sb;
 +      bstart = au_dbstart(dentry);
 +      h_dentry = au_h_dptr(dentry, bstart);
-+      h_ino = h_dentry->d_inode->i_ino;
++      h_inode = d_inode(h_dentry);
++      h_ino = h_inode->i_ino;
 +
 +      /*
 +       * stop 'race'-ing between hardlinks under different
@@ -16175,7 +16209,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +                      mutex_lock(mtx);
 +      }
 +
-+      if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
++      if (unlikely(au_test_fs_unique_ino(h_inode)))
 +              AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
 +                      " b%d, %s, %pd, hi%lu, i%lu.\n",
 +                      bstart, au_sbtype(h_dentry->d_sb), dentry,
@@ -16242,7 +16276,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
 +}
 diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 --- /usr/share/empty/fs/aufs/inode.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/inode.h      2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/inode.h      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,673 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -16919,7 +16953,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      2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/ioctl.c      2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,219 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -17142,8 +17176,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   2015-06-22 08:27:37.880835119 +0200
-@@ -0,0 +1,930 @@
++++ linux/fs/aufs/i_op_add.c   2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,932 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -17186,7 +17220,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      bwh = -1;
 +      sb = dir->i_sb;
 +      if (wh_dentry) {
-+              h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
++              h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
 +              IMustLock(h_dir);
 +              AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
 +              bwh = au_dbwh(dentry);
@@ -17201,7 +17235,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      inode = au_new_inode(dentry, /*must_new*/1);
 +      if (!IS_ERR(inode)) {
 +              d_instantiate(dentry, inode);
-+              dir = dentry->d_parent->d_inode; /* dir inode is locked */
++              dir = d_inode(dentry->d_parent); /* dir inode is locked */
 +              IMustLock(dir);
 +              au_dir_ts(dir, bindex);
 +              dir->i_version++;
@@ -17235,7 +17269,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      err = 0;
 +      if (unlikely(d_unhashed(dentry)))
 +              err = -ENOENT;
-+      if (unlikely(dentry->d_inode))
++      if (unlikely(d_really_is_positive(dentry)))
 +              err = -EEXIST;
 +      return err;
 +}
@@ -17257,15 +17291,17 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +              goto out;
 +
 +      h_dentry = au_h_dptr(dentry, bindex);
-+      h_inode = h_dentry->d_inode;
-+      if (!dentry->d_inode) {
++      if (d_really_is_negative(dentry)) {
 +              err = -EEXIST;
-+              if (unlikely(h_inode))
++              if (unlikely(d_is_positive(h_dentry)))
 +                      goto out;
 +      } else {
 +              /* rename(2) case */
 +              err = -EIO;
-+              if (unlikely(!h_inode || !h_inode->i_nlink))
++              if (unlikely(d_is_negative(h_dentry)))
++                      goto out;
++              h_inode = d_inode(h_dentry);
++              if (unlikely(!h_inode->i_nlink))
 +                      goto out;
 +
 +              h_mode = h_inode->i_mode;
@@ -17460,7 +17496,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +              err = epilog(dir, bstart, wh_dentry, dentry);
 +
 +      /* revert */
-+      if (unlikely(created && err && a->h_path.dentry->d_inode)) {
++      if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
 +              /* no delegation since it is just created */
 +              rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
 +                                  /*force*/0);
@@ -17573,7 +17609,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      parent = d_find_any_alias(dir);
 +      AuDebugOn(!parent);
 +      di_write_lock_parent(parent);
-+      if (unlikely(parent->d_inode != dir))
++      if (unlikely(d_inode(parent) != dir))
 +              goto out_parent;
 +
 +      err = au_digen_test(parent, au_sigen(sb));
@@ -17599,7 +17635,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +              goto out_parent;
 +
 +      h_parent = au_h_dptr(parent, bindex);
-+      err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
++      err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC);
 +      if (unlikely(err))
 +              goto out_mnt;
 +
@@ -17716,7 +17752,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      plink = 0;
 +      h_inode = NULL;
 +      sb = src_dentry->d_sb;
-+      inode = src_dentry->d_inode;
++      inode = d_inode(src_dentry);
 +      if (au_ibstart(inode) <= a->bdst)
 +              h_inode = au_h_iptr(inode, a->bdst);
 +      if (!h_inode || !h_inode->i_nlink) {
@@ -17730,7 +17766,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +              au_set_h_dptr(dentry, a->bdst, NULL);
 +              AuDbg("temporary d_inode...\n");
 +              spin_lock(&dentry->d_lock);
-+              dentry->d_inode = src_dentry->d_inode; /* tmp */
++              dentry->d_inode = d_inode(src_dentry); /* tmp */
 +              spin_unlock(&dentry->d_lock);
 +              h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
 +              if (IS_ERR(h_file))
@@ -17769,7 +17805,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +                      if (IS_ERR(h_src_dentry))
 +                              goto out;
 +
-+                      if (unlikely(!h_src_dentry->d_inode)) {
++                      if (unlikely(d_is_negative(h_src_dentry))) {
 +                              dput(h_src_dentry);
 +                              h_src_dentry = NULL;
 +                      }
@@ -17815,7 +17851,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +      };
 +
 +      IMustLock(dir);
-+      inode = src_dentry->d_inode;
++      inode = d_inode(src_dentry);
 +      IMustLock(inode);
 +
 +      err = -ENOMEM;
@@ -17901,7 +17937,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +              if (!err) {
 +                      h_src_dentry = au_h_dptr(src_dentry, a->bdst);
 +                      err = -ENOENT;
-+                      if (h_src_dentry && h_src_dentry->d_inode) {
++                      if (h_src_dentry && d_is_positive(h_src_dentry)) {
 +                              delegated = NULL;
 +                              err = vfsub_link(h_src_dentry,
 +                                               au_pinned_h_dir(&a->pin),
@@ -18017,7 +18053,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
 +
 +      /* make the dir opaque */
 +      diropq = 0;
-+      h_mtx = &h_path.dentry->d_inode->i_mutex;
++      h_mtx = &d_inode(h_path.dentry)->i_mutex;
 +      if (wh_dentry
 +          || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
 +              mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
@@ -18076,8 +18112,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       2015-06-22 08:29:23.706757681 +0200
-@@ -0,0 +1,1445 @@
++++ linux/fs/aufs/i_op.c       2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,1447 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -18492,7 +18528,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      struct inode *h_dir;
 +
 +      if (add_entry)
-+              IMustLock(parent->d_inode);
++              IMustLock(d_inode(parent));
 +      else
 +              di_write_lock_parent(parent);
 +
@@ -18507,7 +18543,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      }
 +      if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
 +              h_parent = au_h_dptr(parent, bcpup);
-+              h_dir = h_parent->d_inode;
++              h_dir = d_inode(h_parent);
 +              mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
 +              err = au_lkup_neg(dentry, bcpup, /*wh*/0);
 +              /* todo: no unlock here */
@@ -18515,7 +18551,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +
 +              AuDbg("bcpup %d\n", bcpup);
 +              if (!err) {
-+                      if (!dentry->d_inode)
++                      if (d_really_is_negative(dentry))
 +                              au_set_h_dptr(dentry, bstart, NULL);
 +                      au_update_dbrange(dentry, /*do_put_zero*/0);
 +              }
@@ -18566,7 +18602,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +                      bcpup = err;
 +              }
 +
-+              if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
++              if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
 +                      if (add_entry)
 +                              err = AuWbrCopyup(sbinfo, dentry);
 +                      else {
@@ -18583,7 +18619,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              }
 +      } else {
 +              bcpup = args->force_btgt;
-+              AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
++              AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
 +      }
 +
 +      AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
@@ -18594,7 +18630,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      /* copyup the new parent into the branch we process */
 +      err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
 +      if (err >= 0) {
-+              if (!dentry->d_inode) {
++              if (d_really_is_negative(dentry)) {
 +                      au_set_h_dptr(dentry, bstart, NULL);
 +                      au_set_dbstart(dentry, bcpup);
 +                      au_set_dbend(dentry, bcpup);
@@ -18629,7 +18665,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
 +
 +      err = -EBUSY;
-+      if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
++      if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
 +              goto out;
 +
 +      err = 0;
@@ -18657,9 +18693,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
 +              if (!h_d[i])
 +                      continue;
-+              h_i = h_d[i]->d_inode;
-+              if (h_i)
++              if (d_is_positive(h_d[i])) {
++                      h_i = d_inode(h_d[i]);
 +                      err = !h_i->i_nlink;
++              }
 +      }
 +
 +out:
@@ -18747,7 +18784,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +
 +      h_dir = NULL;
 +      p->h_parent = au_h_dptr(p->parent, p->bindex);
-+      p->hdir = au_hi(p->parent->d_inode, p->bindex);
++      p->hdir = au_hi(d_inode(p->parent), p->bindex);
 +      if (p->hdir)
 +              h_dir = p->hdir->hi_inode;
 +
@@ -18834,11 +18871,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
 +{
 +      int err;
-+      struct inode *inode;
 +      struct dentry *parent;
 +
 +      err = 0;
-+      inode = dentry->d_inode;
 +      if (au_digen_test(dentry, sigen)) {
 +              parent = dget_parent(dentry);
 +              di_read_lock_parent(parent, AuLock_IR);
@@ -18868,7 +18903,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              au_fset_wrdir(wr_dir_args.flags, ISDIR);
 +      /* plink or hi_wh() case */
 +      bstart = au_dbstart(dentry);
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      ibstart = au_ibstart(inode);
 +      if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
 +              wr_dir_args.force_btgt = ibstart;
@@ -18893,8 +18928,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              goto out_parent;
 +
 +      a->h_path.dentry = au_h_dptr(dentry, bstart);
-+      a->h_inode = a->h_path.dentry->d_inode;
 +      sz = -1;
++      a->h_inode = d_inode(a->h_path.dentry);
 +      if (ia && (ia->ia_valid & ATTR_SIZE)) {
 +              mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
 +              if (ia->ia_size < i_size_read(a->h_inode))
@@ -18948,7 +18983,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              a->h_path.dentry = hi_wh; /* do not dget here */
 +
 +out_unlock:
-+      a->h_inode = a->h_path.dentry->d_inode;
++      a->h_inode = d_inode(a->h_path.dentry);
 +      if (!err)
 +              goto out; /* success */
 +      au_unpin(&a->pin);
@@ -18971,7 +19006,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      struct file *file;
 +      struct au_icpup_args *a;
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +
 +      err = -ENOMEM;
@@ -19119,7 +19154,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      struct au_icpup_args *a;
 +      struct inode *inode, *h_inode;
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +
 +      err = -ENOMEM;
@@ -19150,7 +19185,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              break;
 +      case AU_ACL_SET:
 +              err = -EOPNOTSUPP;
-+              h_inode = h_path.dentry->d_inode;
++              h_inode = d_inode(h_path.dentry);
 +              if (h_inode->i_op->set_acl)
 +                      err = h_inode->i_op->set_acl(h_inode,
 +                                                   arg->u.acl_set.acl,
@@ -19253,7 +19288,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      } else
 +              di_read_lock_child(dentry, AuLock_IR);
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      bindex = au_ibstart(inode);
 +      h_path->mnt = au_sbr_mnt(sb, bindex);
 +      h_sb = h_path->mnt->mnt_sb;
@@ -19286,7 +19321,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      struct inode *inode;
 +      struct super_block *sb;
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      sb = dentry->d_sb;
 +      err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
 +      if (unlikely(err))
@@ -19298,13 +19333,13 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              /* illegally overlapped or something */
 +              goto out_fill; /* pretending success */
 +
-+      positive = !!h_path.dentry->d_inode;
++      positive = d_is_positive(h_path.dentry);
 +      if (positive)
 +              err = vfs_getattr(&h_path, st);
 +      if (!err) {
 +              if (positive)
 +                      au_refresh_iattr(inode, st,
-+                                       h_path.dentry->d_inode->i_nlink);
++                                       d_inode(h_path.dentry)->i_nlink);
 +              goto out_fill; /* success */
 +      }
 +      AuTraceErr(err);
@@ -19329,10 +19364,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      int err;
 +      struct super_block *sb;
 +      struct dentry *h_dentry;
++      struct inode *inode, *h_inode;
 +
 +      err = -EINVAL;
 +      h_dentry = au_h_dptr(dentry, bindex);
-+      if (unlikely(!h_dentry->d_inode->i_op->readlink))
++      h_inode = d_inode(h_dentry);
++      if (unlikely(!h_inode->i_op->readlink))
 +              goto out;
 +
 +      err = security_inode_readlink(h_dentry);
@@ -19340,11 +19377,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +              goto out;
 +
 +      sb = dentry->d_sb;
-+      if (!au_test_ro(sb, bindex, dentry->d_inode)) {
++      inode = d_inode(dentry);
++      if (!au_test_ro(sb, bindex, inode)) {
 +              vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
-+              fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
++              fsstack_copy_attr_atime(inode, h_inode);
 +      }
-+      err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
++      err = h_inode->i_op->readlink(h_dentry, buf, bufsiz);
 +
 +out:
 +      return err;
@@ -19525,8 +19563,8 @@ 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   2015-06-22 08:27:37.884168534 +0200
-@@ -0,0 +1,506 @@
++++ linux/fs/aufs/i_op_del.c   2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,510 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -19570,7 +19608,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      bstart = au_dbstart(dentry);
 +      if (*bcpup < 0) {
 +              *bcpup = bstart;
-+              if (au_test_ro(sb, bstart, dentry->d_inode)) {
++              if (au_test_ro(sb, bstart, d_inode(dentry))) {
 +                      err = AuWbrCopyup(au_sbi(sb), dentry);
 +                      *bcpup = err;
 +                      if (unlikely(err < 0))
@@ -19578,7 +19616,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +              }
 +      } else
 +              AuDebugOn(bstart < *bcpup
-+                        || au_test_ro(sb, *bcpup, dentry->d_inode));
++                        || au_test_ro(sb, *bcpup, d_inode(dentry)));
 +      AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
 +
 +      if (*bcpup != bstart) {
@@ -19622,10 +19660,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      struct inode *h_inode;
 +
 +      h_dentry = au_h_dptr(dentry, bindex);
-+      h_inode = h_dentry->d_inode;
-+      if (dentry->d_inode) {
++      if (d_really_is_positive(dentry)) {
 +              err = -ENOENT;
-+              if (unlikely(!h_inode || !h_inode->i_nlink))
++              if (unlikely(d_is_negative(h_dentry)))
++                      goto out;
++              h_inode = d_inode(h_dentry);
++              if (unlikely(!h_inode->i_nlink))
 +                      goto out;
 +
 +              h_mode = h_inode->i_mode;
@@ -19640,7 +19680,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      } else {
 +              /* rename(2) case */
 +              err = -EIO;
-+              if (unlikely(h_inode))
++              if (unlikely(d_is_positive(h_dentry)))
 +                      goto out;
 +      }
 +
@@ -19656,7 +19696,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +       */
 +      err = -EACCES;
 +      if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
-+                   && au_test_h_perm(h_parent->d_inode,
++                   && au_test_h_perm(d_inode(h_parent),
 +                                     MAY_EXEC | MAY_WRITE)))
 +              goto out;
 +
@@ -19746,6 +19786,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      int rmdir_later, err, dirwh;
 +      struct dentry *h_dentry;
 +      struct super_block *sb;
++      struct inode *inode;
 +
 +      sb = dentry->d_sb;
 +      SiMustAnyLock(sb);
@@ -19755,7 +19796,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +              goto out;
 +
 +      /* stop monitoring */
-+      au_hn_free(au_hi(dentry->d_inode, bindex));
++      inode = d_inode(dentry);
++      au_hn_free(au_hi(inode, bindex));
 +
 +      if (!au_test_fs_remote(h_dentry->d_sb)) {
 +              dirwh = au_sbi(sb)->si_dirwh;
@@ -19788,7 +19830,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +{
 +      struct inode *inode;
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      d_drop(dentry);
 +      inode->i_ctime = dir->i_ctime;
 +
@@ -19848,7 +19890,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      err = au_d_hashed_positive(dentry);
 +      if (unlikely(err))
 +              goto out_unlock;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +      err = -EISDIR;
 +      if (unlikely(d_is_dir(dentry)))
@@ -19879,7 +19921,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +              }
 +      } else {
 +              /* dir inode is locked */
-+              h_dir = wh_dentry->d_parent->d_inode;
++              h_dir = d_inode(wh_dentry->d_parent);
 +              IMustLock(h_dir);
 +              err = 0;
 +      }
@@ -19892,7 +19934,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +              if (bindex == bstart) {
 +                      vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
 +                      /*ignore*/
-+                      inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
++                      inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
 +              } else
 +                      /* todo: this timestamp may be reverted later */
 +                      inode->i_ctime = h_dir->i_ctime;
@@ -19949,7 +19991,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +      err = au_alive_dir(dentry);
 +      if (unlikely(err))
 +              goto out_unlock;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      IMustLock(inode);
 +      err = -ENOTDIR;
 +      if (unlikely(!d_is_dir(dentry)))
@@ -19989,7 +20031,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +              au_hn_free(au_hi(inode, bstart));
 +
 +              /* dir inode is locked */
-+              IMustLock(wh_dentry->d_parent->d_inode);
++              IMustLock(d_inode(wh_dentry->d_parent));
 +              err = 0;
 +      }
 +
@@ -20035,8 +20077,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
 +}
 diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 --- /usr/share/empty/fs/aufs/i_op_ren.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op_ren.c   2015-06-22 08:27:37.884168534 +0200
-@@ -0,0 +1,1015 @@
++++ linux/fs/aufs/i_op_ren.c   2015-06-28 17:36:09.025073697 +0200
+@@ -0,0 +1,1017 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -20193,7 +20235,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +              RevertFailure("lkup one %pd", a->dst_dentry);
 +              return;
 +      }
-+      if (a->h_path.dentry->d_inode) {
++      if (d_is_positive(a->h_path.dentry)) {
 +              d_drop(a->h_path.dentry);
 +              dput(a->h_path.dentry);
 +              return;
@@ -20319,7 +20361,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +      /* prepare workqueue args for asynchronous rmdir */
 +      h_d = a->dst_h_dentry;
-+      if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
++      if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) {
 +              err = -ENOMEM;
 +              a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
 +              if (unlikely(!a->thargs))
@@ -20345,7 +20387,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +              err = PTR_ERR(h_d);
 +              if (IS_ERR(h_d))
 +                      goto out_whsrc;
-+              if (!h_d->d_inode)
++              if (d_is_negative(h_d))
 +                      dput(h_d);
 +              else
 +                      a->dst_wh_dentry = h_d;
@@ -20365,7 +20407,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +              a->dst_h_dentry = au_h_dptr(d, a->btgt);
 +      }
 +
-+      BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
++      BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_bstart != a->btgt);
 +
 +      /* rename by vfs_rename or cpup */
 +      d = a->dst_dentry;
@@ -20392,7 +20434,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +      AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
 +      a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
 +      vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
-+      a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
++      a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
 +
 +      /* remove whiteout for dentry */
 +      if (a->dst_wh_dentry) {
@@ -20565,20 +20607,18 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +              goto out;
 +
 +      err = -EIO;
-+      h_inode = a->dst_h_dentry->d_inode;
 +      isdir = !!au_ftest_ren(a->flags, ISDIR);
-+      if (!a->dst_dentry->d_inode) {
-+              if (unlikely(h_inode))
-+                      goto out;
-+              err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
-+                               isdir);
++      if (d_really_is_negative(a->dst_dentry)) {
++              if (d_is_negative(a->dst_h_dentry))
++                      err = au_may_add(a->dst_dentry, a->btgt,
++                                       a->dst_h_parent, isdir);
 +      } else {
-+              if (unlikely(!h_inode || !h_inode->i_nlink))
-+                      goto out;
-+              err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
-+                               isdir);
-+              if (unlikely(err))
++              if (unlikely(d_is_negative(a->dst_h_dentry)))
 +                      goto out;
++              h_inode = d_inode(a->dst_h_dentry);
++              if (h_inode->i_nlink)
++                      err = au_may_del(a->dst_dentry, a->btgt,
++                                       a->dst_h_parent, isdir);
 +      }
 +
 +out:
@@ -20639,16 +20679,16 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +      a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
 +                                    a->dst_h_parent, a->dst_hdir);
 +      udba = au_opt_udba(a->src_dentry->d_sb);
-+      if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
-+                   || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
++      if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
++                   || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
 +              err = au_busy_or_stale();
 +      if (!err && au_dbstart(a->src_dentry) == a->btgt)
 +              err = au_h_verify(a->src_h_dentry, udba,
-+                                a->src_h_parent->d_inode, a->src_h_parent,
++                                d_inode(a->src_h_parent), a->src_h_parent,
 +                                a->br);
 +      if (!err && au_dbstart(a->dst_dentry) == a->btgt)
 +              err = au_h_verify(a->dst_h_dentry, udba,
-+                                a->dst_h_parent->d_inode, a->dst_h_parent,
++                                d_inode(a->dst_h_parent), a->dst_h_parent,
 +                                a->br);
 +      if (!err)
 +              goto out; /* success */
@@ -20755,7 +20795,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +      struct au_branch *br;
 +
 +      parent = dentry->d_parent;
-+      IMustLock(parent->d_inode); /* dir is locked */
++      IMustLock(d_inode(parent)); /* dir is locked */
 +
 +      bdiropq = au_dbdiropq(parent);
 +      bwh = au_dbwh(dentry);
@@ -20807,7 +20847,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +      a->h_path.dentry = a->src_h_dentry;
 +      au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
-+      if (a->dst_h_dentry->d_inode) {
++      if (d_is_positive(a->dst_h_dentry)) {
 +              au_fset_ren(a->flags, DT_DSTDIR);
 +              a->h_path.dentry = a->dst_h_dentry;
 +              au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
@@ -20825,14 +20865,14 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +      if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
 +              h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
-+              h_mtx = &h_d->d_inode->i_mutex;
++              h_mtx = &d_inode(h_d)->i_mutex;
 +              mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
 +              au_dtime_revert(a->src_dt + AuCHILD);
 +              mutex_unlock(h_mtx);
 +
 +              if (au_ftest_ren(a->flags, DT_DSTDIR)) {
 +                      h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
-+                      h_mtx = &h_d->d_inode->i_mutex;
++                      h_mtx = &d_inode(h_d)->i_mutex;
 +                      mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
 +                      au_dtime_revert(a->dst_dt + AuCHILD);
 +                      mutex_unlock(h_mtx);
@@ -20861,11 +20901,15 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +
 +      a->src_dir = _src_dir;
 +      a->src_dentry = _src_dentry;
-+      a->src_inode = a->src_dentry->d_inode;
++      a->src_inode = NULL;
++      if (d_really_is_positive(a->src_dentry))
++              a->src_inode = d_inode(a->src_dentry);
 +      a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
 +      a->dst_dir = _dst_dir;
 +      a->dst_dentry = _dst_dentry;
-+      a->dst_inode = a->dst_dentry->d_inode;
++      a->dst_inode = NULL;
++      if (d_really_is_positive(a->dst_dentry))
++              a->dst_inode = d_inode(a->dst_dentry);
 +      a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
 +      if (a->dst_inode) {
 +              IMustLock(a->dst_inode);
@@ -20876,7 +20920,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +      flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
 +      if (d_is_dir(a->src_dentry)) {
 +              au_fset_ren(a->flags, ISDIR);
-+              if (unlikely(d_is_positive(a->dst_dentry)
++              if (unlikely(d_really_is_positive(a->dst_dentry)
 +                           && !d_is_dir(a->dst_dentry)))
 +                      goto out_free;
 +              err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
@@ -20913,7 +20957,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +       * there may exist a problem somewhere else.
 +       */
 +      err = -EINVAL;
-+      if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
++      if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
 +              goto out_unlock;
 +
 +      au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
@@ -21054,7 +21098,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
 +}
 diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
 --- /usr/share/empty/fs/aufs/Kconfig   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/Kconfig      2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/Kconfig      2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,185 @@
 +config AUFS_FS
 +      tristate "Aufs (Advanced multi layered unification filesystem) support"
@@ -21243,7 +21287,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       2015-06-22 08:29:23.706757681 +0200
++++ linux/fs/aufs/loop.c       2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,145 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -21392,7 +21436,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       2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/loop.h       2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,52 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -21448,7 +21492,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
 +#endif /* __AUFS_LOOP_H__ */
 diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
 --- /usr/share/empty/fs/aufs/magic.mk  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/magic.mk     2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/magic.mk     2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,30 @@
 +
 +# defined in ${srctree}/fs/fuse/inode.c
@@ -21482,7 +21526,7 @@ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
 +endif
 diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
 --- /usr/share/empty/fs/aufs/Makefile  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/Makefile     2015-06-22 08:27:37.874168290 +0200
++++ linux/fs/aufs/Makefile     2015-06-28 17:35:44.344717109 +0200
 @@ -0,0 +1,44 @@
 +
 +include ${src}/magic.mk
@@ -21530,7 +21574,7 @@ diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
 diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 --- /usr/share/empty/fs/aufs/module.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/module.c     2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/module.c     2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,210 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -21744,7 +21788,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     2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/module.h     2015-06-28 17:35:44.348050491 +0200
 @@ -0,0 +1,104 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -21852,7 +21896,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     2015-06-22 08:27:37.884168534 +0200
++++ linux/fs/aufs/mvdown.c     2015-06-28 17:36:09.025073697 +0200
 @@ -0,0 +1,694 @@
 +/*
 + * Copyright (C) 2011-2015 Junjiro R. Okajima
@@ -22006,7 +22050,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +                          AuPin_MNT_WRITE | AuPin_DI_LOCKED);
 +              err = au_do_pin(&a->mvd_pin_src);
 +              AuTraceErr(err);
-+              a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
++              a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
 +              if (unlikely(err)) {
 +                      AU_MVD_PR(dmsg, "pin_src failed\n");
 +                      goto out_dst;
@@ -22020,7 +22064,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +                   au_opt_udba(a->sb),
 +                   AuPin_MNT_WRITE | AuPin_DI_LOCKED);
 +      AuTraceErr(err);
-+      a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
++      a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
 +      if (unlikely(err)) {
 +              AU_MVD_PR(dmsg, "pin_src failed\n");
 +              au_pin_hdir_lock(&a->mvd_pin_dst);
@@ -22114,10 +22158,10 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +      }
 +
 +      err = 0;
-+      if (h_path.dentry->d_inode) {
++      if (d_is_positive(h_path.dentry)) {
 +              h_path.mnt = au_br_mnt(br);
 +              delegated = NULL;
-+              err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
++              err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
 +                                 &delegated, /*force*/0);
 +              if (unlikely(err == -EWOULDBLOCK)) {
 +                      pr_warn("cannot retry for NFSv4 delegation"
@@ -22499,13 +22543,13 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +      args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
 +      args->mvdown.au_errno = 0;
 +      args->dentry = dentry;
-+      args->inode = dentry->d_inode;
++      args->inode = d_inode(dentry);
 +      args->sb = dentry->d_sb;
 +
 +      err = -ENOENT;
 +      dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
 +      args->parent = dget_parent(dentry);
-+      args->dir = args->parent->d_inode;
++      args->dir = d_inode(args->parent);
 +      mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
 +      dput(args->parent);
 +      if (unlikely(args->parent != dentry->d_parent)) {
@@ -22550,8 +22594,8 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
 +}
 diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 --- /usr/share/empty/fs/aufs/opts.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/opts.c       2015-06-22 08:29:23.710091096 +0200
-@@ -0,0 +1,1854 @@
++++ linux/fs/aufs/opts.c       2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,1835 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -22598,7 +22642,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +      Opt_warn_perm, Opt_nowarn_perm,
 +      Opt_wbr_copyup, Opt_wbr_create,
 +      Opt_fhsm_sec,
-+      Opt_refrof, Opt_norefrof,
 +      Opt_verbose, Opt_noverbose,
 +      Opt_sum, Opt_nosum, Opt_wsum,
 +      Opt_dirperm1, Opt_nodirperm1,
@@ -22682,9 +22725,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +      {Opt_dirperm1, "dirperm1"},
 +      {Opt_nodirperm1, "nodirperm1"},
 +
-+      {Opt_refrof, "refrof"},
-+      {Opt_norefrof, "norefrof"},
-+
 +      {Opt_verbose, "verbose"},
 +      {Opt_verbose, "v"},
 +      {Opt_noverbose, "noverbose"},
@@ -23250,12 +23290,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              case Opt_nowarn_perm:
 +                      AuLabel(nowarn_perm);
 +                      break;
-+              case Opt_refrof:
-+                      AuLabel(refrof);
-+                      break;
-+              case Opt_norefrof:
-+                      AuLabel(norefrof);
-+                      break;
 +              case Opt_verbose:
 +                      AuLabel(verbose);
 +                      break;
@@ -23742,8 +23776,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              case Opt_diropq_w:
 +              case Opt_warn_perm:
 +              case Opt_nowarn_perm:
-+              case Opt_refrof:
-+              case Opt_norefrof:
 +              case Opt_verbose:
 +              case Opt_noverbose:
 +              case Opt_sum:
@@ -23933,13 +23965,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
 +              break;
 +
-+      case Opt_refrof:
-+              au_opt_set(sbinfo->si_mntflags, REFROF);
-+              break;
-+      case Opt_norefrof:
-+              au_opt_clr(sbinfo->si_mntflags, REFROF);
-+              break;
-+
 +      case Opt_verbose:
 +              au_opt_set(sbinfo->si_mntflags, VERBOSE);
 +              break;
@@ -24172,7 +24197,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +      err = 0;
 +      fhsm = 0;
 +      root = sb->s_root;
-+      dir = root->d_inode;
++      dir = d_inode(root);
 +      do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
 +      bend = au_sbend(sb);
 +      for (bindex = 0; !err && bindex <= bend; bindex++) {
@@ -24345,7 +24370,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              /* go on even if err */
 +      }
 +      if (au_opt_test(tmp, UDBA_HNOTIFY)) {
-+              dir = sb->s_root->d_inode;
++              dir = d_inode(sb->s_root);
 +              au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
 +      }
 +
@@ -24363,7 +24388,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +
 +      SiMustWriteLock(sb);
 +
-+      dir = sb->s_root->d_inode;
++      dir = d_inode(sb->s_root);
 +      sbinfo = au_sbi(sb);
 +      err = 0;
 +      opt_xino = NULL;
@@ -24408,8 +24433,8 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +}
 diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 --- /usr/share/empty/fs/aufs/opts.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/opts.h       2015-06-22 08:27:37.887501948 +0200
-@@ -0,0 +1,211 @@
++++ linux/fs/aufs/opts.h       2015-06-28 17:35:44.351383872 +0200
+@@ -0,0 +1,210 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -24454,7 +24479,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 +#define AuOpt_PLINK           (1 << 6)        /* pseudo-link */
 +#define AuOpt_DIRPERM1                (1 << 7)        /* ignore the lower dir's perm
 +                                                 bits */
-+#define AuOpt_REFROF          (1 << 8)        /* unimplemented */
 +#define AuOpt_ALWAYS_DIROPQ   (1 << 9)        /* policy to creating diropq */
 +#define AuOpt_SUM             (1 << 10)       /* summation for statfs(2) */
 +#define AuOpt_SUM_W           (1 << 11)       /* unimplemented */
@@ -24623,8 +24647,8 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
 +#endif /* __AUFS_OPTS_H__ */
 diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 --- /usr/share/empty/fs/aufs/plink.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/plink.c      2015-06-22 08:27:37.887501948 +0200
-@@ -0,0 +1,532 @@
++++ linux/fs/aufs/plink.c      2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,528 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -24829,7 +24853,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +      struct dentry *h_dentry;
 +      struct mutex *h_mtx;
 +
-+      h_mtx = &h_parent->d_inode->i_mutex;
++      h_mtx = &d_inode(h_parent)->i_mutex;
 +      mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
 +      h_dentry = vfsub_lkup_one(tgtname, h_parent);
 +      mutex_unlock(h_mtx);
@@ -24847,7 +24871,6 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +{
 +      struct dentry *h_dentry, *h_parent;
 +      struct au_branch *br;
-+      struct inode *h_dir;
 +      int wkq_err;
 +      char a[PLINK_NAME_LEN];
 +      struct qstr tgtname = QSTR_INIT(a, 0);
@@ -24856,7 +24879,6 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +
 +      br = au_sbr(inode->i_sb, bindex);
 +      h_parent = br->br_wbr->wbr_plink;
-+      h_dir = h_parent->d_inode;
 +      tgtname.len = plink_name(a, sizeof(a), inode, bindex);
 +
 +      if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
@@ -24886,7 +24908,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +      };
 +      struct inode *h_dir, *delegated;
 +
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
 +again:
 +      h_path.dentry = vfsub_lkup_one(tgt, h_parent);
@@ -24897,8 +24919,8 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +      err = 0;
 +      /* wh.plink dir is not monitored */
 +      /* todo: is it really safe? */
-+      if (h_path.dentry->d_inode
-+          && h_path.dentry->d_inode != h_dentry->d_inode) {
++      if (d_is_positive(h_path.dentry)
++          && d_inode(h_path.dentry) != d_inode(h_dentry)) {
 +              delegated = NULL;
 +              err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
 +              if (unlikely(err == -EWOULDBLOCK)) {
@@ -24911,7 +24933,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +              if (!err)
 +                      goto again;
 +      }
-+      if (!err && !h_path.dentry->d_inode) {
++      if (!err && d_is_negative(h_path.dentry)) {
 +              delegated = NULL;
 +              err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
 +              if (unlikely(err == -EWOULDBLOCK)) {
@@ -24947,13 +24969,11 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +      int err, wkq_err;
 +      struct au_wbr *wbr;
 +      struct dentry *h_parent;
-+      struct inode *h_dir;
 +      char a[PLINK_NAME_LEN];
 +      struct qstr tgtname = QSTR_INIT(a, 0);
 +
 +      wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
 +      h_parent = wbr->wbr_plink;
-+      h_dir = h_parent->d_inode;
 +      tgtname.len = plink_name(a, sizeof(a), inode, bindex);
 +
 +      /* always superio. */
@@ -25159,7 +25179,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       2015-06-22 08:29:23.710091096 +0200
++++ linux/fs/aufs/poll.c       2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,52 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -25215,7 +25235,7 @@ diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
 +}
 diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 --- /usr/share/empty/fs/aufs/posix_acl.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/posix_acl.c  2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/posix_acl.c  2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,99 @@
 +/*
 + * Copyright (C) 2014-2015 Junjiro R. Okajima
@@ -25318,7 +25338,7 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
 +}
 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
 --- /usr/share/empty/fs/aufs/procfs.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/procfs.c     2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/procfs.c     2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,169 @@
 +/*
 + * Copyright (C) 2010-2015 Junjiro R. Okajima
@@ -25491,7 +25511,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        2015-06-22 08:29:23.710091096 +0200
++++ linux/fs/aufs/rdu.c        2015-06-28 17:36:09.028407078 +0200
 @@ -0,0 +1,388 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -25652,7 +25672,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
 +              goto out;
 +
 +      dentry = file->f_path.dentry;
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +#if 1
 +      mutex_lock(&inode->i_mutex);
 +#else
@@ -25883,7 +25903,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      2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/rwsem.h      2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,191 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -26078,8 +26098,8 @@ diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
 +#endif /* __AUFS_RWSEM_H__ */
 diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 --- /usr/share/empty/fs/aufs/sbinfo.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/sbinfo.c     2015-06-22 08:27:37.887501948 +0200
-@@ -0,0 +1,354 @@
++++ linux/fs/aufs/sbinfo.c     2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,356 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -26245,13 +26265,15 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +unsigned int au_sigen_inc(struct super_block *sb)
 +{
 +      unsigned int gen;
++      struct inode *inode;
 +
 +      SiMustWriteLock(sb);
 +
 +      gen = ++au_sbi(sb)->si_generation;
 +      au_update_digen(sb->s_root);
-+      au_update_iigen(sb->s_root->d_inode, /*half*/0);
-+      sb->s_root->d_inode->i_version++;
++      inode = d_inode(sb->s_root);
++      au_update_iigen(inode, /*half*/0);
++      inode->i_version++;
 +      return gen;
 +}
 +
@@ -26436,7 +26458,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        2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/spl.h        2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,111 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -26551,8 +26573,8 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 +#endif /* __AUFS_SPL_H__ */
 diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 --- /usr/share/empty/fs/aufs/super.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/super.c      2015-06-22 08:29:23.710091096 +0200
-@@ -0,0 +1,1007 @@
++++ linux/fs/aufs/super.c      2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,1004 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -26813,7 +26835,6 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      AuBool(PLINK, plink);
 +      AuBool(DIO, dio);
 +      AuBool(DIRPERM1, dirperm1);
-+      /* AuBool(REFROF, refrof); */
 +
 +      v = sbinfo->si_wbr_create;
 +      if (v != AuWbrCreate_Def)
@@ -27128,7 +27149,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      di_read_lock_parent(parent, AuLock_IR);
 +      err = au_refresh_dentry(dentry, parent);
 +      if (!err && dir_flags)
-+              au_hn_reset(dentry->d_inode, dir_flags);
++              au_hn_reset(d_inode(dentry), dir_flags);
 +      di_read_unlock(parent, AuLock_IR);
 +      di_write_unlock(dentry);
 +
@@ -27141,14 +27162,12 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +{
 +      int err;
 +      struct dentry *parent;
-+      struct inode *inode;
 +
 +      err = 0;
 +      parent = dget_parent(dentry);
 +      if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
-+              inode = dentry->d_inode;
-+              if (inode) {
-+                      if (!S_ISDIR(inode->i_mode))
++              if (d_really_is_positive(dentry)) {
++                      if (!d_is_dir(dentry))
 +                              err = au_do_refresh(dentry, /*dir_flags*/0,
 +                                               parent);
 +                      else {
@@ -27175,7 +27194,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      struct dentry **dentries, *d;
 +      struct au_sbinfo *sbinfo;
 +      struct dentry *root = sb->s_root;
-+      const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
++      const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
 +
 +      err = au_dpages_init(&dpages, GFP_NOFS);
 +      if (unlikely(err))
@@ -27256,7 +27275,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +
 +      root = sb->s_root;
 +      DiMustNoWaiters(root);
-+      inode = root->d_inode;
++      inode = d_inode(root);
 +      IiMustNoWaiters(inode);
 +
 +      udba = au_opt_udba(sb);
@@ -27336,7 +27355,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              goto out_opts;
 +
 +      sbinfo = au_sbi(sb);
-+      inode = root->d_inode;
++      inode = d_inode(root);
 +      mutex_lock(&inode->i_mutex);
 +      err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
 +      if (unlikely(err))
@@ -27462,7 +27481,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +              goto out_info;
 +      }
 +      root = sb->s_root;
-+      inode = root->d_inode;
++      inode = d_inode(root);
 +
 +      /*
 +       * actually we can parse options regardless aufs lock here.
@@ -27562,8 +27581,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +};
 diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 --- /usr/share/empty/fs/aufs/super.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/super.h      2015-06-22 08:27:37.887501948 +0200
-@@ -0,0 +1,638 @@
++++ linux/fs/aufs/super.h      2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,635 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -27591,14 +27610,11 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +#ifdef __KERNEL__
 +
 +#include <linux/fs.h>
++#include <linux/kobject.h>
 +#include "rwsem.h"
 +#include "spl.h"
 +#include "wkq.h"
 +
-+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
-+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
-+                             loff_t *);
-+
 +/* policies to select one among multiple writable branches */
 +struct au_wbr_copyup_operations {
 +      int (*copyup)(struct dentry *dentry);
@@ -27713,8 +27729,8 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
 +      unsigned int            si_mntflags;
 +
 +      /* external inode number (bitmap and translation table) */
-+      au_readf_t              si_xread;
-+      au_writef_t             si_xwrite;
++      vfs_readf_t             si_xread;
++      vfs_writef_t            si_xwrite;
 +      struct file             *si_xib;
 +      struct mutex            si_xib_mtx; /* protect xib members */
 +      unsigned long           *si_xib_buf;
@@ -28204,7 +28220,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    2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/sysaufs.c    2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,104 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -28312,7 +28328,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    2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/sysaufs.h    2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,101 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -28417,7 +28433,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      2015-06-22 08:29:23.710091096 +0200
++++ linux/fs/aufs/sysfs.c      2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,372 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -28793,7 +28809,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      2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/sysrq.c      2015-06-28 17:36:09.028407078 +0200
 @@ -0,0 +1,157 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -28845,7 +28861,7 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
 +      pr("root dentry\n");
 +      au_dpri_dentry(sb->s_root);
 +      pr("root inode\n");
-+      au_dpri_inode(sb->s_root->d_inode);
++      au_dpri_inode(d_inode(sb->s_root));
 +#endif
 +
 +#if 0
@@ -28954,7 +28970,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       2015-06-22 08:29:23.710091096 +0200
++++ linux/fs/aufs/vdir.c       2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,888 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -29846,8 +29862,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +}
 diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 --- /usr/share/empty/fs/aufs/vfsub.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/vfsub.c      2015-06-22 08:29:23.710091096 +0200
-@@ -0,0 +1,846 @@
++++ linux/fs/aufs/vfsub.c      2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,848 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -29904,7 +29920,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +                         current_cred());
 +      if (!IS_ERR_OR_NULL(file)
 +          && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
-+              i_readcount_inc(path->dentry->d_inode);
++              i_readcount_inc(d_inode(path->dentry));
 +
 +      return file;
 +}
@@ -29982,7 +29998,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +      int err;
 +
 +      err = kern_path(name, flags, path);
-+      if (!err && path->dentry->d_inode)
++      if (!err && d_is_positive(path->dentry))
 +              vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
 +      return err;
 +}
@@ -29995,12 +30011,12 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +      };
 +
 +      /* VFS checks it too, but by WARN_ON_ONCE() */
-+      IMustLock(parent->d_inode);
++      IMustLock(d_inode(parent));
 +
 +      path.dentry = lookup_one_len(name, parent, len);
 +      if (IS_ERR(path.dentry))
 +              goto out;
-+      if (path.dentry->d_inode)
++      if (d_is_positive(path.dentry))
 +              vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
 +
 +out:
@@ -30161,7 +30177,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +
 +      IMustLock(dir);
 +
-+      err = au_test_nlink(src_dentry->d_inode);
++      err = au_test_nlink(d_inode(src_dentry));
 +      if (unlikely(err))
 +              return err;
 +
@@ -30459,7 +30475,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +              goto out;
 +      }
 +
-+      h_inode = h_path->dentry->d_inode;
++      h_inode = d_inode(h_path->dentry);
 +      h_sb = h_inode->i_sb;
 +      lockdep_off();
 +      sb_start_write(h_sb);
@@ -30568,7 +30584,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +      struct notify_change_args *a = args;
 +      struct inode *h_inode;
 +
-+      h_inode = a->path->dentry->d_inode;
++      h_inode = d_inode(a->path->dentry);
 +      IMustLock(h_inode);
 +
 +      *a->errp = -EPERM;
@@ -30644,9 +30660,11 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
 +
 +      if (!stop_sillyrename)
 +              dget(d);
-+      h_inode = d->d_inode;
-+      if (h_inode)
++      h_inode = NULL;
++      if (d_is_positive(d)) {
++              h_inode = d_inode(d);
 +              ihold(h_inode);
++      }
 +
 +      lockdep_off();
 +      *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
@@ -30696,7 +30714,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      2015-06-22 08:29:23.710091096 +0200
++++ linux/fs/aufs/vfsub.h      2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,286 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -30986,7 +31004,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 2015-06-22 08:27:37.887501948 +0200
++++ linux/fs/aufs/wbr_policy.c 2015-06-28 17:36:09.028407078 +0200
 @@ -0,0 +1,765 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -31020,13 +31038,13 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +      struct iattr ia;
 +      struct inode *h_isrc;
 +
-+      h_isrc = h_src->d_inode;
++      h_isrc = d_inode(h_src);
 +      ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
 +      ia.ia_mode = h_isrc->i_mode;
 +      ia.ia_uid = h_isrc->i_uid;
 +      ia.ia_gid = h_isrc->i_gid;
 +      sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
-+      au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
++      au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
 +      /* no delegation since it is just created */
 +      err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
 +
@@ -31081,7 +31099,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +              goto out;
 +
 +      err = 0;
-+      if (h_path.dentry->d_inode) {
++      if (d_is_positive(h_path.dentry)) {
 +              h_path.mnt = au_br_mnt(br);
 +              err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
 +                                        dentry);
@@ -31106,8 +31124,8 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +      bstart = au_dbstart(dentry);
 +      /* dentry is di-locked */
 +      parent = dget_parent(dentry);
-+      dir = parent->d_inode;
-+      h_dir = h_parent->d_inode;
++      dir = d_inode(parent);
++      h_dir = d_inode(h_parent);
 +      AuDebugOn(h_dir != au_h_iptr(dir, bdst));
 +      IMustLock(h_dir);
 +
@@ -31129,7 +31147,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +              au_fset_cpdown(*flags, WHED);
 +      if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
 +              au_fset_cpdown(*flags, PARENT_OPQ);
-+      h_inode = h_path.dentry->d_inode;
++      h_inode = d_inode(h_path.dentry);
 +      mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
 +      if (au_ftest_cpdown(*flags, WHED)) {
 +              err = au_cpdown_dir_opq(dentry, bdst, flags);
@@ -31150,7 +31168,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +                      goto out_opq;
 +      }
 +
-+      inode = dentry->d_inode;
++      inode = d_inode(dentry);
 +      if (au_ibend(inode) < bdst)
 +              au_set_ibend(inode, bdst);
 +      au_set_h_iptr(inode, bdst, au_igrab(h_inode),
@@ -31269,7 +31287,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +      parent = dget_parent(dentry);
 +      for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
 +              h_parent = au_h_dptr(parent, bindex);
-+              if (!h_parent || !h_parent->d_inode)
++              if (!h_parent || d_is_negative(h_parent))
 +                      continue;
 +
 +              if (!au_br_rdonly(au_sbr(sb, bindex))) {
@@ -31421,7 +31439,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +      for (; bindex <= bend; bindex++) {
 +              if (parent) {
 +                      h_parent = au_h_dptr(parent, bindex);
-+                      if (!h_parent || !h_parent->d_inode)
++                      if (!h_parent || d_is_negative(h_parent))
 +                              continue;
 +              }
 +              br = au_sbr(sb, bindex);
@@ -31569,7 +31587,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +
 +      for (bindex = bstart; bindex <= bend; bindex++) {
 +              h_parent = au_h_dptr(parent, bindex);
-+              if (!h_parent || !h_parent->d_inode)
++              if (!h_parent || d_is_negative(h_parent))
 +                      continue;
 +
 +              br = au_sbr(sb, bindex);
@@ -31648,7 +31666,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +      bstart = au_dbstart(parent);
 +      for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
 +              h_parent = au_h_dptr(parent, bindex);
-+              if (!h_parent || !h_parent->d_inode)
++              if (!h_parent || d_is_negative(h_parent))
 +                      continue;
 +
 +              if (!au_br_rdonly(au_sbr(sb, bindex))) {
@@ -31755,8 +31773,8 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
 +};
 diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 --- /usr/share/empty/fs/aufs/whout.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/whout.c      2015-06-22 08:29:23.710091096 +0200
-@@ -0,0 +1,1064 @@
++++ linux/fs/aufs/whout.c      2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,1063 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -31839,7 +31857,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      }
 +
 +      err = 0;
-+      if (!wh_dentry->d_inode)
++      if (d_is_negative(wh_dentry))
 +              goto out_wh; /* success */
 +
 +      err = 1;
@@ -31848,7 +31866,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +      err = -EIO;
 +      AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
-+              wh_dentry, wh_dentry->d_inode->i_mode);
++              wh_dentry, d_inode(wh_dentry)->i_mode);
 +
 +out_wh:
 +      dput(wh_dentry);
@@ -31864,7 +31882,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      int err;
 +      struct inode *h_dir;
 +
-+      h_dir = h_dentry->d_inode;
++      h_dir = d_inode(h_dentry);
 +      err = au_wh_test(h_dentry, &diropq_name,
 +                       au_test_h_perm_sio(h_dir, MAY_EXEC));
 +      return err;
@@ -31910,7 +31928,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      for (i = 0; i < 3; i++) {
 +              sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
 +              dentry = au_sio_lkup_one(&qs, h_parent);
-+              if (IS_ERR(dentry) || !dentry->d_inode)
++              if (IS_ERR(dentry) || d_is_negative(dentry))
 +                      goto out_name;
 +              dput(dentry);
 +      }
@@ -31940,7 +31958,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      struct dentry *h_parent;
 +
 +      h_parent = h_dentry->d_parent; /* dir inode is locked */
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      IMustLock(h_dir);
 +
 +      h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
@@ -31979,7 +31997,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +       * this may be a violation of unix fs semantics.
 +       */
 +      force = (h_dir->i_mode & S_ISVTX)
-+              && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
++              && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
 +      delegated = NULL;
 +      err = vfsub_unlink(h_dir, h_path, &delegated, force);
 +      if (unlikely(err == -EWOULDBLOCK)) {
@@ -32015,9 +32033,8 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      if (IS_ERR(h_path.dentry))
 +              err = PTR_ERR(h_path.dentry);
 +      else {
-+              if (h_path.dentry->d_inode
-+                  && d_is_reg(h_path.dentry))
-+                      err = do_unlink_wh(h_parent->d_inode, &h_path);
++              if (d_is_reg(h_path.dentry))
++                      err = do_unlink_wh(d_inode(h_parent), &h_path);
 +              dput(h_path.dentry);
 +      }
 +
@@ -32035,7 +32052,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      int err;
 +      struct inode *delegated;
 +
-+      if (!whpath->dentry->d_inode)
++      if (d_is_negative(whpath->dentry))
 +              return;
 +
 +      if (isdir)
@@ -32056,7 +32073,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +static int test_linkable(struct dentry *h_root)
 +{
-+      struct inode *h_dir = h_root->d_inode;
++      struct inode *h_dir = d_inode(h_root);
 +
 +      if (h_dir->i_op->link)
 +              return 0;
@@ -32072,7 +32089,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      int err;
 +
 +      err = -EEXIST;
-+      if (!path->dentry->d_inode) {
++      if (d_is_negative(path->dentry)) {
 +              int mode = S_IRWXU;
 +
 +              if (au_test_nfs(path->dentry->d_sb))
@@ -32115,7 +32132,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      int err;
 +      struct inode *h_dir;
 +
-+      h_dir = h_root->d_inode;
++      h_dir = d_inode(h_root);
 +      h_path->dentry = base[AuBrWh_BASE].dentry;
 +      au_wh_clean(h_dir, h_path, /*isdir*/0);
 +      h_path->dentry = base[AuBrWh_PLINK].dentry;
@@ -32169,8 +32186,8 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +       * todo: should this create be done in /sbin/mount.aufs helper?
 +       */
 +      err = -EEXIST;
-+      h_dir = h_root->d_inode;
-+      if (!base[AuBrWh_BASE].dentry->d_inode) {
++      h_dir = d_inode(h_root);
++      if (d_is_negative(base[AuBrWh_BASE].dentry)) {
 +              h_path->dentry = base[AuBrWh_BASE].dentry;
 +              err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
 +      } else if (d_is_reg(base[AuBrWh_BASE].dentry))
@@ -32261,7 +32278,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +      err = 0;
 +      if (!au_br_writable(br->br_perm)) {
-+              h_dir = h_root->d_inode;
++              h_dir = d_inode(h_root);
 +              au_wh_init_ro(h_dir, base, &path);
 +      } else if (!au_br_wh_linkable(br->br_perm)) {
 +              err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
@@ -32321,7 +32338,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +              goto out;
 +
 +      di_read_lock_parent(a->sb->s_root, AuLock_IR);
-+      dir = a->sb->s_root->d_inode;
++      dir = d_inode(a->sb->s_root);
 +      hdir = au_hi(dir, bindex);
 +      h_root = au_h_dptr(a->sb->s_root, bindex);
 +      AuDebugOn(h_root != au_br_dentry(a->br));
@@ -32417,7 +32434,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      struct inode *h_dir, *delegated;
 +
 +      h_parent = wh->d_parent; /* dir inode is locked */
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      IMustLock(h_dir);
 +
 +      br = au_sbr(sb, bindex);
@@ -32480,7 +32497,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +                      .dentry = opq_dentry,
 +                      .mnt    = au_br_mnt(br)
 +              };
-+              err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
++              err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
 +              if (!err)
 +                      au_set_dbdiropq(dentry, -1);
 +      }
@@ -32510,7 +32527,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      struct dentry *diropq, *h_dentry;
 +
 +      h_dentry = au_h_dptr(dentry, bindex);
-+      if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
++      if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
 +              diropq = do_diropq(dentry, bindex, flags);
 +      else {
 +              int wkq_err;
@@ -32565,7 +32582,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +      sb = dentry->d_sb;
 +      wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
-+      if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
++      if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
 +              err = link_or_create_wh(sb, bindex, wh_dentry);
 +              if (!err) {
 +                      au_set_dbwh(dentry, bindex);
@@ -32700,11 +32717,11 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      struct inode *wh_inode, *h_dir;
 +      struct au_branch *br;
 +
-+      h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
++      h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
 +      IMustLock(h_dir);
 +
 +      br = au_sbr(dir->i_sb, bindex);
-+      wh_inode = wh_dentry->d_inode;
++      wh_inode = d_inode(wh_dentry);
 +      mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
 +
 +      /*
@@ -32776,7 +32793,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      err = -EIO;
 +      ii_write_lock_parent(a->dir);
 +      h_parent = dget_parent(a->wh_dentry);
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      hdir = au_hi(a->dir, bindex);
 +      err = vfsub_mnt_want_write(au_br_mnt(a->br));
 +      if (unlikely(err))
@@ -32823,7 +32840,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      2015-06-22 08:27:37.890835363 +0200
++++ linux/fs/aufs/whout.h      2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,85 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -32912,7 +32929,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
 +#endif /* __AUFS_WHOUT_H__ */
 diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 --- /usr/share/empty/fs/aufs/wkq.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/wkq.c        2015-06-22 08:27:37.890835363 +0200
++++ linux/fs/aufs/wkq.c        2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,213 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -33129,7 +33146,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        2015-06-22 08:27:37.890835363 +0200
++++ linux/fs/aufs/wkq.h        2015-06-28 17:35:44.351383872 +0200
 @@ -0,0 +1,91 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -33224,7 +33241,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 +#endif /* __AUFS_WKQ_H__ */
 diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 --- /usr/share/empty/fs/aufs/xattr.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/xattr.c      2015-06-22 08:27:37.890835363 +0200
++++ linux/fs/aufs/xattr.c      2015-06-28 17:36:09.028407078 +0200
 @@ -0,0 +1,344 @@
 +/*
 + * Copyright (C) 2014-2015 Junjiro R. Okajima
@@ -33303,7 +33320,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +              if (err == -ENODATA
 +                  || (err == -EOPNOTSUPP
 +                      && ((ignore_flags & au_xattr_out_of_list)
-+                          || (au_test_nfs_noacl(h_src->d_inode)
++                          || (au_test_nfs_noacl(d_inode(h_src))
 +                              && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
 +                                  || !strcmp(name,
 +                                             XATTR_NAME_POSIX_ACL_DEFAULT))))
@@ -33315,7 +33332,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +      }
 +
 +      /* unlock it temporary */
-+      h_idst = h_dst->d_inode;
++      h_idst = d_inode(h_dst);
 +      mutex_unlock(&h_idst->i_mutex);
 +      err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
 +      mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
@@ -33339,8 +33356,8 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +
 +      /* try stopping to update the source inode while we are referencing */
 +      /* there should not be the parent-child relationship between them */
-+      h_isrc = h_src->d_inode;
-+      h_idst = h_dst->d_inode;
++      h_isrc = d_inode(h_src);
++      h_idst = d_inode(h_dst);
 +      mutex_unlock(&h_idst->i_mutex);
 +      mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
 +      mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
@@ -33572,8 +33589,8 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +#endif
 diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 --- /usr/share/empty/fs/aufs/xino.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/xino.c       2015-06-22 08:29:23.710091096 +0200
-@@ -0,0 +1,1322 @@
++++ linux/fs/aufs/xino.c       2015-06-28 17:36:09.028407078 +0200
+@@ -0,0 +1,1297 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
 + *
@@ -33600,7 +33617,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +#include "aufs.h"
 +
 +/* todo: unnecessary to support mmap_sem since kernel-space? */
-+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
++ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
 +                 loff_t *pos)
 +{
 +      ssize_t err;
@@ -33629,7 +33646,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
++static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
 +                            size_t size, loff_t *pos)
 +{
 +      ssize_t err;
@@ -33658,7 +33675,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +struct do_xino_fwrite_args {
 +      ssize_t *errp;
-+      au_writef_t func;
++      vfs_writef_t func;
 +      struct file *file;
 +      void *buf;
 +      size_t size;
@@ -33671,8 +33688,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
 +}
 +
-+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
-+                  loff_t *pos)
++ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
++                  size_t size, loff_t *pos)
 +{
 +      ssize_t err;
 +
@@ -33720,7 +33737,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +      base = base_file->f_path.dentry;
 +      parent = base->d_parent; /* dir inode is locked */
-+      dir = parent->d_inode;
++      dir = d_inode(parent);
 +      IMustLock(dir);
 +
 +      file = ERR_PTR(-EINVAL);
@@ -33798,11 +33815,11 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      if (brid >= 0)
 +              bindex = au_br_index(sb, brid);
 +      if (bindex >= 0) {
-+              ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
++              ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
 +              au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
 +      } else {
 +              ldir->parent = dget_parent(xino->f_path.dentry);
-+              ldir->mtx = &ldir->parent->d_inode->i_mutex;
++              ldir->mtx = &d_inode(ldir->parent)->i_mutex;
 +              mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
 +      }
 +}
@@ -33913,7 +33930,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +      err = 0;
 +      sb = args->sb;
-+      dir = sb->s_root->d_inode;
++      dir = d_inode(sb->s_root);
 +      br = args->br;
 +
 +      si_noflush_write_lock(sb);
@@ -33990,7 +34007,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+static int au_xino_do_write(au_writef_t write, struct file *file,
++static int au_xino_do_write(vfs_writef_t write, struct file *file,
 +                          ino_t h_ino, ino_t ino)
 +{
 +      loff_t pos;
@@ -34150,7 +34167,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      struct au_hinode *hi;
 +      struct inode *h_inode;
 +      struct au_branch *br;
-+      au_writef_t xwrite;
++      vfs_writef_t xwrite;
 +
 +      sb = inode->i_sb;
 +      mnt_flags = au_mntflags(sb);
@@ -34326,7 +34343,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      err = 0;
 +      inode = file_inode(file);
 +      h_parent = dget_parent(file->f_path.dentry);
-+      h_dir = h_parent->d_inode;
++      h_dir = d_inode(h_parent);
 +      mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
 +      /* mnt_want_write() is unnecessary here */
 +      /* no delegation since it is just created */
@@ -34452,7 +34469,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      unsigned long pindex;
 +      loff_t pos, pend;
 +      struct au_sbinfo *sbinfo;
-+      au_readf_t func;
++      vfs_readf_t func;
 +      ino_t *ino;
 +      unsigned long *p;
 +
@@ -34570,31 +34587,6 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +/*
 + * xino mount option handlers
 + */
-+static au_readf_t find_readf(struct file *h_file)
-+{
-+      const struct file_operations *fop = h_file->f_op;
-+
-+      if (fop->read)
-+              return fop->read;
-+      if (fop->aio_read)
-+              return do_sync_read;
-+      if (fop->read_iter)
-+              return new_sync_read;
-+      return ERR_PTR(-ENOSYS);
-+}
-+
-+static au_writef_t find_writef(struct file *h_file)
-+{
-+      const struct file_operations *fop = h_file->f_op;
-+
-+      if (fop->write)
-+              return fop->write;
-+      if (fop->aio_write)
-+              return do_sync_write;
-+      if (fop->write_iter)
-+              return new_sync_write;
-+      return ERR_PTR(-ENOSYS);
-+}
 +
 +/* xino bitmap */
 +static void xino_clear_xib(struct super_block *sb)
@@ -34630,8 +34622,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      if (sbinfo->si_xib)
 +              fput(sbinfo->si_xib);
 +      sbinfo->si_xib = file;
-+      sbinfo->si_xread = find_readf(file);
-+      sbinfo->si_xwrite = find_writef(file);
++      sbinfo->si_xread = vfs_readf(file);
++      sbinfo->si_xwrite = vfs_writef(file);
 +
 +      err = -ENOMEM;
 +      if (!sbinfo->si_xib_buf)
@@ -34692,7 +34684,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      } *fpair, *p;
 +      struct au_branch *br;
 +      struct inode *inode;
-+      au_writef_t writef;
++      vfs_writef_t writef;
 +
 +      SiMustWriteLock(sb);
 +
@@ -34702,7 +34694,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      if (unlikely(!fpair))
 +              goto out;
 +
-+      inode = sb->s_root->d_inode;
++      inode = d_inode(sb->s_root);
 +      ino = AUFS_ROOT_INO;
 +      writef = au_sbi(sb)->si_xwrite;
 +      for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
@@ -34792,7 +34784,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      }
 +
 +      au_opt_set(sbinfo->si_mntflags, XINO);
-+      dir = parent->d_inode;
++      dir = d_inode(parent);
 +      mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
 +      /* mnt_want_write() is unnecessary here */
 +      err = au_xino_set_xib(sb, xino->file);
@@ -34898,7 +34890,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       2015-06-22 08:29:23.710091096 +0200
++++ linux/include/uapi/linux/aufs_type.h       2015-06-28 17:36:09.028407078 +0200
 @@ -0,0 +1,419 @@
 +/*
 + * Copyright (C) 2005-2015 Junjiro R. Okajima
@@ -34941,7 +34933,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +
 +#include <linux/limits.h>
 +
-+#define AUFS_VERSION  "3.x-rcN-20150622"
++#define AUFS_VERSION  "4.x-rcN-20150622"
 +
 +/* todo? move this to linux-2.6.19/include/magic.h */
 +#define AUFS_SUPER_MAGIC      ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -35319,3 +35311,277 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +#define AUFS_CTL_FHSM_FD      _IOW(AuCtlType, AuCtl_FHSM_FD, int)
 +
 +#endif /* __AUFS_TYPE_H__ */
+aufs4.x-rcN loopback patch
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index 0160952..866f8e2 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -419,7 +419,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
+ }
+ struct switch_request {
+-      struct file *file;
++      struct file *file, *virt_file;
+       struct completion wait;
+ };
+@@ -439,6 +439,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
+       mapping = file->f_mapping;
+       mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
+       lo->lo_backing_file = file;
++      lo->lo_backing_virt_file = p->virt_file;
+       lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
+               mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
+       lo->old_gfp_mask = mapping_gfp_mask(mapping);
+@@ -450,11 +451,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
+  * First it needs to flush existing IO, it does this by sending a magic
+  * BIO down the pipe. The completion of this BIO does the actual switch.
+  */
+-static int loop_switch(struct loop_device *lo, struct file *file)
++static int loop_switch(struct loop_device *lo, struct file *file,
++                     struct file *virt_file)
+ {
+       struct switch_request w;
+       w.file = file;
++      w.virt_file = virt_file;
+       /* freeze queue and wait for completion of scheduled requests */
+       blk_mq_freeze_queue(lo->lo_queue);
+@@ -473,7 +476,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
+  */
+ static int loop_flush(struct loop_device *lo)
+ {
+-      return loop_switch(lo, NULL);
++      return loop_switch(lo, NULL, NULL);
++}
++
++static struct file *loop_real_file(struct file *file)
++{
++      struct file *f = NULL;
++
++      if (file->f_path.dentry->d_sb->s_op->real_loop)
++              f = file->f_path.dentry->d_sb->s_op->real_loop(file);
++      return f;
+ }
+ /*
+@@ -488,6 +500,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+                         unsigned int arg)
+ {
+       struct file     *file, *old_file;
++      struct file     *f, *virt_file = NULL, *old_virt_file;
+       struct inode    *inode;
+       int             error;
+@@ -504,9 +517,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+       file = fget(arg);
+       if (!file)
+               goto out;
++      f = loop_real_file(file);
++      if (f) {
++              virt_file = file;
++              file = f;
++              get_file(file);
++      }
+       inode = file->f_mapping->host;
+       old_file = lo->lo_backing_file;
++      old_virt_file = lo->lo_backing_virt_file;
+       error = -EINVAL;
+@@ -518,17 +538,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+               goto out_putf;
+       /* and ... switch */
+-      error = loop_switch(lo, file);
++      error = loop_switch(lo, file, virt_file);
+       if (error)
+               goto out_putf;
+       fput(old_file);
++      if (old_virt_file)
++              fput(old_virt_file);
+       if (lo->lo_flags & LO_FLAGS_PARTSCAN)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
+       return 0;
+  out_putf:
+       fput(file);
++      if (virt_file)
++              fput(virt_file);
+  out:
+       return error;
+ }
+@@ -689,7 +713,7 @@ static void loop_config_discard(struct loop_device *lo)
+ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+                      struct block_device *bdev, unsigned int arg)
+ {
+-      struct file     *file, *f;
++      struct file     *file, *f, *virt_file = NULL;
+       struct inode    *inode;
+       struct address_space *mapping;
+       unsigned lo_blocksize;
+@@ -704,6 +728,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+       file = fget(arg);
+       if (!file)
+               goto out;
++      f = loop_real_file(file);
++      if (f) {
++              virt_file = file;
++              file = f;
++              get_file(file);
++      }
+       error = -EBUSY;
+       if (lo->lo_state != Lo_unbound)
+@@ -752,6 +782,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+       lo->lo_device = bdev;
+       lo->lo_flags = lo_flags;
+       lo->lo_backing_file = file;
++      lo->lo_backing_virt_file = virt_file;
+       lo->transfer = NULL;
+       lo->ioctl = NULL;
+       lo->lo_sizelimit = 0;
+@@ -783,6 +814,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
+  out_putf:
+       fput(file);
++      if (virt_file)
++              fput(virt_file);
+  out:
+       /* This is safe: open() is still holding a reference. */
+       module_put(THIS_MODULE);
+@@ -829,6 +862,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
+ static int loop_clr_fd(struct loop_device *lo)
+ {
+       struct file *filp = lo->lo_backing_file;
++      struct file *virt_filp = lo->lo_backing_virt_file;
+       gfp_t gfp = lo->old_gfp_mask;
+       struct block_device *bdev = lo->lo_device;
+@@ -857,6 +891,7 @@ static int loop_clr_fd(struct loop_device *lo)
+       spin_lock_irq(&lo->lo_lock);
+       lo->lo_state = Lo_rundown;
+       lo->lo_backing_file = NULL;
++      lo->lo_backing_virt_file = NULL;
+       spin_unlock_irq(&lo->lo_lock);
+       loop_release_xfer(lo);
+@@ -898,6 +933,8 @@ static int loop_clr_fd(struct loop_device *lo)
+        * bd_mutex which is usually taken before lo_ctl_mutex.
+        */
+       fput(filp);
++      if (virt_filp)
++              fput(virt_filp);
+       return 0;
+ }
+diff --git a/drivers/block/loop.h b/drivers/block/loop.h
+index 301c27f..df84aa0 100644
+--- a/drivers/block/loop.h
++++ b/drivers/block/loop.h
+@@ -46,7 +46,7 @@ struct loop_device {
+       int             (*ioctl)(struct loop_device *, int cmd, 
+                                unsigned long arg); 
+-      struct file *   lo_backing_file;
++      struct file *   lo_backing_file, *lo_backing_virt_file;
+       struct block_device *lo_device;
+       unsigned        lo_blocksize;
+       void            *key_data; 
+diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
+index 91c2ce7..d4ee5a7 100644
+--- a/fs/aufs/f_op.c
++++ b/fs/aufs/f_op.c
+@@ -389,7 +389,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
+       if (IS_ERR(h_file))
+               goto out;
+-      if (au_test_loopback_kthread()) {
++      if (0 && au_test_loopback_kthread()) {
+               au_warn_loopback(h_file->f_path.dentry->d_sb);
+               if (file->f_mapping != h_file->f_mapping) {
+                       file->f_mapping = h_file->f_mapping;
+diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
+index 69f7e96..7941063 100644
+--- a/fs/aufs/loop.c
++++ b/fs/aufs/loop.c
+@@ -130,3 +130,19 @@ void au_loopback_fin(void)
+       symbol_put(loop_backing_file);
+       kfree(au_warn_loopback_array);
+ }
++
++/* ---------------------------------------------------------------------- */
++
++/* support the loopback block device insude aufs */
++
++struct file *aufs_real_loop(struct file *file)
++{
++      struct file *f;
++
++      BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
++      fi_read_lock(file);
++      f = au_hf_top(file);
++      fi_read_unlock(file);
++      AuDebugOn(!f);
++      return f;
++}
+diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
+index 6d9864d..3322557 100644
+--- a/fs/aufs/loop.h
++++ b/fs/aufs/loop.h
+@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
+ int au_loopback_init(void);
+ void au_loopback_fin(void);
++
++struct file *aufs_real_loop(struct file *file);
+ #else
++AuStub(struct file *, loop_backing_file, return NULL)
++
+ AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
+          struct dentry *h_adding)
+ AuStubInt0(au_test_loopback_kthread, void)
+@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
+ AuStubInt0(au_loopback_init, void)
+ AuStubVoid(au_loopback_fin, void)
++
++AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
+ #endif /* BLK_DEV_LOOP */
+ #endif /* __KERNEL__ */
+diff --git a/fs/aufs/super.c b/fs/aufs/super.c
+index ee5780d..da35759 100644
+--- a/fs/aufs/super.c
++++ b/fs/aufs/super.c
+@@ -807,7 +807,10 @@ static const struct super_operations aufs_sop = {
+       .statfs         = aufs_statfs,
+       .put_super      = aufs_put_super,
+       .sync_fs        = aufs_sync_fs,
+-      .remount_fs     = aufs_remount_fs
++      .remount_fs     = aufs_remount_fs,
++#ifdef CONFIG_AUFS_BDEV_LOOP
++      .real_loop      = aufs_real_loop
++#endif
+ };
+ /* ---------------------------------------------------------------------- */
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 3229f97..f63cc0d 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1696,6 +1696,10 @@ struct super_operations {
+                                 struct shrink_control *);
+       long (*free_cached_objects)(struct super_block *,
+                                   struct shrink_control *);
++#if defined(CONFIG_BLK_DEV_LOOP) ||  defined(CONFIG_BLK_DEV_LOOP_MODULE)
++      /* and aufs */
++      struct file *(*real_loop)(struct file *);
++#endif
+ };
+ /*
index 41145f1efe9112bdb50e59fc1ec9f06e86bf340c..984623f978cb7cf24d67a1e857aefda28f59742b 100644 (file)
@@ -196,20 +196,20 @@ Patch85:  kernel-hostap.patch
 Patch100:      kernel-vserver-2.3.patch
 Patch101:      kernel-vserver-fixes.patch
 
-# git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git, read README
+# git://github.com/sfjro/aufs4-standalone.git, read README
 # Patch creation:
-# git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git
-# cd aufs3-standalone
-# git checkout -b aufs4.0 origin/aufs4.0
-# cat aufs3-kbuild.patch aufs3-base.patch aufs3-mmap.patch aufs3-standalone.patch > ~/rpm/packages/kernel/kernel-aufs3.patch
+# git clone git://github.com/sfjro/aufs4-standalone.git
+# cd aufs4-standalone
+# git checkout -b aufs4.1 origin/aufs4.1
+# cat aufs4-kbuild.patch aufs4-base.patch aufs4-mmap.patch aufs4-standalone.patch > ~/rpm/packages/kernel/kernel-aufs4.patch
 # mkdir linux
 # cp -a Documentation fs include linux
-# diff -urN /usr/share/empty linux >> ~/rpm/packages/kernel/kernel-aufs3.patch
+# diff -urN /usr/share/empty linux >> ~/rpm/packages/kernel/kernel-aufs4.patch
 # drop hunk at the end of patch (hunk is patching include/linux/Kbuild with single line change)
-# cat aufs3-loopback.patch >> ~/rpm/packages/kernel/kernel-aufs3.patch
+# cat aufs4-loopback.patch >> ~/rpm/packages/kernel/kernel-aufs4.patch
 #
-Patch145:      kernel-aufs3.patch
-Patch146:      kernel-aufs3+vserver.patch
+Patch145:      kernel-aufs4.patch
+Patch146:      kernel-aufs4+vserver.patch
 
 %define uksm_major_version 0.1.2.3
 %define uksm_version %{uksm_major_version}-for-v3.18
This page took 0.619607 seconds and 4 git commands to generate.