[packages/kernel] Up to 6.8.0 (in progress)

arekm arekm at pld-linux.org
Mon Mar 11 01:56:20 CET 2024


commit bf3804b98e29bb0564b55ff876d74028428a71a8
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sun Mar 10 23:58:22 2024 +0100

    Up to 6.8.0 (in progress)

 kernel-aufs-fixes.patch |   152 -
 kernel-aufs.patch       | 36450 +++++++++++++++++++++++-----------------------
 kernel-hostap.patch     |   183 -
 kernel-multiarch.config |   245 +-
 kernel.spec             |    17 +-
 5 files changed, 18351 insertions(+), 18696 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 0a7e4b33..d0baad33 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -59,9 +59,9 @@
 %define		have_pcmcia	0
 %endif
 
-%define		rel		1
-%define		basever		6.7
-%define		postver		.9
+%define		rel		0.1
+%define		basever		6.8
+%define		postver		.0
 
 # define this to '-%{basever}' for longterm branch
 %define		versuffix	%{nil}
@@ -112,7 +112,7 @@ Epoch:		3
 License:	GPL v2
 Group:		Base/Kernel
 Source0:	https://www.kernel.org/pub/linux/kernel/v6.x/linux-%{basever}.tar.xz
-# Source0-md5:	7861a2ed9d33c0694df738203532b715
+# Source0-md5:	72d623b959a11850b57406f0b9fe3946
 %if "%{postver}" != ".0"
 Patch0:		https://www.kernel.org/pub/linux/kernel/v6.x/patch-%{version}.xz
 # Patch0-md5:	5b31116070986a56ee2747daf53ca48c
@@ -162,14 +162,9 @@ Patch56:	kernel-atmdd.patch
 # http://synce.svn.sourceforge.net/svnroot/synce/trunk/patches/linux-2.6.22-rndis_host-wm5.patch
 Patch59:	kernel-rndis_host-wm5.patch
 
-# adds some ids for hostap suported cards and monitor_enable from/for aircrack-ng
-# http://patches.aircrack-ng.org/hostap-kernel-2.6.18.patch
-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
@@ -595,14 +590,10 @@ cd linux-%{basever}
 # kernel-rndis_host-wm5.patch
 %patch59 -p1
 
-# hostap enhancements from/for aircrack-ng
-%patch85 -p1
-
 %if %{with aufs}
 # aufs
 %patch145 -p1
 %patch147 -p1
-%patch148 -p1
 %endif
 
 %if %{with rescuecd}
diff --git a/kernel-aufs-fixes.patch b/kernel-aufs-fixes.patch
deleted file mode 100644
index 26d072fa..00000000
--- a/kernel-aufs-fixes.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-; 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 1394a799..dcdb3f87 100644
--- a/kernel-aufs.patch
+++ b/kernel-aufs.patch
@@ -1,6548 +1,4328 @@
-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)
+SPDX-License-Identifier: GPL-2.0
+aufs6.x-rcN kbuild 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/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.
-+
-+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".
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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 @@
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+
-+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
-+#
-+# 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/>.
-+
-+Introduction
-+----------------------------------------
-+
-+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
-+1. abbrev. for "advanced multi-layered unification filesystem".
-+2. abbrev. for "another unionfs".
-+3. abbrev. for "auf das" in German which means "on the" in English.
-+   Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
-+   But "Filesystem aufs Filesystem" is hard to understand.
-+4. abbrev. for "African Urban Fashion Show".
-+
-+AUFS is a filesystem with features:
-+- multi layered stackable unification filesystem, the member directory
-+  is called as a branch.
-+- branch permission and attribute, 'readonly', 'real-readonly',
-+  'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
-+  combination.
-+- internal "file copy-on-write".
-+- logical deletion, whiteout.
-+- dynamic branch manipulation, adding, deleting and changing permission.
-+- allow bypassing aufs, user's direct branch access.
-+- external inode number translation table and bitmap which maintains the
-+  persistent aufs inode number.
-+- seekable directory, including NFS readdir.
-+- file mapping, mmap and sharing pages.
-+- pseudo-link, hardlink over branches.
-+- loopback mounted filesystem as a branch.
-+- several policies to select one among multiple writable branches.
-+- revert a single systemcall when an error occurs in aufs.
-+- and more...
-+
-+
-+Multi Layered Stackable Unification Filesystem
-+----------------------------------------------------------------------
-+Most people already knows what it is.
-+It is a filesystem which unifies several directories and provides a
-+merged single directory. When users access a file, the access will be
-+passed/re-directed/converted (sorry, I am not sure which English word is
-+correct) to the real file on the member filesystem. The member
-+filesystem is called 'lower filesystem' or 'branch' and has a mode
-+'readonly' and 'readwrite.' And the deletion for a file on the lower
-+readonly branch is handled by creating 'whiteout' on the upper writable
-+branch.
-+
-+On LKML, there have been discussions about UnionMount (Jan Blunck,
-+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
-+different approaches to implement the merged-view.
-+The former tries putting it into VFS, and the latter implements as a
-+separate filesystem.
-+(If I misunderstand about these implementations, please let me know and
-+I shall correct it. Because it is a long time ago when I read their
-+source files last time).
-+
-+UnionMount's approach will be able to small, but may be hard to share
-+branches between several UnionMount since the whiteout in it is
-+implemented in the inode on branch filesystem and always
-+shared. According to Bharata's post, readdir does not seems to be
-+finished yet.
-+There are several missing features known in this implementations such as
-+- for users, the inode number may change silently. eg. copy-up.
-+- link(2) may break by copy-up.
-+- read(2) may get an obsoleted filedata (fstat(2) too).
-+- fcntl(F_SETLK) may be broken by copy-up.
-+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
-+  open(O_RDWR).
-+
-+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
-+merged into mainline. This is another implementation of UnionMount as a
-+separated filesystem. All the limitations and known problems which
-+UnionMount are equally inherited to "overlay" filesystem.
-+
-+Unionfs has a longer history. When I started implementing a stackable
-+filesystem (Aug 2005), it already existed. It has virtual super_block,
-+inode, dentry and file objects and they have an array pointing lower
-+same kind objects. After contributing many patches for Unionfs, I
-+re-started my project AUFS (Jun 2006).
-+
-+In AUFS, the structure of filesystem resembles to Unionfs, but I
-+implemented my own ideas, approaches and enhancements and it became
-+totally different one.
-+
-+Comparing DM snapshot and fs based implementation
-+- the number of bytes to be copied between devices is much smaller.
-+- the type of filesystem must be one and only.
-+- the fs must be writable, no readonly fs, even for the lower original
-+  device. so the compression fs will not be usable. but if we use
-+  loopback mount, we may address this issue.
-+  for instance,
-+	mount /cdrom/squashfs.img /sq
-+	losetup /sq/ext2.img
-+	losetup /somewhere/cow
-+	dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
-+- it will be difficult (or needs more operations) to extract the
-+  difference between the original device and COW.
-+- DM snapshot-merge may help a lot when users try merging. in the
-+  fs-layer union, users will use rsync(1).
-+
-+You may want to read my old paper "Filesystems in LiveCD"
-+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
-+
-+
-+Several characters/aspects/persona of aufs
-+----------------------------------------------------------------------
-+
-+Aufs has several characters, aspects or persona.
-+1. a filesystem, callee of VFS helper
-+2. sub-VFS, caller of VFS helper for branches
-+3. a virtual filesystem which maintains persistent inode number
-+4. reader/writer of files on branches such like an application
-+
-+1. Callee of VFS Helper
-+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
-+unlink(2) from an application reaches sys_unlink() kernel function and
-+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
-+calls filesystem specific unlink operation. Actually aufs implements the
-+unlink operation but it behaves like a redirector.
-+
-+2. Caller of VFS Helper for Branches
-+aufs_unlink() passes the unlink request to the branch filesystem as if
-+it were called from VFS. So the called unlink operation of the branch
-+filesystem acts as usual. As a caller of VFS helper, aufs should handle
-+every necessary pre/post operation for the branch filesystem.
-+- acquire the lock for the parent dir on a branch
-+- lookup in a branch
-+- revalidate dentry on a branch
-+- mnt_want_write() for a branch
-+- vfs_unlink() for a branch
-+- mnt_drop_write() for a branch
-+- release the lock on a branch
-+
-+3. Persistent Inode Number
-+One of the most important issue for a filesystem is to maintain inode
-+numbers. This is particularly important to support exporting a
-+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
-+backend block device for its own. But some storage is necessary to
-+keep and maintain the inode numbers. It may be a large space and may not
-+suit to keep in memory. Aufs rents some space from its first writable
-+branch filesystem (by default) and creates file(s) on it. These files
-+are created by aufs internally and removed soon (currently) keeping
-+opened.
-+Note: Because these files are removed, they are totally gone after
-+      unmounting aufs. It means the inode numbers are not persistent
-+      across unmount or reboot. I have a plan to make them really
-+      persistent which will be important for aufs on NFS server.
-+
-+4. Read/Write Files Internally (copy-on-write)
-+Because a branch can be readonly, when you write a file on it, aufs will
-+"copy-up" it to the upper writable branch internally. And then write the
-+originally requested thing to the file. Generally kernel doesn't
-+open/read/write file actively. In aufs, even a single write may cause a
-+internal "file copy". This behaviour is very similar to cp(1) command.
-+
-+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 --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
-+#
-+# 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/>.
-+
-+Basic Aufs Internal Structure
-+
-+Superblock/Inode/Dentry/File Objects
-+----------------------------------------------------------------------
-+As like an ordinary filesystem, aufs has its own
-+superblock/inode/dentry/file objects. All these objects have a
-+dynamically allocated array and store the same kind of pointers to the
-+lower filesystem, branch.
-+For example, when you build a union with one readwrite branch and one
-+readonly, mounted /au, /rw and /ro respectively.
-+- /au = /rw + /ro
-+- /ro/fileA exists but /rw/fileA
-+
-+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
-+pointers are stored in a aufs dentry. The array in aufs dentry will be,
-+- [0] = NULL (because /rw/fileA doesn't exist)
-+- [1] = /ro/fileA
-+
-+This style of an array is essentially same to the aufs
-+superblock/inode/dentry/file objects.
-+
-+Because aufs supports manipulating branches, ie. add/delete/change
-+branches dynamically, these objects has its own generation. When
-+branches are changed, the generation in aufs superblock is
-+incremented. And a generation in other object are compared when it is
-+accessed. When a generation in other objects are obsoleted, aufs
-+refreshes the internal array.
-+
-+
-+Superblock
-+----------------------------------------------------------------------
-+Additionally aufs superblock has some data for policies to select one
-+among multiple writable branches, XIB files, pseudo-links and kobject.
-+See below in detail.
-+About the policies which supports copy-down a directory, see
-+wbr_policy.txt too.
-+
-+
-+Branch and XINO(External Inode Number Translation Table)
-+----------------------------------------------------------------------
-+Every branch has its own xino (external inode number translation table)
-+file. The xino file is created and unlinked by aufs internally. When two
-+members of a union exist on the same filesystem, they share the single
-+xino file.
-+The struct of a xino file is simple, just a sequence of aufs inode
-+numbers which is indexed by the lower inode number.
-+In the above sample, assume the inode number of /ro/fileA is i111 and
-+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
-+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
-+
-+When the inode numbers are not contiguous, the xino file will be sparse
-+which has a hole in it and doesn't consume as much disk space as it
-+might appear. If your branch filesystem consumes disk space for such
-+holes, then you should specify 'xino=' option at mounting aufs.
-+
-+Aufs has a mount option to free the disk blocks for such holes in XINO
-+files on tmpfs or ramdisk. But it is not so effective actually. If you
-+meet a problem of disk shortage due to XINO files, then you should try
-+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
-+The patch localizes the assignment inumbers per tmpfs-mount and avoid
-+the holes in XINO files.
-+
-+Also a writable branch has three kinds of "whiteout bases". All these
-+are existed when the branch is joined to aufs, and their names are
-+whiteout-ed doubly, so that users will never see their names in aufs
-+hierarchy.
-+1. a regular file which will be hardlinked to all whiteouts.
-+2. a directory to store a pseudo-link.
-+3. a directory to store an "orphan"-ed file temporary.
-+
-+1. Whiteout Base
-+   When you remove a file on a readonly branch, aufs handles it as a
-+   logical deletion and creates a whiteout on the upper writable branch
-+   as a hardlink of this file in order not to consume inode on the
-+   writable branch.
-+2. Pseudo-link Dir
-+   See below, Pseudo-link.
-+3. Step-Parent Dir
-+   When "fileC" exists on the lower readonly branch only and it is
-+   opened and removed with its parent dir, and then user writes
-+   something into it, then aufs copies-up fileC to this
-+   directory. Because there is no other dir to store fileC. After
-+   creating a file under this dir, the file is unlinked.
-+
-+Because aufs supports manipulating branches, ie. add/delete/change
-+dynamically, a branch has its own id. When the branch order changes,
-+aufs finds the new index by searching the branch id.
-+
-+
-+Pseudo-link
-+----------------------------------------------------------------------
-+Assume "fileA" exists on the lower readonly branch only and it is
-+hardlinked to "fileB" on the branch. When you write something to fileA,
-+aufs copies-up it to the upper writable branch. Additionally aufs
-+creates a hardlink under the Pseudo-link Directory of the writable
-+branch. The inode of a pseudo-link is kept in aufs super_block as a
-+simple list. If fileB is read after unlinking fileA, aufs returns
-+filedata from the pseudo-link instead of the lower readonly
-+branch. Because the pseudo-link is based upon the inode, to keep the
-+inode number by xino (see above) is essentially necessary.
-+
-+All the hardlinks under the Pseudo-link Directory of the writable branch
-+should be restored in a proper location later. Aufs provides a utility
-+to do this. The userspace helpers executed at remounting and unmounting
-+aufs by default.
-+During this utility is running, it puts aufs into the pseudo-link
-+maintenance mode. In this mode, only the process which began the
-+maintenance mode (and its child processes) is allowed to operate in
-+aufs. Some other processes which are not related to the pseudo-link will
-+be allowed to run too, but the rest have to return an error or wait
-+until the maintenance mode ends. If a process already acquires an inode
-+mutex (in VFS), it has to return an error.
-+
-+
-+XIB(external inode number bitmap)
-+----------------------------------------------------------------------
-+Addition to the xino file per a branch, aufs has an external inode number
-+bitmap in a superblock object. It is also an internal file such like a
-+xino file.
-+It is a simple bitmap to mark whether the aufs inode number is in-use or
-+not.
-+To reduce the file I/O, aufs prepares a single memory page to cache xib.
-+
-+As well as XINO files, aufs has a feature to truncate/refresh XIB to
-+reduce the number of consumed disk blocks for these files.
-+
-+
-+Virtual or Vertical Dir, and Readdir in Userspace
-+----------------------------------------------------------------------
-+In order to support multiple layers (branches), aufs readdir operation
-+constructs a virtual dir block on memory. For readdir, aufs calls
-+vfs_readdir() internally for each dir on branches, merges their entries
-+with eliminating the whiteout-ed ones, and sets it to file (dir)
-+object. So the file object has its entry list until it is closed. The
-+entry list will be updated when the file position is zero and becomes
-+obsoleted. This decision is made in aufs automatically.
-+
-+The dynamically allocated memory block for the name of entries has a
-+unit of 512 bytes (by default) and stores the names contiguously (no
-+padding). Another block for each entry is handled by kmem_cache too.
-+During building dir blocks, aufs creates hash list and judging whether
-+the entry is whiteouted by its upper branch or already listed.
-+The merged result is cached in the corresponding inode object and
-+maintained by a customizable life-time option.
-+
-+Some people may call it can be a security hole or invite DoS attack
-+since the opened and once readdir-ed dir (file object) holds its entry
-+list and becomes a pressure for system memory. But I'd say it is similar
-+to files under /proc or /sys. The virtual files in them also holds a
-+memory page (generally) while they are opened. When an idea to reduce
-+memory for them is introduced, it will be applied to aufs too.
-+For those who really hate this situation, I've developed readdir(3)
-+library which operates this merging in userspace. You just need to set
-+LD_PRELOAD environment variable, and aufs will not consume no memory in
-+kernel space for readdir(3).
-+
-+
-+Workqueue
-+----------------------------------------------------------------------
-+Aufs sometimes requires privilege access to a branch. For instance,
-+in copy-up/down operation. When a user process is going to make changes
-+to a file which exists in the lower readonly branch only, and the mode
-+of one of ancestor directories may not be writable by a user
-+process. Here aufs copy-up the file with its ancestors and they may
-+require privilege to set its owner/group/mode/etc.
-+This is a typical case of a application character of aufs (see
-+Introduction).
-+
-+Aufs uses workqueue synchronously for this case. It creates its own
-+workqueue. The workqueue is a kernel thread and has privilege. Aufs
-+passes the request to call mkdir or write (for example), and wait for
-+its completion. This approach solves a problem of a signal handler
-+simply.
-+If aufs didn't adopt the workqueue and changed the privilege of the
-+process, then the process may receive the unexpected SIGXFSZ or other
-+signals.
-+
-+Also aufs uses the system global workqueue ("events" kernel thread) too
-+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
-+whiteout base and etc. This is unrelated to a privilege.
-+Most of aufs operation tries acquiring a rw_semaphore for aufs
-+superblock at the beginning, at the same time waits for the completion
-+of all queued asynchronous tasks.
-+
-+
-+Whiteout
-+----------------------------------------------------------------------
-+The whiteout in aufs is very similar to Unionfs's. That is represented
-+by its filename. UnionMount takes an approach of a file mode, but I am
-+afraid several utilities (find(1) or something) will have to support it.
-+
-+Basically the whiteout represents "logical deletion" which stops aufs to
-+lookup further, but also it represents "dir is opaque" which also stop
-+further lookup.
-+
-+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
-+In order to make several functions in a single systemcall to be
-+revertible, aufs adopts an approach to rename a directory to a temporary
-+unique whiteouted name.
-+For example, in rename(2) dir where the target dir already existed, aufs
-+renames the target dir to a temporary unique whiteouted name before the
-+actual rename on a branch, and then handles other actions (make it opaque,
-+update the attributes, etc). If an error happens in these actions, aufs
-+simply renames the whiteouted name back and returns an error. If all are
-+succeeded, aufs registers a function to remove the whiteouted unique
-+temporary name completely and asynchronously to the system global
-+workqueue.
-+
-+
-+Copy-up
-+----------------------------------------------------------------------
-+It is a well-known feature or concept.
-+When user modifies a file on a readonly branch, aufs operate "copy-up"
-+internally and makes change to the new file on the upper writable branch.
-+When the trigger systemcall does not update the timestamps of the parent
-+dir, aufs reverts it after copy-up.
-+
-+
-+Move-down (aufs3.9 and later)
-+----------------------------------------------------------------------
-+"Copy-up" is one of the essential feature in aufs. It copies a file from
-+the lower readonly branch to the upper writable branch when a user
-+changes something about the file.
-+"Move-down" is an opposite action of copy-up. Basically this action is
-+ran manually instead of automatically and internally.
-+For desgin and implementation, aufs has to consider these issues.
-+- whiteout for the file may exist on the lower branch.
-+- ancestor directories may not exist on the lower branch.
-+- diropq for the ancestor directories may exist on the upper branch.
-+- free space on the lower branch will reduce.
-+- another access to the file may happen during moving-down, including
-+  UDBA (see "Revalidate Dentry and UDBA").
-+- the file should not be hard-linked nor pseudo-linked. they should be
-+  handled by auplink utility later.
-+
-+Sometimes users want to move-down a file from the upper writable branch
-+to the lower readonly or writable branch. For instance,
-+- the free space of the upper writable branch is going to run out.
-+- create a new intermediate branch between the upper and lower branch.
-+- etc.
-+
-+For this purpose, use "aumvdown" command in aufs-util.git.
-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
-+#
-+# 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/>.
-+
-+Support for a branch who has its ->atomic_open()
-+----------------------------------------------------------------------
-+The filesystems who implement its ->atomic_open() are not majority. For
-+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
-+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
-+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
-+sure whether all filesystems who have ->atomic_open() behave like this,
-+but NFSv4 surely returns the error.
-+
-+In order to support ->atomic_open() for aufs, there are a few
-+approaches.
-+
-+A. Introduce aufs_atomic_open()
-+   - calls one of VFS:do_last(), lookup_open() or atomic_open() for
-+     branch fs.
-+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
-+   an aufs user Pip Cet's approach
-+   - calls aufs_create(), VFS finish_open() and notify_change().
-+   - pass fake-mode to finish_open(), and then correct the mode by
-+     notify_change().
-+C. Extend aufs_open() to call branch fs's ->atomic_open()
-+   - no aufs_atomic_open().
-+   - aufs_lookup() registers the TID to an aufs internal object.
-+   - aufs_create() does nothing when the matching TID is registered, but
-+     registers the mode.
-+   - aufs_open() calls branch fs's ->atomic_open() when the matching
-+     TID is registered.
-+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
-+   credential
-+   - no aufs_atomic_open().
-+   - aufs_create() registers the TID to an internal object. this info
-+     represents "this process created this file just now."
-+   - when aufs gets EACCES from branch fs's ->open(), then confirm the
-+     registered TID and re-try open() with superuser's credential.
-+
-+Pros and cons for each approach.
-+
-+A.
-+   - straightforward but highly depends upon VFS internal.
-+   - the atomic behavaiour is kept.
-+   - some of parameters such as nameidata are hard to reproduce for
-+     branch fs.
-+   - large overhead.
-+B.
-+   - easy to implement.
-+   - the atomic behavaiour is lost.
-+C.
-+   - the atomic behavaiour is kept.
-+   - dirty and tricky.
-+   - VFS checks whether the file is created correctly after calling
-+     ->create(), which means this approach doesn't work.
-+D.
-+   - easy to implement.
-+   - the atomic behavaiour is lost.
-+   - to open a file with superuser's credential and give it to a user
-+     process is a bad idea, since the file object keeps the credential
-+     in it. It may affect LSM or something. This approach doesn't work
-+     either.
-+
-+The approach A is ideal, but it hard to implement. So here is a
-+variation of A, which is to be implemented.
-+
-+A-1. Introduce aufs_atomic_open()
-+     - calls branch fs ->atomic_open() if exists. otherwise calls
-+       vfs_create() and finish_open().
-+     - the demerit is that the several checks after branch fs
-+       ->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 --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
-+#
-+# 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/>.
-+
-+Lookup in a Branch
-+----------------------------------------------------------------------
-+Since aufs has a character of sub-VFS (see Introduction), it operates
-+lookup for branches as VFS does. It may be a heavy work. But almost all
-+lookup operation in aufs is the simplest case, ie. lookup only an entry
-+directly connected to its parent. Digging down the directory hierarchy
-+is unnecessary. VFS has a function lookup_one_len() for that use, and
-+aufs calls it.
-+
-+When a branch is a remote filesystem, aufs basically relies upon its
-+->d_revalidate(), also aufs forces the hardest revalidate tests for
-+them.
-+For d_revalidate, aufs implements three levels of revalidate tests. See
-+"Revalidate Dentry and UDBA" in detail.
-+
-+
-+Test Only the Highest One for the Directory Permission (dirperm1 option)
-+----------------------------------------------------------------------
-+Let's try case study.
-+- aufs has two branches, upper readwrite and lower readonly.
-+  /au = /rw + /ro
-+- "dirA" exists under /ro, but /rw. and its mode is 0700.
-+- user invoked "chmod a+rx /au/dirA"
-+- the internal copy-up is activated and "/rw/dirA" is created and its
-+  permission bits are set to world readable.
-+- then "/au/dirA" becomes world readable?
-+
-+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
-+or it may be a natively readonly filesystem. If aufs respects the lower
-+branch, it should not respond readdir request from other users. But user
-+allowed it by chmod. Should really aufs rejects showing the entries
-+under /ro/dirA?
-+
-+To be honest, I don't have a good solution for this case. So aufs
-+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
-+users.
-+When dirperm1 is specified, aufs checks only the highest one for the
-+directory permission, and shows the entries. Otherwise, as usual, checks
-+every dir existing on all branches and rejects the request.
-+
-+As a side effect, dirperm1 option improves the performance of aufs
-+because the number of permission check is reduced when the number of
-+branch is many.
-+
-+
-+Revalidate Dentry and UDBA (User's Direct Branch Access)
-+----------------------------------------------------------------------
-+Generally VFS helpers re-validate a dentry as a part of lookup.
-+0. digging down the directory hierarchy.
-+1. lock the parent dir by its i_mutex.
-+2. lookup the final (child) entry.
-+3. revalidate it.
-+4. call the actual operation (create, unlink, etc.)
-+5. unlock the parent dir
-+
-+If the filesystem implements its ->d_revalidate() (step 3), then it is
-+called. Actually aufs implements it and checks the dentry on a branch is
-+still valid.
-+But it is not enough. Because aufs has to release the lock for the
-+parent dir on a branch at the end of ->lookup() (step 2) and
-+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
-+held by VFS.
-+If the file on a branch is changed directly, eg. bypassing aufs, after
-+aufs released the lock, then the subsequent operation may cause
-+something unpleasant result.
-+
-+This situation is a result of VFS architecture, ->lookup() and
-+->d_revalidate() is separated. But I never say it is wrong. It is a good
-+design from VFS's point of view. It is just not suitable for sub-VFS
-+character in aufs.
-+
-+Aufs supports such case by three level of revalidation which is
-+selectable by user.
-+1. Simple Revalidate
-+   Addition to the native flow in VFS's, confirm the child-parent
-+   relationship on the branch just after locking the parent dir on the
-+   branch in the "actual operation" (step 4). When this validation
-+   fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
-+   checks the validation of the dentry on branches.
-+2. Monitor Changes Internally by Inotify/Fsnotify
-+   Addition to above, in the "actual operation" (step 4) aufs re-lookup
-+   the dentry on the branch, and returns EBUSY if it finds different
-+   dentry.
-+   Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
-+   during it is in cache. When the event is notified, aufs registers a
-+   function to kernel 'events' thread by schedule_work(). And the
-+   function sets some special status to the cached aufs dentry and inode
-+   private data. If they are not cached, then aufs has nothing to
-+   do. When the same file is accessed through aufs (step 0-3) later,
-+   aufs will detect the status and refresh all necessary data.
-+   In this mode, aufs has to ignore the event which is fired by aufs
-+   itself.
-+3. No Extra Validation
-+   This is the simplest test and doesn't add any additional revalidation
-+   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 --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
-+#
-+# 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/>.
-+
-+Branch Manipulation
-+
-+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
-+and changing its permission/attribute, there are a lot of works to do.
-+
-+
-+Add a Branch
-+----------------------------------------------------------------------
-+o Confirm the adding dir exists outside of aufs, including loopback
-+  mount, and its various attributes.
-+o Initialize the xino file and whiteout bases if necessary.
-+  See struct.txt.
-+
-+o Check the owner/group/mode of the directory
-+  When the owner/group/mode of the adding directory differs from the
-+  existing branch, aufs issues a warning because it may impose a
-+  security risk.
-+  For example, when a upper writable branch has a world writable empty
-+  top directory, a malicious user can create any files on the writable
-+  branch directly, like copy-up and modify manually. If something like
-+  /etc/{passwd,shadow} exists on the lower readonly branch but the upper
-+  writable branch, and the writable branch is world-writable, then a
-+  malicious guy may create /etc/passwd on the writable branch directly
-+  and the infected file will be valid in aufs.
-+  I am afraid it can be a security issue, but aufs can do nothing except
-+  producing a warning.
-+
-+
-+Delete a Branch
-+----------------------------------------------------------------------
-+o Confirm the deleting branch is not busy
-+  To be general, there is one merit to adopt "remount" interface to
-+  manipulate branches. It is to discard caches. At deleting a branch,
-+  aufs checks the still cached (and connected) dentries and inodes. If
-+  there are any, then they are all in-use. An inode without its
-+  corresponding dentry can be alive alone (for example, inotify/fsnotify case).
-+
-+  For the cached one, aufs checks whether the same named entry exists on
-+  other branches.
-+  If the cached one is a directory, because aufs provides a merged view
-+  to users, as long as one dir is left on any branch aufs can show the
-+  dir to users. In this case, the branch can be removed from aufs.
-+  Otherwise aufs rejects deleting the branch.
-+
-+  If any file on the deleting branch is opened by aufs, then aufs
-+  rejects deleting.
-+
-+
-+Modify the Permission of a Branch
-+----------------------------------------------------------------------
-+o Re-initialize or remove the xino file and whiteout bases if necessary.
-+  See struct.txt.
-+
-+o rw --> ro: Confirm the modifying branch is not busy
-+  Aufs rejects the request if any of these conditions are true.
-+  - 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 --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
-+#
-+# 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/>.
-+
-+Policies to Select One among Multiple Writable Branches
-+----------------------------------------------------------------------
-+When the number of writable branch is more than one, aufs has to decide
-+the target branch for file creation or copy-up. By default, the highest
-+writable branch which has the parent (or ancestor) dir of the target
-+file is chosen (top-down-parent policy).
-+By user's request, aufs implements some other policies to select the
-+writable branch, for file creation several policies, round-robin,
-+most-free-space, and other policies. For copy-up, top-down-parent,
-+bottom-up-parent, bottom-up and others.
-+
-+As expected, the round-robin policy selects the branch in circular. When
-+you have two writable branches and creates 10 new files, 5 files will be
-+created for each branch. mkdir(2) systemcall is an exception. When you
-+create 10 new directories, all will be created on the same branch.
-+And the most-free-space policy selects the one which has most free
-+space among the writable branches. The amount of free space will be
-+checked by aufs internally, and users can specify its time interval.
-+
-+The policies for copy-up is more simple,
-+top-down-parent is equivalent to the same named on in create policy,
-+bottom-up-parent selects the writable branch where the parent dir
-+exists and the nearest upper one from the copyup-source,
-+bottom-up selects the nearest upper writable branch from the
-+copyup-source, regardless the existence of the parent dir.
-+
-+There are some rules or exceptions to apply these policies.
-+- If there is a readonly branch above the policy-selected branch and
-+  the parent dir is marked as opaque (a variation of whiteout), or the
-+  target (creating) file is whiteout-ed on the upper readonly branch,
-+  then the result of the policy is ignored and the target file will be
-+  created on the nearest upper writable branch than the readonly branch.
-+- If there is a writable branch above the policy-selected branch and
-+  the parent dir is marked as opaque or the target file is whiteouted
-+  on the branch, then the result of the policy is ignored and the target
-+  file will be created on the highest one among the upper writable
-+  branches who has diropq or whiteout. In case of whiteout, aufs removes
-+  it as usual.
-+- link(2) and rename(2) systemcalls are exceptions in every policy.
-+  They try selecting the branch where the source exists as possible
-+  since copyup a large file will take long time. If it can't be,
-+  ie. the branch where the source exists is readonly, then they will
-+  follow the copyup policy.
-+- There is an exception for rename(2) when the target exists.
-+  If the rename target exists, aufs compares the index of the branches
-+  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 --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.
-+//
-+// 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/>.
-+
-+digraph G {
-+node [shape=box];
-+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"];
-+
-+node [shape=oval];
-+
-+aufs_rename -> whinfo [label="store/remove"];
-+
-+node [shape=oval];
-+inode_list [label="h_inum list in branch\ncache"];
-+
-+node [shape=box];
-+whinode [label="h_inum list file"];
-+
-+node [shape=oval];
-+brmgmt [label="br_add/del/mod/umount"];
-+
-+brmgmt -> inode_list [label="create/remove"];
-+brmgmt -> whinode [label="load/store"];
-+
-+inode_list -> whinode [style=dashed,dir=both];
-+
-+aufs_rename -> inode_list [label="add/del"];
-+
-+aufs_lookup -> inode_list [label="search"];
-+
-+aufs_lookup -> whinfo [label="load/remove"];
-+}
-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
-+#
-+# 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/>.
-+
-+Special handling for renaming a directory (DIRREN)
-+----------------------------------------------------------------------
-+First, let's assume we have a simple usecase.
-+
-+- /u = /rw + /ro
-+- /rw/dirA exists
-+- /ro/dirA and /ro/dirA/file exist too
-+- there is no dirB on both branches
-+- a user issues rename("dirA", "dirB")
-+
-+Now, what should aufs behave against this rename(2)?
-+There are a few possible cases.
-+
-+A. returns EROFS.
-+   since dirA exists on a readonly branch which cannot be renamed.
-+B. returns EXDEV.
-+   it is possible to copy-up dirA (only the dir itself), but the child
-+   entries ("file" in this case) should not be. it must be a bad
-+   approach to copy-up recursively.
-+C. returns a success.
-+   even the branch /ro is readonly, aufs tries renaming it. Obviously it
-+   is a violation of aufs' policy.
-+D. construct an extra information which indicates that /ro/dirA should
-+   be handled as the name of dirB.
-+   overlayfs has a similar feature called REDIRECT.
-+
-+Until now, aufs implements the case B only which returns EXDEV, and
-+expects the userspace application behaves like mv(1) which tries
-+issueing rename(2) recursively.
-+
-+A new aufs feature called DIRREN is introduced which implements the case
-+D. There are several "extra information" added.
-+
-+1. detailed info per renamed directory
-+   path: /rw/dirB/$AUFS_WH_DR_INFO_PFX.<lower branch-id>
-+2. the inode-number list of directories on a branch
-+   path: /rw/dirB/$AUFS_WH_DR_BRHINO
-+
-+The filename of "detailed info per directory" represents the lower
-+branch, and its format is
-+- a type of the branch id
-+  one of these.
-+  + uuid (not implemented yet)
-+  + fsid
-+  + dev
-+- the inode-number of the branch root dir
-+
-+And it contains these info in a single regular file.
-+- magic number
-+- branch's inode-number of the logically renamed dir
-+- the name of the before-renamed dir
-+
-+The "detailed info per directory" file is created in aufs rename(2), and
-+loaded in any lookup.
-+The info is considered in lookup for the matching case only. Here
-+"matching" means that the root of branch (in the info filename) is same
-+to the current looking-up branch. After looking-up the before-renamed
-+name, the inode-number is compared. And the matched dentry is used.
-+
-+The "inode-number list of directories" is a regular file which contains
-+simply the inode-numbers on the branch. The file is created or updated
-+in removing the branch, and loaded in adding the branch. Its lifetime is
-+equal to the branch.
-+The list is referred in lookup, and when the current target inode is
-+found in the list, the aufs tries loading the "detailed info per
-+directory" and get the changed and valid name of the dir.
-+
-+Theoretically these "extra informaiton" may be able to be put into XATTR
-+in the dir inode. But aufs doesn't choose this way because
-+1. XATTR may not be supported by the branch (or its configuration)
-+2. XATTR may have its size limit.
-+3. XATTR may be less easy to convert than a regular file, when the
-+   format of the info is changed in the future.
-+At the same time, I agree that the regular file approach is much slower
-+than XATTR approach. So, in the future, aufs may take the XATTR or other
-+better approach.
-+
-+This DIRREN feature is enabled by aufs configuration, and is activated
-+by a new mount option.
-+
-+For the more complicated case, there is a work with UDBA option, which
-+is to dected the direct access to the branches (by-passing aufs) and to
-+maintain the cashes in aufs. Since a single cached aufs dentry may
-+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 --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
-+#
-+# 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/>.
-+
-+File-based Hierarchical Storage Management (FHSM)
-+----------------------------------------------------------------------
-+Hierarchical Storage Management (or HSM) is a well-known feature in the
-+storage world. Aufs provides this feature as file-based with multiple
-+writable branches, based upon the principle of "Colder, the Lower".
-+Here the word "colder" means that the less used files, and "lower" means
-+that the position in the order of the stacked branches vertically.
-+These multiple writable branches are prioritized, ie. the topmost one
-+should be the fastest drive and be used heavily.
-+
-+o Characters in aufs FHSM story
-+- aufs itself and a new branch attribute.
-+- a new ioctl interface to move-down and to establish a connection with
-+  the daemon ("move-down" is a converse of "copy-up").
-+- userspace tool and daemon.
-+
-+The userspace daemon establishes a connection with aufs and waits for
-+the notification. The notified information is very similar to struct
-+statfs containing the number of consumed blocks and inodes.
-+When the consumed blocks/inodes of a branch exceeds the user-specified
-+upper watermark, the daemon activates its move-down process until the
-+consumed blocks/inodes reaches the user-specified lower watermark.
-+
-+The actual move-down is done by aufs based upon the request from
-+user-space since we need to maintain the inode number and the internal
-+pointer arrays in aufs.
-+
-+Currently aufs FHSM handles the regular files only. Additionally they
-+must not be hard-linked nor pseudo-linked.
-+
-+
-+o Cowork of aufs and the user-space daemon
-+  During the userspace daemon established the connection, aufs sends a
-+  small notification to it whenever aufs writes something into the
-+  writable branch. But it may cost high since aufs issues statfs(2)
-+  internally. So user can specify a new option to cache the
-+  info. Actually the notification is controlled by these factors.
-+  + the specified cache time.
-+  + classified as "force" by aufs internally.
-+  Until the specified time expires, aufs doesn't send the info
-+  except the forced cases. When aufs decide forcing, the info is always
-+  notified to userspace.
-+  For example, the number of free inodes is generally large enough and
-+  the shortage of it happens rarely. So aufs doesn't force the
-+  notification when creating a new file, directory and others. This is
-+  the typical case which aufs doesn't force.
-+  When aufs writes the actual filedata and the files consumes any of new
-+  blocks, the aufs forces notifying.
-+
-+
-+o Interfaces in aufs
-+- New branch attribute.
-+  + fhsm
-+    Specifies that the branch is managed by FHSM feature. In other word,
-+    participant in the FHSM.
-+    When nofhsm is set to the branch, it will not be the source/target
-+    branch of the move-down operation. This attribute is set
-+    independently from coo and moo attributes, and if you want full
-+    FHSM, you should specify them as well.
-+- New mount option.
-+  + fhsm_sec
-+    Specifies a second to suppress many less important info to be
-+    notified.
-+- New ioctl.
-+  + AUFS_CTL_FHSM_FD
-+    create a new file descriptor which userspace can read the notification
-+    (a subset of struct statfs) from aufs.
-+- Module parameter 'brs'
-+  It has to be set to 1. Otherwise the new mount option 'fhsm' will not
-+  be set.
-+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
-+  When there are two or more branches with fhsm attributes,
-+  /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
-+  terminates it. As a result of remounting and branch-manipulation, the
-+  number of branches with fhsm attribute can be one. In this case,
-+  /sbin/mount.aufs will terminate the user-space daemon.
-+
-+
-+Finally the operation is done as these steps in kernel-space.
-+- make sure that,
-+  + no one else is using the file.
-+  + the file is not hard-linked.
-+  + the file is not pseudo-linked.
-+  + the file is a regular file.
-+  + the parent dir is not opaqued.
-+- find the target writable branch.
-+- make sure the file is not whiteout-ed by the upper (than the target)
-+  branch.
-+- make the parent dir on the target branch.
-+- mutex lock the inode on the branch.
-+- unlink the whiteout on the target branch (if exists).
-+- lookup and create the whiteout-ed temporary name on the target branch.
-+- copy the file as the whiteout-ed temporary name on the target branch.
-+- rename the whiteout-ed temporary name to the original name.
-+- unlink the file on the source branch.
-+- maintain the internal pointer array and the external inode number
-+  table (XINO).
-+- maintain the timestamps and other attributes of the parent dir and the
-+  file.
-+
-+And of course, in every step, an error may happen. So the operation
-+should restore the original file state after an error happens.
-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
-+#
-+# 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/>.
-+
-+mmap(2) -- File Memory Mapping
-+----------------------------------------------------------------------
-+In aufs, the file-mapped pages are handled by a branch fs directly, no
-+interaction with aufs. It means aufs_mmap() calls the branch fs's
-+->mmap().
-+This approach is simple and good, but there is one problem.
-+Under /proc, several entries show the mmapped files by its path (with
-+device and inode number), and the printed path will be the path on the
-+branch fs's instead of virtual aufs's.
-+This is not a problem in most cases, but some utilities lsof(1) (and its
-+user) may expect the path on aufs.
-+
-+To address this issue, aufs adds a new member called vm_prfile in struct
-+vm_area_struct (and struct vm_region). The original vm_file points to
-+the file on the branch fs in order to handle everything correctly as
-+usual. The new vm_prfile points to a virtual file in aufs, and the
-+show-functions in procfs refers to vm_prfile if it is set.
-+Also we need to maintain several other places where touching vm_file
-+such like
-+- fork()/clone() copies vma and the reference count of vm_file is
-+  incremented.
-+- merging vma maintains the ref count too.
-+
-+This is not a good approach. It just fakes the printed path. But it
-+leaves all behaviour around f_mapping unchanged. This is surely an
-+advantage.
-+Actually aufs had adopted another complicated approach which calls
-+generic_file_mmap() and handles struct vm_operations_struct. In this
-+approach, aufs met a hard problem and I could not solve it without
-+switching the approach.
-+
-+There may be one more another approach which is
-+- bind-mount the branch-root onto the aufs-root internally
-+- grab the new vfsmount (ie. struct mount)
-+- lazy-umount the branch-root internally
-+- in open(2) the aufs-file, open the branch-file with the hidden
-+  vfsmount (instead of the original branch's vfsmount)
-+- ideally this "bind-mount and lazy-umount" should be done atomically,
-+  but it may be possible from userspace by the mount helper.
-+
-+Adding the internal hidden vfsmount and using it in opening a file, the
-+file path under /proc will be printed correctly. This approach looks
-+smarter, but is not possible I am afraid.
-+- aufs-root may be bind-mount later. when it happens, another hidden
-+  vfsmount will be required.
-+- it is hard to get the chance to bind-mount and lazy-umount
-+  + in kernel-space, FS can have vfsmount in open(2) via
-+    file->f_path, and aufs can know its vfsmount. But several locks are
-+    already acquired, and if aufs tries to bind-mount and lazy-umount
-+    here, then it may cause a deadlock.
-+  + in user-space, bind-mount doesn't invoke the mount helper.
-+- since /proc shows dev and ino, aufs has to give vma these info. it
-+  means a new member vm_prinode will be necessary. this is essentially
-+  equivalent to vm_prfile described above.
-+
-+I have to give up this "looks-smater" approach.
-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
-+#
-+# 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/>.
-+
-+Listing XATTR/EA and getting the value
-+----------------------------------------------------------------------
-+For the inode standard attributes (owner, group, timestamps, etc.), aufs
-+shows the values from the topmost existing file. This behaviour is good
-+for the non-dir entries since the bahaviour exactly matches the shown
-+information. But for the directories, aufs considers all the same named
-+entries on the lower branches. Which means, if one of the lower entry
-+rejects readdir call, then aufs returns an error even if the topmost
-+entry allows it. This behaviour is necessary to respect the branch fs's
-+security, but can make users confused since the user-visible standard
-+attributes don't match the behaviour.
-+To address this issue, aufs has a mount option called dirperm1 which
-+checks the permission for the topmost entry only, and ignores the lower
-+entry's permission.
-+
-+A similar issue can happen around XATTR.
-+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
-+always set. Otherwise these very unpleasant situation would happen.
-+- listxattr(2) may return the duplicated entries.
-+- users may not be able to remove or reset the XATTR forever,
-+
-+
-+XATTR/EA support in the internal (copy,move)-(up,down)
-+----------------------------------------------------------------------
-+Generally the extended attributes of inode are categorized as these.
-+- "security" for LSM and capability.
-+- "system" for posix ACL, 'acl' mount option is required for the branch
-+  fs generally.
-+- "trusted" for userspace, CAP_SYS_ADMIN is required.
-+- "user" for userspace, 'user_xattr' mount option is required for the
-+  branch fs generally.
-+
-+Moreover there are some other categories. Aufs handles these rather
-+unpopular categories as the ordinary ones, ie. there is no special
-+condition nor exception.
-+
-+In copy-up, the support for XATTR on the dst branch may differ from the
-+src branch. In this case, the copy-up operation will get an error and
-+the original user operation which triggered the copy-up will fail. It
-+can happen that even all copy-up will fail.
-+When both of src and dst branches support XATTR and if an error occurs
-+during copying XATTR, then the copy-up should fail obviously. That is a
-+good reason and aufs should return an error to userspace. But when only
-+the src branch support that XATTR, aufs should not return an error.
-+For example, the src branch supports ACL but the dst branch doesn't
-+because the dst branch may natively un-support it or temporary
-+un-support it due to "noacl" mount option. Of course, the dst branch fs
-+may NOT return an error even if the XATTR is not supported. It is
-+totally up to the branch fs.
-+
-+Anyway when the aufs internal copy-up gets an error from the dst branch
-+fs, then aufs tries removing the just copied entry and returns the error
-+to the userspace. The worst case of this situation will be all copy-up
-+will fail.
-+
-+For the copy-up operation, there two basic approaches.
-+- copy the specified XATTR only (by category above), and return the
-+  error unconditionally if it happens.
-+- copy all XATTR, and ignore the error on the specified category only.
-+
-+In order to support XATTR and to implement the correct behaviour, aufs
-+chooses the latter approach and introduces some new branch attributes,
-+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
-+They correspond to the XATTR namespaces (see above). Additionally, to be
-+convenient, "icex" is also provided which means all "icex*" attributes
-+are set (here the word "icex" stands for "ignore copy-error on XATTR").
-+
-+The meaning of these attributes is to ignore the error from setting
-+XATTR on that branch.
-+Note that aufs tries copying all XATTR unconditionally, and ignores the
-+error from the dst branch according to the specified attributes.
-+
-+Some XATTR may have its default value. The default value may come from
-+the parent dir or the environment. If the default value is set at the
-+file creating-time, it will be overwritten by copy-up.
-+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 --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
-+#
-+# 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 Aufs via NFS
-+----------------------------------------------------------------------
-+Here is an approach.
-+- like xino/xib, add a new file 'xigen' which stores aufs inode
-+  generation.
-+- iget_locked(): initialize aufs inode generation for a new inode, and
-+  store it in xigen file.
-+- destroy_inode(): increment aufs inode generation and store it in xigen
-+  file. it is necessary even if it is not unlinked, because any data of
-+  inode may be changed by UDBA.
-+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
-+  build file handle by
-+  + branch id (4 bytes)
-+  + superblock generation (4 bytes)
-+  + inode number (4 or 8 bytes)
-+  + parent dir inode number (4 or 8 bytes)
-+  + inode generation (4 bytes))
-+  + return value of exportfs_encode_fh() for the parent on a branch (4
-+    bytes)
-+  + file handle for a branch (by exportfs_encode_fh())
-+- fh_to_dentry():
-+  + find the index of a branch from its id in handle, and check it is
-+    still exist in aufs.
-+  + 1st level: get the inode number from handle and search it in cache.
-+  + 2nd level: if not found in cache, get the parent inode number from
-+    the handle and search it in cache. and then open the found parent
-+    dir, find the matching inode number by vfs_readdir() and get its
-+    name, and call lookup_one_len() for the target dentry.
-+  + 3rd level: if the parent dir is not cached, call
-+    exportfs_decode_fh() for a branch and get the parent on a branch,
-+    build a pathname of it, convert it a pathname in aufs, call
-+    path_lookup(). now aufs gets a parent dir dentry, then handle it as
-+    the 2nd level.
-+  + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
-+    for every branch, but not itself. to get this, (currently) aufs
-+    searches in current->nsproxy->mnt_ns list. it may not be a good
-+    idea, but I didn't get other approach.
-+  + test the generation of the gotten inode.
-+- every inode operation: they may get EBUSY due to UDBA. in this case,
-+  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 --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
-+#
-+# 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/>.
-+
-+Show Whiteout Mode (shwh)
-+----------------------------------------------------------------------
-+Generally aufs hides the name of whiteouts. But in some cases, to show
-+them is very useful for users. For instance, creating a new middle layer
-+(branch) by merging existing layers.
-+
-+(borrowing aufs1 HOW-TO from a user, Michael Towers)
-+When you have three branches,
-+- Bottom: 'system', squashfs (underlying base system), read-only
-+- Middle: 'mods', squashfs, read-only
-+- Top: 'overlay', ram (tmpfs), read-write
-+
-+The top layer is loaded at boot time and saved at shutdown, to preserve
-+the changes made to the system during the session.
-+When larger changes have been made, or smaller changes have accumulated,
-+the size of the saved top layer data grows. At this point, it would be
-+nice to be able to merge the two overlay branches ('mods' and 'overlay')
-+and rewrite the 'mods' squashfs, clearing the top layer and thus
-+restoring save and load speed.
-+
-+This merging is simplified by the use of another aufs mount, of just the
-+two overlay branches using the 'shwh' option.
-+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
-+	aufs /livesys/merge_union
-+
-+A merged view of these two branches is then available at
-+/livesys/merge_union, and the new feature is that the whiteouts are
-+visible!
-+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
-+writing to all branches. Also the default mode for all branches is 'ro'.
-+It is now possible to save the combined contents of the two overlay
-+branches to a new squashfs, e.g.:
-+# mksquashfs /livesys/merge_union /path/to/newmods.squash
-+
-+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 --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
-+#
-+# 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 FS operations
-+----------------------------------------------------------------------
-+Generally FS operations (struct inode_operations, struct
-+address_space_operations, struct file_operations, etc.) are defined as
-+"static const", but it never means that FS have only one set of
-+operation. Some FS have multiple sets of them. For instance, ext2 has
-+three sets, one for XIP, for NOBH, and for normal.
-+Since aufs overrides and redirects these operations, sometimes aufs has
-+to change its behaviour according to the branch FS type. More importantly
-+VFS acts differently if a function (member in the struct) is set or
-+not. It means aufs should have several sets of operations and select one
-+among them according to the branch FS definition.
-+
-+In order to solve this problem and not to affect the behaviour of VFS,
-+aufs defines these operations dynamically. For instance, aufs defines
-+dummy direct_IO function for struct address_space_operations, but it may
-+not be set to the address_space_operations actually. When the branch FS
-+doesn't have it, aufs doesn't set it to its address_space_operations
-+while the function definition itself is still alive. So the behaviour
-+itself will not change, and it will return an error when direct_IO is
-+not set.
-+
-+The lifetime of these dynamically generated operation object is
-+maintained by aufs branch object. When the branch is removed from aufs,
-+the reference counter of the object is decremented. When it reaches
-+zero, the dynamically generated operation object will be freed.
-+
-+This approach is designed to support AIO (io_submit), Direct I/O and
-+XIP (DAX) mainly.
-+Currently this approach is applied to address_space_operations for
-+regular files only.
-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
-+
- 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;
-+
-+	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);
-+
- /* 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.
-+
-+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
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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 */
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+config AUFS_BDEV_LOOP
-+	bool
-+	depends on BLK_DEV_LOOP
-+	default y
-+	help
-+	Automatic configuration for internal use.
-+	Convert =[ym] into =y.
-+
-+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
-+
-+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
-+
-+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
-+
-+# 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 */
-+/*
-+ * 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/>.
-+ */
-+
-+/*
-+ * all header files
-+ */
-+
-+#ifndef __AUFS_H__
-+#define __AUFS_H__
-+
-+#ifdef __KERNEL__
-+
-+#define AuStub(type, name, body, ...) \
-+	static inline type name(__VA_ARGS__) { body; }
-+
-+#define AuStubVoid(name, ...) \
-+	AuStub(void, name, , __VA_ARGS__)
-+#define AuStubInt0(name, ...) \
-+	AuStub(int, name, return 0, __VA_ARGS__)
-+
-+#include "debug.h"
-+
-+#include "branch.h"
-+#include "cpup.h"
-+#include "dcsub.h"
-+#include "dbgaufs.h"
-+#include "dentry.h"
-+#include "dir.h"
-+#include "dirren.h"
-+#include "dynop.h"
-+#include "file.h"
-+#include "fstype.h"
-+#include "hbl.h"
-+#include "inode.h"
-+#include "lcnt.h"
-+#include "loop.h"
-+#include "module.h"
-+#include "opts.h"
-+#include "rwsem.h"
-+#include "super.h"
-+#include "sysaufs.h"
-+#include "vfsub.h"
-+#include "whout.h"
-+#include "wkq.h"
-+
-+#endif /* __KERNEL__ */
-+#endif /* __AUFS_H__ */
-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
-+/*
-+ * 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/>.
-+ */
-+
-+/*
-+ * branch management
-+ */
-+
-+#include <linux/compat.h>
-+#include <linux/statfs.h>
-+#include "aufs.h"
-+
-+/*
-+ * free a single branch
-+ */
-+static void au_br_do_free(struct au_branch *br)
-+{
-+	int i;
-+	struct au_wbr *wbr;
-+	struct au_dykey **key;
-+
-+	au_hnotify_fin_br(br);
-+	/* always, regardless the mount option */
-+	au_dr_hino_free(&br->br_dirren);
-+	au_xino_put(br);
-+
-+	AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0));
-+	au_lcnt_fin(&br->br_nfiles, /*do_sync*/0);
-+	AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0));
-+	au_lcnt_fin(&br->br_count, /*do_sync*/0);
-+
-+	wbr = br->br_wbr;
-+	if (wbr) {
-+		for (i = 0; i < AuBrWh_Last; i++)
-+			dput(wbr->wbr_wh[i]);
-+		AuDebugOn(atomic_read(&wbr->wbr_wh_running));
-+		AuRwDestroy(&wbr->wbr_wh_rwsem);
-+	}
-+
-+	if (br->br_fhsm) {
-+		au_br_fhsm_fin(br->br_fhsm);
-+		au_kfree_try_rcu(br->br_fhsm);
-+	}
-+
-+	key = br->br_dykey;
-+	for (i = 0; i < AuBrDynOp; i++, key++)
-+		if (*key)
-+			au_dy_put(*key);
-+		else
-+			break;
-+
-+	/* recursive lock, s_umount of branch's */
-+	/* synchronize_rcu(); */ /* why? */
-+	lockdep_off();
-+	path_put(&br->br_path);
-+	lockdep_on();
-+	au_kfree_rcu(wbr);
-+	au_lcnt_wait_for_fin(&br->br_nfiles);
-+	au_lcnt_wait_for_fin(&br->br_count);
-+	/* I don't know why, but percpu_refcount requires this */
-+	/* synchronize_rcu(); */
-+	au_kfree_rcu(br);
-+}
-+
-+/*
-+ * frees all branches
-+ */
-+void au_br_free(struct au_sbinfo *sbinfo)
-+{
-+	aufs_bindex_t bmax;
-+	struct au_branch **br;
-+
-+	AuRwMustWriteLock(&sbinfo->si_rwsem);
-+
-+	bmax = sbinfo->si_bbot + 1;
-+	br = sbinfo->si_branch;
-+	while (bmax--)
-+		au_br_do_free(*br++);
-+}
-+
-+/*
-+ * find the index of a branch which is specified by @br_id.
-+ */
-+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
-+{
-+	aufs_bindex_t bindex, bbot;
-+
-+	bbot = au_sbbot(sb);
-+	for (bindex = 0; bindex <= bbot; bindex++)
-+		if (au_sbr_id(sb, bindex) == br_id)
-+			return bindex;
-+	return -1;
-+}
-+
-+/* ---------------------------------------------------------------------- */
-+
-+/*
-+ * add a branch
-+ */
-+
-+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
-+			struct dentry *h_root)
-+{
-+	if (unlikely(h_adding == h_root
-+		     || au_test_loopback_overlap(sb, h_adding)))
-+		return 1;
-+	if (h_adding->d_sb != h_root->d_sb)
-+		return 0;
-+	return au_test_subdir(h_adding, h_root)
-+		|| au_test_subdir(h_root, h_adding);
-+}
-+
-+/*
-+ * returns a newly allocated branch. @new_nbranch is a number of branches
-+ * after adding a branch.
-+ */
-+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
-+				     int perm)
-+{
-+	struct au_branch *add_branch;
-+	struct dentry *root;
-+	struct inode *inode;
-+	int err;
-+
-+	err = -ENOMEM;
-+	add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
-+	if (unlikely(!add_branch))
-+		goto out;
-+	add_branch->br_xino = au_xino_alloc(/*nfile*/1);
-+	if (unlikely(!add_branch->br_xino))
-+		goto out_br;
-+	err = au_hnotify_init_br(add_branch, perm);
-+	if (unlikely(err))
-+		goto out_xino;
-+
-+	if (au_br_writable(perm)) {
-+		/* may be freed separately at changing the branch permission */
-+		add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
-+					     GFP_NOFS);
-+		if (unlikely(!add_branch->br_wbr))
-+			goto out_hnotify;
-+	}
-+
-+	if (au_br_fhsm(perm)) {
-+		err = au_fhsm_br_alloc(add_branch);
-+		if (unlikely(err))
-+			goto out_wbr;
-+	}
-+
-+	root = sb->s_root;
-+	err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
-+	if (!err)
-+		err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
-+	if (!err) {
-+		inode = d_inode(root);
-+		err = au_hinode_realloc(au_ii(inode), new_nbranch,
-+					/*may_shrink*/0);
-+	}
-+	if (!err)
-+		return add_branch; /* success */
-+
-+out_wbr:
-+	au_kfree_rcu(add_branch->br_wbr);
-+out_hnotify:
-+	au_hnotify_fin_br(add_branch);
-+out_xino:
-+	au_xino_put(add_branch);
-+out_br:
-+	au_kfree_rcu(add_branch);
-+out:
-+	return ERR_PTR(err);
-+}
-+
-+/*
-+ * test if the branch permission is legal or not.
-+ */
-+static int test_br(struct inode *inode, int brperm, char *path)
-+{
-+	int err;
-+
-+	err = (au_br_writable(brperm) && IS_RDONLY(inode));
-+	if (!err)
-+		goto out;
-+
-+	err = -EINVAL;
-+	pr_err("write permission for readonly mount or inode, %s\n", path);
-+
-+out:
-+	return err;
-+}
-+
-+/*
-+ * returns:
-+ * 0: success, the caller will add it
-+ * plus: success, it is already unified, the caller should ignore it
-+ * minus: error
-+ */
-+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
-+{
-+	int err;
-+	aufs_bindex_t bbot, bindex;
-+	struct dentry *root, *h_dentry;
-+	struct inode *inode, *h_inode;
-+
-+	root = sb->s_root;
-+	bbot = au_sbbot(sb);
-+	if (unlikely(bbot >= 0
-+		     && au_find_dbindex(root, add->path.dentry) >= 0)) {
-+		err = 1;
-+		if (!remount) {
-+			err = -EINVAL;
-+			pr_err("%s duplicated\n", add->pathname);
-+		}
-+		goto out;
-+	}
-+
-+	err = -ENOSPC; /* -E2BIG; */
-+	if (unlikely(AUFS_BRANCH_MAX <= add->bindex
-+		     || AUFS_BRANCH_MAX - 1 <= bbot)) {
-+		pr_err("number of branches exceeded %s\n", add->pathname);
-+		goto out;
-+	}
-+
-+	err = -EDOM;
-+	if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
-+		pr_err("bad index %d\n", add->bindex);
-+		goto out;
-+	}
-+
-+	inode = d_inode(add->path.dentry);
-+	err = -ENOENT;
-+	if (unlikely(!inode->i_nlink)) {
-+		pr_err("no existence %s\n", add->pathname);
-+		goto out;
-+	}
-+
-+	err = -EINVAL;
-+	if (unlikely(inode->i_sb == sb)) {
-+		pr_err("%s must be outside\n", add->pathname);
-+		goto out;
-+	}
-+
-+	if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
-+		pr_err("unsupported filesystem, %s (%s)\n",
-+		       add->pathname, au_sbtype(inode->i_sb));
-+		goto out;
-+	}
-+
-+	if (unlikely(inode->i_sb->s_stack_depth)) {
-+		pr_err("already stacked, %s (%s)\n",
-+		       add->pathname, au_sbtype(inode->i_sb));
-+		goto out;
-+	}
-+
-+	err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
-+	if (unlikely(err))
-+		goto out;
-+
-+	if (bbot < 0)
-+		return 0; /* success */
-+
-+	err = -EINVAL;
-+	for (bindex = 0; bindex <= bbot; bindex++)
-+		if (unlikely(test_overlap(sb, add->path.dentry,
-+					  au_h_dptr(root, bindex)))) {
-+			pr_err("%s is overlapped\n", add->pathname);
-+			goto out;
-+		}
-+
-+	err = 0;
-+	if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
-+		h_dentry = au_h_dptr(root, 0);
-+		h_inode = d_inode(h_dentry);
-+		if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
-+		    || !uid_eq(h_inode->i_uid, inode->i_uid)
-+		    || !gid_eq(h_inode->i_gid, inode->i_gid))
-+			pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
-+				add->pathname,
-+				i_uid_read(inode), i_gid_read(inode),
-+				(inode->i_mode & S_IALLUGO),
-+				i_uid_read(h_inode), i_gid_read(h_inode),
-+				(h_inode->i_mode & S_IALLUGO));
-+	}
-+
-+out:
-+	return err;
-+}
-+
-+/*
-+ * initialize or clean the whiteouts for an adding branch
-+ */
-+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
-+			 int new_perm)
-+{
-+	int err, old_perm;
-+	aufs_bindex_t bindex;
-+	struct inode *h_inode;
-+	struct au_wbr *wbr;
-+	struct au_hinode *hdir;
-+	struct dentry *h_dentry;
-+
-+	err = vfsub_mnt_want_write(au_br_mnt(br));
-+	if (unlikely(err))
-+		goto out;
-+
-+	wbr = br->br_wbr;
-+	old_perm = br->br_perm;
-+	br->br_perm = new_perm;
-+	hdir = NULL;
-+	h_inode = NULL;
-+	bindex = au_br_index(sb, br->br_id);
-+	if (0 <= bindex) {
-+		hdir = au_hi(d_inode(sb->s_root), bindex);
-+		au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
-+	} else {
-+		h_dentry = au_br_dentry(br);
-+		h_inode = d_inode(h_dentry);
-+		inode_lock_nested(h_inode, AuLsc_I_PARENT);
-+	}
-+	if (!wbr)
-+		err = au_wh_init(br, sb);
-+	else {
-+		wbr_wh_write_lock(wbr);
-+		err = au_wh_init(br, sb);
-+		wbr_wh_write_unlock(wbr);
-+	}
-+	if (hdir)
-+		au_hn_inode_unlock(hdir);
-+	else
-+		inode_unlock(h_inode);
-+	vfsub_mnt_drop_write(au_br_mnt(br));
-+	br->br_perm = old_perm;
-+
-+	if (!err && wbr && !au_br_writable(new_perm)) {
-+		au_kfree_rcu(wbr);
-+		br->br_wbr = NULL;
-+	}
-+
-+out:
-+	return err;
-+}
-+
-+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
-+		       int perm)
-+{
-+	int err;
-+	struct kstatfs kst;
-+	struct au_wbr *wbr;
-+
-+	wbr = br->br_wbr;
-+	au_rw_init(&wbr->wbr_wh_rwsem);
-+	atomic_set(&wbr->wbr_wh_running, 0);
-+
-+	/*
-+	 * a limit for rmdir/rename a dir
-+	 * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
-+	 */
-+	err = vfs_statfs(&br->br_path, &kst);
-+	if (unlikely(err))
-+		goto out;
-+	err = -EINVAL;
-+	if (kst.f_namelen >= NAME_MAX)
-+		err = au_br_init_wh(sb, br, perm);
-+	else
-+		pr_err("%pd(%s), unsupported namelen %ld\n",
-+		       au_br_dentry(br),
-+		       au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
-+
-+out:
-+	return err;
-+}
-+
-+/* initialize a new branch */
-+static int au_br_init(struct au_branch *br, struct super_block *sb,
-+		      struct au_opt_add *add)
-+{
-+	int err;
-+	struct au_branch *brbase;
-+	struct file *xf;
-+	struct inode *h_inode;
-+
-+	err = 0;
-+	br->br_perm = add->perm;
-+	br->br_path = add->path; /* set first, path_get() later */
-+	spin_lock_init(&br->br_dykey_lock);
-+	au_lcnt_init(&br->br_nfiles, /*release*/NULL);
-+	au_lcnt_init(&br->br_count, /*release*/NULL);
-+	br->br_id = au_new_br_id(sb);
-+	AuDebugOn(br->br_id < 0);
-+
-+	/* always, regardless the given option */
-+	err = au_dr_br_init(sb, br, &add->path);
-+	if (unlikely(err))
-+		goto out_err;
-+
-+	if (au_br_writable(add->perm)) {
-+		err = au_wbr_init(br, sb, add->perm);
-+		if (unlikely(err))
-+			goto out_err;
-+	}
-+
-+	if (au_opt_test(au_mntflags(sb), XINO)) {
-+		brbase = au_sbr(sb, 0);
-+		xf = au_xino_file(brbase->br_xino, /*idx*/-1);
-+		AuDebugOn(!xf);
-+		h_inode = d_inode(add->path.dentry);
-+		err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path);
-+		if (unlikely(err)) {
-+			AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1));
-+			goto out_err;
-+		}
-+	}
-+
-+	sysaufs_br_init(br);
-+	path_get(&br->br_path);
-+	goto out; /* success */
-+
-+out_err:
-+	memset(&br->br_path, 0, sizeof(br->br_path));
-+out:
-+	return err;
-+}
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 89fdbefd1075..0038eb501478 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -338,6 +338,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 c09016257f05..3899fae66d3f 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/
+SPDX-License-Identifier: GPL-2.0
+aufs6.x-rcN base patch
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 9ed4d3868539..c0f45969bcf8 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3365,6 +3365,19 @@ F:	kernel/audit*
+ F:	lib/*audit.c
+ K:	\baudit_[a-z_0-9]\+\b
+ 
++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
 +
-+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
-+			     struct au_branch *br, aufs_bindex_t bbot,
-+			     aufs_bindex_t amount)
+ 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 f8145499da38..333b3915fe86 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -641,6 +641,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 au_branch **brp;
-+
-+	AuRwMustWriteLock(&sbinfo->si_rwsem);
++	struct file *ret;
++	struct loop_device *l;
 +
-+	brp = sbinfo->si_branch + bindex;
-+	memmove(brp + 1, brp, sizeof(*brp) * amount);
-+	*brp = br;
-+	sbinfo->si_bbot++;
-+	if (unlikely(bbot < 0))
-+		sbinfo->si_bbot = 0;
++	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);
 +
-+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
-+			     aufs_bindex_t bbot, aufs_bindex_t amount)
+ /* 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 b813528fb147..78e322b59b8d 100644
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1219,7 +1219,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, *dentry;
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index c80a6acad742..96a562b48ec7 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 5a51315c6678..a4b6ce51848e 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -860,6 +860,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)
 +{
-+	struct au_hdentry *hdp;
-+
-+	AuRwMustWriteLock(&dinfo->di_rwsem);
-+
-+	hdp = au_hdentry(dinfo, bindex);
-+	memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
-+	au_h_dentry_init(hdp);
-+	dinfo->di_bbot++;
-+	if (unlikely(bbot < 0))
-+		dinfo->di_btop = 0;
++	return check_mnt(real_mount(mnt));
 +}
 +
-+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
-+			     aufs_bindex_t bbot, aufs_bindex_t amount)
-+{
-+	struct au_hinode *hip;
+ /*
+  * vfsmount lock must be held for write
+  */
+diff --git a/fs/splice.c b/fs/splice.c
+index 218e24b1ac40..7210ddc5aa81 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -933,7 +933,7 @@ static int warn_unsupported(struct file *file, const char *op)
+ /*
+  * Attempt to initiate a splice from pipe to file.
+  */
+-static ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out,
++ssize_t 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))
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 023f37c60709..96ca249ee1e6 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1104,6 +1104,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);
+@@ -2001,6 +2002,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 08b0d1d9d78b..009f69c4e09d 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -192,6 +192,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);
 +
-+	AuRwMustWriteLock(&iinfo->ii_rwsem);
+ /*
+  * 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);
 +
-+	hip = au_hinode(iinfo, bindex);
-+	memmove(hip + 1, hip, sizeof(*hip) * amount);
-+	au_hinode_init(hip);
-+	iinfo->ii_bbot++;
-+	if (unlikely(bbot < 0))
-+		iinfo->ii_btop = 0;
-+}
+ 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 9dec4861d09f..14583d846864 100644
+--- a/include/linux/splice.h
++++ b/include/linux/splice.h
+@@ -108,4 +108,7 @@ 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;
 +
-+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
-+			 aufs_bindex_t bindex)
-+{
-+	struct dentry *root, *h_dentry;
-+	struct inode *root_inode, *h_inode;
-+	aufs_bindex_t bbot, amount;
++extern ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out,
++			      loff_t *ppos, size_t len, unsigned int flags);
+ #endif
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index 151bd3de5936..2223ee909c10 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 98a031ac2648..a7a2ff2a7f61 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2215,7 +2215,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/fs/proc/nommu.c b/fs/proc/nommu.c
+index c6e7ebc63756..d7ccfd909764 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;
 +
-+	root = sb->s_root;
-+	root_inode = d_inode(root);
-+	bbot = au_sbbot(sb);
-+	amount = bbot + 1 - bindex;
-+	h_dentry = au_br_dentry(br);
-+	au_sbilist_lock();
-+	au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
-+	au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
-+	au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
-+	au_set_h_dptr(root, bindex, dget(h_dentry));
-+	h_inode = d_inode(h_dentry);
-+	au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
-+	au_sbilist_unlock();
-+}
++		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 3f78ebbb795f..f96ec77db39e 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -273,7 +273,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
+ 	const char *name = NULL;
+ 
+ 	if (file) {
+-		const struct inode *inode = file_user_inode(vma->vm_file);
++		const struct inode *inode
++			= file_inode(file = vma_pr_or_file(vma));
+ 
+ 		dev = inode->i_sb->s_dev;
+ 		ino = inode->i_ino;
+@@ -2701,7 +2702,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;
+ 	char buffer[64];
+ 	struct mempolicy *pol;
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index bce674533000..b12b5a75c799 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;
 +
-+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
-+{
-+	int err;
-+	aufs_bindex_t bbot, add_bindex;
-+	struct dentry *root, *h_dentry;
-+	struct inode *root_inode;
-+	struct au_branch *add_branch;
++		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 f5a97dec5169..a5b0edc8e290 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2432,6 +2432,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);
 +
-+	root = sb->s_root;
-+	root_inode = d_inode(root);
-+	IMustLock(root_inode);
-+	IiMustWriteLock(root_inode);
-+	err = test_add(sb, add, remount);
-+	if (unlikely(err < 0))
-+		goto out;
-+	if (err) {
-+		err = 0;
-+		goto out; /* success */
-+	}
++#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__)
 +
-+	bbot = au_sbbot(sb);
-+	add_branch = au_br_alloc(sb, bbot + 2, add->perm);
-+	err = PTR_ERR(add_branch);
-+	if (IS_ERR(add_branch))
-+		goto out;
++#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);
 +
-+	err = au_br_init(add_branch, sb, add);
-+	if (unlikely(err)) {
-+		au_br_do_free(add_branch);
-+		goto out;
-+	}
++#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 */
 +
-+	add_bindex = add->bindex;
-+	sysaufs_brs_del(sb, add_bindex);	/* remove successors */
-+	au_br_do_add(sb, add_branch, add_bindex);
-+	sysaufs_brs_add(sb, add_bindex);	/* append successors */
-+	dbgaufs_brs_add(sb, add_bindex, /*topdown*/0);	/* rename successors */
++#else
 +
-+	h_dentry = add->path.dentry;
-+	if (!add_bindex) {
-+		au_cpup_attr_all(root_inode, /*force*/1);
-+		sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
-+	} else
-+		au_add_nlink(root_inode, d_inode(h_dentry));
++#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)
 +
-+out:
-+	return err;
-+}
++#ifndef CONFIG_MMU
++#define vmr_pr_or_file(region)		(region)->vm_file
++#define vmr_fput(region)		fput((region)->vm_file)
++#endif /* !CONFIG_MMU */
 +
-+/* ---------------------------------------------------------------------- */
++#endif /* CONFIG_AUFS_FS */
 +
-+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
-+				       unsigned long long max __maybe_unused,
-+				       void *arg)
-+{
-+	unsigned long long n;
-+	struct file **p, *f;
-+	struct hlist_bl_head *files;
-+	struct hlist_bl_node *pos;
-+	struct au_finfo *finfo;
+ 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 8b611e13153e..838af328941a 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -527,6 +527,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
+@@ -691,6 +694,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 0d944e92a43f..bc073aaca2dc 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -716,7 +716,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 (vma_is_shared_maywrite(tmp))
+ 				mapping_allow_writable(mapping);
+diff --git a/mm/Makefile b/mm/Makefile
+index e4b5b75aaec9..2ec2544009fb 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -134,3 +134,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 750e779c23db..b84a752ff676 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -3587,7 +3587,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 d89770eaab6b..6bfba84b5ff0 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);
+@@ -2357,7 +2357,7 @@ static 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);
+@@ -2855,7 +2855,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. */
+@@ -2950,7 +2950,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);
+@@ -3012,6 +3012,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);
+@@ -3070,10 +3073,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;
 +
-+	n = 0;
-+	p = a;
-+	files = &au_sbi(sb)->si_files;
-+	hlist_bl_lock(files);
-+	hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
-+		f = finfo->fi_file;
-+		if (file_count(f)
-+		    && !special_file(file_inode(f)->i_mode)) {
-+			get_file(f);
-+			*p++ = f;
-+			n++;
-+			AuDebugOn(n > max);
-+		}
++		new_vma = find_vma(mm, ret);
++		if (!new_vma->vm_prfile)
++			new_vma->vm_prfile = prfile;
++		if (prfile)
++			get_file(prfile);
 +	}
-+	hlist_bl_unlock(files);
++	/*
++	 * 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)
+@@ -3420,7 +3447,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))
+@@ -3434,7 +3461,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 b6dc558d3144..d96655486468 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
++ */
 +
-+	return n;
-+}
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/fs.h>
 +
-+static struct file **au_farray_alloc(struct super_block *sb,
-+				     unsigned long long *max)
++/* #define PRFILE_TRACE */
++static inline void prfile_trace(struct file *f, struct file *pr,
++			      const char func[], int line, const char func2[])
 +{
-+	struct au_sbinfo *sbi;
-+
-+	sbi = au_sbi(sb);
-+	*max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1);
-+	return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
++#ifdef PRFILE_TRACE
++	if (pr)
++		pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
++#endif
 +}
 +
-+static void au_farray_free(struct file **a, unsigned long long max)
++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
++			     int line)
 +{
-+	unsigned long long ull;
++	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
 +
-+	for (ull = 0; ull < max; ull++)
<Skipped 37623 lines>
================================================================

---- gitweb:

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



More information about the pld-cvs-commit mailing list