[packages/kernel] Rel 1; switch to aufs from https://github.com/tombriden/linux/commits/linux-6.7.y for now
arekm
arekm at pld-linux.org
Mon Jan 29 10:19:27 CET 2024
commit b622d832656bdf738eab530c75e20b1eeb8841bc
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Mon Jan 29 08:55:36 2024 +0100
Rel 1; switch to aufs from https://github.com/tombriden/linux/commits/linux-6.7.y for now
kernel-aufs-fixes.patch | 152 +
kernel-aufs.patch | 19770 +++++++++++++++++++++++-----------------------
kernel.spec | 4 +-
3 files changed, 10096 insertions(+), 9830 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index f9fe40b1..d4023508 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -59,7 +59,7 @@
%define have_pcmcia 0
%endif
-%define rel 0.1
+%define rel 1
%define basever 6.7
%define postver .2
@@ -169,6 +169,7 @@ Patch85: kernel-hostap.patch
# see update-source.sh
Patch145: kernel-aufs.patch
Patch147: kernel-aufs-make.patch
+Patch148: kernel-aufs-fixes.patch
# Show normal colors in menuconfig with ncurses ABI 6
Patch250: kernel-fix_256colors_menuconfig.patch
@@ -602,6 +603,7 @@ cd linux-%{basever}
# aufs
%patch145 -p1
%patch147 -p1
+%patch148 -p1
%endif
%if %{with rescuecd}
diff --git a/kernel-aufs-fixes.patch b/kernel-aufs-fixes.patch
new file mode 100644
index 00000000..26d072fa
--- /dev/null
+++ b/kernel-aufs-fixes.patch
@@ -0,0 +1,152 @@
+; https://github.com/sfjro/aufs-standalone/issues/35
+; from https://github.com/tombriden/linux/commits/linux-6.7.y
+;
+From 29bbb4f7a4322a7dbbebb9ac80088ef02085457a Mon Sep 17 00:00:00 2001
+From: Tom Briden <tom at decompile.me.uk>
+Date: Fri, 22 Dec 2023 08:09:43 +0000
+Subject: [PATCH] fix(aufs): apply fix from upstream
+
+---
+ fs/aufs/i_op.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c
+index a5cc8743c2bca4..f64e465c37e8ae 100644
+--- a/fs/aufs/i_op.c
++++ b/fs/aufs/i_op.c
+@@ -1293,9 +1293,14 @@ static int aufs_getattr(struct mnt_idmap *idmap, const struct path *path,
+ goto out_fill; /* pretending success */
+
+ positive = d_is_positive(h_path.dentry);
+- if (positive)
++ if (positive) {
+ /* no vfsub version */
+ err = vfs_getattr(&h_path, st, request, query);
++ if (query & AT_GETATTR_NOSEC)
++ err = vfs_getattr_nosec(&h_path, st, request, query);
++ else
++ err = vfs_getattr(&h_path, st, request, query);
++ }
+ if (!err) {
+ if (positive)
+ au_refresh_iattr(inode, st,
+From 4f20b6e23c56db7520a8416b752f7820920ec283 Mon Sep 17 00:00:00 2001
+From: Tom Briden <tom at decompile.me.uk>
+Date: Thu, 11 Jan 2024 11:20:23 +0000
+Subject: [PATCH] aufs: fixes for linux-6.7.y
+
+---
+ fs/aufs/branch.c | 2 +-
+ fs/aufs/cpup.c | 8 ++++----
+ fs/aufs/dir.c | 2 +-
+ fs/aufs/i_op.c | 4 ++--
+ fs/aufs/vfsub.h | 2 +-
+ fs/namespace.c | 1 -
+ fs/proc/base.c | 2 +-
+ 7 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
+index 2a85d744d2b5f7..3ecc05573cc028 100644
+--- a/fs/aufs/branch.c
++++ b/fs/aufs/branch.c
+@@ -1293,7 +1293,7 @@ static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
+ if (hf->f_mode & FMODE_READ)
+ i_readcount_inc(h_inode);
+ put_write_access(h_inode);
+- __mnt_drop_write(hf->f_path.mnt);
++ mnt_put_write_access(hf->f_path.mnt);
+ }
+ }
+
+diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
+index 8c8bd5f7b28d81..3f09876a3bd5ee 100644
+--- a/fs/aufs/cpup.c
++++ b/fs/aufs/cpup.c
+@@ -133,8 +133,8 @@ void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
+ dt->dt_dentry = dentry;
+ dt->dt_h_path = *h_path;
+ h_inode = d_inode(h_path->dentry);
+- dt->dt_atime = h_inode->i_atime;
+- dt->dt_mtime = h_inode->i_mtime;
++ dt->dt_atime = h_inode->__i_atime;
++ dt->dt_mtime = h_inode->__i_mtime;
+ /* smp_mb(); */
+ }
+
+@@ -200,8 +200,8 @@ int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct path *h_src,
+ } else {
+ ia.ia_uid = h_isrc->i_uid;
+ ia.ia_gid = h_isrc->i_gid;
+- ia.ia_atime = h_isrc->i_atime;
+- ia.ia_mtime = h_isrc->i_mtime;
++ ia.ia_atime = h_isrc->__i_atime;
++ ia.ia_mtime = h_isrc->__i_mtime;
+ if (h_idst->i_mode != h_isrc->i_mode
+ && !S_ISLNK(h_idst->i_mode)) {
+ ia.ia_valid |= ATTR_MODE;
+diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c
+index ee900ea3264b22..e986deffef5e9e 100644
+--- a/fs/aufs/dir.c
++++ b/fs/aufs/dir.c
+@@ -145,7 +145,7 @@ static void au_do_dir_ts(void *arg)
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
+ h_dir = au_h_iptr(dir, btop);
+ if (h_dir->i_nlink
+- && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
++ && timespec64_compare(&h_dir->__i_mtime, &dt.dt_mtime) < 0) {
+ dt.dt_h_path = h_path;
+ au_dtime_revert(&dt);
+ }
+diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c
+index f64e465c37e8ae..020a88b719567c 100644
+--- a/fs/aufs/i_op.c
++++ b/fs/aufs/i_op.c
+@@ -1167,8 +1167,8 @@ static void au_refresh_iattr(struct inode *inode, struct kstat *st,
+ /* don't i_[ug]id_write() here */
+ inode->i_uid = st->uid;
+ inode->i_gid = st->gid;
+- inode->i_atime = st->atime;
+- inode->i_mtime = st->mtime;
++ inode->__i_atime = st->atime;
++ inode->__i_mtime = st->mtime;
+ inode_set_ctime_to_ts(inode, st->ctime);
+
+ au_cpup_attr_nlink(inode, /*force*/0);
+diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h
+index ed218d95770d0c..b45603c2d651bf 100644
+--- a/fs/aufs/vfsub.h
++++ b/fs/aufs/vfsub.h
+@@ -33,7 +33,7 @@
+
+ /* copied from linux/fs/internal.h */
+ /* todo: BAD approach!! */
+-extern void __mnt_drop_write(struct vfsmount *);
++extern void mnt_put_write_access(struct vfsmount *);
+ extern struct file *alloc_empty_file(int, const struct cred *);
+
+ /* ---------------------------------------------------------------------- */
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 1b942a6b72fa9f..07e2fee153f7f3 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -489,7 +489,6 @@ void mnt_put_write_access_file(struct file *file)
+ if (!(file->f_mode & FMODE_WRITER))
+ mnt_put_write_access(file->f_path.mnt);
+ }
+-EXPORT_SYMBOL_GPL(__mnt_drop_write);
+
+ void mnt_drop_write_file(struct file *file)
+ {
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index dd31e3b6bf77cc..d4dcd73a765a20 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2214,7 +2214,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
+ rc = -ENOENT;
+ vma = find_exact_vma(mm, vm_start, vm_end);
+ if (vma && vma->vm_file) {
+- *path = *file_user_path(vma->vm_file);
++ *path = vma_pr_or_file(vma)->f_path;
+ path_get(path);
+ rc = 0;
+ }
diff --git a/kernel-aufs.patch b/kernel-aufs.patch
index a5dcb9a0..1394a799 100644
--- a/kernel-aufs.patch
+++ b/kernel-aufs.patch
@@ -1,1008 +1,749 @@
-SPDX-License-Identifier: GPL-2.0
-aufs6.x-rcN kbuild patch
+From 8dcf5b3ed788c0909dc1248a00a8997cdeefde1e Mon Sep 17 00:00:00 2001
+From: Tom Briden <tom at decompile.me.uk>
+Date: Thu, 11 Jan 2024 11:05:05 +0000
+Subject: [PATCH] Make AUFS friendly (aufs6.x-rcN 20231106)
-diff --git a/fs/Kconfig b/fs/Kconfig
-index aa7e03cc1941..bf780967b6c4 100644
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -331,6 +331,7 @@ source "fs/sysv/Kconfig"
- source "fs/ufs/Kconfig"
- source "fs/erofs/Kconfig"
- source "fs/vboxsf/Kconfig"
-+source "fs/aufs/Kconfig"
-
- endif # MISC_FILESYSTEMS
-
-diff --git a/fs/Makefile b/fs/Makefile
-index f9541f40be4e..3a0e13ee39e7 100644
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -129,3 +129,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/
- obj-$(CONFIG_EROFS_FS) += erofs/
- obj-$(CONFIG_VBOXSF_FS) += vboxsf/
- obj-$(CONFIG_ZONEFS_FS) += zonefs/
-+obj-$(CONFIG_AUFS_FS) += aufs/
-SPDX-License-Identifier: GPL-2.0
-aufs6.x-rcN base patch
+Patches applied from sfjro/aufs5-standalone
+---
+ Documentation/ABI/testing/debugfs-aufs | 55 +
+ Documentation/ABI/testing/sysfs-aufs | 31 +
+ Documentation/filesystems/aufs/README | 409 ++++
+ .../filesystems/aufs/design/01intro.txt | 171 ++
+ .../filesystems/aufs/design/02struct.txt | 258 +++
+ .../filesystems/aufs/design/03atomic_open.txt | 85 +
+ .../filesystems/aufs/design/03lookup.txt | 113 +
+ .../filesystems/aufs/design/04branch.txt | 74 +
+ .../filesystems/aufs/design/05wbr_policy.txt | 64 +
+ .../filesystems/aufs/design/06dirren.dot | 44 +
+ .../filesystems/aufs/design/06dirren.txt | 102 +
+ .../filesystems/aufs/design/06fhsm.txt | 118 +
+ .../filesystems/aufs/design/06mmap.txt | 72 +
+ .../filesystems/aufs/design/06xattr.txt | 94 +
+ .../filesystems/aufs/design/07export.txt | 58 +
+ .../filesystems/aufs/design/08shwh.txt | 52 +
+ .../filesystems/aufs/design/10dynop.txt | 47 +
+ MAINTAINERS | 13 +
+ drivers/block/loop.c | 18 +
+ fs/Kconfig | 1 +
+ fs/Makefile | 1 +
+ fs/aufs/Kconfig | 199 ++
+ fs/aufs/Makefile | 46 +
+ fs/aufs/aufs.h | 62 +
+ fs/aufs/branch.c | 1427 ++++++++++++
+ fs/aufs/branch.h | 375 ++++
+ fs/aufs/conf.mk | 40 +
+ fs/aufs/cpup.c | 1459 +++++++++++++
+ fs/aufs/cpup.h | 100 +
+ fs/aufs/dbgaufs.c | 526 +++++
+ fs/aufs/dbgaufs.h | 53 +
+ fs/aufs/dcsub.c | 225 ++
+ fs/aufs/dcsub.h | 137 ++
+ fs/aufs/debug.c | 448 ++++
+ fs/aufs/debug.h | 226 ++
+ fs/aufs/dentry.c | 1168 ++++++++++
+ fs/aufs/dentry.h | 270 +++
+ fs/aufs/dinfo.c | 555 +++++
+ fs/aufs/dir.c | 765 +++++++
+ fs/aufs/dir.h | 134 ++
+ fs/aufs/dirren.c | 1315 +++++++++++
+ fs/aufs/dirren.h | 140 ++
+ fs/aufs/dynop.c | 366 ++++
+ fs/aufs/dynop.h | 77 +
+ fs/aufs/export.c | 830 +++++++
+ fs/aufs/f_op.c | 771 +++++++
+ fs/aufs/fhsm.c | 426 ++++
+ fs/aufs/file.c | 865 ++++++++
+ fs/aufs/file.h | 342 +++
+ fs/aufs/finfo.c | 149 ++
+ fs/aufs/fsctx.c | 1242 +++++++++++
+ fs/aufs/fstype.h | 401 ++++
+ fs/aufs/hbl.h | 65 +
+ fs/aufs/hfsnotify.c | 290 +++
+ fs/aufs/hfsplus.c | 60 +
+ fs/aufs/hnotify.c | 715 ++++++
+ fs/aufs/i_op.c | 1516 +++++++++++++
+ fs/aufs/i_op_add.c | 972 +++++++++
+ fs/aufs/i_op_del.c | 523 +++++
+ fs/aufs/i_op_ren.c | 1260 +++++++++++
+ fs/aufs/iinfo.c | 286 +++
+ fs/aufs/inode.c | 531 +++++
+ fs/aufs/inode.h | 707 ++++++
+ fs/aufs/ioctl.c | 220 ++
+ fs/aufs/lcnt.h | 186 ++
+ fs/aufs/loop.c | 148 ++
+ fs/aufs/loop.h | 55 +
+ fs/aufs/magic.mk | 31 +
+ fs/aufs/module.c | 273 +++
+ fs/aufs/module.h | 180 ++
+ fs/aufs/mvdown.c | 706 ++++++
+ fs/aufs/opts.c | 1032 +++++++++
+ fs/aufs/opts.h | 263 +++
+ fs/aufs/plink.c | 516 +++++
+ fs/aufs/poll.c | 51 +
+ fs/aufs/posix_acl.c | 108 +
+ fs/aufs/procfs.c | 170 ++
+ fs/aufs/rdu.c | 384 ++++
+ fs/aufs/rwsem.h | 85 +
+ fs/aufs/sbinfo.c | 316 +++
+ fs/aufs/super.c | 871 ++++++++
+ fs/aufs/super.h | 592 +++++
+ fs/aufs/sysaufs.c | 94 +
+ fs/aufs/sysaufs.h | 102 +
+ fs/aufs/sysfs.c | 374 ++++
+ fs/aufs/sysrq.c | 149 ++
+ fs/aufs/vdir.c | 896 ++++++++
+ fs/aufs/vfsub.c | 918 ++++++++
+ fs/aufs/vfsub.h | 403 ++++
+ fs/aufs/wbr_policy.c | 830 +++++++
+ fs/aufs/whout.c | 1072 +++++++++
+ fs/aufs/whout.h | 87 +
+ fs/aufs/wkq.c | 372 ++++
+ fs/aufs/wkq.h | 89 +
+ fs/aufs/xattr.c | 360 +++
+ fs/aufs/xino.c | 1926 +++++++++++++++++
+ fs/dcache.c | 4 +-
+ fs/exec.c | 1 +
+ fs/fcntl.c | 5 +-
+ fs/file_table.c | 1 +
+ fs/namespace.c | 9 +
+ fs/notify/group.c | 1 +
+ fs/open.c | 1 +
+ fs/proc/nommu.c | 5 +-
+ fs/proc/task_mmu.c | 7 +-
+ fs/proc/task_nommu.c | 5 +-
+ fs/read_write.c | 2 +
+ fs/splice.c | 5 +-
+ fs/xattr.c | 1 +
+ include/linux/fs.h | 2 +
+ include/linux/lockdep.h | 2 +
+ include/linux/mm.h | 37 +
+ include/linux/mm_types.h | 6 +
+ include/linux/mnt_namespace.h | 3 +
+ include/linux/splice.h | 6 +
+ include/uapi/linux/aufs_type.h | 452 ++++
+ kernel/fork.c | 2 +-
+ kernel/locking/lockdep.c | 4 +-
+ kernel/task_work.c | 1 +
+ mm/Makefile | 1 +
+ mm/filemap.c | 2 +-
+ mm/mmap.c | 41 +-
+ mm/nommu.c | 10 +-
+ mm/prfile.c | 86 +
+ security/security.c | 8 +
+ 125 files changed, 38490 insertions(+), 23 deletions(-)
+ create mode 100644 Documentation/ABI/testing/debugfs-aufs
+ create mode 100644 Documentation/ABI/testing/sysfs-aufs
+ create mode 100644 Documentation/filesystems/aufs/README
+ create mode 100644 Documentation/filesystems/aufs/design/01intro.txt
+ create mode 100644 Documentation/filesystems/aufs/design/02struct.txt
+ create mode 100644 Documentation/filesystems/aufs/design/03atomic_open.txt
+ create mode 100644 Documentation/filesystems/aufs/design/03lookup.txt
+ create mode 100644 Documentation/filesystems/aufs/design/04branch.txt
+ create mode 100644 Documentation/filesystems/aufs/design/05wbr_policy.txt
+ create mode 100644 Documentation/filesystems/aufs/design/06dirren.dot
+ create mode 100644 Documentation/filesystems/aufs/design/06dirren.txt
+ create mode 100644 Documentation/filesystems/aufs/design/06fhsm.txt
+ create mode 100644 Documentation/filesystems/aufs/design/06mmap.txt
+ create mode 100644 Documentation/filesystems/aufs/design/06xattr.txt
+ create mode 100644 Documentation/filesystems/aufs/design/07export.txt
+ create mode 100644 Documentation/filesystems/aufs/design/08shwh.txt
+ create mode 100644 Documentation/filesystems/aufs/design/10dynop.txt
+ create mode 100644 fs/aufs/Kconfig
+ create mode 100644 fs/aufs/Makefile
+ create mode 100644 fs/aufs/aufs.h
+ create mode 100644 fs/aufs/branch.c
+ create mode 100644 fs/aufs/branch.h
+ create mode 100644 fs/aufs/conf.mk
+ create mode 100644 fs/aufs/cpup.c
+ create mode 100644 fs/aufs/cpup.h
+ create mode 100644 fs/aufs/dbgaufs.c
+ create mode 100644 fs/aufs/dbgaufs.h
+ create mode 100644 fs/aufs/dcsub.c
+ create mode 100644 fs/aufs/dcsub.h
+ create mode 100644 fs/aufs/debug.c
+ create mode 100644 fs/aufs/debug.h
+ create mode 100644 fs/aufs/dentry.c
+ create mode 100644 fs/aufs/dentry.h
+ create mode 100644 fs/aufs/dinfo.c
+ create mode 100644 fs/aufs/dir.c
+ create mode 100644 fs/aufs/dir.h
+ create mode 100644 fs/aufs/dirren.c
+ create mode 100644 fs/aufs/dirren.h
+ create mode 100644 fs/aufs/dynop.c
+ create mode 100644 fs/aufs/dynop.h
+ create mode 100644 fs/aufs/export.c
+ create mode 100644 fs/aufs/f_op.c
+ create mode 100644 fs/aufs/fhsm.c
+ create mode 100644 fs/aufs/file.c
+ create mode 100644 fs/aufs/file.h
+ create mode 100644 fs/aufs/finfo.c
+ create mode 100644 fs/aufs/fsctx.c
+ create mode 100644 fs/aufs/fstype.h
+ create mode 100644 fs/aufs/hbl.h
+ create mode 100644 fs/aufs/hfsnotify.c
+ create mode 100644 fs/aufs/hfsplus.c
+ create mode 100644 fs/aufs/hnotify.c
+ create mode 100644 fs/aufs/i_op.c
+ create mode 100644 fs/aufs/i_op_add.c
+ create mode 100644 fs/aufs/i_op_del.c
+ create mode 100644 fs/aufs/i_op_ren.c
+ create mode 100644 fs/aufs/iinfo.c
+ create mode 100644 fs/aufs/inode.c
+ create mode 100644 fs/aufs/inode.h
+ create mode 100644 fs/aufs/ioctl.c
+ create mode 100644 fs/aufs/lcnt.h
+ create mode 100644 fs/aufs/loop.c
+ create mode 100644 fs/aufs/loop.h
+ create mode 100644 fs/aufs/magic.mk
+ create mode 100644 fs/aufs/module.c
+ create mode 100644 fs/aufs/module.h
+ create mode 100644 fs/aufs/mvdown.c
+ create mode 100644 fs/aufs/opts.c
+ create mode 100644 fs/aufs/opts.h
+ create mode 100644 fs/aufs/plink.c
+ create mode 100644 fs/aufs/poll.c
+ create mode 100644 fs/aufs/posix_acl.c
+ create mode 100644 fs/aufs/procfs.c
+ create mode 100644 fs/aufs/rdu.c
+ create mode 100644 fs/aufs/rwsem.h
+ create mode 100644 fs/aufs/sbinfo.c
+ create mode 100644 fs/aufs/super.c
+ create mode 100644 fs/aufs/super.h
+ create mode 100644 fs/aufs/sysaufs.c
+ create mode 100644 fs/aufs/sysaufs.h
+ create mode 100644 fs/aufs/sysfs.c
+ create mode 100644 fs/aufs/sysrq.c
+ create mode 100644 fs/aufs/vdir.c
+ create mode 100644 fs/aufs/vfsub.c
+ create mode 100644 fs/aufs/vfsub.h
+ create mode 100644 fs/aufs/wbr_policy.c
+ create mode 100644 fs/aufs/whout.c
+ create mode 100644 fs/aufs/whout.h
+ create mode 100644 fs/aufs/wkq.c
+ create mode 100644 fs/aufs/wkq.h
+ create mode 100644 fs/aufs/xattr.c
+ create mode 100644 fs/aufs/xino.c
+ create mode 100644 include/uapi/linux/aufs_type.h
+ create mode 100644 mm/prfile.c
-diff --git a/MAINTAINERS b/MAINTAINERS
-index bf0f54c24f81..39b1844bce57 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -3316,6 +3316,19 @@ F: include/uapi/linux/audit.h
- F: kernel/audit*
- F: lib/*audit.c
-
-+AUFS (advanced multi layered unification filesystem) FILESYSTEM
-+M: "J. R. Okajima" <hooanon05g at gmail.com>
-+L: aufs-users at lists.sourceforge.net (members only)
-+L: linux-unionfs at vger.kernel.org
-+S: Supported
-+W: http://aufs.sourceforge.net
-+T: git://github.com/sfjro/aufs4-linux.git
-+F: Documentation/ABI/testing/debugfs-aufs
-+F: Documentation/ABI/testing/sysfs-aufs
-+F: Documentation/filesystems/aufs/
-+F: fs/aufs/
-+F: include/uapi/linux/aufs_type.h
+diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs
+new file mode 100644
+index 00000000000000..45b739879d7696
+--- /dev/null
++++ b/Documentation/ABI/testing/debugfs-aufs
+@@ -0,0 +1,55 @@
++What: /debug/aufs/si_<id>/
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ Under /debug/aufs, a directory named si_<id> is created
++ per aufs mount, where <id> is a unique id generated
++ internally.
+
- AUXILIARY BUS DRIVER
- M: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
- R: Dave Ertman <david.m.ertman at intel.com>
-diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index 9f2d412fc560..1fefc6a8d049 100644
---- a/drivers/block/loop.c
-+++ b/drivers/block/loop.c
-@@ -645,6 +645,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
- goto done;
- }
-
-+/*
-+ * for AUFS
-+ * no get/put for file.
-+ */
-+struct file *loop_backing_file(struct super_block *sb)
-+{
-+ struct file *ret;
-+ struct loop_device *l;
++What: /debug/aufs/si_<id>/plink
++Date: Apr 2013
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It has three lines and shows the information about the
++ pseudo-link. The first line is a single number
++ representing a number of buckets. The second line is a
++ number of pseudo-links per buckets (separated by a
++ blank). The last line is a single number representing a
++ total number of psedo-links.
++ When the aufs mount option 'noplink' is specified, it
++ will show "1\n0\n0\n".
+
-+ ret = NULL;
-+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
-+ l = sb->s_bdev->bd_disk->private_data;
-+ ret = l->lo_backing_file;
-+ }
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(loop_backing_file);
++What: /debug/aufs/si_<id>/xib
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the consumed blocks by xib (External Inode Number
++ Bitmap), its block size and file size.
++ When the aufs mount option 'noxino' is specified, it
++ will be empty. About XINO files, see the aufs manual.
+
- /* loop sysfs attributes */
-
- static ssize_t loop_attr_show(struct device *dev, char *page,
-diff --git a/fs/dcache.c b/fs/dcache.c
-index 25ac74d30bff..6c930ceed526 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -1345,7 +1345,7 @@ enum d_walk_ret {
- *
- * The @enter() callbacks are called with d_lock held.
- */
--static void d_walk(struct dentry *parent, void *data,
-+void d_walk(struct dentry *parent, void *data,
- enum d_walk_ret (*enter)(void *, struct dentry *))
- {
- struct dentry *this_parent;
-diff --git a/fs/fcntl.c b/fs/fcntl.c
-index e871009f6c88..d62e114c1b1a 100644
---- a/fs/fcntl.c
-+++ b/fs/fcntl.c
-@@ -34,7 +34,7 @@
-
- #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
-
--static int setfl(int fd, struct file * filp, unsigned int arg)
-+int setfl(int fd, struct file * filp, unsigned int arg)
- {
- struct inode * inode = file_inode(filp);
- int error = 0;
-@@ -64,6 +64,8 @@ static int setfl(int fd, struct file * filp, unsigned int arg)
-
- if (filp->f_op->check_flags)
- error = filp->f_op->check_flags(arg);
-+ if (!error && filp->f_op->setfl)
-+ error = filp->f_op->setfl(filp, arg);
- if (error)
- return error;
-
-diff --git a/fs/namespace.c b/fs/namespace.c
-index e157efc54023..6c57487f126b 100644
---- a/fs/namespace.c
-+++ b/fs/namespace.c
-@@ -872,6 +872,12 @@ static inline int check_mnt(struct mount *mnt)
- return mnt->mnt_ns == current->nsproxy->mnt_ns;
- }
-
-+/* for aufs, CONFIG_AUFS_BR_FUSE */
-+int is_current_mnt_ns(struct vfsmount *mnt)
-+{
-+ return check_mnt(real_mount(mnt));
-+}
++What: /debug/aufs/si_<id>/xi<branch-index>
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the consumed blocks by xino (External Inode Number
++ Translation Table), its link count, block size and file
++ size.
++ Due to the file size limit, there may exist multiple
++ xino files per branch. In this case, "-N" is added to
++ the filename and it corresponds to the index of the
++ internal xino array. "-0" is omitted.
++ When the aufs mount option 'noxino' is specified, Those
++ entries won't exist. About XINO files, see the aufs
++ manual.
+
- /*
- * vfsmount lock must be held for write
- */
-diff --git a/fs/splice.c b/fs/splice.c
-index d983d375ff11..7216ef993b5f 100644
---- a/fs/splice.c
-+++ b/fs/splice.c
-@@ -925,8 +925,8 @@ static int warn_unsupported(struct file *file, const char *op)
- /*
- * Attempt to initiate a splice from pipe to file.
- */
--static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
-- loff_t *ppos, size_t len, unsigned int flags)
-+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
-+ loff_t *ppos, size_t len, unsigned int flags)
- {
- if (unlikely(!out->f_op->splice_write))
- return warn_unsupported(out, "write");
-diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 4aeb3fa11927..dd5871d0c429 100644
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -1099,6 +1099,7 @@ extern void fasync_free(struct fasync_struct *);
- /* can be called from interrupts */
- extern void kill_fasync(struct fasync_struct **, int, int);
-
-+extern int setfl(int fd, struct file *filp, unsigned int arg);
- extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
- extern int f_setown(struct file *filp, int who, int force);
- extern void f_delown(struct file *filp);
-@@ -1901,6 +1902,7 @@ struct file_operations {
- int (*lock) (struct file *, int, struct file_lock *);
- unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- int (*check_flags)(int);
-+ int (*setfl)(struct file *, unsigned long);
- int (*flock) (struct file *, int, struct file_lock *);
- ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
- ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
-diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
-index dc2844b071c2..069ffb776c2c 100644
---- a/include/linux/lockdep.h
-+++ b/include/linux/lockdep.h
-@@ -249,6 +249,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock,
- return lock->key == key;
- }
-
-+struct lock_class *lockdep_hlock_class(struct held_lock *hlock);
++What: /debug/aufs/si_<id>/xigen
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the consumed blocks by xigen (External Inode
++ Generation Table), its block size and file size.
++ If CONFIG_AUFS_EXPORT is disabled, this entry will not
++ be created.
++ When the aufs mount option 'noxino' is specified, it
++ will be empty. About XINO files, see the aufs manual.
+diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs
+new file mode 100644
+index 00000000000000..48500c0569e658
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-aufs
+@@ -0,0 +1,31 @@
++What: /sys/fs/aufs/si_<id>/
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ Under /sys/fs/aufs, a directory named si_<id> is created
++ per aufs mount, where <id> is a unique id generated
++ internally.
+
- /*
- * Acquire a lock.
- *
-diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
-index 8f882f5881e8..6b9808f09843 100644
---- a/include/linux/mnt_namespace.h
-+++ b/include/linux/mnt_namespace.h
-@@ -7,12 +7,15 @@ struct mnt_namespace;
- struct fs_struct;
- struct user_namespace;
- struct ns_common;
-+struct vfsmount;
-
- extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
- struct user_namespace *, struct fs_struct *);
- extern void put_mnt_ns(struct mnt_namespace *ns);
- extern struct ns_common *from_mnt_ns(struct mnt_namespace *);
-
-+extern int is_current_mnt_ns(struct vfsmount *mnt);
++What: /sys/fs/aufs/si_<id>/br<idx>
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the abolute path of a member directory (which
++ is called branch) in aufs, and its permission.
+
- extern const struct file_operations proc_mounts_operations;
- extern const struct file_operations proc_mountinfo_operations;
- extern const struct file_operations proc_mountstats_operations;
-diff --git a/include/linux/splice.h b/include/linux/splice.h
-index 6c461573434d..7416cf375ad1 100644
---- a/include/linux/splice.h
-+++ b/include/linux/splice.h
-@@ -99,4 +99,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
-
- extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
- extern const struct pipe_buf_operations default_pipe_buf_ops;
++What: /sys/fs/aufs/si_<id>/brid<idx>
++Date: July 2013
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the id of a member directory (which is called
++ branch) in aufs.
+
-+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
-+ loff_t *ppos, size_t len, unsigned int flags);
-+extern long do_splice_to(struct file *in, loff_t *ppos,
-+ struct pipe_inode_info *pipe, size_t len,
-+ unsigned int flags);
- #endif
-diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
-index e85b5ad3e206..db4297f60bd3 100644
---- a/kernel/locking/lockdep.c
-+++ b/kernel/locking/lockdep.c
-@@ -218,7 +218,7 @@ unsigned long max_lock_class_idx;
- struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
- DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS);
-
--static inline struct lock_class *hlock_class(struct held_lock *hlock)
-+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
- {
- unsigned int class_idx = hlock->class_idx;
-
-@@ -239,6 +239,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
- */
- return lock_classes + class_idx;
- }
-+#define hlock_class(hlock) lockdep_hlock_class(hlock)
-
- #ifdef CONFIG_LOCK_STAT
- static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats);
-SPDX-License-Identifier: GPL-2.0
-aufs6.x-rcN mmap patch
-
-diff --git a/fs/proc/base.c b/fs/proc/base.c
-index ffd54617c354..29ec720c8038 100644
---- a/fs/proc/base.c
-+++ b/fs/proc/base.c
-@@ -2218,7 +2218,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
- rc = -ENOENT;
- vma = find_exact_vma(mm, vm_start, vm_end);
- if (vma && vma->vm_file) {
-- *path = vma->vm_file->f_path;
-+ *path = vma_pr_or_file(vma)->f_path;
- path_get(path);
- rc = 0;
- }
-diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
-index 4d3493579458..42edd9a42c78 100644
---- a/fs/proc/nommu.c
-+++ b/fs/proc/nommu.c
-@@ -39,7 +39,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
- file = region->vm_file;
-
- if (file) {
-- struct inode *inode = file_inode(region->vm_file);
-+ struct inode *inode;
++What: /sys/fs/aufs/si_<id>/xi_path
++Date: March 2009
++Contact: J. R. Okajima <hooanon05g at gmail.com>
++Description:
++ It shows the abolute path of XINO (External Inode Number
++ Bitmap, Translation Table and Generation Table) file
++ even if it is the default path.
++ When the aufs mount option 'noxino' is specified, it
++ will be empty. About XINO files, see the aufs manual.
+diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README
+new file mode 100644
+index 00000000000000..04a4d069bb52a0
+--- /dev/null
++++ b/Documentation/filesystems/aufs/README
+@@ -0,0 +1,409 @@
+
-+ file = vmr_pr_or_file(region);
-+ inode = file_inode(file);
- dev = inode->i_sb->s_dev;
- ino = inode->i_ino;
- }
-diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 3dd5be96691b..40d9d970b308 100644
---- a/fs/proc/task_mmu.c
-+++ b/fs/proc/task_mmu.c
-@@ -271,7 +271,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
- const char *name = NULL;
-
- if (file) {
-- struct inode *inode = file_inode(vma->vm_file);
-+ struct inode *inode;
++Aufs6 -- advanced multi layered unification filesystem version 6.x
++http://aufs.sf.net
++Junjiro R. Okajima
+
-+ file = vma_pr_or_file(vma);
-+ inode = file_inode(file);
- dev = inode->i_sb->s_dev;
- ino = inode->i_ino;
- pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1943,7 +1946,7 @@ static int show_numa_map(struct seq_file *m, void *v)
- struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
- struct vm_area_struct *vma = v;
- struct numa_maps *md = &numa_priv->md;
-- struct file *file = vma->vm_file;
-+ struct file *file = vma_pr_or_file(vma);
- struct mm_struct *mm = vma->vm_mm;
- struct mempolicy *pol;
- char buffer[64];
-diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
-index a8ac0dd8041e..9fca456e2259 100644
---- a/fs/proc/task_nommu.c
-+++ b/fs/proc/task_nommu.c
-@@ -137,7 +137,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
- file = vma->vm_file;
-
- if (file) {
-- struct inode *inode = file_inode(vma->vm_file);
-+ struct inode *inode;
+
-+ file = vma_pr_or_file(vma);
-+ inode = file_inode(file);
- dev = inode->i_sb->s_dev;
- 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 bf5d0b1b16f4..94b956eff452 100644
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -2409,6 +2409,43 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
- static inline struct vm_area_struct *vma_lookup(struct mm_struct *mm,
- unsigned long addr);
-
-+#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
-+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
-+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
-+ int);
-+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
-+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
++0. Introduction
++----------------------------------------
++In the early days, aufs was entirely re-designed and re-implemented
++Unionfs Version 1.x series. Adding many original ideas, approaches,
++improvements and implementations, it became totally different from
++Unionfs while keeping the basic features.
++Later, Unionfs Version 2.x series began taking some of the same
++approaches to aufs1's.
++Unionfs was being developed by Professor Erez Zadok at Stony Brook
++University and his team.
+
-+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
-+ __LINE__)
-+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
-+ __LINE__)
-+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
-+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
++Aufs6 supports linux-v6.0 and later, try aufs6.0 branch in
++aufs-linux.git or aufs-standalone.git.
++If you want older kernel version support,
++- for linux-v5.x series, try aufs-linux.git or aufs-standalone.git
++- for linux-v4.x series, try aufs4-linux.git or aufs4-standalone.git
++- for linux-v3.x series, try aufs3-linux.git or aufs3-standalone.git
++- for linux-v2.6.16 and later, try aufs2-2.6.git, aufs2-standalone.git
++ or aufs1 from CVS on SourceForge.
+
-+#ifndef CONFIG_MMU
-+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
-+extern void vmr_do_fput(struct vm_region *, const char[], int);
++Note: the name of aufs5-linux.git and aufs5-standalone.git on github
++ were changed. Now they are aufs-linux.git and
++ aufs-standalone.git and they contain aufs5 and later branches.
+
-+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
-+ __LINE__)
-+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
-+#endif /* !CONFIG_MMU */
++Note: it becomes clear that "Aufs was rejected. Let's give it up."
++ According to Christoph Hellwig, linux rejects all union-type
++ filesystems but UnionMount.
++<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
+
-+#else
++PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
++ UnionMount, and he pointed out an issue around a directory mutex
++ lock and aufs addressed it. But it is still unsure whether aufs will
++ be merged (or any other union solution).
++<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
+
-+#define vma_file_update_time(vma) file_update_time((vma)->vm_file)
-+#define vma_pr_or_file(vma) (vma)->vm_file
-+#define vma_get_file(vma) get_file((vma)->vm_file)
-+#define vma_fput(vma) fput((vma)->vm_file)
+
-+#ifndef CONFIG_MMU
-+#define vmr_pr_or_file(region) (region)->vm_file
-+#define vmr_fput(region) fput((region)->vm_file)
-+#endif /* !CONFIG_MMU */
++1. Features
++----------------------------------------
++- unite several directories into a single virtual filesystem. The member
++ directory is called as a branch.
++- you can specify the permission flags to the branch, which are 'readonly',
++ 'readwrite' and 'whiteout-able.'
++- by upper writable branch, internal copyup and whiteout, files/dirs on
++ readonly branch are modifiable logically.
++- dynamic branch manipulation, add, del.
++- etc...
+
-+#endif /* CONFIG_AUFS_FS */
++Also there are many enhancements in aufs, such as:
++- test only the highest one for the directory permission (dirperm1)
++- copyup on open (coo=)
++- 'move' policy for copy-up between two writable branches, after
++ checking free space.
++- xattr, acl
++- readdir(3) in userspace.
++- keep inode number by external inode number table
++- keep the timestamps of file/dir in internal copyup operation
++- seekable directory, supporting NFS readdir.
++- whiteout is hardlinked in order to reduce the consumption of inodes
++ on branch
++- do not copyup, nor create a whiteout when it is unnecessary
++- revert a single systemcall when an error occurs in aufs
++- remount interface instead of ioctl
++- maintain /etc/mtab by an external command, /sbin/mount.aufs.
++- loopback mounted filesystem as a branch
++- kernel thread for removing the dir who has a plenty of whiteouts
++- support copyup sparse file (a file which has a 'hole' in it)
++- default permission flags for branches
++- selectable permission flags for ro branch, whether whiteout can
++ exist or not
++- export via NFS.
++- support <sysfs>/fs/aufs and <debugfs>/aufs.
++- support multiple writable branches, some policies to select one
++ among multiple writable branches.
++- a new semantics for link(2) and rename(2) to support multiple
++ writable branches.
++- no glibc changes are required.
++- pseudo hardlink (hardlink over branches)
++- allow a direct access manually to a file on branch, e.g. bypassing aufs.
++ including NFS or remote filesystem branch.
++- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
++- and more...
+
- extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
- void *buf, int len, unsigned int gup_flags);
- extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
-diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index 36c5b43999e6..ce93e97f76a6 100644
---- a/include/linux/mm_types.h
-+++ b/include/linux/mm_types.h
-@@ -524,6 +524,9 @@ struct vm_region {
- unsigned long vm_top; /* region allocated to here */
- unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
- struct file *vm_file; /* the backing file or NULL */
-+#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
-+ struct file *vm_prfile; /* the virtual backing file or NULL */
-+#endif
-
- int vm_usage; /* region usage count (access under nommu_region_sem) */
- bool vm_icache_flushed : 1; /* true if the icache has been flushed for
-@@ -637,6 +640,9 @@ struct vm_area_struct {
- unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
- units */
- struct file * vm_file; /* File we map to (can be NULL). */
-+#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
-+ struct file *vm_prfile; /* shadow of vm_file */
-+#endif
- void * vm_private_data; /* was vm_pte (shared mem) */
-
- #ifdef CONFIG_ANON_VMA_NAME
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 3b6d20dfb9a8..ccad0325cfa9 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -731,7 +731,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
- if (file) {
- struct address_space *mapping = file->f_mapping;
-
-- get_file(file);
-+ vma_get_file(tmp);
- i_mmap_lock_write(mapping);
- if (tmp->vm_flags & VM_SHARED)
- mapping_allow_writable(mapping);
-diff --git a/mm/Makefile b/mm/Makefile
-index ec65984e2ade..d59461647ccd 100644
---- a/mm/Makefile
-+++ b/mm/Makefile
-@@ -138,3 +138,4 @@ obj-$(CONFIG_IO_MAPPING) += io-mapping.o
- obj-$(CONFIG_HAVE_BOOTMEM_INFO_NODE) += bootmem_info.o
- obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o
- obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o
-+obj-y += prfile.o
-diff --git a/mm/filemap.c b/mm/filemap.c
-index 582f5317ff71..c024ebb30073 100644
---- a/mm/filemap.c
-+++ b/mm/filemap.c
-@@ -3599,7 +3599,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
- vm_fault_t ret = VM_FAULT_LOCKED;
-
- sb_start_pagefault(mapping->host->i_sb);
-- file_update_time(vmf->vma->vm_file);
-+ vma_file_update_time(vmf->vma);
- folio_lock(folio);
- if (folio->mapping != mapping) {
- folio_unlock(folio);
-diff --git a/mm/mmap.c b/mm/mmap.c
-index b56a7f0c9f85..5eb114409e07 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -140,7 +140,7 @@ static void remove_vma(struct vm_area_struct *vma, bool unreachable)
- if (vma->vm_ops && vma->vm_ops->close)
- vma->vm_ops->close(vma);
- if (vma->vm_file)
-- fput(vma->vm_file);
-+ vma_fput(vma);
- mpol_put(vma_policy(vma));
- if (unreachable)
- __vm_area_free(vma);
-@@ -554,7 +554,7 @@ static inline void vma_complete(struct vma_prepare *vp,
- if (vp->file) {
- uprobe_munmap(vp->remove, vp->remove->vm_start,
- vp->remove->vm_end);
-- fput(vp->file);
-+ vma_fput(vp->vma);
- }
- if (vp->remove->anon_vma)
- anon_vma_merge(vp->vma, vp->remove);
-@@ -2364,7 +2364,7 @@ int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
- goto out_free_mpol;
-
- if (new->vm_file)
-- get_file(new->vm_file);
-+ vma_get_file(new);
-
- if (new->vm_ops && new->vm_ops->open)
- new->vm_ops->open(new);
-@@ -2781,7 +2781,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
- * and cause general protection fault
- * ultimately.
- */
-- fput(vma->vm_file);
-+ vma_fput(vma);
- vm_area_free(vma);
- vma = merge;
- /* Update vm_flags to pick up the change. */
-@@ -2876,7 +2876,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
-
- if (file || vma->vm_file) {
- unmap_and_free_vma:
-- fput(vma->vm_file);
-+ vma_fput(vma);
- vma->vm_file = NULL;
-
- vma_iter_set(&vmi, vma->vm_end);
-@@ -2938,6 +2938,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
- unsigned long populate = 0;
- unsigned long ret = -EINVAL;
- struct file *file;
-+#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
-+ struct file *prfile;
-+#endif
-
- pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n",
- current->comm, current->pid);
-@@ -2996,10 +2999,34 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
- if (vma->vm_flags & VM_LOCKED)
- flags |= MAP_LOCKED;
-
-+#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
-+ vma_get_file(vma);
-+ file = vma->vm_file;
-+ prfile = vma->vm_prfile;
-+ ret = do_mmap(vma->vm_file, start, size,
-+ prot, flags, /*vm_flags*/0, pgoff, &populate, NULL);
-+ if (!IS_ERR_VALUE(ret) && file && prfile) {
-+ struct vm_area_struct *new_vma;
++Currently these features are dropped temporary from aufs6.
++See design/08plan.txt in detail.
++- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
++ (robr)
++- statistics of aufs thread (/sys/fs/aufs/stat)
+
-+ new_vma = find_vma(mm, ret);
-+ if (!new_vma->vm_prfile)
-+ new_vma->vm_prfile = prfile;
-+ if (prfile)
-+ get_file(prfile);
-+ }
-+ /*
-+ * two fput()s instead of vma_fput(vma),
-+ * coz vma may not be available anymore.
-+ */
-+ fput(file);
-+ if (prfile)
-+ fput(prfile);
-+#else
- file = get_file(vma->vm_file);
- ret = do_mmap(vma->vm_file, start, size,
- prot, flags, 0, pgoff, &populate, NULL);
- fput(file);
-+#endif /* CONFIG_AUFS_FS */
- out:
- mmap_write_unlock(mm);
- if (populate)
-@@ -3350,7 +3377,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
- if (anon_vma_clone(new_vma, vma))
- goto out_free_mempol;
- if (new_vma->vm_file)
-- get_file(new_vma->vm_file);
-+ vma_get_file(new_vma);
- if (new_vma->vm_ops && new_vma->vm_ops->open)
- new_vma->vm_ops->open(new_vma);
- if (vma_link(mm, new_vma))
-@@ -3364,7 +3391,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
- new_vma->vm_ops->close(new_vma);
-
- if (new_vma->vm_file)
-- fput(new_vma->vm_file);
-+ vma_fput(new_vma);
-
- unlink_anon_vmas(new_vma);
- out_free_mempol:
-diff --git a/mm/nommu.c b/mm/nommu.c
-index 7f9e9e5a0e12..69663f2bd4c4 100644
---- a/mm/nommu.c
-+++ b/mm/nommu.c
-@@ -523,7 +523,7 @@ static void __put_nommu_region(struct vm_region *region)
- up_write(&nommu_region_sem);
-
- if (region->vm_file)
-- fput(region->vm_file);
-+ vmr_fput(region);
-
- /* IO memory and memory shared directly out of the pagecache
- * from ramfs/tmpfs mustn't be released here */
-@@ -603,7 +603,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
- if (vma->vm_ops && vma->vm_ops->close)
- vma->vm_ops->close(vma);
- if (vma->vm_file)
-- fput(vma->vm_file);
-+ vma_fput(vma);
- put_nommu_region(vma->vm_region);
- vm_area_free(vma);
- }
-@@ -1135,7 +1135,7 @@ unsigned long do_mmap(struct file *file,
- goto error_just_free;
- }
- }
-- fput(region->vm_file);
-+ vmr_fput(region);
- kmem_cache_free(vm_region_jar, region);
- region = pregion;
- result = start;
-@@ -1221,10 +1221,10 @@ unsigned long do_mmap(struct file *file,
- error:
- vma_iter_free(&vmi);
- if (region->vm_file)
-- fput(region->vm_file);
-+ vmr_fput(region);
- kmem_cache_free(vm_region_jar, region);
- if (vma->vm_file)
-- fput(vma->vm_file);
-+ vma_fput(vma);
- vm_area_free(vma);
- return ret;
-
-diff --git a/mm/prfile.c b/mm/prfile.c
-new file mode 100644
-index 000000000000..8f820a235364
---- /dev/null
-+++ b/mm/prfile.c
-@@ -0,0 +1,86 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Mainly for aufs which mmap(2) different file and wants to print different
-+ * path in /proc/PID/maps.
-+ * Call these functions via macros defined in linux/mm.h.
-+ *
-+ * See Documentation/filesystems/aufs/design/06mmap.txt
-+ *
-+ * Copyright (c) 2014-2022 Junjro R. Okajima
-+ * Copyright (c) 2014 Ian Campbell
-+ */
++Features or just an idea in the future (see also design/*.txt),
++- reorder the branch index without del/re-add.
++- permanent xino files for NFSD
++- an option for refreshing the opened files after add/del branches
++- light version, without branch manipulation. (unnecessary?)
++- copyup in userspace
++- inotify in userspace
++- readv/writev
+
-+#include <linux/mm.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
+
-+/* #define PRFILE_TRACE */
-+static inline void prfile_trace(struct file *f, struct file *pr,
-+ const char func[], int line, const char func2[])
-+{
-+#ifdef PRFILE_TRACE
-+ if (pr)
-+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
-+#endif
-+}
++2. Download
++----------------------------------------
++There are three GIT trees for aufs6, aufs-linux.git,
++aufs-standalone.git, and aufs-util.git.
++While the aufs-util is always necessary, you need either of aufs-linux
++or aufs-standalone.
+
-+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
-+ int line)
-+{
-+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++The aufs-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 aufs6 as an external kernel module.
++Several extra patches are not included in this tree. Only
++aufs-standalone tree contains them. They are described in the later
++section "Configuration and Compilation."
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ file_update_time(f);
-+ if (f && pr)
-+ file_update_time(pr);
-+}
++On the other hand, the aufs-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.
+
-+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
-+ int line)
-+{
-+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++You will find GIT branches whose name is in form of "aufs6.x" where "x"
++represents the linux kernel version, "linux-6.x". For instance,
++"aufs6.0" is for linux-6.0. For latest "linux-6.x-rcN", use
++"aufs6.x-rcN" branch.
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ return (f && pr) ? pr : f;
-+}
++o aufs-linux tree
++$ git clone --reference /your/linux/git/tree \
++ git://github.com/sfjro/aufs-linux.git aufs-linux.git
++- if you don't have linux GIT tree, then remove "--reference ..."
++$ cd aufs-linux.git
++$ git checkout origin/aufs6.0
+
-+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
-+{
-+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++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 aufs git://github.com/sfjro/aufs-linux.git
++$ git fetch aufs
++$ git checkout -b my6.0 v6.0
++$ (add your local change...)
++$ git pull aufs aufs6.0
++- now you have v6.0 + your_changes + aufs6.0 in you my6.0 branch.
++- you may need to solve some conflicts between your_changes and
++ aufs6.0. in this case, git-rerere is recommended so that you can
++ solve the similar conflicts automatically when you upgrade to 6.1 or
++ later in the future.
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ get_file(f);
-+ if (f && pr)
-+ get_file(pr);
-+}
++o aufs-standalone tree
++$ git clone git://github.com/sfjro/aufs-standalone.git aufs-standalone.git
++$ cd aufs-standalone.git
++$ git checkout origin/aufs6.0
+
-+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
-+{
-+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++o aufs-util tree
++$ 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/aufs6.0
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ fput(f);
-+ if (f && pr)
-+ fput(pr);
-+}
++Note: The 6.x-rcN branch is to be used with `rc' kernel versions ONLY.
++The minor version number, 'x' in '6.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.
+
-+#ifndef CONFIG_MMU
-+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
-+ int line)
-+{
-+ struct file *f = region->vm_file, *pr = region->vm_prfile;
++Since aufs-util has its own minor version number, you may not be
++able to find a GIT branch in aufs-util for your kernel's
++exact minor version number.
++In this case, you should git-checkout the branch for the
++nearest lower number.
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ return (f && pr) ? pr : f;
-+}
++For (an unreleased) example:
++If you are using "linux-6.10" and the "aufs6.10" branch
++does not exist in aufs-util repository, then "aufs6.9", "aufs6.8"
++or something numerically smaller is the branch for your kernel.
+
-+void vmr_do_fput(struct vm_region *region, const char func[], int line)
-+{
-+ struct file *f = region->vm_file, *pr = region->vm_prfile;
++Also you can view all branches by
++ $ git branch -a
+
-+ prfile_trace(f, pr, func, line, __func__);
-+ fput(f);
-+ if (f && pr)
-+ fput(pr);
-+}
-+#endif /* !CONFIG_MMU */
-SPDX-License-Identifier: GPL-2.0
-aufs6.x-rcN standalone patch
-
-diff --git a/fs/dcache.c b/fs/dcache.c
-index 6c930ceed526..576ad162cdec 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -1450,6 +1450,7 @@ void d_walk(struct dentry *parent, void *data,
- seq = 1;
- goto again;
- }
-+EXPORT_SYMBOL_GPL(d_walk);
-
- struct check_mount {
- struct vfsmount *mnt;
-@@ -3051,6 +3052,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
-
- write_sequnlock(&rename_lock);
- }
-+EXPORT_SYMBOL_GPL(d_exchange);
-
- /**
- * d_ancestor - search for an ancestor
-diff --git a/fs/exec.c b/fs/exec.c
-index 6518e33ea813..b67efac6a1ad 100644
---- a/fs/exec.c
-+++ b/fs/exec.c
-@@ -112,6 +112,7 @@ bool path_noexec(const struct path *path)
- return (path->mnt->mnt_flags & MNT_NOEXEC) ||
- (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
- }
-+EXPORT_SYMBOL_GPL(path_noexec);
-
- #ifdef CONFIG_USELIB
- /*
-diff --git a/fs/fcntl.c b/fs/fcntl.c
-index d62e114c1b1a..ceef001775bd 100644
---- a/fs/fcntl.c
-+++ b/fs/fcntl.c
-@@ -87,6 +87,7 @@ int setfl(int fd, struct file * filp, unsigned int arg)
- out:
- return error;
- }
-+EXPORT_SYMBOL_GPL(setfl);
-
- static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
- int force)
-diff --git a/fs/file_table.c b/fs/file_table.c
-index ee21b3da9d08..c45ac36795dd 100644
---- a/fs/file_table.c
-+++ b/fs/file_table.c
-@@ -225,6 +225,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
- }
- return ERR_PTR(-ENFILE);
- }
-+EXPORT_SYMBOL_GPL(alloc_empty_file);
-
- /*
- * Variant of alloc_empty_file() that doesn't check and modify nr_files.
-diff --git a/fs/namespace.c b/fs/namespace.c
-index 6c57487f126b..16be9ac1c734 100644
---- a/fs/namespace.c
-+++ b/fs/namespace.c
-@@ -466,6 +466,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
- mnt_dec_writers(real_mount(mnt));
- preempt_enable();
- }
-+EXPORT_SYMBOL_GPL(__mnt_drop_write);
-
- /**
- * mnt_drop_write - give up write access to a mount
-@@ -877,6 +878,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
- {
- return check_mnt(real_mount(mnt));
- }
-+EXPORT_SYMBOL_GPL(is_current_mnt_ns);
-
- /*
- * vfsmount lock must be held for write
-@@ -2152,6 +2154,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
- }
- return 0;
- }
-+EXPORT_SYMBOL_GPL(iterate_mounts);
-
- static void lock_mnt_tree(struct mount *mnt)
- {
-diff --git a/fs/notify/group.c b/fs/notify/group.c
-index 1de6631a3925..3008eb37a18d 100644
---- a/fs/notify/group.c
-+++ b/fs/notify/group.c
-@@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
- {
- refcount_inc(&group->refcnt);
- }
-+EXPORT_SYMBOL_GPL(fsnotify_get_group);
-
- /*
- * Drop a reference to a group. Free it if it's through.
-diff --git a/fs/open.c b/fs/open.c
-index 98f6601fbac6..8624e4ffa15b 100644
---- a/fs/open.c
-+++ b/fs/open.c
-@@ -67,6 +67,7 @@ int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry,
- inode_unlock(dentry->d_inode);
- return ret;
- }
-+EXPORT_SYMBOL_GPL(do_truncate);
-
- long vfs_truncate(const struct path *path, loff_t length)
- {
-diff --git a/fs/read_write.c b/fs/read_write.c
-index 4771701c896b..c79270aba792 100644
---- a/fs/read_write.c
-+++ b/fs/read_write.c
-@@ -477,6 +477,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
- inc_syscr(current);
- return ret;
- }
-+EXPORT_SYMBOL_GPL(vfs_read);
-
- static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
- {
-@@ -592,6 +593,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
- file_end_write(file);
- return ret;
- }
-+EXPORT_SYMBOL_GPL(vfs_write);
-
- /* file_ppos returns &file->f_pos or NULL if file is stream */
- static inline loff_t *file_ppos(struct file *file)
-diff --git a/fs/splice.c b/fs/splice.c
-index 7216ef993b5f..7ce1f1bc4268 100644
---- a/fs/splice.c
-+++ b/fs/splice.c
-@@ -932,6 +932,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
- return warn_unsupported(out, "write");
- return out->f_op->splice_write(pipe, out, ppos, len, flags);
- }
-+EXPORT_SYMBOL_GPL(do_splice_from);
-
- /*
- * Indicate to the caller that there was a premature EOF when reading from the
-diff --git a/fs/xattr.c b/fs/xattr.c
-index efd4736bc94b..ce1a2c39ab23 100644
---- a/fs/xattr.c
-+++ b/fs/xattr.c
-@@ -406,6 +406,7 @@ vfs_getxattr_alloc(struct mnt_idmap *idmap, struct dentry *dentry,
- *xattr_value = value;
- return error;
- }
-+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
-
- ssize_t
- __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
-diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
-index db4297f60bd3..9aca18312afb 100644
---- a/kernel/locking/lockdep.c
-+++ b/kernel/locking/lockdep.c
-@@ -239,6 +239,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
- */
- return lock_classes + class_idx;
- }
-+EXPORT_SYMBOL_GPL(lockdep_hlock_class);
- #define hlock_class(hlock) lockdep_hlock_class(hlock)
-
- #ifdef CONFIG_LOCK_STAT
-diff --git a/kernel/task_work.c b/kernel/task_work.c
-index 065e1ef8fc8d..c623c6f0c645 100644
---- a/kernel/task_work.c
-+++ b/kernel/task_work.c
-@@ -182,3 +182,4 @@ void task_work_run(void)
- } while (work);
- }
- }
-+EXPORT_SYMBOL_GPL(task_work_run);
-diff --git a/security/security.c b/security/security.c
-index 23b129d482a7..fca4c5707a1c 100644
---- a/security/security.c
-+++ b/security/security.c
-@@ -1750,6 +1750,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
- return 0;
- return call_int_hook(path_rmdir, 0, dir, dentry);
- }
-+EXPORT_SYMBOL_GPL(security_path_rmdir);
-
- /**
- * security_path_unlink() - Check if removing a hard link is allowed
-@@ -1785,6 +1786,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
- return 0;
- return call_int_hook(path_symlink, 0, dir, dentry, old_name);
- }
-+EXPORT_SYMBOL_GPL(security_path_symlink);
-
- /**
- * security_path_link - Check if creating a hard link is allowed
-@@ -1803,6 +1805,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
- return 0;
- return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
- }
-+EXPORT_SYMBOL_GPL(security_path_link);
-
- /**
- * security_path_rename() - Check if renaming a file is allowed
-@@ -1864,6 +1867,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
- return 0;
- return call_int_hook(path_chmod, 0, path, mode);
- }
-+EXPORT_SYMBOL_GPL(security_path_chmod);
-
- /**
- * security_path_chown() - Check if changing the file's owner/group is allowed
-@@ -1881,6 +1885,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
- return 0;
- return call_int_hook(path_chown, 0, path, uid, gid);
- }
-+EXPORT_SYMBOL_GPL(security_path_chown);
-
- /**
- * security_path_chroot() - Check if changing the root directory is allowed
-@@ -2110,6 +2115,7 @@ int security_inode_permission(struct inode *inode, int mask)
- return 0;
- return call_int_hook(inode_permission, 0, inode, mask);
- }
-+EXPORT_SYMBOL_GPL(security_inode_permission);
-
- /**
- * security_inode_setattr() - Check if setting file attributes is allowed
-@@ -2588,6 +2594,7 @@ int security_file_permission(struct file *file, int mask)
-
- return fsnotify_perm(file, mask);
- }
-+EXPORT_SYMBOL_GPL(security_file_permission);
-
- /**
- * security_file_alloc() - Allocate and init a file's LSM blob
-@@ -2854,6 +2861,7 @@ int security_file_truncate(struct file *file)
- {
- return call_int_hook(file_truncate, 0, file);
- }
-+EXPORT_SYMBOL_GPL(security_file_truncate);
-
- /**
- * security_task_alloc() - Allocate a task's LSM blob
-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 2022-11-05 23:02:18.955889283 +0100
-@@ -0,0 +1,55 @@
-+What: /debug/aufs/si_<id>/
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ Under /debug/aufs, a directory named si_<id> is created
-+ per aufs mount, where <id> is a unique id generated
-+ internally.
+
-+What: /debug/aufs/si_<id>/plink
-+Date: Apr 2013
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It has three lines and shows the information about the
-+ pseudo-link. The first line is a single number
-+ representing a number of buckets. The second line is a
-+ number of pseudo-links per buckets (separated by a
-+ blank). The last line is a single number representing a
-+ total number of psedo-links.
-+ When the aufs mount option 'noplink' is specified, it
-+ will show "1\n0\n0\n".
++3. Configuration and Compilation
++----------------------------------------
++Make sure you have git-checkout'ed the correct branch.
++
++For aufs-linux tree,
++- enable CONFIG_AUFS_FS.
++- set other aufs configurations if necessary.
++- for aufs5.13 and later
++ Because aufs is not only an ordinary filesystem (callee of VFS), but
++ also a caller of VFS functions for branch filesystems, subclassing of
++ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
++ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
++ need to customize some LOCKDEP numbers. Here are what I use on my
++ test environment.
++ CONFIG_LOCKDEP_BITS=21
++ CONFIG_LOCKDEP_CHAINS_BITS=21
++ CONFIG_LOCKDEP_STACK_TRACE_BITS=24
++ Also you will need to expand some constant values in LOCKDEP. Refer
++ to lockdep-debug.patch in aufs-standalone.git.
++
++For aufs-standalone tree,
++There are several ways to build.
+
-+What: /debug/aufs/si_<id>/xib
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the consumed blocks by xib (External Inode Number
-+ Bitmap), its block size and file size.
-+ When the aufs mount option 'noxino' is specified, it
-+ will be empty. About XINO files, see the aufs manual.
++1.
++- apply ./aufs6-kbuild.patch to your kernel source files.
++- apply ./aufs6-base.patch too.
++- apply ./aufs6-mmap.patch too.
++- apply ./aufs6-standalone.patch too, if you have a plan to set
++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs-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
++ =m or =y.
++- and build your kernel as usual.
++- install the built kernel.
++- install the header files too by "make headers_install" to the
++ directory where you specify. By default, it is $PWD/usr.
++ "make help" shows a brief note for headers_install.
++- and reboot your system.
+
-+What: /debug/aufs/si_<id>/xi<branch-index>
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the consumed blocks by xino (External Inode Number
-+ Translation Table), its link count, block size and file
-+ size.
-+ Due to the file size limit, there may exist multiple
-+ xino files per branch. In this case, "-N" is added to
-+ the filename and it corresponds to the index of the
-+ internal xino array. "-0" is omitted.
-+ When the aufs mount option 'noxino' is specified, Those
-+ entries won't exist. About XINO files, see the aufs
-+ manual.
++2.
++- module only (CONFIG_AUFS_FS=m).
++- apply ./aufs6-base.patch to your kernel source files.
++- apply ./aufs6-mmap.patch too.
++- apply ./aufs6-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
++ every aufs configurations.
++- build the module by simple "make".
++- you can specify ${KDIR} make variable which points to your kernel
++ source tree.
++- install the files
++ + run "make install" to install the aufs module, or copy the built
++ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
++ + run "make install_headers" (instead of headers_install) to install
++ the modified aufs header file (you can specify DESTDIR which is
++ 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 aufs6-kbuild.patch, nor copying source files to your
++ kernel source tree.
+
-+What: /debug/aufs/si_<id>/xigen
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the consumed blocks by xigen (External Inode
-+ Generation Table), its block size and file size.
-+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
-+ be created.
-+ When the aufs mount option 'noxino' is specified, it
-+ 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 2022-11-05 23:02:18.955889283 +0100
-@@ -0,0 +1,31 @@
-+What: /sys/fs/aufs/si_<id>/
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ Under /sys/fs/aufs, a directory named si_<id> is created
-+ per aufs mount, where <id> is a unique id generated
-+ internally.
++Note: The header file aufs_type.h is necessary to build aufs-util
++ as well as "make headers_install" in the kernel source tree.
++ headers_install is subject to be forgotten, but it is essentially
++ necessary, not only for building aufs-util.
++ You may not meet problems without headers_install in some older
++ version though.
+
-+What: /sys/fs/aufs/si_<id>/br<idx>
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the abolute path of a member directory (which
-+ is called branch) in aufs, and its permission.
++And then,
++- read README in aufs-util, build and install it
++- note that your distribution may contain an obsoleted version of
++ aufs_type.h in /usr/include/linux or something. When you build aufs
++ utilities, make sure that your compiler refers the correct aufs header
++ file which is built by "make headers_install."
++- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
++ then run "make install_ulib" too. And refer to the aufs manual in
++ detail.
+
-+What: /sys/fs/aufs/si_<id>/brid<idx>
-+Date: July 2013
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the id of a member directory (which is called
-+ branch) in aufs.
++There several other patches in aufs-standalone.git. They are all
++optional. When you meet some problems, they will help you.
++- aufs6-loopback.patch
++ Supports a nested loopback mount in a branch-fs. This patch is
++ unnecessary until aufs produces a message like "you may want to try
++ another patch for loopback file".
++- vfs-ino.patch
++ Modifies a system global kernel internal function get_next_ino() in
++ order to stop assigning 0 for an inode-number. Not directly related to
++ aufs, but recommended generally.
++- tmpfs-idr.patch
++ Keeps the tmpfs inode number as the lowest value. Effective to reduce
++ the size of aufs XINO files for tmpfs branch. Also it prevents the
++ duplication of inode number, which is important for backup tools and
++ other utilities. When you find aufs XINO files for tmpfs branch
++ growing too much, try this patch.
++- lockdep-debug.patch
++ Similar to some kernel configurations for LOCKDEP (see the top of
++ this section), you will need expand some constants in LOCKDEP for
++ aufs if you enable CONFIG_LOCKDEP.
+
-+What: /sys/fs/aufs/si_<id>/xi_path
-+Date: March 2009
-+Contact: J. R. Okajima <hooanon05g at gmail.com>
-+Description:
-+ It shows the abolute path of XINO (External Inode Number
-+ Bitmap, Translation Table and Generation Table) file
-+ even if it is the default path.
-+ When the aufs mount option 'noxino' is specified, it
-+ 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 2022-11-05 23:02:18.955889283 +0100
++
++4. Usage
++----------------------------------------
++At first, make sure aufs-util are installed, and please read the aufs
++manual, aufs.5 in aufs-util.git tree.
++$ man -l aufs.5
++
++And then,
++$ mkdir /tmp/rw /tmp/aufs
++# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
++
++Here is another example. The result is equivalent.
++# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
++ Or
++# mount -t aufs -o br:/tmp/rw none /tmp/aufs
++# mount -o remount,append:${HOME} /tmp/aufs
++
++Then, you can see whole tree of your home dir through /tmp/aufs. If
++you modify a file under /tmp/aufs, the one on your home directory is
++not affected, instead the same named file will be newly created under
++/tmp/rw. And all of your modification to a file will be applied to
++the one under /tmp/rw. This is called the file based Copy on Write
++(COW) method.
++Aufs mount options are described in aufs.5.
++If you run chroot or something and make your aufs as a root directory,
++then you need to customize the shutdown script. See the aufs manual in
++detail.
++
++Additionally, there are some sample usages of aufs which are a
++diskless system with network booting, and LiveCD over NFS.
++See sample dir in CVS tree on SourceForge.
++
++
++5. Contact
++----------------------------------------
++When you have any problems or strange behaviour in aufs, please let me
++know with:
++- /proc/mounts (instead of the output of mount(8))
++- /sys/module/aufs/*
++- /sys/fs/aufs/* (if you have them)
++- /debug/aufs/* (if you have them)
++- linux kernel version
++ if your kernel is not plain, for example modified by distributor,
++ the url where i can download its source is necessary too.
++- aufs version which was printed at loading the module or booting the
++ system, instead of the date you downloaded.
++- configuration (define/undefine CONFIG_AUFS_xxx)
++- kernel configuration or /proc/config.gz (if you have it)
++- LSM (linux security module, if you are using)
++- behaviour which you think to be incorrect
++- actual operation, reproducible one is better
++- mailto: aufs-users at lists.sourceforge.net
++
++Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
++and Feature Requests) on SourceForge. Please join and write to
++aufs-users ML.
++
++
++6. Acknowledgements
++----------------------------------------
++Thanks to everyone who have tried and are using aufs, whoever
++have reported a bug or any feedback.
++
++Especially donators:
++Tomas Matejicek(slax.org) made a donation (much more than once).
++ Since Apr 2010, Tomas M (the author of Slax and Linux Live
++ scripts) is making "doubling" donations.
++ Unfortunately I cannot list all of the donators, but I really
++ appreciate.
++ It ends Aug 2010, but the ordinary donation URL is still available.
++ <http://sourceforge.net/donate/index.php?group_id=167503>
++Dai Itasaka made a donation (2007/8).
++Chuck Smith made a donation (2008/4, 10 and 12).
++Henk Schoneveld made a donation (2008/9).
++Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
++Francois Dupoux made a donation (2008/11).
++Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
++ aufs2 GIT tree (2009/2).
++William Grant made a donation (2009/3).
++Patrick Lane made a donation (2009/4).
++The Mail Archive (mail-archive.com) made donations (2009/5).
++Nippy Networks (Ed Wildgoose) made a donation (2009/7).
++New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
++Pavel Pronskiy made a donation (2011/2).
++Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
++ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
++Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
++11).
++Sam Liddicott made a donation (2011/9).
++Era Scarecrow made a donation (2013/4).
++Bor Ratajc made a donation (2013/4).
++Alessandro Gorreta made a donation (2013/4).
++POIRETTE Marc made a donation (2013/4).
++Alessandro Gorreta made a donation (2013/4).
++lauri kasvandik made a donation (2013/5).
++"pemasu from Finland" made a donation (2013/7).
++The Parted Magic Project made a donation (2013/9 and 11).
++Pavel Barta made a donation (2013/10).
++Nikolay Pertsev made a donation (2014/5).
++James B made a donation (2014/7, 2015/7, and 2021/12).
++Stefano Di Biase made a donation (2014/8).
++Daniel Epellei made a donation (2015/1).
++OmegaPhil made a donation (2016/1, 2018/4).
++Tomasz Szewczyk made a donation (2016/4).
++James Burry made a donation (2016/12).
++Carsten Rose made a donation (2018/9).
++Porteus Kiosk made a donation (2018/10).
++huronOS team: Enya Quetzalli made donations (2022/5, 2023/5 and 8).
++Vasily Mikhaylichenko made a donation (2023/5).
++
++Thank you very much.
++Donations are always, including future donations, very important and
++helpful for me to keep on developing aufs.
++
++
++7.
++----------------------------------------
++If you are an experienced user, no explanation is needed. Aufs is
++just a linux filesystem.
++
++
++Enjoy!
++
++# Local variables: ;
++# mode: text;
++# End: ;
+diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt
+new file mode 100644
+index 00000000000000..4c468b3264b56b
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/01intro.txt
@@ -0,0 +1,171 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -1175,9 +916,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt lin
+Some people may think it is better to pass such work to user space
+helper, instead of doing in kernel space. Actually I am still thinking
+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 2022-11-05 23:02:18.955889283 +0100
+diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt
+new file mode 100644
+index 00000000000000..83be46121ae26f
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/02struct.txt
@@ -0,0 +1,258 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -1437,9 +1180,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt li
+- etc.
+
+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 2022-11-05 23:02:18.955889283 +0100
+diff --git a/Documentation/filesystems/aufs/design/03atomic_open.txt b/Documentation/filesystems/aufs/design/03atomic_open.txt
+new file mode 100644
+index 00000000000000..4811f243246545
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/03atomic_open.txt
@@ -0,0 +1,85 @@
+
+# Copyright (C) 2015-2022 Junjiro R. Okajima
@@ -1526,9 +1271,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.t
+ ->atomic_open() are lost. in the ordinary case, the checks are
+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
+ 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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt
+new file mode 100644
+index 00000000000000..766a28be02637a
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/03lookup.txt
@@ -0,0 +1,113 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -1643,9 +1390,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt li
+ test, and skip the revalidation in step 4. It is useful and improves
+ aufs performance when system surely hide the aufs branches from user,
+ 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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt
+new file mode 100644
+index 00000000000000..ffeb97dcaff350
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/04branch.txt
@@ -0,0 +1,74 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -1721,9 +1470,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt li
+ - a file on the branch is mmap-ed.
+ - a regular file on the branch is opened for write and there is no
+ 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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt
+new file mode 100644
+index 00000000000000..a2143bfe6efc87
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt
@@ -0,0 +1,64 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -1789,9 +1540,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx
+ where the source and the target exists and selects the higher
+ one. If the selected branch is readonly, then aufs follows the
+ copyup policy.
-diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
---- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06dirren.dot 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/06dirren.dot b/Documentation/filesystems/aufs/design/06dirren.dot
+new file mode 100644
+index 00000000000000..4e6c7e7c20ef13
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/06dirren.dot
@@ -0,0 +1,44 @@
+
+// to view this graph, run dot(1) command in GRAPHVIZ.
@@ -1837,9 +1590,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot li
+
+aufs_lookup -> whinfo [label="load/remove"];
+}
-diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
---- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/06dirren.txt 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/06dirren.txt b/Documentation/filesystems/aufs/design/06dirren.txt
+new file mode 100644
+index 00000000000000..58ec5e22fe3d00
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/06dirren.txt
@@ -0,0 +1,102 @@
+
+# Copyright (C) 2017-2022 Junjiro R. Okajima
@@ -1943,9 +1698,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt li
+contains two names, before- and after-rename, the name comparision in
+UDBA handler may not work correctly. In this case, the behaviour will be
+equivalen to udba=reval case.
-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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt
+new file mode 100644
+index 00000000000000..d3b56325ff87ad
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/06fhsm.txt
@@ -0,0 +1,118 @@
+
+# Copyright (C) 2011-2022 Junjiro R. Okajima
@@ -2065,9 +1822,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linu
+
+And of course, in every step, an error may happen. So the operation
+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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt
+new file mode 100644
+index 00000000000000..ddc65ce97fa3e8
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/06mmap.txt
@@ -0,0 +1,72 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -2141,9 +1900,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu
+ equivalent to vm_prfile described above.
+
+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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt
+new file mode 100644
+index 00000000000000..4e5ead3ad74194
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/06xattr.txt
@@ -0,0 +1,94 @@
+
+# Copyright (C) 2014-2022 Junjiro R. Okajima
@@ -2239,9 +2000,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt lin
+Some contradiction may happen I am afraid.
+Do we need another attribute to stop copying XATTR? I am unsure. For
+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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt
+new file mode 100644
+index 00000000000000..40b2f1f1204932
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/07export.txt
@@ -0,0 +1,58 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -2301,9 +2064,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt li
+ convert it into ESTALE for NFSD.
+- readdir(): call lockdep_on/off() because filldir in NFSD calls
+ 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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/08shwh.txt b/Documentation/filesystems/aufs/design/08shwh.txt
+new file mode 100644
+index 00000000000000..67245e98e6b472
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/08shwh.txt
@@ -0,0 +1,52 @@
+
+# Copyright (C) 2005-2022 Junjiro R. Okajima
@@ -2357,9 +2122,11 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linu
+
+This new squashfs archive can be stored on the boot device and the
+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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt
+new file mode 100644
+index 00000000000000..da382ec2dc05d6
+--- /dev/null
++++ b/Documentation/filesystems/aufs/design/10dynop.txt
@@ -0,0 +1,47 @@
+
+# Copyright (C) 2010-2022 Junjiro R. Okajima
@@ -2408,422 +2175,342 @@ 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/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 2023-09-02 12:00:06.376642958 +0200
-@@ -0,0 +1,409 @@
-+
-+Aufs6 -- advanced multi layered unification filesystem version 6.x
-+http://aufs.sf.net
-+Junjiro R. Okajima
-+
-+
-+0. Introduction
-+----------------------------------------
-+In the early days, aufs was entirely re-designed and re-implemented
-+Unionfs Version 1.x series. Adding many original ideas, approaches,
-+improvements and implementations, it became totally different from
-+Unionfs while keeping the basic features.
-+Later, Unionfs Version 2.x series began taking some of the same
-+approaches to aufs1's.
-+Unionfs was being developed by Professor Erez Zadok at Stony Brook
-+University and his team.
-+
-+Aufs6 supports linux-v6.0 and later, try aufs6.0 branch in
-+aufs-linux.git or aufs-standalone.git.
-+If you want older kernel version support,
-+- for linux-v5.x series, try aufs-linux.git or aufs-standalone.git
-+- for linux-v4.x series, try aufs4-linux.git or aufs4-standalone.git
-+- for linux-v3.x series, try aufs3-linux.git or aufs3-standalone.git
-+- for linux-v2.6.16 and later, try aufs2-2.6.git, aufs2-standalone.git
-+ or aufs1 from CVS on SourceForge.
-+
-+Note: the name of aufs5-linux.git and aufs5-standalone.git on github
-+ were changed. Now they are aufs-linux.git and
-+ aufs-standalone.git and they contain aufs5 and later branches.
-+
-+Note: it becomes clear that "Aufs was rejected. Let's give it up."
-+ According to Christoph Hellwig, linux rejects all union-type
-+ filesystems but UnionMount.
-+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
-+
-+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
-+ UnionMount, and he pointed out an issue around a directory mutex
-+ lock and aufs addressed it. But it is still unsure whether aufs will
-+ be merged (or any other union solution).
-+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
-+
-+
-+1. Features
-+----------------------------------------
-+- unite several directories into a single virtual filesystem. The member
-+ directory is called as a branch.
-+- you can specify the permission flags to the branch, which are 'readonly',
-+ 'readwrite' and 'whiteout-able.'
-+- by upper writable branch, internal copyup and whiteout, files/dirs on
-+ readonly branch are modifiable logically.
-+- dynamic branch manipulation, add, del.
-+- etc...
-+
-+Also there are many enhancements in aufs, such as:
-+- test only the highest one for the directory permission (dirperm1)
-+- copyup on open (coo=)
-+- 'move' policy for copy-up between two writable branches, after
-+ checking free space.
-+- xattr, acl
-+- readdir(3) in userspace.
-+- keep inode number by external inode number table
-+- keep the timestamps of file/dir in internal copyup operation
-+- seekable directory, supporting NFS readdir.
-+- whiteout is hardlinked in order to reduce the consumption of inodes
-+ on branch
-+- do not copyup, nor create a whiteout when it is unnecessary
-+- revert a single systemcall when an error occurs in aufs
-+- remount interface instead of ioctl
-+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
-+- loopback mounted filesystem as a branch
-+- kernel thread for removing the dir who has a plenty of whiteouts
-+- support copyup sparse file (a file which has a 'hole' in it)
-+- default permission flags for branches
-+- selectable permission flags for ro branch, whether whiteout can
-+ exist or not
-+- export via NFS.
-+- support <sysfs>/fs/aufs and <debugfs>/aufs.
-+- support multiple writable branches, some policies to select one
-+ among multiple writable branches.
-+- a new semantics for link(2) and rename(2) to support multiple
-+ writable branches.
-+- no glibc changes are required.
-+- pseudo hardlink (hardlink over branches)
-+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
-+ including NFS or remote filesystem branch.
-+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
-+- and more...
-+
-+Currently these features are dropped temporary from aufs6.
-+See design/08plan.txt in detail.
-+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
-+ (robr)
-+- statistics of aufs thread (/sys/fs/aufs/stat)
-+
-+Features or just an idea in the future (see also design/*.txt),
-+- reorder the branch index without del/re-add.
-+- permanent xino files for NFSD
-+- an option for refreshing the opened files after add/del branches
-+- light version, without branch manipulation. (unnecessary?)
-+- copyup in userspace
-+- inotify in userspace
-+- readv/writev
-+
-+
-+2. Download
-+----------------------------------------
-+There are three GIT trees for aufs6, aufs-linux.git,
-+aufs-standalone.git, and aufs-util.git.
-+While the aufs-util is always necessary, you need either of aufs-linux
-+or aufs-standalone.
-+
-+The aufs-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 aufs6 as an external kernel module.
-+Several extra patches are not included in this tree. Only
-+aufs-standalone tree contains them. They are described in the later
-+section "Configuration and Compilation."
-+
-+On the other hand, the aufs-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 "aufs6.x" where "x"
-+represents the linux kernel version, "linux-6.x". For instance,
-+"aufs6.0" is for linux-6.0. For latest "linux-6.x-rcN", use
-+"aufs6.x-rcN" branch.
-+
-+o aufs-linux tree
-+$ git clone --reference /your/linux/git/tree \
-+ git://github.com/sfjro/aufs-linux.git aufs-linux.git
-+- if you don't have linux GIT tree, then remove "--reference ..."
-+$ cd aufs-linux.git
-+$ git checkout origin/aufs6.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 aufs git://github.com/sfjro/aufs-linux.git
-+$ git fetch aufs
-+$ git checkout -b my6.0 v6.0
-+$ (add your local change...)
-+$ git pull aufs aufs6.0
-+- now you have v6.0 + your_changes + aufs6.0 in you my6.0 branch.
-+- you may need to solve some conflicts between your_changes and
-+ aufs6.0. in this case, git-rerere is recommended so that you can
-+ solve the similar conflicts automatically when you upgrade to 6.1 or
-+ later in the future.
-+
-+o aufs-standalone tree
-+$ git clone git://github.com/sfjro/aufs-standalone.git aufs-standalone.git
-+$ cd aufs-standalone.git
-+$ git checkout origin/aufs6.0
-+
-+o aufs-util tree
-+$ 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/aufs6.0
-+
-+Note: The 6.x-rcN branch is to be used with `rc' kernel versions ONLY.
-+The minor version number, 'x' in '6.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.
-+
-+Since aufs-util has its own minor version number, you may not be
-+able to find a GIT branch in aufs-util for your kernel's
-+exact minor version number.
-+In this case, you should git-checkout the branch for the
-+nearest lower number.
-+
-+For (an unreleased) example:
-+If you are using "linux-6.10" and the "aufs6.10" branch
-+does not exist in aufs-util repository, then "aufs6.9", "aufs6.8"
-+or something numerically smaller is the branch for your kernel.
-+
-+Also you can view all branches by
-+ $ git branch -a
-+
-+
-+3. Configuration and Compilation
-+----------------------------------------
-+Make sure you have git-checkout'ed the correct branch.
+diff --git a/MAINTAINERS b/MAINTAINERS
+index a7c4cf8201e012..5b377eebc87952 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3347,6 +3347,19 @@ F: include/uapi/linux/audit.h
+ F: kernel/audit*
+ F: lib/*audit.c
+
++AUFS (advanced multi layered unification filesystem) FILESYSTEM
++M: "J. R. Okajima" <hooanon05g at gmail.com>
++L: aufs-users at lists.sourceforge.net (members only)
++L: linux-unionfs at vger.kernel.org
++S: Supported
++W: http://aufs.sourceforge.net
++T: git://github.com/sfjro/aufs4-linux.git
++F: Documentation/ABI/testing/debugfs-aufs
++F: Documentation/ABI/testing/sysfs-aufs
++F: Documentation/filesystems/aufs/
++F: fs/aufs/
++F: include/uapi/linux/aufs_type.h
+
-+For aufs-linux tree,
-+- enable CONFIG_AUFS_FS.
-+- set other aufs configurations if necessary.
-+- for aufs5.13 and later
-+ Because aufs is not only an ordinary filesystem (callee of VFS), but
-+ also a caller of VFS functions for branch filesystems, subclassing of
-+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
-+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
-+ need to customize some LOCKDEP numbers. Here are what I use on my
-+ test environment.
-+ CONFIG_LOCKDEP_BITS=21
-+ CONFIG_LOCKDEP_CHAINS_BITS=21
-+ CONFIG_LOCKDEP_STACK_TRACE_BITS=24
-+ Also you will need to expand some constant values in LOCKDEP. Refer
-+ to lockdep-debug.patch in aufs-standalone.git.
+ AUXILIARY BUS DRIVER
+ M: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+ R: Dave Ertman <david.m.ertman at intel.com>
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index 9f2d412fc560e1..1fefc6a8d049c7 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -645,6 +645,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+ goto done;
+ }
+
++/*
++ * for AUFS
++ * no get/put for file.
++ */
++struct file *loop_backing_file(struct super_block *sb)
++{
++ struct file *ret;
++ struct loop_device *l;
+
-+For aufs-standalone tree,
-+There are several ways to build.
++ ret = NULL;
++ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
++ l = sb->s_bdev->bd_disk->private_data;
++ ret = l->lo_backing_file;
++ }
++ return ret;
++}
++EXPORT_SYMBOL_GPL(loop_backing_file);
+
-+1.
-+- apply ./aufs6-kbuild.patch to your kernel source files.
-+- apply ./aufs6-base.patch too.
-+- apply ./aufs6-mmap.patch too.
-+- apply ./aufs6-standalone.patch too, if you have a plan to set
-+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs-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
-+ =m or =y.
-+- and build your kernel as usual.
-+- install the built kernel.
-+- install the header files too by "make headers_install" to the
-+ directory where you specify. By default, it is $PWD/usr.
-+ "make help" shows a brief note for headers_install.
-+- and reboot your system.
+ /* loop sysfs attributes */
+
+ static ssize_t loop_attr_show(struct device *dev, char *page,
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 42837617a55b54..6eaf5cde00fde8 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -333,6 +333,7 @@ source "fs/sysv/Kconfig"
+ source "fs/ufs/Kconfig"
+ source "fs/erofs/Kconfig"
+ source "fs/vboxsf/Kconfig"
++source "fs/aufs/Kconfig"
+
+ endif # MISC_FILESYSTEMS
+
+diff --git a/fs/Makefile b/fs/Makefile
+index 75522f88e76367..8743be00607ec7 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -130,3 +130,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/
+ obj-$(CONFIG_EROFS_FS) += erofs/
+ obj-$(CONFIG_VBOXSF_FS) += vboxsf/
+ obj-$(CONFIG_ZONEFS_FS) += zonefs/
++obj-$(CONFIG_AUFS_FS) += aufs/
+diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig
+new file mode 100644
+index 00000000000000..a5008b87a55f1f
+--- /dev/null
++++ b/fs/aufs/Kconfig
+@@ -0,0 +1,199 @@
++# SPDX-License-Identifier: GPL-2.0
++config AUFS_FS
++ tristate "Aufs (Advanced multi layered unification filesystem) support"
++ help
++ Aufs is a stackable unification filesystem such as Unionfs,
++ which unifies several directories and provides a merged single
++ directory.
++ In the early days, aufs was entirely re-designed and
++ re-implemented Unionfs Version 1.x series. Introducing many
++ original ideas, approaches and improvements, it becomes totally
++ different from Unionfs while keeping the basic features.
+
-+2.
-+- module only (CONFIG_AUFS_FS=m).
-+- apply ./aufs6-base.patch to your kernel source files.
-+- apply ./aufs6-mmap.patch too.
-+- apply ./aufs6-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
-+ every aufs configurations.
-+- build the module by simple "make".
-+- you can specify ${KDIR} make variable which points to your kernel
-+ source tree.
-+- install the files
-+ + run "make install" to install the aufs module, or copy the built
-+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
-+ + run "make install_headers" (instead of headers_install) to install
-+ the modified aufs header file (you can specify DESTDIR which is
-+ 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 aufs6-kbuild.patch, nor copying source files to your
-+ kernel source tree.
++if AUFS_FS
++choice
++ prompt "Maximum number of branches"
++ default AUFS_BRANCH_MAX_127
++ help
++ Specifies the maximum number of branches (or member directories)
++ in a single aufs. The larger value consumes more system
++ resources and has a minor impact to performance.
++config AUFS_BRANCH_MAX_127
++ bool "127"
++ help
++ Specifies the maximum number of branches (or member directories)
++ in a single aufs. The larger value consumes more system
++ resources and has a minor impact to performance.
++config AUFS_BRANCH_MAX_511
++ bool "511"
++ help
++ Specifies the maximum number of branches (or member directories)
++ in a single aufs. The larger value consumes more system
++ resources and has a minor impact to performance.
++config AUFS_BRANCH_MAX_1023
++ bool "1023"
++ help
++ Specifies the maximum number of branches (or member directories)
++ in a single aufs. The larger value consumes more system
++ resources and has a minor impact to performance.
++config AUFS_BRANCH_MAX_32767
++ bool "32767"
++ help
++ Specifies the maximum number of branches (or member directories)
++ in a single aufs. The larger value consumes more system
++ resources and has a minor impact to performance.
++endchoice
+
-+Note: The header file aufs_type.h is necessary to build aufs-util
-+ as well as "make headers_install" in the kernel source tree.
-+ headers_install is subject to be forgotten, but it is essentially
-+ necessary, not only for building aufs-util.
-+ You may not meet problems without headers_install in some older
-+ version though.
++config AUFS_SBILIST
++ bool
++ depends on AUFS_MAGIC_SYSRQ || PROC_FS
++ default y
++ help
++ Automatic configuration for internal use.
++ When aufs supports Magic SysRq or /proc, enabled automatically.
+
-+And then,
-+- read README in aufs-util, build and install it
-+- note that your distribution may contain an obsoleted version of
-+ aufs_type.h in /usr/include/linux or something. When you build aufs
-+ utilities, make sure that your compiler refers the correct aufs header
-+ file which is built by "make headers_install."
-+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
-+ then run "make install_ulib" too. And refer to the aufs manual in
-+ detail.
++config AUFS_HNOTIFY
++ bool "Detect direct branch access (bypassing aufs)"
++ help
++ If you want to modify files on branches directly, eg. bypassing aufs,
++ and want aufs to detect the changes of them fully, then enable this
++ option and use 'udba=notify' mount option.
++ Currently there is only one available configuration, "fsnotify".
++ It will have a negative impact to the performance.
++ See detail in aufs.5.
+
-+There several other patches in aufs-standalone.git. They are all
-+optional. When you meet some problems, they will help you.
-+- aufs6-loopback.patch
-+ Supports a nested loopback mount in a branch-fs. This patch is
-+ unnecessary until aufs produces a message like "you may want to try
-+ another patch for loopback file".
-+- vfs-ino.patch
-+ Modifies a system global kernel internal function get_next_ino() in
-+ order to stop assigning 0 for an inode-number. Not directly related to
-+ aufs, but recommended generally.
-+- tmpfs-idr.patch
-+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
-+ the size of aufs XINO files for tmpfs branch. Also it prevents the
-+ duplication of inode number, which is important for backup tools and
-+ other utilities. When you find aufs XINO files for tmpfs branch
-+ growing too much, try this patch.
-+- lockdep-debug.patch
-+ Similar to some kernel configurations for LOCKDEP (see the top of
-+ this section), you will need expand some constants in LOCKDEP for
-+ aufs if you enable CONFIG_LOCKDEP.
++choice
++ prompt "method" if AUFS_HNOTIFY
++ default AUFS_HFSNOTIFY
++config AUFS_HFSNOTIFY
++ bool "fsnotify"
++ select FSNOTIFY
++endchoice
+
++config AUFS_EXPORT
++ bool "NFS-exportable aufs"
++ depends on EXPORTFS
++ help
++ If you want to export your mounted aufs via NFS, then enable this
++ option. There are several requirements for this configuration.
++ See detail in aufs.5.
+
-+4. Usage
-+----------------------------------------
-+At first, make sure aufs-util are installed, and please read the aufs
-+manual, aufs.5 in aufs-util.git tree.
-+$ man -l aufs.5
++config AUFS_INO_T_64
++ bool
++ depends on AUFS_EXPORT
++ depends on 64BIT && !(ALPHA || S390)
++ default y
++ help
++ Automatic configuration for internal use.
++ /* typedef unsigned long/int __kernel_ino_t */
++ /* alpha and s390x are int */
+
-+And then,
-+$ mkdir /tmp/rw /tmp/aufs
-+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
++config AUFS_XATTR
++ bool "support for XATTR/EA (including Security Labels)"
++ help
++ If your branch fs supports XATTR/EA and you want to make them
++ available in aufs too, then enable this opsion and specify the
++ branch attributes for EA.
++ See detail in aufs.5.
+
-+Here is another example. The result is equivalent.
-+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
-+ Or
-+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
-+# mount -o remount,append:${HOME} /tmp/aufs
++config AUFS_FHSM
++ bool "File-based Hierarchical Storage Management"
++ help
++ Hierarchical Storage Management (or HSM) is a well-known feature
++ in the storage world. Aufs provides this feature as file-based.
++ with multiple branches.
++ These multiple branches are prioritized, ie. the topmost one
++ should be the fastest drive and be used heavily.
+
-+Then, you can see whole tree of your home dir through /tmp/aufs. If
-+you modify a file under /tmp/aufs, the one on your home directory is
-+not affected, instead the same named file will be newly created under
-+/tmp/rw. And all of your modification to a file will be applied to
-+the one under /tmp/rw. This is called the file based Copy on Write
-+(COW) method.
-+Aufs mount options are described in aufs.5.
-+If you run chroot or something and make your aufs as a root directory,
-+then you need to customize the shutdown script. See the aufs manual in
-+detail.
++config AUFS_RDU
++ bool "Readdir in userspace"
++ help
++ Aufs has two methods to provide a merged view for a directory,
++ by a user-space library and by kernel-space natively. The latter
++ is always enabled but sometimes large and slow.
++ If you enable this option, install the library in aufs2-util
++ package, and set some environment variables for your readdir(3),
++ then the work will be handled in user-space which generally
++ shows better performance in most cases.
++ See detail in aufs.5.
+
-+Additionally, there are some sample usages of aufs which are a
-+diskless system with network booting, and LiveCD over NFS.
-+See sample dir in CVS tree on SourceForge.
++config AUFS_DIRREN
++ bool "Workaround for rename(2)-ing a directory"
++ help
++ By default, aufs returns EXDEV error in renameing a dir who has
++ his child on the lower branch, since it is a bad idea to issue
++ rename(2) internally for every lower branch. But user may not
++ accept this behaviour. So here is a workaround to allow such
++ rename(2) and store some extra information on the writable
++ branch. Obviously this costs high (and I don't like it).
++ To use this feature, you need to enable this configuration AND
++ to specify the mount option `dirren.'
++ See details in aufs.5 and the design documents.
+
++config AUFS_SHWH
++ bool "Show whiteouts"
++ help
++ If you want to make the whiteouts in aufs visible, then enable
++ this option and specify 'shwh' mount option. Although it may
++ sounds like philosophy or something, but in technically it
++ simply shows the name of whiteout with keeping its behaviour.
+
-+5. Contact
-+----------------------------------------
-+When you have any problems or strange behaviour in aufs, please let me
-+know with:
-+- /proc/mounts (instead of the output of mount(8))
-+- /sys/module/aufs/*
-+- /sys/fs/aufs/* (if you have them)
-+- /debug/aufs/* (if you have them)
-+- linux kernel version
-+ if your kernel is not plain, for example modified by distributor,
-+ the url where i can download its source is necessary too.
-+- aufs version which was printed at loading the module or booting the
-+ system, instead of the date you downloaded.
-+- configuration (define/undefine CONFIG_AUFS_xxx)
-+- kernel configuration or /proc/config.gz (if you have it)
-+- LSM (linux security module, if you are using)
-+- behaviour which you think to be incorrect
-+- actual operation, reproducible one is better
-+- mailto: aufs-users at lists.sourceforge.net
++config AUFS_BR_RAMFS
++ bool "Ramfs (initramfs/rootfs) as an aufs branch"
++ help
++ If you want to use ramfs as an aufs branch fs, then enable this
++ option. Generally tmpfs is recommended.
++ Aufs prohibited them to be a branch fs by default, because
++ initramfs becomes unusable after switch_root or something
++ generally. If you sets initramfs as an aufs branch and boot your
++ system by switch_root, you will meet a problem easily since the
++ files in initramfs may be inaccessible.
++ Unless you are going to use ramfs as an aufs branch fs without
++ switch_root or something, leave it N.
+
-+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
-+and Feature Requests) on SourceForge. Please join and write to
-+aufs-users ML.
++config AUFS_BR_FUSE
++ bool "Fuse fs as an aufs branch"
++ depends on FUSE_FS
++ select AUFS_POLL
++ help
++ If you want to use fuse-based userspace filesystem as an aufs
++ branch fs, then enable this option.
++ It implements the internal poll(2) operation which is
++ implemented by fuse only (curretnly).
+
++config AUFS_POLL
++ bool
++ help
++ Automatic configuration for internal use.
+
-+6. Acknowledgements
-+----------------------------------------
-+Thanks to everyone who have tried and are using aufs, whoever
-+have reported a bug or any feedback.
++config AUFS_BR_HFSPLUS
++ bool "Hfsplus as an aufs branch"
++ depends on HFSPLUS_FS
++ default y
++ help
++ If you want to use hfsplus fs as an aufs branch fs, then enable
++ this option. This option introduces a small overhead at
++ copying-up a file on hfsplus.
+
-+Especially donators:
-+Tomas Matejicek(slax.org) made a donation (much more than once).
-+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
-+ scripts) is making "doubling" donations.
-+ Unfortunately I cannot list all of the donators, but I really
-+ appreciate.
-+ It ends Aug 2010, but the ordinary donation URL is still available.
-+ <http://sourceforge.net/donate/index.php?group_id=167503>
-+Dai Itasaka made a donation (2007/8).
-+Chuck Smith made a donation (2008/4, 10 and 12).
-+Henk Schoneveld made a donation (2008/9).
-+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
-+Francois Dupoux made a donation (2008/11).
-+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
-+ aufs2 GIT tree (2009/2).
-+William Grant made a donation (2009/3).
-+Patrick Lane made a donation (2009/4).
-+The Mail Archive (mail-archive.com) made donations (2009/5).
-+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
-+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
-+Pavel Pronskiy made a donation (2011/2).
-+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
-+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
-+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
-+11).
-+Sam Liddicott made a donation (2011/9).
-+Era Scarecrow made a donation (2013/4).
-+Bor Ratajc made a donation (2013/4).
-+Alessandro Gorreta made a donation (2013/4).
-+POIRETTE Marc made a donation (2013/4).
-+Alessandro Gorreta made a donation (2013/4).
-+lauri kasvandik made a donation (2013/5).
-+"pemasu from Finland" made a donation (2013/7).
-+The Parted Magic Project made a donation (2013/9 and 11).
-+Pavel Barta made a donation (2013/10).
-+Nikolay Pertsev made a donation (2014/5).
-+James B made a donation (2014/7, 2015/7, and 2021/12).
-+Stefano Di Biase made a donation (2014/8).
-+Daniel Epellei made a donation (2015/1).
-+OmegaPhil made a donation (2016/1, 2018/4).
-+Tomasz Szewczyk made a donation (2016/4).
-+James Burry made a donation (2016/12).
-+Carsten Rose made a donation (2018/9).
-+Porteus Kiosk made a donation (2018/10).
-+huronOS team: Enya Quetzalli made donations (2022/5, 2023/5 and 8).
-+Vasily Mikhaylichenko made a donation (2023/5).
++config AUFS_BDEV_LOOP
++ bool
++ depends on BLK_DEV_LOOP
++ default y
++ help
++ Automatic configuration for internal use.
++ Convert =[ym] into =y.
+
-+Thank you very much.
-+Donations are always, including future donations, very important and
-+helpful for me to keep on developing aufs.
++config AUFS_DEBUG
++ bool "Debug aufs"
++ help
++ Enable this to compile aufs internal debug code.
++ It will have a negative impact to the performance.
+
++config AUFS_MAGIC_SYSRQ
++ bool
++ depends on AUFS_DEBUG && MAGIC_SYSRQ
++ default y
++ help
++ Automatic configuration for internal use.
++ When aufs supports Magic SysRq, enabled automatically.
++endif
+diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile
+new file mode 100644
+index 00000000000000..4af8ecde3e3fad
+--- /dev/null
++++ b/fs/aufs/Makefile
+@@ -0,0 +1,46 @@
++# SPDX-License-Identifier: GPL-2.0
+
-+7.
-+----------------------------------------
-+If you are an experienced user, no explanation is needed. Aufs is
-+just a linux filesystem.
++include ${src}/magic.mk
++ifeq (${CONFIG_AUFS_FS},m)
++include ${src}/conf.mk
++endif
++-include ${src}/priv_def.mk
+
++# cf. include/linux/kernel.h
++# enable pr_debug
++ccflags-y += -DDEBUG
++# sparse requires the full pathname
++ifdef M
++ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
++else
++ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
++endif
+
-+Enjoy!
++obj-$(CONFIG_AUFS_FS) += aufs.o
++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o fsctx.o \
++ wkq.o vfsub.o dcsub.o \
++ cpup.o whout.o wbr_policy.o \
++ dinfo.o dentry.o \
++ dynop.o \
++ finfo.o file.o f_op.o \
++ dir.o vdir.o \
++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
++ mvdown.o ioctl.o
+
-+# Local variables: ;
-+# mode: text;
-+# 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 2022-11-05 23:02:18.959222617 +0100
++# all are boolean
++aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
++aufs-$(CONFIG_SYSFS) += sysfs.o
++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
++aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
++aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
++aufs-$(CONFIG_AUFS_EXPORT) += export.o
++aufs-$(CONFIG_AUFS_XATTR) += xattr.o
++aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
++aufs-$(CONFIG_AUFS_DIRREN) += dirren.o
++aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
++aufs-$(CONFIG_AUFS_POLL) += poll.o
++aufs-$(CONFIG_AUFS_RDU) += rdu.o
++aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
++aufs-$(CONFIG_AUFS_DEBUG) += debug.o
++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
+diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h
+new file mode 100644
+index 00000000000000..20430cf7904263
+--- /dev/null
++++ b/fs/aufs/aufs.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -2887,9 +2574,11 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
+
+#endif /* __KERNEL__ */
+#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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
+new file mode 100644
+index 00000000000000..2a85d744d2b5f7
+--- /dev/null
++++ b/fs/aufs/branch.c
@@ -0,0 +1,1427 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -4318,9 +4007,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
+
+ return err;
+}
-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 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h
+new file mode 100644
+index 00000000000000..6818ba8df8a24f
+--- /dev/null
++++ b/fs/aufs/branch.h
@@ -0,0 +1,375 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -4697,9 +4388,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
+
+#endif /* __KERNEL__ */
+#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 2022-11-05 23:02:18.959222617 +0100
+diff --git a/fs/aufs/conf.mk b/fs/aufs/conf.mk
+new file mode 100644
+index 00000000000000..12782f8e0f3819
+--- /dev/null
++++ b/fs/aufs/conf.mk
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0
+
@@ -4741,9 +4434,11 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
+${obj}/sysfs.o: ${AuConfName}
+
+-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 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
+new file mode 100644
+index 00000000000000..8c8bd5f7b28d81
+--- /dev/null
++++ b/fs/aufs/cpup.c
@@ -0,0 +1,1459 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -6204,9 +5899,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
+ dput(parent);
+ return err;
+}
-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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h
+new file mode 100644
+index 00000000000000..decd8f01425a05
+--- /dev/null
++++ b/fs/aufs/cpup.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -6308,9 +6005,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
+
+#endif /* __KERNEL__ */
+#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 2023-10-10 22:51:18.033248030 +0200
+diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c
+new file mode 100644
+index 00000000000000..d5811df890b5f5
+--- /dev/null
++++ b/fs/aufs/dbgaufs.c
@@ -0,0 +1,526 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -6838,9 +6537,11 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
+ err = 0;
+ return err;
+}
-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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h
+new file mode 100644
+index 00000000000000..30f1694224e004
+--- /dev/null
++++ b/fs/aufs/dbgaufs.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -6895,9 +6596,11 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
+
+#endif /* __KERNEL__ */
+#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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c
+new file mode 100644
+index 00000000000000..fa2a9ad2b49b61
+--- /dev/null
++++ b/fs/aufs/dcsub.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -7124,9 +6827,11 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
+
+ return path_is_under(path + 0, path + 1);
+}
-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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h
+new file mode 100644
+index 00000000000000..7e4f4eba0343b2
+--- /dev/null
++++ b/fs/aufs/dcsub.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -7265,9 +6970,11 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DCSUB_H__ */
-diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
---- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.c 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c
+new file mode 100644
+index 00000000000000..e503bb357984ec
+--- /dev/null
++++ b/fs/aufs/debug.c
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -7717,9 +7424,11 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
+
+ return 0;
+}
-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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h
+new file mode 100644
+index 00000000000000..f757588e5000ac
+--- /dev/null
++++ b/fs/aufs/debug.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -7947,9 +7656,11 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
+
+#endif /* __KERNEL__ */
+#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 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c
+new file mode 100644
+index 00000000000000..ed7ce8f6d1a1bf
+--- /dev/null
++++ b/fs/aufs/dentry.c
@@ -0,0 +1,1168 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -9119,9 +8830,11 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
+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 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h
+new file mode 100644
+index 00000000000000..da4c9063d7e1c8
+--- /dev/null
++++ b/fs/aufs/dentry.h
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -9393,9 +9106,11 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
+
+#endif /* __KERNEL__ */
+#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 2022-12-17 09:21:34.796521861 +0100
+diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c
+new file mode 100644
+index 00000000000000..bf4a94414309dc
+--- /dev/null
++++ b/fs/aufs/dinfo.c
@@ -0,0 +1,555 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -9952,9 +9667,11 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
+ return bindex;
+ return -1;
+}
-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 2023-10-31 09:31:04.196547417 +0100
+diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c
+new file mode 100644
+index 00000000000000..ee900ea3264b22
+--- /dev/null
++++ b/fs/aufs/dir.c
@@ -0,0 +1,765 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -10721,9 +10438,11 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
+ .flush = aufs_flush_dir,
+ .fsync = aufs_fsync_dir
+};
-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 2022-11-05 23:02:18.962555950 +0100
+diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h
+new file mode 100644
+index 00000000000000..382342bd6ecff3
+--- /dev/null
++++ b/fs/aufs/dir.h
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
@@ -10859,9 +10578,11 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DIR_H__ */
-diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
---- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dirren.c 2023-10-10 22:51:18.033248030 +0200
+diff --git a/fs/aufs/dirren.c b/fs/aufs/dirren.c
+new file mode 100644
+index 00000000000000..2a6295ab6576b8
+--- /dev/null
++++ b/fs/aufs/dirren.c
@@ -0,0 +1,1315 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -12100,91 +11821,611 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
+ return err;
+}
+
-+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
-+ ino_t h_ino)
++int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
++ ino_t h_ino)
++{
++ int match;
++ struct au_drinfo *drinfo;
++
++ match = 1;
++ if (!lkup->dirren.drinfo)
++ goto out;
++ AuDebugOn(lkup->dirren.ninfo <= bindex);
++ drinfo = lkup->dirren.drinfo[bindex];
++ if (!drinfo)
++ goto out;
++
++ match = (drinfo->ino == h_ino);
++ AuDbg("match %d\n", match);
++
++out:
++ return match;
++}
++
++/* ---------------------------------------------------------------------- */
++
++int au_dr_opt_set(struct super_block *sb)
++{
++ int err;
++ aufs_bindex_t bindex, bbot;
++ struct au_branch *br;
++
++ err = 0;
++ bbot = au_sbbot(sb);
++ for (bindex = 0; !err && bindex <= bbot; bindex++) {
++ br = au_sbr(sb, bindex);
++ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
++ }
++
++ return err;
++}
++
++int au_dr_opt_flush(struct super_block *sb)
++{
++ int err;
++ aufs_bindex_t bindex, bbot;
++ struct au_branch *br;
++
++ err = 0;
++ bbot = au_sbbot(sb);
++ for (bindex = 0; !err && bindex <= bbot; bindex++) {
++ br = au_sbr(sb, bindex);
++ if (au_br_writable(br->br_perm))
++ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
++ }
++
++ return err;
++}
++
++int au_dr_opt_clr(struct super_block *sb, int no_flush)
++{
++ int err;
++ aufs_bindex_t bindex, bbot;
++ struct au_branch *br;
++
++ err = 0;
++ if (!no_flush) {
++ err = au_dr_opt_flush(sb);
++ if (unlikely(err))
++ goto out;
++ }
++
++ bbot = au_sbbot(sb);
++ for (bindex = 0; bindex <= bbot; bindex++) {
++ br = au_sbr(sb, bindex);
++ au_dr_hino_free(&br->br_dirren);
++ }
++
++out:
++ return err;
++}
+diff --git a/fs/aufs/dirren.h b/fs/aufs/dirren.h
+new file mode 100644
+index 00000000000000..d2d57d95a77ecc
+--- /dev/null
++++ b/fs/aufs/dirren.h
+@@ -0,0 +1,140 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2017-2022 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/>.
++ */
++
++/*
++ * renamed dir info
++ */
++
++#ifndef __AUFS_DIRREN_H__
++#define __AUFS_DIRREN_H__
++
++#ifdef __KERNEL__
++
++#include <linux/dcache.h>
++#include <linux/statfs.h>
++#include <linux/uuid.h>
++#include "hbl.h"
++
++#define AuDirren_NHASH 100
++
++#ifdef CONFIG_AUFS_DIRREN
++enum au_brid_type {
++ AuBrid_Unset,
++ AuBrid_UUID,
++ AuBrid_FSID,
++ AuBrid_DEV
++};
++
++struct au_dr_brid {
++ enum au_brid_type type;
++ union {
++ uuid_t uuid; /* unimplemented yet */
++ fsid_t fsid;
++ dev_t dev;
++ };
++};
++
++/* 20 is the max digits length of ulong 64 */
++/* brid-type "_" uuid "_" inum */
++#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
++#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
++
++struct au_dr_hino {
++ struct hlist_bl_node dr_hnode;
++ ino_t dr_h_ino;
++};
++
++struct au_dr_br {
++ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
++ struct au_dr_brid dr_brid;
++};
++
++struct au_dr_lookup {
++ /* dr_name is pointed by struct au_do_lookup_args.name */
++ struct qstr dr_name; /* subset of dr_info */
++ aufs_bindex_t ninfo;
++ struct au_drinfo **drinfo;
++};
++#else
++struct au_dr_hino;
++/* empty */
++struct au_dr_br { };
++struct au_dr_lookup { };
++#endif
++
++/* ---------------------------------------------------------------------- */
++
++struct au_branch;
++struct au_do_lookup_args;
++struct au_hinode;
++#ifdef CONFIG_AUFS_DIRREN
++int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
++ struct au_dr_hino *add_ent);
++void au_dr_hino_free(struct au_dr_br *dr);
++int au_dr_br_init(struct super_block *sb, struct au_branch *br,
++ const struct path *path);
++int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
++int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
++ struct qstr *dst_name, void *_rev);
++void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
++void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
++int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
++ aufs_bindex_t bindex);
++int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
++int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
++ ino_t h_ino);
++void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
++int au_dr_opt_set(struct super_block *sb);
++int au_dr_opt_flush(struct super_block *sb);
++int au_dr_opt_clr(struct super_block *sb, int no_flush);
++#else
++AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
++ struct au_dr_hino *add_ent);
++AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
++AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
++ const struct path *path);
++AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
++AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
++ struct qstr *dst_name, void *_rev);
++AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
++AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
++ void *rev);
++AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
++ aufs_bindex_t bindex);
++AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
++AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup,
++ aufs_bindex_t bindex, ino_t h_ino);
++AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup);
++AuStubInt0(au_dr_opt_set, struct super_block *sb);
++AuStubInt0(au_dr_opt_flush, struct super_block *sb);
++AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush);
++#endif
++
++/* ---------------------------------------------------------------------- */
++
++#ifdef CONFIG_AUFS_DIRREN
++static inline int au_dr_ihash(ino_t h_ino)
++{
++ return h_ino % AuDirren_NHASH;
++}
++#else
++AuStubInt0(au_dr_ihash, ino_t h_ino);
++#endif
++
++#endif /* __KERNEL__ */
++#endif /* __AUFS_DIRREN_H__ */
+diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c
+new file mode 100644
+index 00000000000000..54fd16ecb6d340
+--- /dev/null
++++ b/fs/aufs/dynop.c
+@@ -0,0 +1,366 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2010-2022 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/>.
++ */
++
++/*
++ * dynamically customizable operations for regular files
++ */
++
++#include "aufs.h"
++
++#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
++
++/*
++ * How large will these lists be?
++ * Usually just a few elements, 20-30 at most for each, I guess.
++ */
++static struct hlist_bl_head dynop[AuDyLast];
++
++static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl,
++ const void *h_op)
++{
++ struct au_dykey *key, *tmp;
++ struct hlist_bl_node *pos;
++
++ key = NULL;
++ hlist_bl_lock(hbl);
++ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
++ if (tmp->dk_op.dy_hop == h_op) {
++ if (kref_get_unless_zero(&tmp->dk_kref))
++ key = tmp;
++ break;
++ }
++ hlist_bl_unlock(hbl);
++
++ return key;
++}
++
++static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
++{
++ struct au_dykey **k, *found;
++ const void *h_op = key->dk_op.dy_hop;
++ int i;
++
++ found = NULL;
++ k = br->br_dykey;
++ for (i = 0; i < AuBrDynOp; i++)
++ if (k[i]) {
++ if (k[i]->dk_op.dy_hop == h_op) {
++ found = k[i];
++ break;
++ }
++ } else
++ break;
++ if (!found) {
++ spin_lock(&br->br_dykey_lock);
++ for (; i < AuBrDynOp; i++)
++ if (k[i]) {
++ if (k[i]->dk_op.dy_hop == h_op) {
++ found = k[i];
++ break;
++ }
++ } else {
++ k[i] = key;
++ break;
++ }
++ spin_unlock(&br->br_dykey_lock);
++ BUG_ON(i == AuBrDynOp); /* expand the array */
++ }
++
++ return found;
++}
++
++/* kref_get() if @key is already added */
++static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key)
++{
++ struct au_dykey *tmp, *found;
++ struct hlist_bl_node *pos;
++ const void *h_op = key->dk_op.dy_hop;
++
++ found = NULL;
++ hlist_bl_lock(hbl);
++ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
++ if (tmp->dk_op.dy_hop == h_op) {
++ if (kref_get_unless_zero(&tmp->dk_kref))
++ found = tmp;
++ break;
++ }
++ if (!found)
++ hlist_bl_add_head(&key->dk_hnode, hbl);
++ hlist_bl_unlock(hbl);
++
++ if (!found)
++ DyPrSym(key);
++ return found;
++}
++
++static void dy_free_rcu(struct rcu_head *rcu)
++{
++ struct au_dykey *key;
++
++ key = container_of(rcu, struct au_dykey, dk_rcu);
++ DyPrSym(key);
++ kfree(key);
++}
++
++static void dy_free(struct kref *kref)
++{
++ struct au_dykey *key;
++ struct hlist_bl_head *hbl;
++
++ key = container_of(kref, struct au_dykey, dk_kref);
++ hbl = dynop + key->dk_op.dy_type;
++ au_hbl_del(&key->dk_hnode, hbl);
++ call_rcu(&key->dk_rcu, dy_free_rcu);
++}
++
++void au_dy_put(struct au_dykey *key)
++{
++ kref_put(&key->dk_kref, dy_free);
++}
++
++/* ---------------------------------------------------------------------- */
++
++#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
++
++#ifdef CONFIG_AUFS_DEBUG
++#define DyDbgDeclare(cnt) unsigned int cnt = 0
++#define DyDbgInc(cnt) do { cnt++; } while (0)
++#else
++#define DyDbgDeclare(cnt) do {} while (0)
++#define DyDbgInc(cnt) do {} while (0)
++#endif
++
++#define DySet(func, dst, src, h_op, h_sb) do { \
++ DyDbgInc(cnt); \
++ if (h_op->func) { \
++ if (src.func) \
++ dst.func = src.func; \
++ else \
++ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
++ } \
++} while (0)
++
++#define DySetForce(func, dst, src) do { \
++ AuDebugOn(!src.func); \
++ DyDbgInc(cnt); \
++ dst.func = src.func; \
++} while (0)
++
++#define DySetAop(func) \
++ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
++#define DySetAopForce(func) \
++ DySetForce(func, dyaop->da_op, aufs_aop)
++
++static void dy_aop(struct au_dykey *key, const void *h_op,
++ struct super_block *h_sb __maybe_unused)
++{
++ struct au_dyaop *dyaop = (void *)key;
++ const struct address_space_operations *h_aop = h_op;
++ DyDbgDeclare(cnt);
++
++ AuDbg("%s\n", au_sbtype(h_sb));
++
++ DySetAop(writepage);
++ DySetAopForce(read_folio); /* force */
++ DySetAop(writepages);
++ DySetAop(dirty_folio);
++ DySetAop(invalidate_folio);
++ DySetAop(readahead);
++ DySetAop(write_begin);
++ DySetAop(write_end);
++ DySetAop(bmap);
++ DySetAop(release_folio);
++ DySetAop(free_folio);
++ /* this one will be changed according to an aufs mount option */
++ DySetAop(direct_IO);
++ DySetAop(migrate_folio);
++ DySetAop(launder_folio);
++ DySetAop(is_partially_uptodate);
++ DySetAop(is_dirty_writeback);
++ DySetAop(error_remove_page);
++ DySetAop(swap_activate);
++ DySetAop(swap_deactivate);
++ DySetAop(swap_rw);
++
++ DyDbgSize(cnt, *h_aop);
++}
++
++/* ---------------------------------------------------------------------- */
++
++static void dy_bug(struct kref *kref)
++{
++ BUG();
++}
++
++static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
++{
++ struct au_dykey *key, *old;
++ struct hlist_bl_head *hbl;
++ struct op {
++ unsigned int sz;
++ void (*set)(struct au_dykey *key, const void *h_op,
++ struct super_block *h_sb __maybe_unused);
++ };
++ static const struct op a[] = {
++ [AuDy_AOP] = {
++ .sz = sizeof(struct au_dyaop),
++ .set = dy_aop
++ }
++ };
++ const struct op *p;
++
++ hbl = dynop + op->dy_type;
++ key = dy_gfind_get(hbl, op->dy_hop);
++ if (key)
++ goto out_add; /* success */
++
++ p = a + op->dy_type;
++ key = kzalloc(p->sz, GFP_NOFS);
++ if (unlikely(!key)) {
++ key = ERR_PTR(-ENOMEM);
++ goto out;
++ }
++
++ key->dk_op.dy_hop = op->dy_hop;
++ kref_init(&key->dk_kref);
++ p->set(key, op->dy_hop, au_br_sb(br));
++ old = dy_gadd(hbl, key);
++ if (old) {
++ au_kfree_rcu(key);
++ key = old;
++ }
++
++out_add:
++ old = dy_bradd(br, key);
++ if (old)
++ /* its ref-count should never be zero here */
++ kref_put(&key->dk_kref, dy_bug);
++out:
++ return key;
++}
++
++/* ---------------------------------------------------------------------- */
++/*
++ * Aufs prohibits O_DIRECT by default even if the branch supports it.
++ * This behaviour is necessary to return an error from open(O_DIRECT) instead
++ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
++ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
++ * See the aufs manual in detail.
++ */
++static void dy_adx(struct au_dyaop *dyaop, int do_dx)
++{
++ if (!do_dx)
++ dyaop->da_op.direct_IO = NULL;
++ else
++ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
++}
++
++static struct au_dyaop *dy_aget(struct au_branch *br,
++ const struct address_space_operations *h_aop,
++ int do_dx)
+{
-+ int match;
-+ struct au_drinfo *drinfo;
++ struct au_dyaop *dyaop;
++ struct au_dynop op;
+
-+ match = 1;
-+ if (!lkup->dirren.drinfo)
-+ goto out;
-+ AuDebugOn(lkup->dirren.ninfo <= bindex);
-+ drinfo = lkup->dirren.drinfo[bindex];
-+ if (!drinfo)
++ op.dy_type = AuDy_AOP;
++ op.dy_haop = h_aop;
++ dyaop = (void *)dy_get(&op, br);
++ if (IS_ERR(dyaop))
+ goto out;
-+
-+ match = (drinfo->ino == h_ino);
-+ AuDbg("match %d\n", match);
++ dy_adx(dyaop, do_dx);
+
+out:
-+ return match;
++ return dyaop;
+}
+
-+/* ---------------------------------------------------------------------- */
-+
-+int au_dr_opt_set(struct super_block *sb)
++int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
++ struct inode *h_inode)
+{
-+ int err;
-+ aufs_bindex_t bindex, bbot;
++ int err, do_dx;
++ struct super_block *sb;
+ struct au_branch *br;
++ struct au_dyaop *dyaop;
++
++ AuDebugOn(!S_ISREG(h_inode->i_mode));
++ IiMustWriteLock(inode);
++
++ sb = inode->i_sb;
++ br = au_sbr(sb, bindex);
++ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
++ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
++ err = PTR_ERR(dyaop);
++ if (IS_ERR(dyaop))
++ /* unnecessary to call dy_fput() */
++ goto out;
+
+ err = 0;
-+ bbot = au_sbbot(sb);
-+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
-+ br = au_sbr(sb, bindex);
-+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
-+ }
++ inode->i_mapping->a_ops = &dyaop->da_op;
+
++out:
+ return err;
+}
+
-+int au_dr_opt_flush(struct super_block *sb)
++/*
++ * Is it safe to replace a_ops during the inode/file is in operation?
++ * Yes, I hope so.
++ */
++int au_dy_irefresh(struct inode *inode)
+{
+ int err;
-+ aufs_bindex_t bindex, bbot;
-+ struct au_branch *br;
++ aufs_bindex_t btop;
++ struct inode *h_inode;
+
+ err = 0;
-+ bbot = au_sbbot(sb);
-+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
-+ br = au_sbr(sb, bindex);
-+ if (au_br_writable(br->br_perm))
-+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
++ if (S_ISREG(inode->i_mode)) {
++ btop = au_ibtop(inode);
++ h_inode = au_h_iptr(inode, btop);
++ err = au_dy_iaop(inode, btop, h_inode);
+ }
-+
+ return err;
+}
+
-+int au_dr_opt_clr(struct super_block *sb, int no_flush)
++void au_dy_arefresh(int do_dx)
+{
-+ int err;
-+ aufs_bindex_t bindex, bbot;
-+ struct au_branch *br;
++ struct hlist_bl_head *hbl;
++ struct hlist_bl_node *pos;
++ struct au_dykey *key;
+
-+ err = 0;
-+ if (!no_flush) {
-+ err = au_dr_opt_flush(sb);
-+ if (unlikely(err))
-+ goto out;
-+ }
++ hbl = dynop + AuDy_AOP;
++ hlist_bl_lock(hbl);
++ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode)
++ dy_adx((void *)key, do_dx);
++ hlist_bl_unlock(hbl);
++}
+
-+ bbot = au_sbbot(sb);
-+ for (bindex = 0; bindex <= bbot; bindex++) {
-+ br = au_sbr(sb, bindex);
-+ au_dr_hino_free(&br->br_dirren);
-+ }
++/* ---------------------------------------------------------------------- */
+
-+out:
-+ return err;
++void __init au_dy_init(void)
++{
++ int i;
++
++ for (i = 0; i < AuDyLast; i++)
++ INIT_HLIST_BL_HEAD(dynop + i);
+}
-diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
---- /usr/share/empty/fs/aufs/dirren.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dirren.h 2022-11-05 23:02:18.962555950 +0100
-@@ -0,0 +1,140 @@
++
++void au_dy_fin(void)
++{
++ int i;
++
++ for (i = 0; i < AuDyLast; i++)
++ WARN_ON(!hlist_bl_empty(dynop + i));
++}
+diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h
+new file mode 100644
+index 00000000000000..60d89364b67600
+--- /dev/null
++++ b/fs/aufs/dynop.h
+@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
-+ * Copyright (C) 2017-2022 Junjiro R. Okajima
++ * Copyright (C) 2010-2022 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
@@ -12201,582 +12442,906 @@ diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
+ */
+
+/*
-+ * renamed dir info
++ * dynamically customizable operations (for regular files only)
+ */
+
-+#ifndef __AUFS_DIRREN_H__
-+#define __AUFS_DIRREN_H__
++#ifndef __AUFS_DYNOP_H__
++#define __AUFS_DYNOP_H__
+
+#ifdef __KERNEL__
+
-+#include <linux/dcache.h>
-+#include <linux/statfs.h>
-+#include <linux/uuid.h>
-+#include "hbl.h"
-+
-+#define AuDirren_NHASH 100
++#include <linux/fs.h>
++#include <linux/kref.h>
+
-+#ifdef CONFIG_AUFS_DIRREN
-+enum au_brid_type {
-+ AuBrid_Unset,
-+ AuBrid_UUID,
-+ AuBrid_FSID,
-+ AuBrid_DEV
-+};
++enum {AuDy_AOP, AuDyLast};
+
-+struct au_dr_brid {
-+ enum au_brid_type type;
++struct au_dynop {
++ int dy_type;
+ union {
-+ uuid_t uuid; /* unimplemented yet */
-+ fsid_t fsid;
-+ dev_t dev;
++ const void *dy_hop;
++ const struct address_space_operations *dy_haop;
+ };
+};
+
-+/* 20 is the max digits length of ulong 64 */
-+/* brid-type "_" uuid "_" inum */
-+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
-+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
++struct au_dykey {
++ union {
++ struct hlist_bl_node dk_hnode;
++ struct rcu_head dk_rcu;
++ };
++ struct au_dynop dk_op;
+
-+struct au_dr_hino {
-+ struct hlist_bl_node dr_hnode;
-+ ino_t dr_h_ino;
++ /*
++ * during I am in the branch local array, kref is gotten. when the
++ * branch is removed, kref is put.
++ */
++ struct kref dk_kref;
+};
+
-+struct au_dr_br {
-+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
-+ struct au_dr_brid dr_brid;
++/* stop unioning since their sizes are very different from each other */
++struct au_dyaop {
++ struct au_dykey da_key;
++ struct address_space_operations da_op; /* not const */
+};
++/* make sure that 'struct au_dykey *' can be any type */
++static_assert(!offsetof(struct au_dyaop, da_key));
+
-+struct au_dr_lookup {
-+ /* dr_name is pointed by struct au_do_lookup_args.name */
-+ struct qstr dr_name; /* subset of dr_info */
-+ aufs_bindex_t ninfo;
-+ struct au_drinfo **drinfo;
-+};
++/* ---------------------------------------------------------------------- */
++
++/* dynop.c */
++struct au_branch;
++void au_dy_put(struct au_dykey *key);
++int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
++ struct inode *h_inode);
++int au_dy_irefresh(struct inode *inode);
++void au_dy_arefresh(int do_dio);
++
++void __init au_dy_init(void);
++void au_dy_fin(void);
++
++#endif /* __KERNEL__ */
++#endif /* __AUFS_DYNOP_H__ */
+diff --git a/fs/aufs/export.c b/fs/aufs/export.c
+new file mode 100644
+index 00000000000000..4c639e5d40f6bf
+--- /dev/null
++++ b/fs/aufs/export.c
+@@ -0,0 +1,830 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2005-2022 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/>.
++ */
++
++/*
++ * export via nfs
++ */
++
++#include <linux/exportfs.h>
++#include <linux/fs_struct.h>
++#include <linux/nsproxy.h>
++#include <linux/random.h>
++#include <linux/writeback.h>
++#include "aufs.h"
++
++union conv {
++#ifdef CONFIG_AUFS_INO_T_64
++ __u32 a[2];
+#else
-+struct au_dr_hino;
-+/* empty */
-+struct au_dr_br { };
-+struct au_dr_lookup { };
++ __u32 a[1];
+#endif
++ ino_t ino;
++};
+
-+/* ---------------------------------------------------------------------- */
++static ino_t decode_ino(__u32 *a)
++{
++ union conv u;
+
-+struct au_branch;
-+struct au_do_lookup_args;
-+struct au_hinode;
-+#ifdef CONFIG_AUFS_DIRREN
-+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
-+ struct au_dr_hino *add_ent);
-+void au_dr_hino_free(struct au_dr_br *dr);
-+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
-+ const struct path *path);
-+int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
-+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
-+ struct qstr *dst_name, void *_rev);
-+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
-+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
-+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
-+ aufs_bindex_t bindex);
-+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
-+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
-+ ino_t h_ino);
-+void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
-+int au_dr_opt_set(struct super_block *sb);
-+int au_dr_opt_flush(struct super_block *sb);
-+int au_dr_opt_clr(struct super_block *sb, int no_flush);
++ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
++ u.a[0] = a[0];
++#ifdef CONFIG_AUFS_INO_T_64
++ u.a[1] = a[1];
++#endif
++ return u.ino;
++}
++
++static void encode_ino(__u32 *a, ino_t ino)
++{
++ union conv u;
++
++ u.ino = ino;
++ a[0] = u.a[0];
++#ifdef CONFIG_AUFS_INO_T_64
++ a[1] = u.a[1];
++#endif
++}
++
++/* NFS file handle */
++enum {
++ Fh_br_id,
++ Fh_sigen,
++#ifdef CONFIG_AUFS_INO_T_64
++ /* support 64bit inode number */
++ Fh_ino1,
++ Fh_ino2,
++ Fh_dir_ino1,
++ Fh_dir_ino2,
+#else
-+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
-+ struct au_dr_hino *add_ent);
-+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
-+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
-+ const struct path *path);
-+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
-+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
-+ struct qstr *dst_name, void *_rev);
-+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
-+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
-+ void *rev);
-+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
-+ aufs_bindex_t bindex);
<Skipped 18213 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/b622d832656bdf738eab530c75e20b1eeb8841bc
More information about the pld-cvs-commit
mailing list