-aufs4.x-rcN kbuild patch
+aufs4.1 kbuild patch
diff --git a/fs/Kconfig b/fs/Kconfig
index 011f433..b1083f6 100644
header-y += auto_fs4.h
header-y += auto_fs.h
header-y += auxvec.h
-aufs4.x-rcN base patch
+aufs4.1 base patch
diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..feac5ea 100644
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags);
#endif
-aufs4.x-rcN mmap patch
+aufs4.1 mmap patch
diff --git a/fs/buffer.c b/fs/buffer.c
index c7a5602..8c50a22 100644
lock_page(page);
if (page->mapping != inode->i_mapping) {
unlock_page(page);
-diff --git a/mm/madvise.c b/mm/madvise.c
-index d551475..1ebf71b 100644
---- a/mm/madvise.c
-+++ b/mm/madvise.c
-@@ -320,12 +320,12 @@ static long madvise_remove(struct vm_area_struct *vma,
- * vma's reference to the file) can go away as soon as we drop
- * mmap_sem.
- */
-- get_file(f);
-+ vma_get_file(vma);
- up_read(¤t->mm->mmap_sem);
- error = vfs_fallocate(f,
- FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
- offset, end - start);
-- fput(f);
-+ vma_fput(vma);
- down_read(¤t->mm->mmap_sem);
- return error;
- }
diff --git a/mm/memory.c b/mm/memory.c
index 22e037e..62096a2 100644
--- a/mm/memory.c
if (new_vma->vm_ops && new_vma->vm_ops->open)
new_vma->vm_ops->open(new_vma);
vma_link(mm, new_vma, prev, rb_link, rb_parent);
-diff --git a/mm/msync.c b/mm/msync.c
-index bb04d53..5c24c54 100644
---- a/mm/msync.c
-+++ b/mm/msync.c
-@@ -84,10 +84,10 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
- start = vma->vm_end;
- if ((flags & MS_SYNC) && file &&
- (vma->vm_flags & VM_SHARED)) {
-- get_file(file);
-+ vma_get_file(vma);
- up_read(&mm->mmap_sem);
- error = vfs_fsync_range(file, fstart, fend, 1);
-- fput(file);
-+ vma_fput(vma);
- if (error || start >= end)
- goto out;
- down_read(&mm->mmap_sem);
diff --git a/mm/nommu.c b/mm/nommu.c
index e544508..dd6f74a 100644
--- a/mm/nommu.c
return ret;
diff --git a/mm/prfile.c b/mm/prfile.c
new file mode 100644
-index 0000000..6aa5ab5
+index 0000000..b323b8a
--- /dev/null
+++ b/mm/prfile.c
@@ -0,0 +1,86 @@
+{
+#ifdef PRFILE_TRACE
+ if (pr)
-+ pr_info("%s:%d: %s, %p\n", func, line, func2,
++ pr_info("%s:%d: %s, %s\n", func, line, func2,
+ f ? (char *)f->f_path.dentry->d_name.name : "(null)");
+#endif
+}
+ fput(pr);
+}
+#endif /* !CONFIG_MMU */
-aufs4.x-rcN standalone patch
+aufs4.1 standalone patch
diff --git a/fs/dcache.c b/fs/dcache.c
index bc261e2..8d7951d 100644
{
diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/ABI/testing/debugfs-aufs 2015-06-28 17:35:44.344717109 +0200
++++ linux/Documentation/ABI/testing/debugfs-aufs 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,50 @@
+What: /debug/aufs/si_<id>/
+Date: March 2009
+ will be empty. About XINO files, see the aufs manual.
diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-06-28 17:35:44.344717109 +0200
++++ linux/Documentation/ABI/testing/sysfs-aufs 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,31 @@
+What: /sys/fs/aufs/si_<id>/
+Date: March 2009
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,170 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,258 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,85 @@
+
+# Copyright (C) 2015 Junjiro R. Okajima
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,113 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,74 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,64 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,120 @@
+
+# Copyright (C) 2011-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,72 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,96 @@
+
+# Copyright (C) 2014-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,58 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+ 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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,52 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+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-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,47 @@
+
+# Copyright (C) 2010-2015 Junjiro R. Okajima
+regular files only.
diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/README 2015-06-28 17:35:44.344717109 +0200
++++ linux/Documentation/filesystems/aufs/README 2015-09-24 10:47:58.244719488 +0200
@@ -0,0 +1,383 @@
+
+Aufs4 -- advanced multi layered unification filesystem version 4.x
+The Parted Magic Project made a donation (2013/9 and 11).
+Pavel Barta made a donation (2013/10).
+Nikolay Pertsev made a donation (2014/5).
-+James B made a donation (2014/7).
++James B made a donation (2014/7 and 2015/7).
+Stefano Di Biase made a donation (2014/8).
+Daniel Epellei made a donation (2015/1).
+
+# 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-28 17:35:44.344717109 +0200
++++ linux/fs/aufs/aufs.h 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/branch.c 2015-12-10 18:46:31.223310574 +0100
@@ -0,0 +1,1414 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/branch.h 2015-12-10 18:46:31.223310574 +0100
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/conf.mk 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,38 @@
+
+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
+-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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/cpup.c 2015-11-11 17:21:46.915530388 +0100
@@ -0,0 +1,1319 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ goto out_parent;
+ if (unlikely(d_is_negative(h_src))) {
+ err = -EIO;
-+ AuIOErr("i%lu exists on a upper branch "
++ AuIOErr("i%lu exists on b%d "
+ "but not pseudo-linked\n",
-+ inode->i_ino);
++ inode->i_ino, cpg->bdst);
+ dput(h_src);
+ goto out_parent;
+ }
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/cpup.h 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dbgaufs.c 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dbgaufs.h 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dcsub.c 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/dcsub.h 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/debug.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/debug.h 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,1105 @@
++++ linux/fs/aufs/dentry.c 2015-11-11 17:21:46.918863802 +0100
+@@ -0,0 +1,1136 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ if (dirperm1)
+ au_fset_lkup(args.flags, IGNORE_PERM);
+
-+ if (au_dbwh(dentry) >= 0)
++ if (au_dbwh(dentry) == bindex)
+ break;
+ if (!h_dentry)
+ continue;
+ return err;
+}
+
++void au_refresh_dop(struct dentry *dentry, int force_reval)
++{
++ const struct dentry_operations *dop
++ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
++ static const unsigned int mask
++ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
++
++ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
++
++ if (dentry->d_op == dop)
++ return;
++
++ AuDbg("%pd\n", dentry);
++ spin_lock(&dentry->d_lock);
++ if (dop == &aufs_dop)
++ dentry->d_flags |= mask;
++ else
++ dentry->d_flags &= ~mask;
++ dentry->d_op = dop;
++ spin_unlock(&dentry->d_lock);
++}
++
+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
+{
+ int err, ebrange;
+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
+ && inode
+ && !(inode->i_state && I_LINKABLE)
-+ && (IS_DEADDIR(inode) || !inode->i_nlink))
++ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
++ AuTraceErr(err);
+ goto out_inval;
++ }
+
+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
+ if (do_udba && inode) {
+
+ if (bstart >= 0) {
+ h_inode = au_h_iptr(inode, bstart);
-+ if (h_inode && au_test_higen(inode, h_inode))
++ if (h_inode && au_test_higen(inode, h_inode)) {
++ AuTraceErr(err);
+ goto out_inval;
++ }
+ }
+ }
+
+ .d_weak_revalidate = aufs_d_revalidate,
+ .d_release = aufs_d_release
+};
++
++/* aufs_dop without d_revalidate */
++const struct dentry_operations aufs_dop_noreval = {
++ .d_release = aufs_d_release
++};
diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dentry.h 2015-06-28 17:35:44.348050491 +0200
-@@ -0,0 +1,233 @@
++++ linux/fs/aufs/dentry.h 2015-11-11 17:21:46.918863802 +0100
+@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+/* ---------------------------------------------------------------------- */
+
+/* dentry.c */
-+extern const struct dentry_operations aufs_dop;
++extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
+struct au_branch;
+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
++void au_refresh_dop(struct dentry *dentry, int force_reval);
+
+/* dinfo.c */
+void au_di_init_once(void *_di);
+#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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/dinfo.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/dir.c 2015-12-10 17:59:16.836166410 +0100
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ sb = a->dentry->d_sb;
+ if (d_really_is_negative(a->dentry))
+ goto out;
-+ aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */
-+
+ /* no dir->i_mutex lock */
++ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
++
+ dir = d_inode(a->dentry);
+ bstart = au_ibstart(dir);
+ bindex = au_br_index(sb, a->brid);
+};
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dir.h 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dynop.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/dynop.h 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/export.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/fhsm.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2011-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,841 @@
++++ linux/fs/aufs/file.c 2015-11-11 17:21:46.918863802 +0100
+@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+{ AuUnsupport(); }
+static int aufs_releasepage(struct page *page, gfp_t gfp)
+{ AuUnsupport(); return 0; }
++#if 0 /* called by memory compaction regardless file */
+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
+ struct page *page, enum migrate_mode mode)
+{ AuUnsupport(); return 0; }
++#endif
+static int aufs_launder_page(struct page *page)
+{ AuUnsupport(); return 0; }
+static int aufs_is_partially_uptodate(struct page *page,
+ /* no bmap, no block device */
+ .invalidatepage = aufs_invalidatepage,
+ .releasepage = aufs_releasepage,
-+ .migratepage = aufs_migratepage,
++ /* is fallback_migrate_page ok? */
++ /* .migratepage = aufs_migratepage, */
+ .launder_page = aufs_launder_page,
+ .is_partially_uptodate = aufs_is_partially_uptodate,
+ .is_dirty_writeback = aufs_is_dirty_writeback,
+};
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/file.h 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/finfo.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/f_op.c 2015-09-24 10:47:58.251386326 +0200
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+};
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/fstype.h 2015-12-10 17:59:16.836166410 +0100
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+
+#include <linux/fs.h>
+#include <linux/magic.h>
-+#include <linux/romfs_fs.h>
+#include <linux/nfs_fs.h>
++#include <linux/romfs_fs.h>
+
+static inline int au_test_aufs(struct super_block *sb)
+{
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/hfsnotify.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+};
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/hfsplus.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/hnotify.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/iinfo.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,500 @@
++++ linux/fs/aufs/inode.c 2015-12-10 17:59:16.836166410 +0100
+@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ return err;
+}
+
++void au_refresh_iop(struct inode *inode, int force_getattr)
++{
++ int type;
++ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
++ const struct inode_operations *iop
++ = force_getattr ? aufs_iop : sbi->si_iop_array;
++
++ if (inode->i_op == iop)
++ return;
++
++ switch (inode->i_mode & S_IFMT) {
++ case S_IFDIR:
++ type = AuIop_DIR;
++ break;
++ case S_IFLNK:
++ type = AuIop_SYMLINK;
++ break;
++ default:
++ type = AuIop_OTHER;
++ break;
++ }
++
++ inode->i_op = iop + type;
++ /* unnecessary smp_wmb() */
++}
++
+int au_refresh_hinode_self(struct inode *inode)
+{
+ int err, update;
+ struct dentry *h_dentry;
+ struct inode *h_inode;
+ struct au_iinfo *iinfo;
++ struct inode_operations *iop;
+
+ IiMustWriteLock(inode);
+
+ err = 0;
+ isdir = 0;
++ iop = au_sbi(inode->i_sb)->si_iop_array;
+ bstart = au_dbstart(dentry);
+ h_dentry = au_h_dptr(dentry, bstart);
+ h_inode = d_inode(h_dentry);
+ switch (mode & S_IFMT) {
+ case S_IFREG:
+ btail = au_dbtail(dentry);
-+ inode->i_op = &aufs_iop;
++ inode->i_op = iop + AuIop_OTHER;
+ inode->i_fop = &aufs_file_fop;
+ err = au_dy_iaop(inode, bstart, h_inode);
+ if (unlikely(err))
+ case S_IFDIR:
+ isdir = 1;
+ btail = au_dbtaildir(dentry);
-+ inode->i_op = &aufs_dir_iop;
++ inode->i_op = iop + AuIop_DIR;
+ inode->i_fop = &aufs_dir_fop;
+ break;
+ case S_IFLNK:
+ btail = au_dbtail(dentry);
-+ inode->i_op = &aufs_symlink_iop;
++ inode->i_op = iop + AuIop_SYMLINK;
+ break;
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFSOCK:
+ btail = au_dbtail(dentry);
-+ inode->i_op = &aufs_iop;
++ inode->i_op = iop + AuIop_OTHER;
+ init_special_inode(inode, mode, h_inode->i_rdev);
+ break;
+ default:
+}
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-28 17:35:44.348050491 +0200
-@@ -0,0 +1,673 @@
++++ linux/fs/aufs/inode.h 2015-12-10 17:59:16.836166410 +0100
+@@ -0,0 +1,681 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+
+/* inode.c */
+struct inode *au_igrab(struct inode *inode);
++void au_refresh_iop(struct inode *inode, int force_getattr);
+int au_refresh_hinode_self(struct inode *inode);
+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+}
+
+/* i_op.c */
-+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
++enum {
++ AuIop_SYMLINK,
++ AuIop_DIR,
++ AuIop_OTHER,
++ AuIop_Last
++};
++extern struct inode_operations aufs_iop[AuIop_Last],
++ aufs_iop_nogetattr[AuIop_Last];
+
+/* au_wr_dir flags */
+#define AuWrDir_ADD_ENTRY 1
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/ioctl.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/i_op_add.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,932 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,1447 @@
++++ linux/fs/aufs/i_op.c 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,1449 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+
+/* ---------------------------------------------------------------------- */
+
-+struct inode_operations aufs_symlink_iop = {
-+ .permission = aufs_permission,
++/* no getattr version will be set by module.c:aufs_init() */
++struct inode_operations aufs_iop_nogetattr[AuIop_Last],
++ aufs_iop[] = {
++ [AuIop_SYMLINK] = {
++ .permission = aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
-+ .get_acl = aufs_get_acl,
-+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
++ .get_acl = aufs_get_acl,
++ .set_acl = aufs_set_acl, /* unsupport for symlink? */
+#endif
+
-+ .setattr = aufs_setattr,
-+ .getattr = aufs_getattr,
++ .setattr = aufs_setattr,
++ .getattr = aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
-+ .setxattr = aufs_setxattr,
-+ .getxattr = aufs_getxattr,
-+ .listxattr = aufs_listxattr,
-+ .removexattr = aufs_removexattr,
++ .setxattr = aufs_setxattr,
++ .getxattr = aufs_getxattr,
++ .listxattr = aufs_listxattr,
++ .removexattr = aufs_removexattr,
+#endif
+
-+ .readlink = aufs_readlink,
-+ .follow_link = aufs_follow_link,
-+ .put_link = aufs_put_link,
-+
-+ /* .update_time = aufs_update_time */
-+};
++ .readlink = aufs_readlink,
++ .follow_link = aufs_follow_link,
++ .put_link = aufs_put_link,
+
-+struct inode_operations aufs_dir_iop = {
-+ .create = aufs_create,
-+ .lookup = aufs_lookup,
-+ .link = aufs_link,
-+ .unlink = aufs_unlink,
-+ .symlink = aufs_symlink,
-+ .mkdir = aufs_mkdir,
-+ .rmdir = aufs_rmdir,
-+ .mknod = aufs_mknod,
-+ .rename = aufs_rename,
-+
-+ .permission = aufs_permission,
++ /* .update_time = aufs_update_time */
++ },
++ [AuIop_DIR] = {
++ .create = aufs_create,
++ .lookup = aufs_lookup,
++ .link = aufs_link,
++ .unlink = aufs_unlink,
++ .symlink = aufs_symlink,
++ .mkdir = aufs_mkdir,
++ .rmdir = aufs_rmdir,
++ .mknod = aufs_mknod,
++ .rename = aufs_rename,
++
++ .permission = aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
-+ .get_acl = aufs_get_acl,
-+ .set_acl = aufs_set_acl,
++ .get_acl = aufs_get_acl,
++ .set_acl = aufs_set_acl,
+#endif
+
-+ .setattr = aufs_setattr,
-+ .getattr = aufs_getattr,
++ .setattr = aufs_setattr,
++ .getattr = aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
-+ .setxattr = aufs_setxattr,
-+ .getxattr = aufs_getxattr,
-+ .listxattr = aufs_listxattr,
-+ .removexattr = aufs_removexattr,
++ .setxattr = aufs_setxattr,
++ .getxattr = aufs_getxattr,
++ .listxattr = aufs_listxattr,
++ .removexattr = aufs_removexattr,
+#endif
+
-+ .update_time = aufs_update_time,
-+ .atomic_open = aufs_atomic_open,
-+ .tmpfile = aufs_tmpfile
-+};
-+
-+struct inode_operations aufs_iop = {
-+ .permission = aufs_permission,
++ .update_time = aufs_update_time,
++ .atomic_open = aufs_atomic_open,
++ .tmpfile = aufs_tmpfile
++ },
++ [AuIop_OTHER] = {
++ .permission = aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
-+ .get_acl = aufs_get_acl,
-+ .set_acl = aufs_set_acl,
++ .get_acl = aufs_get_acl,
++ .set_acl = aufs_set_acl,
+#endif
+
-+ .setattr = aufs_setattr,
-+ .getattr = aufs_getattr,
++ .setattr = aufs_setattr,
++ .getattr = aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
-+ .setxattr = aufs_setxattr,
-+ .getxattr = aufs_getxattr,
-+ .listxattr = aufs_listxattr,
-+ .removexattr = aufs_removexattr,
++ .setxattr = aufs_setxattr,
++ .getxattr = aufs_getxattr,
++ .listxattr = aufs_listxattr,
++ .removexattr = aufs_removexattr,
+#endif
+
-+ .update_time = aufs_update_time
++ .update_time = aufs_update_time
++ }
+};
diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/i_op_del.c 2015-06-28 17:36:09.025073697 +0200
++++ linux/fs/aufs/i_op_del.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,1017 @@
++++ linux/fs/aufs/i_op_ren.c 2015-12-10 17:59:16.836166410 +0100
+@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+/*
+ * functions for reverting.
+ * when an error happened in a single rename systemcall, we should revert
-+ * everything as if nothing happend.
++ * everything as if nothing happened.
+ * we don't need to revert the copied-up/down the parent dir since they are
+ * harmless.
+ */
+ if (unlikely(d_really_is_positive(a->dst_dentry)
+ && !d_is_dir(a->dst_dentry)))
+ goto out_free;
-+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
-+ AuLock_DIR | flags);
-+ } else
-+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
-+ flags);
++ flags |= AuLock_DIRS;
++ }
++ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, flags);
+ if (unlikely(err))
+ goto out_free;
+
+
+ /*
+ * is it possible?
-+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
++ * yes, it happened (in linux-3.3-rcN) but I don't know why.
+ * there may exist a problem somewhere else.
+ */
+ err = -EINVAL;
+}
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-28 17:35:44.344717109 +0200
++++ linux/fs/aufs/Kconfig 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,185 @@
+config AUFS_FS
+ tristate "Aufs (Advanced multi layered unification filesystem) support"
+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-28 17:35:44.348050491 +0200
-@@ -0,0 +1,145 @@
++++ linux/fs/aufs/loop.c 2015-11-11 17:21:46.918863802 +0100
+@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ int err;
+ struct super_block *sb __maybe_unused;
+
-+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
++ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
+
+ err = 0;
+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
+
+void au_loopback_fin(void)
+{
-+ symbol_put(loop_backing_file);
++ if (backing_file_func)
++ symbol_put(loop_backing_file);
+ kfree(au_warn_loopback_array);
+}
diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/loop.h 2015-06-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/loop.h 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/magic.mk 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,30 @@
+
+# defined in ${srctree}/fs/fuse/inode.c
+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-28 17:35:44.344717109 +0200
++++ linux/fs/aufs/Makefile 2015-09-24 10:47:58.248052907 +0200
@@ -0,0 +1,44 @@
+
+include ${src}/magic.mk
+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-28 17:35:44.348050491 +0200
-@@ -0,0 +1,210 @@
++++ linux/fs/aufs/module.c 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+
+int au_seq_path(struct seq_file *seq, struct path *path)
+{
-+ return seq_path(seq, path, au_esc_chars);
++ int err;
++
++ err = seq_path(seq, path, au_esc_chars);
++ if (err > 0)
++ err = 0;
++ else if (err < 0)
++ err = -ENOMEM;
++
++ return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
+
++ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
++ for (i = 0; i < AuIop_Last; i++)
++ aufs_iop_nogetattr[i].getattr = NULL;
++
+ au_sbilist_init();
+ sysaufs_brs_init();
+ au_debug_init();
+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-28 17:35:44.348050491 +0200
++++ linux/fs/aufs/module.h 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.025073697 +0200
-@@ -0,0 +1,694 @@
++++ linux/fs/aufs/mvdown.c 2015-12-10 17:59:16.839499823 +0100
+@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2011-2015 Junjiro R. Okajima
+ *
+ au_set_dbstart(a->dentry, a->mvd_bdst);
+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
+ au_set_ibstart(a->inode, a->mvd_bdst);
++ } else {
++ /* hide the lower */
++ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
++ au_set_dbend(a->dentry, a->mvd_bsrc);
++ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
++ au_set_ibend(a->inode, a->mvd_bsrc);
+ }
+ if (au_dbend(a->dentry) < a->mvd_bdst)
+ au_set_dbend(a->dentry, a->mvd_bdst);
+ int err, e;
+ unsigned char dmsg;
+ struct au_mvd_args *args;
++ struct inode *inode;
+
++ inode = d_inode(dentry);
+ err = -EPERM;
+ if (unlikely(!capable(CAP_SYS_ADMIN)))
+ goto out;
+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
+ args->mvdown.au_errno = 0;
+ args->dentry = dentry;
-+ args->inode = d_inode(dentry);
++ args->inode = inode;
+ args->sb = dentry->d_sb;
+
+ err = -ENOENT;
+ goto out_dir;
+ }
+
-+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
-+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
++ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
+ if (unlikely(err))
+ goto out_inode;
+
+ goto out_parent;
+
+ au_cpup_attr_timesizes(args->dir);
-+ au_cpup_attr_timesizes(args->inode);
-+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
++ au_cpup_attr_timesizes(inode);
++ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
++ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
+ /* au_digen_dec(dentry); */
+
+out_parent:
+ di_write_unlock(args->parent);
+ aufs_read_unlock(dentry, AuLock_DW);
+out_inode:
-+ mutex_unlock(&args->inode->i_mutex);
++ mutex_unlock(&inode->i_mutex);
+out_dir:
+ mutex_unlock(&args->dir->i_mutex);
+out_free:
+}
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-28 17:36:09.028407078 +0200
-@@ -0,0 +1,1835 @@
++++ linux/fs/aufs/opts.c 2015-12-10 17:59:16.839499823 +0100
+@@ -0,0 +1,1859 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+{
+ int err, fhsm;
+ aufs_bindex_t bindex, bend;
-+ unsigned char do_plink, skip, do_free;
++ unsigned char do_plink, skip, do_free, can_no_dreval;
+ struct au_branch *br;
+ struct au_wbr *wbr;
-+ struct dentry *root;
++ struct dentry *root, *dentry;
+ struct inode *dir, *h_dir;
+ struct au_sbinfo *sbinfo;
+ struct au_hinode *hdir;
+ root = sb->s_root;
+ dir = d_inode(root);
+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
++ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
++ UDBA_NONE);
+ bend = au_sbend(sb);
+ for (bindex = 0; !err && bindex <= bend; bindex++) {
+ skip = 0;
+ if (wbr)
+ wbr_wh_read_unlock(wbr);
+
++ if (can_no_dreval) {
++ dentry = br->br_path.dentry;
++ spin_lock(&dentry->d_lock);
++ if (dentry->d_flags &
++ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
++ can_no_dreval = 0;
++ spin_unlock(&dentry->d_lock);
++ }
++
+ if (au_br_fhsm(br->br_perm)) {
+ fhsm++;
+ AuDebugOn(!br->br_fhsm);
+ }
+ }
+
++ if (can_no_dreval)
++ au_fset_si(sbinfo, NO_DREVAL);
++ else
++ au_fclr_si(sbinfo, NO_DREVAL);
++
+ if (fhsm >= 2) {
+ au_fset_si(sbinfo, FHSM);
+ for (bindex = bend; bindex >= 0; bindex--) {
+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
+{
+ int err, rerr;
++ unsigned char no_dreval;
+ struct inode *dir;
+ struct au_opt_xino *opt_xino;
+ struct au_opt *opt;
+
+ SiMustWriteLock(sb);
+
++ err = 0;
+ dir = d_inode(sb->s_root);
+ sbinfo = au_sbi(sb);
-+ err = 0;
+ opt_xino = NULL;
+ opt = opts->opt;
+ while (err >= 0 && opt->type != Opt_tail) {
+ AuTraceErr(err);
+ /* go on even err */
+
++ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
+ if (unlikely(rerr && !err))
+ err = rerr;
+
++ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
++ au_fset_opts(opts->flags, REFRESH_IDOP);
++
+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
+ rerr = au_xib_trunc(sb);
+ if (unlikely(rerr && !err))
+
+ /* will be handled by the caller */
+ if (!au_ftest_opts(opts->flags, REFRESH)
-+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
++ && (opts->given_udba
++ || au_opt_test(sbinfo->si_mntflags, XINO)
++ || au_ftest_opts(opts->flags, REFRESH_IDOP)
++ ))
+ au_fset_opts(opts->flags, REFRESH);
+
+ AuDbg("status 0x%x\n", opts->flags);
+}
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-28 17:35:44.351383872 +0200
-@@ -0,0 +1,210 @@
++++ linux/fs/aufs/opts.h 2015-12-10 17:59:16.839499823 +0100
+@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+#define AuOpts_REFRESH (1 << 1)
+#define AuOpts_TRUNC_XIB (1 << 2)
+#define AuOpts_REFRESH_DYAOP (1 << 3)
++#define AuOpts_REFRESH_IDOP (1 << 4)
+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
+#define au_fset_opts(flags, name) \
+ do { (flags) |= AuOpts_##name; } while (0)
+#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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/plink.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/poll.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/posix_acl.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/procfs.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+}
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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/rdu.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/rwsem.h 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.028407078 +0200
-@@ -0,0 +1,356 @@
++++ linux/fs/aufs/sbinfo.c 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+
+ au_sphl_init(&sbinfo->si_files);
+
++ /* with getattr by default */
++ sbinfo->si_iop_array = aufs_iop;
++
+ /* leave other members for sysaufs and si_mnt. */
+ sbinfo->si_sb = sb;
+ sb->s_fs_info = sbinfo;
+
+ if (au_ftest_lock(flags, GEN)) {
+ err = au_digen_test(dentry, au_sigen(sb));
-+ AuDebugOn(!err && au_dbrange_test(dentry));
++ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
++ AuDebugOn(!err && au_dbrange_test(dentry));
++ else if (!err)
++ err = au_dbrange_test(dentry);
+ if (unlikely(err))
+ aufs_read_unlock(dentry, flags);
+ }
+ if (unlikely(err))
+ goto out;
+
-+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
++ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
+
+ if (au_ftest_lock(flags, GEN)) {
+ sigen = au_sigen(sb);
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/spl.h 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.028407078 +0200
-@@ -0,0 +1,1004 @@
++++ linux/fs/aufs/super.c 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,1046 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ path.mnt = au_br_mnt(br);
+ path.dentry = hdp[bindex].hd_dentry;
+ err = au_seq_path(seq, &path);
-+ if (err > 0) {
++ if (!err) {
+ au_optstr_br_perm(&perm, br->br_perm);
+ err = seq_printf(seq, "=%s", perm.a);
+ if (err == -1)
+
+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
+ struct au_sbinfo *sbinfo,
-+ const unsigned int dir_flags)
++ const unsigned int dir_flags, unsigned int do_idop)
+{
+ int err;
+ struct dentry *parent;
+ }
+ dput(parent);
+
++ if (!err) {
++ if (do_idop)
++ au_refresh_dop(dentry, /*force_reval*/0);
++ } else
++ au_refresh_dop(dentry, /*force_reval*/1);
++
+ AuTraceErr(err);
+ return err;
+}
+
-+static int au_refresh_d(struct super_block *sb)
++static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
+{
+ int err, i, j, ndentry, e;
+ unsigned int sigen;
+ struct dentry *root = sb->s_root;
+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
+
++ if (do_idop)
++ au_refresh_dop(root, /*force_reval*/0);
++
+ err = au_dpages_init(&dpages, GFP_NOFS);
+ if (unlikely(err))
+ goto out;
+ ndentry = dpage->ndentry;
+ for (j = 0; j < ndentry; j++) {
+ d = dentries[j];
-+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
++ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
++ do_idop);
+ if (unlikely(e && !err))
+ err = e;
+ /* go on even err */
+ return err;
+}
+
-+static int au_refresh_i(struct super_block *sb)
++static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
+{
+ int err, e;
+ unsigned int sigen;
+ inode = array[ull];
+ if (unlikely(!inode))
+ break;
++
++ e = 0;
++ ii_write_lock_child(inode);
+ if (au_iigen(inode, NULL) != sigen) {
-+ ii_write_lock_child(inode);
+ e = au_refresh_hinode_self(inode);
-+ ii_write_unlock(inode);
+ if (unlikely(e)) {
++ au_refresh_iop(inode, /*force_getattr*/1);
+ pr_err("error %d, i%lu\n", e, inode->i_ino);
+ if (!err)
+ err = e;
+ /* go on even if err */
+ }
+ }
++ if (!e && do_idop)
++ au_refresh_iop(inode, /*force_getattr*/0);
++ ii_write_unlock(inode);
+ }
+
+ au_iarray_free(array, max);
+ return err;
+}
+
-+static void au_remount_refresh(struct super_block *sb)
++static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
+{
+ int err, e;
+ unsigned int udba;
+ struct dentry *root;
+ struct inode *inode;
+ struct au_branch *br;
++ struct au_sbinfo *sbi;
+
+ au_sigen_inc(sb);
-+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
++ sbi = au_sbi(sb);
++ au_fclr_si(sbi, FAILED_REFRESH_DIR);
+
+ root = sb->s_root;
+ DiMustNoWaiters(root);
+ }
+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
+
++ if (do_idop) {
++ if (au_ftest_si(sbi, NO_DREVAL)) {
++ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
++ sb->s_d_op = &aufs_dop_noreval;
++ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
++ sbi->si_iop_array = aufs_iop_nogetattr;
++ } else {
++ AuDebugOn(sb->s_d_op == &aufs_dop);
++ sb->s_d_op = &aufs_dop;
++ AuDebugOn(sbi->si_iop_array == aufs_iop);
++ sbi->si_iop_array = aufs_iop;
++ }
++ pr_info("reset to %pf and %pf\n",
++ sb->s_d_op, sbi->si_iop_array);
++ }
++
+ di_write_unlock(root);
-+ err = au_refresh_d(sb);
-+ e = au_refresh_i(sb);
++ err = au_refresh_d(sb, do_idop);
++ e = au_refresh_i(sb, do_idop);
+ if (unlikely(e && !err))
+ err = e;
+ /* aufs_write_lock() calls ..._child() */
+ au_opts_free(&opts);
+
+ if (au_ftest_opts(opts.flags, REFRESH))
-+ au_remount_refresh(sb);
++ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
+
+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
+ mntflags = au_mntflags(sb);
+ if (IS_ERR(inode))
+ goto out;
+
-+ inode->i_op = &aufs_dir_iop;
++ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
+ inode->i_fop = &aufs_dir_fop;
+ inode->i_mode = S_IFDIR;
+ set_nlink(inode, 2);
+{
+ int err;
+ struct au_opts opts;
++ struct au_sbinfo *sbinfo;
+ struct dentry *root;
+ struct inode *inode;
+ char *arg = raw_data;
+ err = au_si_alloc(sb);
+ if (unlikely(err))
+ goto out_opts;
++ sbinfo = au_sbi(sb);
+
+ /* all timestamps always follow the ones on the branch */
+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
+ aufs_write_lock(root);
+ err = au_opts_mount(sb, &opts);
+ au_opts_free(&opts);
++ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
++ sb->s_d_op = &aufs_dop_noreval;
++ pr_info("%pf\n", sb->s_d_op);
++ au_refresh_dop(root, /*force_reval*/0);
++ sbinfo->si_iop_array = aufs_iop_nogetattr;
++ au_refresh_iop(inode, /*force_getattr*/0);
++ }
+ aufs_write_unlock(root);
+ mutex_unlock(&inode->i_mutex);
+ if (!err)
+ dput(root);
+ sb->s_root = NULL;
+out_info:
-+ dbgaufs_si_fin(au_sbi(sb));
-+ kobject_put(&au_sbi(sb)->si_kobj);
++ dbgaufs_si_fin(sbinfo);
++ kobject_put(&sbinfo->si_kobj);
+ sb->s_fs_info = NULL;
+out_opts:
+ free_page((unsigned long)opts.opt);
+ sbinfo->si_wbr_create_ops->fin(sb);
+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
-+ au_remount_refresh(sb);
++ au_remount_refresh(sb, /*do_idop*/0);
+ }
+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
+ au_plink_put(sb, /*verbose*/1);
+};
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-28 17:36:09.028407078 +0200
-@@ -0,0 +1,635 @@
++++ linux/fs/aufs/super.h 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ /* file list */
+ struct au_sphlhead si_files;
+
++ /* with/without getattr, brother of sb->s_d_op */
++ struct inode_operations *si_iop_array;
++
+ /*
+ * sysfs and lifetime management.
+ * this is not a small structure and it may be a waste of memory in case
+ * if it is false, refreshing dirs at access time is unnecesary
+ */
+#define AuSi_FAILED_REFRESH_DIR 1
-+
+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
++#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
+
+#ifndef CONFIG_AUFS_FHSM
+#undef AuSi_FHSM
+#define AuLock_IR (1 << 1) /* read-lock inode */
+#define AuLock_IW (1 << 2) /* write-lock inode */
+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
-+#define AuLock_DIR (1 << 4) /* target is a dir */
++#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
+#define AuLock_GEN (1 << 7) /* test digen/iigen */
+#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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/sysaufs.c 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/sysaufs.h 2015-09-24 10:47:58.254719746 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.351383872 +0200
-@@ -0,0 +1,372 @@
++++ linux/fs/aufs/sysfs.c 2015-12-10 18:46:31.223310574 +0100
+@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ case AuBrSysfs_BR:
+ path.mnt = au_br_mnt(br);
+ path.dentry = au_h_dptr(root, bindex);
-+ au_seq_path(seq, &path);
-+ au_optstr_br_perm(&perm, br->br_perm);
-+ err = seq_printf(seq, "=%s\n", perm.a);
++ err = au_seq_path(seq, &path);
++ if (!err) {
++ au_optstr_br_perm(&perm, br->br_perm);
++ err = seq_printf(seq, "=%s\n", perm.a);
++ }
+ break;
+ case AuBrSysfs_BRID:
+ err = seq_printf(seq, "%d\n", br->br_id);
+ if (unlikely(err))
+ break;
+
-+ au_seq_path(seq, &br->br_path);
++ err = au_seq_path(seq, &br->br_path);
++ if (unlikely(err))
++ break;
+ err = seq_putc(seq, '\0');
+ if (!err && seq->count <= sz) {
+ err = copy_to_user(arg->path, seq->buf, seq->count);
+}
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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/sysrq.c 2015-12-10 18:46:31.223310574 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/vdir.c 2015-11-11 17:21:46.922197217 +0100
@@ -0,0 +1,888 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+
+/* ---------------------------------------------------------------------- */
+
-+/* estimate the apropriate size for name hash table */
++/* estimate the appropriate size for name hash table */
+unsigned int au_rdhash_est(loff_t sz)
+{
+ unsigned int n;
+
+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
+ if (!vdir->vd_deblk_sz) {
-+ /* estimate the apropriate size for deblk */
++ /* estimate the appropriate size for deblk */
+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
+ }
+}
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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/vfsub.c 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/vfsub.h 2015-12-10 18:46:31.223310574 +0100
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/wbr_policy.c 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+};
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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/whout.c 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,1063 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/whout.h 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/wkq.c 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+}
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-28 17:35:44.351383872 +0200
++++ linux/fs/aufs/wkq.h 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+#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-28 17:36:09.028407078 +0200
++++ linux/fs/aufs/xattr.c 2015-09-24 10:47:58.258053165 +0200
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2014-2015 Junjiro R. Okajima
+#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-28 17:36:09.028407078 +0200
-@@ -0,0 +1,1297 @@
++++ linux/fs/aufs/xino.c 2015-11-11 17:21:46.922197217 +0100
+@@ -0,0 +1,1296 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ int err;
+
+ err = au_seq_path(seq, &file->f_path);
-+ if (unlikely(err < 0))
++ if (unlikely(err))
+ goto out;
+
-+ err = 0;
+#define Deleted "\\040(deleted)"
+ seq->count -= sizeof(Deleted) - 1;
+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
+}
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-28 17:36:09.028407078 +0200
++++ linux/include/uapi/linux/aufs_type.h 2015-12-10 18:46:31.223310574 +0100
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+
+#include <linux/limits.h>
+
-+#define AUFS_VERSION "4.x-rcN-20150622"
++#define AUFS_VERSION "4.1-20151116"
+
+/* todo? move this to linux-2.6.19/include/magic.h */
+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
+
+#endif /* __AUFS_TYPE_H__ */
-aufs4.x-rcN loopback patch
+aufs4.1 loopback patch
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0160952..866f8e2 100644
if (file->f_mapping != h_file->f_mapping) {
file->f_mapping = h_file->f_mapping;
diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
-index 69f7e96..7941063 100644
+index f324758..4555e7b 100644
--- a/fs/aufs/loop.c
+++ b/fs/aufs/loop.c
-@@ -130,3 +130,19 @@ void au_loopback_fin(void)
- symbol_put(loop_backing_file);
+@@ -131,3 +131,19 @@ void au_loopback_fin(void)
+ symbol_put(loop_backing_file);
kfree(au_warn_loopback_array);
}
+
#endif /* __KERNEL__ */
diff --git a/fs/aufs/super.c b/fs/aufs/super.c
-index ee5780d..da35759 100644
+index 7efab49..ed357c7 100644
--- a/fs/aufs/super.c
+++ b/fs/aufs/super.c
-@@ -807,7 +807,10 @@ static const struct super_operations aufs_sop = {
+@@ -840,7 +840,10 @@ static const struct super_operations aufs_sop = {
.statfs = aufs_statfs,
.put_super = aufs_put_super,
.sync_fs = aufs_sync_fs,