[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