[packages/kernel] - initial 4.14.0

arekm arekm at pld-linux.org
Sun Nov 12 23:03:33 CET 2017


commit 8b6a494719f4150ce54b9e4d30810ece069c1c73
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sun Nov 12 23:03:17 2017 +0100

    - initial 4.14.0

 ...1-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch |    0
 ...x-shadowed-local-variable-in-unpack_trans.patch |   51 -
 ...parmor-Fix-logical-error-in-verify_header.patch |   32 -
 ...apparmor-Fix-an-error-code-in-aafs_create.patch |   37 -
 ...dundant-condition-prev_ns.-in-label.c-149.patch |   29 -
 ...parmor-add-the-ability-to-mediate-signals.patch |  397 ---
 0007-apparmor-add-mount-mediation.patch            | 1051 ------
 ...eanup-conditional-check-for-label-in-labe.patch |   71 -
 ...d-support-for-absolute-root-view-based-la.patch |   63 -
 ...ke-policy_unpack-able-to-audit-different-.patch |  219 --
 ...rmor-add-more-debug-asserts-to-apparmorfs.patch |   78 -
 ...ve-new_null_profile-to-after-profile-look.patch |  194 --
 ...x-race-condition-in-null-profile-creation.patch |   60 -
 ...sure-unconfined-profiles-have-dfas-initia.patch |   36 -
 ...x-incorrect-type-assignment-when-freeing-.patch |   39 -
 kernel-aufs4.patch                                 | 3520 +++++++++++++++-----
 kernel.spec                                        |   47 +-
 17 files changed, 2750 insertions(+), 3174 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 41ffc068..93ecbd27 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -69,9 +69,9 @@
 %define		have_pcmcia	0
 %endif
 
-%define		rel		1
-%define		basever		4.13
-%define		postver		.12
+%define		rel		0.1
+%define		basever		4.14
+%define		postver		.0
 
 # define this to '-%{basever}' for longterm branch
 %define		versuffix	%{nil}
@@ -120,7 +120,7 @@ Epoch:		3
 License:	GPL v2
 Group:		Base/Kernel
 Source0:	https://www.kernel.org/pub/linux/kernel/v4.x/linux-%{basever}.tar.xz
-# Source0-md5:	ab1a2abc6f37b752dd2595338bec4e78
+# Source0-md5:	bacdb9ffdcd922aa069a5e1520160e24
 %if "%{postver}" != ".0"
 Patch0:		https://www.kernel.org/pub/linux/kernel/v4.x/patch-%{version}.xz
 # Patch0-md5:	665b55e1f24ec56de55f7d0302d7c4f5
@@ -197,10 +197,9 @@ Patch101:	kernel-vserver-fixes.patch
 # Patch creation:
 # git clone git://github.com/sfjro/aufs4-standalone.git
 # cd aufs4-standalone
-# git checkout -b aufs4.12 origin/aufs4.12
+# git checkout -b aufs4.14 origin/aufs4.14
 # cat aufs4-kbuild.patch aufs4-base.patch aufs4-mmap.patch aufs4-standalone.patch > ~/rpm/packages/kernel/kernel-aufs4.patch
-# rm -rf linux && mkdir linux
-# cp -a Documentation fs include linux
+# rm -rf linux && mkdir linux; cp -a Documentation fs include linux
 # diff -urN /usr/share/empty linux | filterdiff -x linux/include/uapi/linux/Kbuild >> ~/rpm/packages/kernel/kernel-aufs4.patch
 # cat aufs4-loopback.patch >> ~/rpm/packages/kernel/kernel-aufs4.patch
 #
@@ -218,23 +217,9 @@ Patch2000:	kernel-small_fixes.patch
 Patch2001:	kernel-pwc-uncompress.patch
 Patch2003:	kernel-regressions.patch
 
-# http://bazaar.launchpad.net/~apparmor-dev/apparmor/master/files/head:/kernel-patches/v4.13/
-Patch5001:	0002-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch
-Patch5002:	0003-apparmor-Fix-logical-error-in-verify_header.patch
-Patch5003:	0004-apparmor-Fix-an-error-code-in-aafs_create.patch
-Patch5004:	0005-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch
-Patch5005:	0006-apparmor-add-the-ability-to-mediate-signals.patch
-Patch5006:	0007-apparmor-add-mount-mediation.patch
-Patch5007:	0008-apparmor-cleanup-conditional-check-for-label-in-labe.patch
-Patch5008:	0009-apparmor-add-support-for-absolute-root-view-based-la.patch
-Patch5009:	0010-apparmor-make-policy_unpack-able-to-audit-different-.patch
-Patch5010:	0011-apparmor-add-more-debug-asserts-to-apparmorfs.patch
-Patch5011:	0012-apparmor-add-base-infastructure-for-socket-mediation.patch
-Patch5012:	0013-apparmor-move-new_null_profile-to-after-profile-look.patch
-Patch5013:	0014-apparmor-fix-race-condition-in-null-profile-creation.patch
-Patch5014:	0015-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch
-Patch5015:	0016-apparmor-fix-incorrect-type-assignment-when-freeing-.patch
-Patch5016:	0017-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
+# https://gitlab.com/apparmor/apparmor/tree/master/kernel-patches/v4.14
+Patch5001:	0012-apparmor-add-base-infastructure-for-socket-mediation.patch
+Patch5002:	0001-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
 
 # for rescuecd
 # based on ftp://ftp.leg.uct.ac.za/pub/linux/rip/tmpfs_root-2.6.30.diff.gz
@@ -706,20 +691,6 @@ rm -f localversion-rt
 %if %{with apparmor}
 %patch5001 -p1
 %patch5002 -p1
-%patch5003 -p1
-%patch5004 -p1
-%patch5005 -p1
-%patch5006 -p1
-%patch5007 -p1
-%patch5008 -p1
-%patch5009 -p1
-%patch5010 -p1
-%patch5011 -p1
-%patch5012 -p1
-%patch5013 -p1
-%patch5014 -p1
-%patch5015 -p1
-%patch5016 -p1
 %endif
 
 %patch250 -p1
diff --git a/0017-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch b/0001-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
similarity index 100%
rename from 0017-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
rename to 0001-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
diff --git a/0002-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch b/0002-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch
deleted file mode 100644
index 4d9836d9..00000000
--- a/0002-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From c6cad5e65a23dcafa1821ca381901297664d9c64 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert at linux-m68k.org>
-Date: Thu, 6 Jul 2017 10:56:21 +0200
-Subject: [PATCH 02/17] apparmor: Fix shadowed local variable in
- unpack_trans_table()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-with W=2:
-
-    security/apparmor/policy_unpack.c: In function ‘unpack_trans_table’:
-    security/apparmor/policy_unpack.c:469: warning: declaration of ‘pos’ shadows a previous local
-    security/apparmor/policy_unpack.c:451: warning: shadowed declaration is here
-
-Rename the old "pos" to "saved_pos" to fix this.
-
-Fixes: 5379a3312024a8be ("apparmor: support v7 transition format compatible with label_parse")
-Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
-Reviewed-by: Serge Hallyn <serge at hallyn.com>
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit 966d631935a578fadb5770f17a957ee1a969d868)
----
- security/apparmor/policy_unpack.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index c600f4dd1783..2d5a1a007b06 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -448,7 +448,7 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
-  */
- static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
- {
--	void *pos = e->pos;
-+	void *saved_pos = e->pos;
- 
- 	/* exec table is optional */
- 	if (unpack_nameX(e, AA_STRUCT, "xtable")) {
-@@ -511,7 +511,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
- 
- fail:
- 	aa_free_domain_entries(&profile->file.trans);
--	e->pos = pos;
-+	e->pos = saved_pos;
- 	return 0;
- }
- 
--- 
-2.11.0
-
diff --git a/0003-apparmor-Fix-logical-error-in-verify_header.patch b/0003-apparmor-Fix-logical-error-in-verify_header.patch
deleted file mode 100644
index be4f854c..00000000
--- a/0003-apparmor-Fix-logical-error-in-verify_header.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 9934296cba701d429a0fc0cf071a40c8c3a1587e Mon Sep 17 00:00:00 2001
-From: Christos Gkekas <chris.gekas at gmail.com>
-Date: Sat, 8 Jul 2017 20:50:21 +0100
-Subject: [PATCH 03/17] apparmor: Fix logical error in verify_header()
-
-verify_header() is currently checking whether interface version is less
-than 5 *and* greater than 7, which always evaluates to false. Instead it
-should check whether it is less than 5 *or* greater than 7.
-
-Signed-off-by: Christos Gkekas <chris.gekas at gmail.com>
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit c54a2175e3a6bf6c697d249bba1aa729e06c7ba8)
----
- security/apparmor/policy_unpack.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 2d5a1a007b06..bda0dce3b582 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -832,7 +832,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
- 	 * if not specified use previous version
- 	 * Mask off everything that is not kernel abi version
- 	 */
--	if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) {
-+	if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
- 		audit_iface(NULL, NULL, NULL, "unsupported interface version",
- 			    e, error);
- 		return error;
--- 
-2.11.0
-
diff --git a/0004-apparmor-Fix-an-error-code-in-aafs_create.patch b/0004-apparmor-Fix-an-error-code-in-aafs_create.patch
deleted file mode 100644
index 4e937e00..00000000
--- a/0004-apparmor-Fix-an-error-code-in-aafs_create.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 8b3851c7b83f32f2be9d4b48371ddf033afedf62 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter at oracle.com>
-Date: Thu, 13 Jul 2017 10:39:20 +0300
-Subject: [PATCH 04/17] apparmor: Fix an error code in aafs_create()
-
-We accidentally forgot to set the error code on this path.  It means we
-return NULL instead of an error pointer.  I looked through a bunch of
-callers and I don't think it really causes a big issue, but the
-documentation says we're supposed to return error pointers here.
-
-Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
-Acked-by: Serge Hallyn <serge at hallyn.com>
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit aee58bf341db52a3a3563c6b972bfd4fc2d41e46)
----
- security/apparmor/apparmorfs.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 853c2ec8e0c9..2caeb748070c 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -248,8 +248,10 @@ static struct dentry *aafs_create(const char *name, umode_t mode,
- 
- 	inode_lock(dir);
- 	dentry = lookup_one_len(name, parent, strlen(name));
--	if (IS_ERR(dentry))
-+	if (IS_ERR(dentry)) {
-+		error = PTR_ERR(dentry);
- 		goto fail_lock;
-+	}
- 
- 	if (d_really_is_positive(dentry)) {
- 		error = -EEXIST;
--- 
-2.11.0
-
diff --git a/0005-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch b/0005-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch
deleted file mode 100644
index beea3de9..00000000
--- a/0005-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 4b56e146905bbad2c79ea92e3f49e210ca527572 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Mon, 31 Jul 2017 23:44:37 -0700
-Subject: [PATCH 05/17] apparmor: Redundant condition: prev_ns. in
- [label.c:1498]
-
-Reported-by: David Binderman <dcb314 at hotmail.com>
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit d323d2c17cfcc54b6845bfc1d13bca5cef210fc7)
----
- security/apparmor/label.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index e052eaba1cf6..e324f4df3e34 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1495,7 +1495,7 @@ static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
- 		view = profiles_ns(profile);
- 
- 	if (view != profile->ns &&
--	    (!prev_ns || (prev_ns && *prev_ns != profile->ns))) {
-+	    (!prev_ns || (*prev_ns != profile->ns))) {
- 		if (prev_ns)
- 			*prev_ns = profile->ns;
- 		ns_name = aa_ns_name(view, profile->ns,
--- 
-2.11.0
-
diff --git a/0006-apparmor-add-the-ability-to-mediate-signals.patch b/0006-apparmor-add-the-ability-to-mediate-signals.patch
deleted file mode 100644
index ee3672db..00000000
--- a/0006-apparmor-add-the-ability-to-mediate-signals.patch
+++ /dev/null
@@ -1,397 +0,0 @@
-From f9e20353a6c5726775867db81b6085e8ab425a36 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Tue, 18 Jul 2017 22:56:22 -0700
-Subject: [PATCH 06/17] apparmor: add the ability to mediate signals
-
-Add signal mediation where the signal can be mediated based on the
-signal, direction, or the label or the peer/target. The signal perms
-are verified on a cross check to ensure policy consistency in the case
-of incremental policy load/replacement.
-
-The optimization of skipping the cross check when policy is guaranteed
-to be consistent (single compile unit) remains to be done.
-
-policy rules have the form of
-  SIGNAL_RULE = [ QUALIFIERS ] 'signal' [ SIGNAL ACCESS PERMISSIONS ]
-                [ SIGNAL SET ] [ SIGNAL PEER ]
-
-  SIGNAL ACCESS PERMISSIONS = SIGNAL ACCESS | SIGNAL ACCESS LIST
-
-  SIGNAL ACCESS LIST = '(' Comma or space separated list of SIGNAL
-                           ACCESS ')'
-
-  SIGNAL ACCESS = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' |
-                    'receive' )
-
-  SIGNAL SET = 'set' '=' '(' SIGNAL LIST ')'
-
-  SIGNAL LIST = Comma or space separated list of SIGNALS
-
-  SIGNALS = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' |
-              'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' |
-	      'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' |
-	      'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' |
-	      'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' |
-	      'sys' | 'emt' | 'exists' | 'rtmin+0' ... 'rtmin+32'
-            )
-
-  SIGNAL PEER = 'peer' '=' AARE
-
-eg.
-  signal,                                 # allow all signals
-  signal send set=(hup, kill) peer=foo,
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit c6bf1adaecaa719d7c56338cc43b2982214f2f44)
----
- security/apparmor/apparmorfs.c        |  7 +++
- security/apparmor/include/apparmor.h  |  1 +
- security/apparmor/include/audit.h     |  2 +
- security/apparmor/include/ipc.h       |  6 +++
- security/apparmor/include/sig_names.h | 95 +++++++++++++++++++++++++++++++++
- security/apparmor/ipc.c               | 99 +++++++++++++++++++++++++++++++++++
- security/apparmor/lsm.c               | 21 ++++++++
- 7 files changed, 231 insertions(+)
- create mode 100644 security/apparmor/include/sig_names.h
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 2caeb748070c..a5f9e1aa51f7 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -32,6 +32,7 @@
- #include "include/audit.h"
- #include "include/context.h"
- #include "include/crypto.h"
-+#include "include/ipc.h"
- #include "include/policy_ns.h"
- #include "include/label.h"
- #include "include/policy.h"
-@@ -2129,6 +2130,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
- 	{ }
- };
- 
-+static struct aa_sfs_entry aa_sfs_entry_signal[] = {
-+	AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
-+	{ }
-+};
-+
- static struct aa_sfs_entry aa_sfs_entry_domain[] = {
- 	AA_SFS_FILE_BOOLEAN("change_hat",	1),
- 	AA_SFS_FILE_BOOLEAN("change_hatv",	1),
-@@ -2179,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- 	AA_SFS_DIR("rlimit",			aa_sfs_entry_rlimit),
- 	AA_SFS_DIR("caps",			aa_sfs_entry_caps),
- 	AA_SFS_DIR("ptrace",			aa_sfs_entry_ptrace),
-+	AA_SFS_DIR("signal",			aa_sfs_entry_signal),
- 	AA_SFS_DIR("query",			aa_sfs_entry_query),
- 	{ }
- };
-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-index aaf893f4e4f5..962a20a75e01 100644
---- a/security/apparmor/include/apparmor.h
-+++ b/security/apparmor/include/apparmor.h
-@@ -28,6 +28,7 @@
- #define AA_CLASS_RLIMITS	5
- #define AA_CLASS_DOMAIN		6
- #define AA_CLASS_PTRACE		9
-+#define AA_CLASS_SIGNAL		10
- #define AA_CLASS_LABEL		16
- 
- #define AA_CLASS_LAST		AA_CLASS_LABEL
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index c68839a44351..d9a156ae11b9 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -86,6 +86,7 @@ enum audit_type {
- #define OP_SHUTDOWN "socket_shutdown"
- 
- #define OP_PTRACE "ptrace"
-+#define OP_SIGNAL "signal"
- 
- #define OP_EXEC "exec"
- 
-@@ -126,6 +127,7 @@ struct apparmor_audit_data {
- 			long pos;
- 			const char *ns;
- 		} iface;
-+		int signal;
- 		struct {
- 			int rlim;
- 			unsigned long max;
-diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
-index 656fdb81c8a0..5ffc218d1e74 100644
---- a/security/apparmor/include/ipc.h
-+++ b/security/apparmor/include/ipc.h
-@@ -27,8 +27,14 @@ struct aa_profile;
- 
- #define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
- 			     AA_MAY_BE_READ | AA_MAY_BE_TRACED)
-+#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)
-+
-+#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
-+	"segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
-+	"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
- 
- int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- 		  u32 request);
-+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
- 
- #endif /* __AA_IPC_H */
-diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h
-new file mode 100644
-index 000000000000..0d4395f231ca
---- /dev/null
-+++ b/security/apparmor/include/sig_names.h
-@@ -0,0 +1,95 @@
-+#include <linux/signal.h>
-+
-+#define SIGUNKNOWN 0
-+#define MAXMAPPED_SIG 35
-+/* provide a mapping of arch signal to internal signal # for mediation
-+ * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO
-+ * map to the same entry those that may/or may not get a separate entry
-+ */
-+static const int sig_map[MAXMAPPED_SIG] = {
-+	[0] = MAXMAPPED_SIG,	/* existence test */
-+	[SIGHUP] = 1,
-+	[SIGINT] = 2,
-+	[SIGQUIT] = 3,
-+	[SIGILL] = 4,
-+	[SIGTRAP] = 5,		/* -, 5, - */
-+	[SIGABRT] = 6,		/*  SIGIOT: -, 6, - */
-+	[SIGBUS] = 7,		/* 10, 7, 10 */
-+	[SIGFPE] = 8,
-+	[SIGKILL] = 9,
-+	[SIGUSR1] = 10,		/* 30, 10, 16 */
-+	[SIGSEGV] = 11,
-+	[SIGUSR2] = 12,		/* 31, 12, 17 */
-+	[SIGPIPE] = 13,
-+	[SIGALRM] = 14,
-+	[SIGTERM] = 15,
-+	[SIGSTKFLT] = 16,	/* -, 16, - */
-+	[SIGCHLD] = 17,		/* 20, 17, 18.  SIGCHLD -, -, 18 */
-+	[SIGCONT] = 18,		/* 19, 18, 25 */
-+	[SIGSTOP] = 19,		/* 17, 19, 23 */
-+	[SIGTSTP] = 20,		/* 18, 20, 24 */
-+	[SIGTTIN] = 21,		/* 21, 21, 26 */
-+	[SIGTTOU] = 22,		/* 22, 22, 27 */
-+	[SIGURG] = 23,		/* 16, 23, 21 */
-+	[SIGXCPU] = 24,		/* 24, 24, 30 */
-+	[SIGXFSZ] = 25,		/* 25, 25, 31 */
-+	[SIGVTALRM] = 26,	/* 26, 26, 28 */
-+	[SIGPROF] = 27,		/* 27, 27, 29 */
-+	[SIGWINCH] = 28,	/* 28, 28, 20 */
-+	[SIGIO] = 29,		/* SIGPOLL: 23, 29, 22 */
-+	[SIGPWR] = 30,		/* 29, 30, 19.  SIGINFO 29, -, - */
-+#ifdef SIGSYS
-+	[SIGSYS] = 31,		/* 12, 31, 12. often SIG LOST/UNUSED */
-+#endif
-+#ifdef SIGEMT
-+	[SIGEMT] = 32,		/* 7, - , 7 */
-+#endif
-+#if defined(SIGLOST) && SIGPWR != SIGLOST		/* sparc */
-+	[SIGLOST] = 33,		/* unused on Linux */
-+#endif
-+#if defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
-+	[SIGUNUSED] = 34,	/* -, 31, - */
-+#endif
-+};
-+
-+/* this table is ordered post sig_map[sig] mapping */
-+static const char *const sig_names[MAXMAPPED_SIG + 1] = {
-+	"unknown",
-+	"hup",
-+	"int",
-+	"quit",
-+	"ill",
-+	"trap",
-+	"abrt",
-+	"bus",
-+	"fpe",
-+	"kill",
-+	"usr1",
-+	"segv",
-+	"usr2",
-+	"pipe",
-+	"alrm",
-+	"term",
-+	"stkflt",
-+	"chld",
-+	"cont",
-+	"stop",
-+	"stp",
-+	"ttin",
-+	"ttou",
-+	"urg",
-+	"xcpu",
-+	"xfsz",
-+	"vtalrm",
-+	"prof",
-+	"winch",
-+	"io",
-+	"pwr",
-+	"sys",
-+	"emt",
-+	"lost",
-+	"unused",
-+
-+	"exists",	/* always last existence test mapped to MAXMAPPED_SIG */
-+};
-+
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-index 11e66b5bbc42..66fb9ede9447 100644
---- a/security/apparmor/ipc.c
-+++ b/security/apparmor/ipc.c
-@@ -20,6 +20,7 @@
- #include "include/context.h"
- #include "include/policy.h"
- #include "include/ipc.h"
-+#include "include/sig_names.h"
- 
- /**
-  * audit_ptrace_mask - convert mask to permission string
-@@ -121,3 +122,101 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- }
- 
- 
-+static inline int map_signal_num(int sig)
-+{
-+	if (sig > SIGRTMAX)
-+		return SIGUNKNOWN;
-+	else if (sig >= SIGRTMIN)
-+		return sig - SIGRTMIN + 128;	/* rt sigs mapped to 128 */
-+	else if (sig <= MAXMAPPED_SIG)
-+		return sig_map[sig];
-+	return SIGUNKNOWN;
-+}
-+
-+/**
-+ * audit_file_mask - convert mask to permission string
-+ * @buffer: buffer to write string to (NOT NULL)
-+ * @mask: permission mask to convert
-+ */
-+static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
-+{
-+	if (mask & MAY_READ)
-+		audit_log_string(ab, "receive");
-+	if (mask & MAY_WRITE)
-+		audit_log_string(ab, "send");
-+}
-+
-+/**
-+ * audit_cb - call back for signal specific audit fields
-+ * @ab: audit_buffer  (NOT NULL)
-+ * @va: audit struct to audit values of  (NOT NULL)
-+ */
-+static void audit_signal_cb(struct audit_buffer *ab, void *va)
-+{
-+	struct common_audit_data *sa = va;
-+
-+	if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
-+		audit_log_format(ab, " requested_mask=");
-+		audit_signal_mask(ab, aad(sa)->request);
-+		if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
-+			audit_log_format(ab, " denied_mask=");
-+			audit_signal_mask(ab, aad(sa)->denied);
-+		}
-+	}
-+	if (aad(sa)->signal <= MAXMAPPED_SIG)
-+		audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
-+	else
-+		audit_log_format(ab, " signal=rtmin+%d",
-+				 aad(sa)->signal - 128);
-+	audit_log_format(ab, " peer=");
-+	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
-+			FLAGS_NONE, GFP_ATOMIC);
-+}
-+
-+/* TODO: update to handle compound name&name2, conditionals */
-+static void profile_match_signal(struct aa_profile *profile, const char *label,
-+				 int signal, struct aa_perms *perms)
-+{
-+	unsigned int state;
-+
-+	/* TODO: secondary cache check <profile, profile, perm> */
-+	state = aa_dfa_next(profile->policy.dfa,
-+			    profile->policy.start[AA_CLASS_SIGNAL],
-+			    signal);
-+	state = aa_dfa_match(profile->policy.dfa, state, label);
-+	aa_compute_perms(profile->policy.dfa, state, perms);
-+}
-+
-+static int profile_signal_perm(struct aa_profile *profile,
-+			       struct aa_profile *peer, u32 request,
-+			       struct common_audit_data *sa)
-+{
-+	struct aa_perms perms;
-+
-+	if (profile_unconfined(profile) ||
-+	    !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
-+		return 0;
-+
-+	aad(sa)->peer = &peer->label;
-+	profile_match_signal(profile, peer->base.hname, aad(sa)->signal,
-+			     &perms);
-+	aa_apply_modes_to_perms(profile, &perms);
-+	return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
-+}
-+
-+static int aa_signal_cross_perm(struct aa_profile *sender,
-+				struct aa_profile *target,
-+				struct common_audit_data *sa)
-+{
-+	return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa),
-+		      profile_signal_perm(target, sender, MAY_READ, sa));
-+}
-+
-+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
-+{
-+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
-+
-+	aad(&sa)->signal = map_signal_num(sig);
-+	return xcheck_labels_profiles(sender, target, aa_signal_cross_perm,
-+				      &sa);
-+}
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 867bcd154c7e..af22f3dfbcce 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -656,6 +656,26 @@ static int apparmor_task_setrlimit(struct task_struct *task,
- 	return error;
- }
- 
-+static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
-+			      int sig, u32 secid)
-+{
-+	struct aa_label *cl, *tl;
-+	int error;
-+
-+	if (secid)
-+		/* TODO: after secid to label mapping is done.
-+		 *  Dealing with USB IO specific behavior
-+		 */
-+		return 0;
-+	cl = __begin_current_label_crit_section();
-+	tl = aa_get_task_label(target);
-+	error = aa_may_signal(cl, tl, sig);
-+	aa_put_label(tl);
-+	__end_current_label_crit_section(cl);
-+
-+	return error;
-+}
-+
- static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- 	LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
- 	LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
-@@ -697,6 +717,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- 	LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec),
- 
- 	LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
-+	LSM_HOOK_INIT(task_kill, apparmor_task_kill),
- };
- 
- /*
--- 
-2.11.0
-
diff --git a/0007-apparmor-add-mount-mediation.patch b/0007-apparmor-add-mount-mediation.patch
deleted file mode 100644
index 99dac5c1..00000000
--- a/0007-apparmor-add-mount-mediation.patch
+++ /dev/null
@@ -1,1051 +0,0 @@
-From f37356d0a41499f9222f9f2b9c0147b500ae4285 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Tue, 18 Jul 2017 23:04:47 -0700
-Subject: [PATCH 07/17] apparmor: add mount mediation
-
-Add basic mount mediation. That allows controlling based on basic
-mount parameters. It does not include special mount parameters for
-apparmor, super block labeling, or any triggers for apparmor namespace
-parameter modifications on pivot root.
-
-default userspace policy rules have the form of
-  MOUNT RULE = ( MOUNT | REMOUNT | UMOUNT )
-
-  MOUNT = [ QUALIFIERS ] 'mount' [ MOUNT CONDITIONS ] [ SOURCE FILEGLOB ]
-          [ '->' MOUNTPOINT FILEGLOB ]
-
-  REMOUNT = [ QUALIFIERS ] 'remount' [ MOUNT CONDITIONS ]
-            MOUNTPOINT FILEGLOB
-
-  UMOUNT = [ QUALIFIERS ] 'umount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB
-
-  MOUNT CONDITIONS = [ ( 'fstype' | 'vfstype' ) ( '=' | 'in' )
-                       MOUNT FSTYPE EXPRESSION ]
-		       [ 'options' ( '=' | 'in' ) MOUNT FLAGS EXPRESSION ]
-
-  MOUNT FSTYPE EXPRESSION = ( MOUNT FSTYPE LIST | MOUNT EXPRESSION )
-
-  MOUNT FSTYPE LIST = Comma separated list of valid filesystem and
-                      virtual filesystem types (eg ext4, debugfs, etc)
-
-  MOUNT FLAGS EXPRESSION = ( MOUNT FLAGS LIST | MOUNT EXPRESSION )
-
-  MOUNT FLAGS LIST = Comma separated list of MOUNT FLAGS.
-
-  MOUNT FLAGS = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' |
-                  'noexec' | 'exec' | 'sync' | 'async' | 'remount' |
-		  'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' |
-		  'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' |
-		  'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' |
-		  'unbindable' | 'runbindable' | 'private' | 'rprivate' |
-		  'slave' | 'rslave' | 'shared' | 'rshared' |
-		  'relatime' | 'norelatime' | 'iversion' | 'noiversion' |
-		  'strictatime' | 'nouser' | 'user' )
-
-  MOUNT EXPRESSION = ( ALPHANUMERIC | AARE ) ...
-
-  PIVOT ROOT RULE = [ QUALIFIERS ] pivot_root [ oldroot=OLD PUT FILEGLOB ]
-                    [ NEW ROOT FILEGLOB ]
-
-  SOURCE FILEGLOB = FILEGLOB
-
-  MOUNTPOINT FILEGLOB = FILEGLOB
-
-eg.
-  mount,
-  mount /dev/foo,
-  mount options=ro /dev/foo -> /mnt/,
-  mount options in (ro,atime) /dev/foo -> /mnt/,
-  mount options=ro options=atime,
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit fa488437d0f95b2e5db1e624341fe0d5a233f729)
----
- security/apparmor/Makefile           |   2 +-
- security/apparmor/apparmorfs.c       |   8 +-
- security/apparmor/domain.c           |   4 +-
- security/apparmor/include/apparmor.h |   1 +
- security/apparmor/include/audit.h    |  11 +
- security/apparmor/include/domain.h   |   5 +
- security/apparmor/include/mount.h    |  54 +++
- security/apparmor/lsm.c              |  64 ++++
- security/apparmor/mount.c            | 696 +++++++++++++++++++++++++++++++++++
- 9 files changed, 841 insertions(+), 4 deletions(-)
- create mode 100644 security/apparmor/include/mount.h
- create mode 100644 security/apparmor/mount.c
-
-diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
-index a16b195274de..81a34426d024 100644
---- a/security/apparmor/Makefile
-+++ b/security/apparmor/Makefile
-@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
- 
- apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
-               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
--              resource.o secid.o file.o policy_ns.o label.o
-+              resource.o secid.o file.o policy_ns.o label.o mount.o
- apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
- 
- clean-files := capability_names.h rlim_names.h
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index a5f9e1aa51f7..8fa6c898c44b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -2159,9 +2159,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
- 	{ }
- };
- 
-+static struct aa_sfs_entry aa_sfs_entry_mount[] = {
-+	AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
-+	{ }
-+};
-+
- static struct aa_sfs_entry aa_sfs_entry_ns[] = {
- 	AA_SFS_FILE_BOOLEAN("profile",		1),
--	AA_SFS_FILE_BOOLEAN("pivot_root",	1),
-+	AA_SFS_FILE_BOOLEAN("pivot_root",	0),
- 	{ }
- };
- 
-@@ -2180,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- 	AA_SFS_DIR("policy",			aa_sfs_entry_policy),
- 	AA_SFS_DIR("domain",			aa_sfs_entry_domain),
- 	AA_SFS_DIR("file",			aa_sfs_entry_file),
-+	AA_SFS_DIR("mount",			aa_sfs_entry_mount),
- 	AA_SFS_DIR("namespaces",		aa_sfs_entry_ns),
- 	AA_SFS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
- 	AA_SFS_DIR("rlimit",			aa_sfs_entry_rlimit),
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index d0594446ae3f..ffc8c75a6785 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name)
-  *
-  * Returns: refcounted label, or NULL on failure (MAYBE NULL)
-  */
--static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
--				       const char **name)
-+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
-+				const char **name)
- {
- 	struct aa_label *label = NULL;
- 	u32 xtype = xindex & AA_X_TYPE_MASK;
-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-index 962a20a75e01..829082c35faa 100644
---- a/security/apparmor/include/apparmor.h
-+++ b/security/apparmor/include/apparmor.h
-@@ -27,6 +27,7 @@
- #define AA_CLASS_NET		4
- #define AA_CLASS_RLIMITS	5
- #define AA_CLASS_DOMAIN		6
-+#define AA_CLASS_MOUNT		7
- #define AA_CLASS_PTRACE		9
- #define AA_CLASS_SIGNAL		10
- #define AA_CLASS_LABEL		16
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index d9a156ae11b9..c3fe1c5ef3bc 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -71,6 +71,10 @@ enum audit_type {
- #define OP_FMPROT "file_mprotect"
- #define OP_INHERIT "file_inherit"
- 
-+#define OP_PIVOTROOT "pivotroot"
-+#define OP_MOUNT "mount"
-+#define OP_UMOUNT "umount"
-+
- #define OP_CREATE "create"
- #define OP_POST_CREATE "post_create"
- #define OP_BIND "bind"
-@@ -132,6 +136,13 @@ struct apparmor_audit_data {
- 			int rlim;
- 			unsigned long max;
- 		} rlim;
-+		struct {
-+			const char *src_name;
-+			const char *type;
-+			const char *trans;
-+			const char *data;
-+			unsigned long flags;
-+		} mnt;
- 	};
- };
- 
-diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
-index bab5810b6e9a..db27403346c5 100644
---- a/security/apparmor/include/domain.h
-+++ b/security/apparmor/include/domain.h
-@@ -15,6 +15,8 @@
- #include <linux/binfmts.h>
- #include <linux/types.h>
- 
-+#include "label.h"
-+
- #ifndef __AA_DOMAIN_H
- #define __AA_DOMAIN_H
- 
-@@ -29,6 +31,9 @@ struct aa_domain {
- #define AA_CHANGE_ONEXEC  4
- #define AA_CHANGE_STACK 8
- 
-+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
-+				const char **name);
-+
- int apparmor_bprm_set_creds(struct linux_binprm *bprm);
- int apparmor_bprm_secureexec(struct linux_binprm *bprm);
- 
-diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
-new file mode 100644
-index 000000000000..25d6067fa6ef
---- /dev/null
-+++ b/security/apparmor/include/mount.h
-@@ -0,0 +1,54 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor file mediation function definitions.
-+ *
-+ * Copyright 2017 Canonical Ltd.
-+ *
-+ * 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, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_MOUNT_H
-+#define __AA_MOUNT_H
-+
-+#include <linux/fs.h>
-+#include <linux/path.h>
-+
-+#include "domain.h"
-+#include "policy.h"
-+
-+/* mount perms */
-+#define AA_MAY_PIVOTROOT	0x01
-+#define AA_MAY_MOUNT		0x02
-+#define AA_MAY_UMOUNT		0x04
-+#define AA_AUDIT_DATA		0x40
-+#define AA_MNT_CONT_MATCH	0x40
-+
-+#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
-+
-+int aa_remount(struct aa_label *label, const struct path *path,
-+	       unsigned long flags, void *data);
-+
-+int aa_bind_mount(struct aa_label *label, const struct path *path,
-+		  const char *old_name, unsigned long flags);
-+
-+
-+int aa_mount_change_type(struct aa_label *label, const struct path *path,
-+			 unsigned long flags);
-+
-+int aa_move_mount(struct aa_label *label, const struct path *path,
-+		  const char *old_name);
-+
-+int aa_new_mount(struct aa_label *label, const char *dev_name,
-+		 const struct path *path, const char *type, unsigned long flags,
-+		 void *data);
-+
-+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
-+
-+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
-+		 const struct path *new_path);
-+
-+#endif /* __AA_MOUNT_H */
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index af22f3dfbcce..4ad0b3a45142 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -38,6 +38,7 @@
- #include "include/policy.h"
- #include "include/policy_ns.h"
- #include "include/procattr.h"
-+#include "include/mount.h"
- 
- /* Flag indicating whether initialization completed */
- int apparmor_initialized;
-@@ -511,6 +512,65 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma,
- 			   !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
- }
- 
-+static int apparmor_sb_mount(const char *dev_name, const struct path *path,
-+			     const char *type, unsigned long flags, void *data)
-+{
-+	struct aa_label *label;
-+	int error = 0;
-+
-+	/* Discard magic */
-+	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
-+		flags &= ~MS_MGC_MSK;
-+
-+	flags &= ~AA_MS_IGNORE_MASK;
-+
-+	label = __begin_current_label_crit_section();
-+	if (!unconfined(label)) {
-+		if (flags & MS_REMOUNT)
-+			error = aa_remount(label, path, flags, data);
-+		else if (flags & MS_BIND)
-+			error = aa_bind_mount(label, path, dev_name, flags);
-+		else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
-+				  MS_UNBINDABLE))
-+			error = aa_mount_change_type(label, path, flags);
-+		else if (flags & MS_MOVE)
-+			error = aa_move_mount(label, path, dev_name);
-+		else
-+			error = aa_new_mount(label, dev_name, path, type,
-+					     flags, data);
-+	}
-+	__end_current_label_crit_section(label);
-+
-+	return error;
-+}
-+
-+static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
-+{
-+	struct aa_label *label;
-+	int error = 0;
-+
-+	label = __begin_current_label_crit_section();
-+	if (!unconfined(label))
-+		error = aa_umount(label, mnt, flags);
-+	__end_current_label_crit_section(label);
-+
-+	return error;
-+}
-+
-+static int apparmor_sb_pivotroot(const struct path *old_path,
-+				 const struct path *new_path)
-+{
-+	struct aa_label *label;
-+	int error = 0;
-+
-+	label = aa_get_current_label();
-+	if (!unconfined(label))
-+		error = aa_pivotroot(label, old_path, new_path);
-+	aa_put_label(label);
-+
-+	return error;
-+}
-+
- static int apparmor_getprocattr(struct task_struct *task, char *name,
- 				char **value)
- {
-@@ -682,6 +742,10 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- 	LSM_HOOK_INIT(capget, apparmor_capget),
- 	LSM_HOOK_INIT(capable, apparmor_capable),
- 
-+	LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
-+	LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
-+	LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
-+
- 	LSM_HOOK_INIT(path_link, apparmor_path_link),
- 	LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
- 	LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
-diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
-new file mode 100644
-index 000000000000..82a64b58041d
---- /dev/null
-+++ b/security/apparmor/mount.c
-@@ -0,0 +1,696 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor mediation of files
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009-2017 Canonical Ltd.
-+ *
-+ * 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, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+
-+#include "include/apparmor.h"
-+#include "include/audit.h"
-+#include "include/context.h"
-+#include "include/domain.h"
-+#include "include/file.h"
-+#include "include/match.h"
-+#include "include/mount.h"
-+#include "include/path.h"
-+#include "include/policy.h"
-+
-+
-+static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
-+{
-+	if (flags & MS_RDONLY)
-+		audit_log_format(ab, "ro");
-+	else
-+		audit_log_format(ab, "rw");
-+	if (flags & MS_NOSUID)
-+		audit_log_format(ab, ", nosuid");
-+	if (flags & MS_NODEV)
-+		audit_log_format(ab, ", nodev");
-+	if (flags & MS_NOEXEC)
-+		audit_log_format(ab, ", noexec");
-+	if (flags & MS_SYNCHRONOUS)
-+		audit_log_format(ab, ", sync");
-+	if (flags & MS_REMOUNT)
-+		audit_log_format(ab, ", remount");
-+	if (flags & MS_MANDLOCK)
-+		audit_log_format(ab, ", mand");
-+	if (flags & MS_DIRSYNC)
-+		audit_log_format(ab, ", dirsync");
-+	if (flags & MS_NOATIME)
-+		audit_log_format(ab, ", noatime");
-+	if (flags & MS_NODIRATIME)
-+		audit_log_format(ab, ", nodiratime");
-+	if (flags & MS_BIND)
-+		audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
-+	if (flags & MS_MOVE)
-+		audit_log_format(ab, ", move");
-+	if (flags & MS_SILENT)
-+		audit_log_format(ab, ", silent");
-+	if (flags & MS_POSIXACL)
-+		audit_log_format(ab, ", acl");
-+	if (flags & MS_UNBINDABLE)
-+		audit_log_format(ab, flags & MS_REC ? ", runbindable" :
-+				 ", unbindable");
-+	if (flags & MS_PRIVATE)
-+		audit_log_format(ab, flags & MS_REC ? ", rprivate" :
-+				 ", private");
-+	if (flags & MS_SLAVE)
-+		audit_log_format(ab, flags & MS_REC ? ", rslave" :
-+				 ", slave");
-+	if (flags & MS_SHARED)
-+		audit_log_format(ab, flags & MS_REC ? ", rshared" :
-+				 ", shared");
-+	if (flags & MS_RELATIME)
-+		audit_log_format(ab, ", relatime");
-+	if (flags & MS_I_VERSION)
-+		audit_log_format(ab, ", iversion");
-+	if (flags & MS_STRICTATIME)
-+		audit_log_format(ab, ", strictatime");
-+	if (flags & MS_NOUSER)
-+		audit_log_format(ab, ", nouser");
-+}
-+
-+/**
-+ * audit_cb - call back for mount specific audit fields
-+ * @ab: audit_buffer  (NOT NULL)
-+ * @va: audit struct to audit values of  (NOT NULL)
-+ */
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+	struct common_audit_data *sa = va;
-+
-+	if (aad(sa)->mnt.type) {
-+		audit_log_format(ab, " fstype=");
-+		audit_log_untrustedstring(ab, aad(sa)->mnt.type);
-+	}
-+	if (aad(sa)->mnt.src_name) {
-+		audit_log_format(ab, " srcname=");
-+		audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
-+	}
-+	if (aad(sa)->mnt.trans) {
-+		audit_log_format(ab, " trans=");
-+		audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
-+	}
-+	if (aad(sa)->mnt.flags) {
-+		audit_log_format(ab, " flags=\"");
-+		audit_mnt_flags(ab, aad(sa)->mnt.flags);
-+		audit_log_format(ab, "\"");
-+	}
-+	if (aad(sa)->mnt.data) {
-+		audit_log_format(ab, " options=");
-+		audit_log_untrustedstring(ab, aad(sa)->mnt.data);
-+	}
-+}
-+
-+/**
-+ * audit_mount - handle the auditing of mount operations
-+ * @profile: the profile being enforced  (NOT NULL)
-+ * @op: operation being mediated (NOT NULL)
-+ * @name: name of object being mediated (MAYBE NULL)
-+ * @src_name: src_name of object being mediated (MAYBE_NULL)
-+ * @type: type of filesystem (MAYBE_NULL)
-+ * @trans: name of trans (MAYBE NULL)
-+ * @flags: filesystem idependent mount flags
-+ * @data: filesystem mount flags
-+ * @request: permissions requested
-+ * @perms: the permissions computed for the request (NOT NULL)
-+ * @info: extra information message (MAYBE NULL)
-+ * @error: 0 if operation allowed else failure error code
-+ *
-+ * Returns: %0 or error on failure
-+ */
-+static int audit_mount(struct aa_profile *profile, const char *op,
-+		       const char *name, const char *src_name,
-+		       const char *type, const char *trans,
-+		       unsigned long flags, const void *data, u32 request,
-+		       struct aa_perms *perms, const char *info, int error)
-+{
-+	int audit_type = AUDIT_APPARMOR_AUTO;
-+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
-+
-+	if (likely(!error)) {
-+		u32 mask = perms->audit;
-+
-+		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
-+			mask = 0xffff;
-+
-+		/* mask off perms that are not being force audited */
-+		request &= mask;
-+
-+		if (likely(!request))
-+			return 0;
-+		audit_type = AUDIT_APPARMOR_AUDIT;
-+	} else {
-+		/* only report permissions that were denied */
-+		request = request & ~perms->allow;
-+
-+		if (request & perms->kill)
-+			audit_type = AUDIT_APPARMOR_KILL;
-+
-+		/* quiet known rejects, assumes quiet and kill do not overlap */
-+		if ((request & perms->quiet) &&
-+		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
-+		    AUDIT_MODE(profile) != AUDIT_ALL)
-+			request &= ~perms->quiet;
-+
-+		if (!request)
-+			return error;
-+	}
-+
-+	aad(&sa)->name = name;
-+	aad(&sa)->mnt.src_name = src_name;
-+	aad(&sa)->mnt.type = type;
-+	aad(&sa)->mnt.trans = trans;
-+	aad(&sa)->mnt.flags = flags;
-+	if (data && (perms->audit & AA_AUDIT_DATA))
-+		aad(&sa)->mnt.data = data;
-+	aad(&sa)->info = info;
-+	aad(&sa)->error = error;
-+
-+	return aa_audit(audit_type, profile, &sa, audit_cb);
-+}
-+
-+/**
-+ * match_mnt_flags - Do an ordered match on mount flags
-+ * @dfa: dfa to match against
-+ * @state: state to start in
-+ * @flags: mount flags to match against
-+ *
-+ * Mount flags are encoded as an ordered match. This is done instead of
-+ * checking against a simple bitmask, to allow for logical operations
-+ * on the flags.
-+ *
-+ * Returns: next state after flags match
-+ */
-+static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
-+				    unsigned long flags)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i <= 31 ; ++i) {
-+		if ((1 << i) & flags)
-+			state = aa_dfa_next(dfa, state, i + 1);
-+	}
-+
-+	return state;
-+}
-+
-+/**
-+ * compute_mnt_perms - compute mount permission associated with @state
-+ * @dfa: dfa to match against (NOT NULL)
-+ * @state: state match finished in
-+ *
-+ * Returns: mount permissions
-+ */
-+static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
-+					   unsigned int state)
-+{
-+	struct aa_perms perms;
-+
-+	perms.kill = 0;
-+	perms.allow = dfa_user_allow(dfa, state);
-+	perms.audit = dfa_user_audit(dfa, state);
-+	perms.quiet = dfa_user_quiet(dfa, state);
-+	perms.xindex = dfa_user_xindex(dfa, state);
-+
-+	return perms;
-+}
-+
-+static const char * const mnt_info_table[] = {
-+	"match succeeded",
-+	"failed mntpnt match",
-+	"failed srcname match",
-+	"failed type match",
-+	"failed flags match",
-+	"failed data match"
-+};
-+
-+/*
-+ * Returns 0 on success else element that match failed in, this is the
-+ * index into the mnt_info_table above
-+ */
-+static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
-+			const char *mntpnt, const char *devname,
-+			const char *type, unsigned long flags,
-+			void *data, bool binary, struct aa_perms *perms)
-+{
-+	unsigned int state;
-+
-+	AA_BUG(!dfa);
-+	AA_BUG(!perms);
-+
-+	state = aa_dfa_match(dfa, start, mntpnt);
-+	state = aa_dfa_null_transition(dfa, state);
-+	if (!state)
-+		return 1;
-+
-+	if (devname)
-+		state = aa_dfa_match(dfa, state, devname);
-+	state = aa_dfa_null_transition(dfa, state);
-+	if (!state)
-+		return 2;
-+
-+	if (type)
-+		state = aa_dfa_match(dfa, state, type);
-+	state = aa_dfa_null_transition(dfa, state);
-+	if (!state)
-+		return 3;
-+
-+	state = match_mnt_flags(dfa, state, flags);
-+	if (!state)
-+		return 4;
-+	*perms = compute_mnt_perms(dfa, state);
-+	if (perms->allow & AA_MAY_MOUNT)
-+		return 0;
-+
-+	/* only match data if not binary and the DFA flags data is expected */
-+	if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) {
-+		state = aa_dfa_null_transition(dfa, state);
-+		if (!state)
-+			return 4;
-+
-+		state = aa_dfa_match(dfa, state, data);
-+		if (!state)
-+			return 5;
-+		*perms = compute_mnt_perms(dfa, state);
-+		if (perms->allow & AA_MAY_MOUNT)
-+			return 0;
-+	}
-+
-+	/* failed at end of flags match */
-+	return 4;
-+}
-+
-+
-+static int path_flags(struct aa_profile *profile, const struct path *path)
-+{
-+	AA_BUG(!profile);
-+	AA_BUG(!path);
-+
-+	return profile->path_flags |
-+		(S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0);
-+}
-+
-+/**
-+ * match_mnt_path_str - handle path matching for mount
-+ * @profile: the confining profile
-+ * @mntpath: for the mntpnt (NOT NULL)
-+ * @buffer: buffer to be used to lookup mntpath
-+ * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR)
-+ * @type: string for the dev type (MAYBE NULL)
-+ * @flags: mount flags to match
-+ * @data: fs mount data (MAYBE NULL)
-+ * @binary: whether @data is binary
-+ * @devinfo: error str if (IS_ERR(@devname))
-+ *
-+ * Returns: 0 on success else error
-+ */
-+static int match_mnt_path_str(struct aa_profile *profile,
-+			      const struct path *mntpath, char *buffer,
-+			      const char *devname, const char *type,
-+			      unsigned long flags, void *data, bool binary,
-+			      const char *devinfo)
-+{
-+	struct aa_perms perms = { };
-+	const char *mntpnt = NULL, *info = NULL;
-+	int pos, error;
-+
-+	AA_BUG(!profile);
-+	AA_BUG(!mntpath);
-+	AA_BUG(!buffer);
-+
-+	error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer,
-+			     &mntpnt, &info, profile->disconnected);
-+	if (error)
-+		goto audit;
-+	if (IS_ERR(devname)) {
-+		error = PTR_ERR(devname);
-+		devname = NULL;
-+		info = devinfo;
-+		goto audit;
-+	}
-+
-+	error = -EACCES;
-+	pos = do_match_mnt(profile->policy.dfa,
-+			   profile->policy.start[AA_CLASS_MOUNT],
-+			   mntpnt, devname, type, flags, data, binary, &perms);
-+	if (pos) {
-+		info = mnt_info_table[pos];
-+		goto audit;
-+	}
-+	error = 0;
-+
-+audit:
-+	return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
-+			   flags, data, AA_MAY_MOUNT, &perms, info, error);
-+}
-+
-+/**
-+ * match_mnt - handle path matching for mount
-+ * @profile: the confining profile
-+ * @mntpath: for the mntpnt (NOT NULL)
-+ * @buffer: buffer to be used to lookup mntpath
-+ * @devpath: path devname/src_name (MAYBE NULL)
-+ * @devbuffer: buffer to be used to lookup devname/src_name
-+ * @type: string for the dev type (MAYBE NULL)
-+ * @flags: mount flags to match
-+ * @data: fs mount data (MAYBE NULL)
-+ * @binary: whether @data is binary
-+ *
-+ * Returns: 0 on success else error
-+ */
-+static int match_mnt(struct aa_profile *profile, const struct path *path,
-+		     char *buffer, struct path *devpath, char *devbuffer,
-+		     const char *type, unsigned long flags, void *data,
-+		     bool binary)
-+{
-+	const char *devname = NULL, *info = NULL;
-+	int error = -EACCES;
-+
-+	AA_BUG(!profile);
-+	AA_BUG(devpath && !devbuffer);
-+
-+	if (devpath) {
-+		error = aa_path_name(devpath, path_flags(profile, devpath),
-+				     devbuffer, &devname, &info,
-+				     profile->disconnected);
-+		if (error)
-+			devname = ERR_PTR(error);
-+	}
-+
-+	return match_mnt_path_str(profile, path, buffer, devname, type, flags,
-+				  data, binary, info);
-+}
-+
-+int aa_remount(struct aa_label *label, const struct path *path,
-+	       unsigned long flags, void *data)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL;
-+	bool binary;
-+	int error;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!path);
-+
-+	binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
-+
-+	get_buffers(buffer);
-+	error = fn_for_each_confined(label, profile,
-+			match_mnt(profile, path, buffer, NULL, NULL, NULL,
-+				  flags, data, binary));
-+	put_buffers(buffer);
-+
-+	return error;
-+}
-+
-+int aa_bind_mount(struct aa_label *label, const struct path *path,
-+		  const char *dev_name, unsigned long flags)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL, *old_buffer = NULL;
-+	struct path old_path;
-+	int error;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!path);
-+
-+	if (!dev_name || !*dev_name)
-+		return -EINVAL;
-+
-+	flags &= MS_REC | MS_BIND;
-+
-+	error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
-+	if (error)
-+		return error;
-+
-+	get_buffers(buffer, old_buffer);
-+	error = fn_for_each_confined(label, profile,
-+			match_mnt(profile, path, buffer, &old_path, old_buffer,
-+				  NULL, flags, NULL, false));
-+	put_buffers(buffer, old_buffer);
-+	path_put(&old_path);
-+
-+	return error;
-+}
-+
-+int aa_mount_change_type(struct aa_label *label, const struct path *path,
-+			 unsigned long flags)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL;
-+	int error;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!path);
-+
-+	/* These are the flags allowed by do_change_type() */
-+	flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
-+		  MS_UNBINDABLE);
-+
-+	get_buffers(buffer);
-+	error = fn_for_each_confined(label, profile,
-+			match_mnt(profile, path, buffer, NULL, NULL, NULL,
-+				  flags, NULL, false));
-+	put_buffers(buffer);
-+
-+	return error;
-+}
-+
-+int aa_move_mount(struct aa_label *label, const struct path *path,
-+		  const char *orig_name)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL, *old_buffer = NULL;
-+	struct path old_path;
-+	int error;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!path);
-+
-+	if (!orig_name || !*orig_name)
-+		return -EINVAL;
-+
-+	error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
-+	if (error)
-+		return error;
-+
-+	get_buffers(buffer, old_buffer);
-+	error = fn_for_each_confined(label, profile,
-+			match_mnt(profile, path, buffer, &old_path, old_buffer,
-+				  NULL, MS_MOVE, NULL, false));
-+	put_buffers(buffer, old_buffer);
-+	path_put(&old_path);
-+
-+	return error;
-+}
-+
-+int aa_new_mount(struct aa_label *label, const char *dev_name,
-+		 const struct path *path, const char *type, unsigned long flags,
-+		 void *data)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL, *dev_buffer = NULL;
-+	bool binary = true;
-+	int error;
-+	int requires_dev = 0;
-+	struct path tmp_path, *dev_path = NULL;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!path);
-+
-+	if (type) {
-+		struct file_system_type *fstype;
-+
-+		fstype = get_fs_type(type);
-+		if (!fstype)
-+			return -ENODEV;
-+		binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
-+		requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
-+		put_filesystem(fstype);
-+
-+		if (requires_dev) {
-+			if (!dev_name || !*dev_name)
-+				return -ENOENT;
-+
-+			error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
-+			if (error)
-+				return error;
-+			dev_path = &tmp_path;
-+		}
-+	}
-+
-+	get_buffers(buffer, dev_buffer);
-+	if (dev_path) {
-+		error = fn_for_each_confined(label, profile,
-+			match_mnt(profile, path, buffer, dev_path, dev_buffer,
-+				  type, flags, data, binary));
-+	} else {
-+		error = fn_for_each_confined(label, profile,
-+			match_mnt_path_str(profile, path, buffer, dev_name,
-+					   type, flags, data, binary, NULL));
-+	}
-+	put_buffers(buffer, dev_buffer);
-+	if (dev_path)
-+		path_put(dev_path);
-+
-+	return error;
-+}
-+
-+static int profile_umount(struct aa_profile *profile, struct path *path,
-+			  char *buffer)
-+{
-+	struct aa_perms perms = { };
-+	const char *name = NULL, *info = NULL;
-+	unsigned int state;
-+	int error;
-+
-+	AA_BUG(!profile);
-+	AA_BUG(!path);
-+
-+	error = aa_path_name(path, path_flags(profile, path), buffer, &name,
-+			     &info, profile->disconnected);
-+	if (error)
-+		goto audit;
-+
-+	state = aa_dfa_match(profile->policy.dfa,
-+			     profile->policy.start[AA_CLASS_MOUNT],
-+			     name);
-+	perms = compute_mnt_perms(profile->policy.dfa, state);
-+	if (AA_MAY_UMOUNT & ~perms.allow)
-+		error = -EACCES;
-+
-+audit:
-+	return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
-+			   AA_MAY_UMOUNT, &perms, info, error);
-+}
-+
-+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
-+{
-+	struct aa_profile *profile;
-+	char *buffer = NULL;
-+	int error;
-+	struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
-+
-+	AA_BUG(!label);
-+	AA_BUG(!mnt);
-+
-+	get_buffers(buffer);
-+	error = fn_for_each_confined(label, profile,
-+			profile_umount(profile, &path, buffer));
-+	put_buffers(buffer);
-+
-+	return error;
-+}
-+
-+/* helper fn for transition on pivotroot
-+ *
-+ * Returns: label for transition or ERR_PTR. Does not return NULL
-+ */
-+static struct aa_label *build_pivotroot(struct aa_profile *profile,
-+					const struct path *new_path,
-+					char *new_buffer,
-+					const struct path *old_path,
-+					char *old_buffer)
-+{
-+	const char *old_name, *new_name = NULL, *info = NULL;
-+	const char *trans_name = NULL;
-+	struct aa_perms perms = { };
-+	unsigned int state;
-+	int error;
-+
-+	AA_BUG(!profile);
-+	AA_BUG(!new_path);
-+	AA_BUG(!old_path);
-+
-+	if (profile_unconfined(profile))
-+		return aa_get_newest_label(&profile->label);
-+
-+	error = aa_path_name(old_path, path_flags(profile, old_path),
-+			     old_buffer, &old_name, &info,
-+			     profile->disconnected);
-+	if (error)
-+		goto audit;
-+	error = aa_path_name(new_path, path_flags(profile, new_path),
-+			     new_buffer, &new_name, &info,
-+			     profile->disconnected);
-+	if (error)
-+		goto audit;
-+
-+	error = -EACCES;
-+	state = aa_dfa_match(profile->policy.dfa,
-+			     profile->policy.start[AA_CLASS_MOUNT],
-+			     new_name);
-+	state = aa_dfa_null_transition(profile->policy.dfa, state);
-+	state = aa_dfa_match(profile->policy.dfa, state, old_name);
-+	perms = compute_mnt_perms(profile->policy.dfa, state);
-+
-+	if (AA_MAY_PIVOTROOT & perms.allow)
-+		error = 0;
-+
-+audit:
-+	error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
-+			    NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
-+			    &perms, info, error);
-+	if (error)
-+		return ERR_PTR(error);
-+
-+	return aa_get_newest_label(&profile->label);
-+}
-+
-+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
-+		 const struct path *new_path)
-+{
-+	struct aa_profile *profile;
-+	struct aa_label *target = NULL;
-+	char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
-+	int error;
-+
-+	AA_BUG(!label);
-+	AA_BUG(!old_path);
-+	AA_BUG(!new_path);
-+
-+	get_buffers(old_buffer, new_buffer);
-+	target = fn_label_build(label, profile, GFP_ATOMIC,
-+			build_pivotroot(profile, new_path, new_buffer,
-+					old_path, old_buffer));
-+	if (!target) {
-+		info = "label build failed";
-+		error = -ENOMEM;
-+		goto fail;
-+	} else if (!IS_ERR(target)) {
-+		error = aa_replace_current_label(target);
-+		if (error) {
-+			/* TODO: audit target */
-+			aa_put_label(target);
-+			goto out;
-+		}
-+	} else
-+		/* already audited error */
-+		error = PTR_ERR(target);
-+out:
-+	put_buffers(old_buffer, new_buffer);
-+
-+	return error;
-+
-+fail:
-+	/* TODO: add back in auditing of new_name and old_name */
-+	error = fn_for_each(label, profile,
-+			audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
-+				    NULL /* old_name */,
-+				    NULL, NULL,
-+				    0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
-+				    error));
-+	goto out;
-+}
--- 
-2.11.0
-
diff --git a/0008-apparmor-cleanup-conditional-check-for-label-in-labe.patch b/0008-apparmor-cleanup-conditional-check-for-label-in-labe.patch
deleted file mode 100644
index 20892df4..00000000
--- a/0008-apparmor-cleanup-conditional-check-for-label-in-labe.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 763d17c9a18b0df7dbec2740f10dc40d378e3cc1 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Sun, 6 Aug 2017 05:36:40 -0700
-Subject: [PATCH 08/17] apparmor: cleanup conditional check for label in
- label_print
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit 7e57939b9d67dcfc2c8348fd0e2c76a2f0349c75)
----
- security/apparmor/label.c | 22 ++++++++--------------
- 1 file changed, 8 insertions(+), 14 deletions(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index e324f4df3e34..38be7a89cc31 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1450,9 +1450,11 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
-  * cached label name is present and visible
-  * @label->hname only exists if label is namespace hierachical
-  */
--static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label)
-+static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label,
-+				   int flags)
- {
--	if (label->hname && labels_ns(label) == ns)
-+	if (label->hname && (!ns || labels_ns(label) == ns) &&
-+	    !(flags & ~FLAG_SHOW_MODE))
- 		return true;
- 
- 	return false;
-@@ -1710,10 +1712,8 @@ void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
- 	AA_BUG(!ab);
- 	AA_BUG(!label);
- 
--	if (!ns)
--		ns = labels_ns(label);
--
--	if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
-+	if (!use_label_hname(ns, label, flags) ||
-+	    display_mode(ns, label, flags)) {
- 		len  = aa_label_asxprint(&name, ns, label, flags, gfp);
- 		if (len == -1) {
- 			AA_DEBUG("label print error");
-@@ -1738,10 +1738,7 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
- 	AA_BUG(!f);
- 	AA_BUG(!label);
- 
--	if (!ns)
--		ns = labels_ns(label);
--
--	if (!use_label_hname(ns, label)) {
-+	if (!use_label_hname(ns, label, flags)) {
- 		char *str;
- 		int len;
- 
-@@ -1764,10 +1761,7 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
- {
- 	AA_BUG(!label);
- 
--	if (!ns)
--		ns = labels_ns(label);
--
--	if (!use_label_hname(ns, label)) {
-+	if (!use_label_hname(ns, label, flags)) {
- 		char *str;
- 		int len;
- 
--- 
-2.11.0
-
diff --git a/0009-apparmor-add-support-for-absolute-root-view-based-la.patch b/0009-apparmor-add-support-for-absolute-root-view-based-la.patch
deleted file mode 100644
index 84ee7a1d..00000000
--- a/0009-apparmor-add-support-for-absolute-root-view-based-la.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 6b092bbbf9e17b10f709d11b3bc2d7e493617934 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Sun, 6 Aug 2017 05:39:08 -0700
-Subject: [PATCH 09/17] apparmor: add support for absolute root view based
- labels
-
-With apparmor policy virtualization based on policy namespace View's
-we don't generally want/need absolute root based views, however there
-are cases like debugging and some secid based conversions where
-using a root based view is important.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit eadfbf0898eda94cee0d982626aa24a3146db48b)
----
- security/apparmor/include/label.h |  1 +
- security/apparmor/label.c         | 10 +++++++++-
- 2 files changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
-index 9a283b722755..af22dcbbcb8a 100644
---- a/security/apparmor/include/label.h
-+++ b/security/apparmor/include/label.h
-@@ -310,6 +310,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
- #define FLAG_SHOW_MODE 1
- #define FLAG_VIEW_SUBNS 2
- #define FLAG_HIDDEN_UNCONFINED 4
-+#define FLAG_ABS_ROOT 8
- int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
- 		      struct aa_label *label, int flags);
- int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index 38be7a89cc31..52b4ef14840d 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1607,8 +1607,13 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
- 	AA_BUG(!str && size != 0);
- 	AA_BUG(!label);
- 
--	if (!ns)
-+	if (flags & FLAG_ABS_ROOT) {
-+		ns = root_ns;
-+		len = snprintf(str, size, "=");
-+		update_for_len(total, len, size, str);
-+	} else if (!ns) {
- 		ns = labels_ns(label);
-+	}
- 
- 	label_for_each(i, label, profile) {
- 		if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
-@@ -1868,6 +1873,9 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
- 		if (*str == '&')
- 			str++;
- 	}
-+	if (*str == '=')
-+		base = &root_ns->unconfined->label;
-+
- 	error = vec_setup(profile, vec, len, gfp);
- 	if (error)
- 		return ERR_PTR(error);
--- 
-2.11.0
-
diff --git a/0010-apparmor-make-policy_unpack-able-to-audit-different-.patch b/0010-apparmor-make-policy_unpack-able-to-audit-different-.patch
deleted file mode 100644
index 7e481b28..00000000
--- a/0010-apparmor-make-policy_unpack-able-to-audit-different-.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-From aa4b6bded85552bc5f9f22d2e18ce86c5c17947c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Tue, 18 Jul 2017 23:37:18 -0700
-Subject: [PATCH 10/17] apparmor: make policy_unpack able to audit different
- info messages
-
-Switch unpack auditing to using the generic name field in the audit
-struct and make it so we can start adding new info messages about
-why an unpack failed.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit 1489d896c5649e9ce1b6000b4857f8baa7a6ab63)
----
- security/apparmor/include/audit.h |  4 +--
- security/apparmor/policy_unpack.c | 52 ++++++++++++++++++++++++++++-----------
- 2 files changed, 40 insertions(+), 16 deletions(-)
-
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index c3fe1c5ef3bc..620e81169659 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -127,9 +127,9 @@ struct apparmor_audit_data {
- 			} fs;
- 		};
- 		struct {
--			const char *name;
--			long pos;
-+			struct aa_profile *profile;
- 			const char *ns;
-+			long pos;
- 		} iface;
- 		int signal;
- 		struct {
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index bda0dce3b582..4ede87c30f8b 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
- 		audit_log_format(ab, " ns=");
- 		audit_log_untrustedstring(ab, aad(sa)->iface.ns);
- 	}
--	if (aad(sa)->iface.name) {
-+	if (aad(sa)->name) {
- 		audit_log_format(ab, " name=");
--		audit_log_untrustedstring(ab, aad(sa)->iface.name);
-+		audit_log_untrustedstring(ab, aad(sa)->name);
- 	}
- 	if (aad(sa)->iface.pos)
- 		audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
-@@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
- 		aad(&sa)->iface.pos = e->pos - e->start;
- 	aad(&sa)->iface.ns = ns_name;
- 	if (new)
--		aad(&sa)->iface.name = new->base.hname;
-+		aad(&sa)->name = new->base.hname;
- 	else
--		aad(&sa)->iface.name = name;
-+		aad(&sa)->name = name;
- 	aad(&sa)->info = info;
- 	aad(&sa)->error = error;
- 
-@@ -583,6 +583,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- {
- 	struct aa_profile *profile = NULL;
- 	const char *tmpname, *tmpns = NULL, *name = NULL;
-+	const char *info = "failed to unpack profile";
- 	size_t ns_len;
- 	struct rhashtable_params params = { 0 };
- 	char *key = NULL;
-@@ -604,8 +605,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
- 	if (tmpns) {
- 		*ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
--		if (!*ns_name)
-+		if (!*ns_name) {
-+			info = "out of memory";
- 			goto fail;
-+		}
- 		name = tmpname;
- 	}
- 
-@@ -624,12 +627,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	if (IS_ERR(profile->xmatch)) {
- 		error = PTR_ERR(profile->xmatch);
- 		profile->xmatch = NULL;
-+		info = "bad xmatch";
- 		goto fail;
- 	}
- 	/* xmatch_len is not optional if xmatch is set */
- 	if (profile->xmatch) {
--		if (!unpack_u32(e, &tmp, NULL))
-+		if (!unpack_u32(e, &tmp, NULL)) {
-+			info = "missing xmatch len";
- 			goto fail;
-+		}
- 		profile->xmatch_len = tmp;
- 	}
- 
-@@ -637,8 +643,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	(void) unpack_str(e, &profile->disconnected, "disconnected");
- 
- 	/* per profile debug flags (complain, audit) */
--	if (!unpack_nameX(e, AA_STRUCT, "flags"))
-+	if (!unpack_nameX(e, AA_STRUCT, "flags")) {
-+		info = "profile missing flags";
- 		goto fail;
-+	}
-+	info = "failed to unpack profile flags";
- 	if (!unpack_u32(e, &tmp, NULL))
- 		goto fail;
- 	if (tmp & PACKED_FLAG_HAT)
-@@ -667,6 +676,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 		/* set a default value if path_flags field is not present */
- 		profile->path_flags = PATH_MEDIATE_DELETED;
- 
-+	info = "failed to unpack profile capabilities";
- 	if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
- 		goto fail;
- 	if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
-@@ -676,6 +686,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	if (!unpack_u32(e, &tmpcap.cap[0], NULL))
- 		goto fail;
- 
-+	info = "failed to unpack upper profile capabilities";
- 	if (unpack_nameX(e, AA_STRUCT, "caps64")) {
- 		/* optional upper half of 64 bit caps */
- 		if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
-@@ -690,6 +701,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 			goto fail;
- 	}
- 
-+	info = "failed to unpack extended profile capabilities";
- 	if (unpack_nameX(e, AA_STRUCT, "capsx")) {
- 		/* optional extended caps mediation mask */
- 		if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
-@@ -700,11 +712,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 			goto fail;
- 	}
- 
--	if (!unpack_rlimits(e, profile))
-+	if (!unpack_rlimits(e, profile)) {
-+		info = "failed to unpack profile rlimits";
- 		goto fail;
-+	}
- 
- 	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
- 		/* generic policy dfa - optional and may be NULL */
-+		info = "failed to unpack policydb";
- 		profile->policy.dfa = unpack_dfa(e);
- 		if (IS_ERR(profile->policy.dfa)) {
- 			error = PTR_ERR(profile->policy.dfa);
-@@ -734,6 +749,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	if (IS_ERR(profile->file.dfa)) {
- 		error = PTR_ERR(profile->file.dfa);
- 		profile->file.dfa = NULL;
-+		info = "failed to unpack profile file rules";
- 		goto fail;
- 	} else if (profile->file.dfa) {
- 		if (!unpack_u32(e, &profile->file.start, "dfa_start"))
-@@ -746,10 +762,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 	} else
- 		profile->file.dfa = aa_get_dfa(nulldfa);
- 
--	if (!unpack_trans_table(e, profile))
-+	if (!unpack_trans_table(e, profile)) {
-+		info = "failed to unpack profile transition table";
- 		goto fail;
-+	}
- 
- 	if (unpack_nameX(e, AA_STRUCT, "data")) {
-+		info = "out of memory";
- 		profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
- 		if (!profile->data)
- 			goto fail;
-@@ -761,8 +780,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 		params.hashfn = strhash;
- 		params.obj_cmpfn = datacmp;
- 
--		if (rhashtable_init(profile->data, &params))
-+		if (rhashtable_init(profile->data, &params)) {
-+			info = "failed to init key, value hash table";
- 			goto fail;
-+		}
- 
- 		while (unpack_strdup(e, &key, NULL)) {
- 			data = kzalloc(sizeof(*data), GFP_KERNEL);
-@@ -784,12 +805,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 					       profile->data->p);
- 		}
- 
--		if (!unpack_nameX(e, AA_STRUCTEND, NULL))
-+		if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
-+			info = "failed to unpack end of key, value data table";
- 			goto fail;
-+		}
- 	}
- 
--	if (!unpack_nameX(e, AA_STRUCTEND, NULL))
-+	if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
-+		info = "failed to unpack end of profile";
- 		goto fail;
-+	}
- 
- 	return profile;
- 
-@@ -798,8 +823,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- 		name = NULL;
- 	else if (!name)
- 		name = "unknown";
--	audit_iface(profile, NULL, name, "failed to unpack profile", e,
--		    error);
-+	audit_iface(profile, NULL, name, info, e, error);
- 	aa_free_profile(profile);
- 
- 	return ERR_PTR(error);
--- 
-2.11.0
-
diff --git a/0011-apparmor-add-more-debug-asserts-to-apparmorfs.patch b/0011-apparmor-add-more-debug-asserts-to-apparmorfs.patch
deleted file mode 100644
index 85eafc85..00000000
--- a/0011-apparmor-add-more-debug-asserts-to-apparmorfs.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From ba3f778a2ef31454032c2ca9c99d9212feb4dcf1 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Tue, 18 Jul 2017 23:41:13 -0700
-Subject: [PATCH 11/17] apparmor: add more debug asserts to apparmorfs
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-Acked-by: Seth Arnold <seth.arnold at canonical.com>
-(cherry picked from commit 52c9542126fb04df1f12c605b6c22719c9096794)
----
- security/apparmor/apparmorfs.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 8fa6c898c44b..7acea14c850b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1446,6 +1446,10 @@ void __aafs_profile_migrate_dents(struct aa_profile *old,
- {
- 	int i;
- 
-+	AA_BUG(!old);
-+	AA_BUG(!new);
-+	AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
-+
- 	for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
- 		new->dents[i] = old->dents[i];
- 		if (new->dents[i])
-@@ -1509,6 +1513,9 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- 	struct dentry *dent = NULL, *dir;
- 	int error;
- 
-+	AA_BUG(!profile);
-+	AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
-+
- 	if (!parent) {
- 		struct aa_profile *p;
- 		p = aa_deref_parent(profile);
-@@ -1734,6 +1741,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
- 
- 	if (!ns)
- 		return;
-+	AA_BUG(!mutex_is_locked(&ns->lock));
- 
- 	list_for_each_entry(child, &ns->base.profiles, base.list)
- 		__aafs_profile_rmdir(child);
-@@ -1906,6 +1914,10 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
- {
- 	struct aa_ns *parent, *next;
- 
-+	AA_BUG(!root);
-+	AA_BUG(!ns);
-+	AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
-+
- 	/* is next namespace a child */
- 	if (!list_empty(&ns->sub_ns)) {
- 		next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
-@@ -1940,6 +1952,9 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
- static struct aa_profile *__first_profile(struct aa_ns *root,
- 					  struct aa_ns *ns)
- {
-+	AA_BUG(!root);
-+	AA_BUG(ns && !mutex_is_locked(&ns->lock));
-+
- 	for (; ns; ns = __next_ns(root, ns)) {
- 		if (!list_empty(&ns->base.profiles))
- 			return list_first_entry(&ns->base.profiles,
-@@ -1962,6 +1977,8 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
- 	struct aa_profile *parent;
- 	struct aa_ns *ns = p->ns;
- 
-+	AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
-+
- 	/* is next profile a child */
- 	if (!list_empty(&p->base.profiles))
- 		return list_first_entry(&p->base.profiles, typeof(*p),
--- 
-2.11.0
-
diff --git a/0013-apparmor-move-new_null_profile-to-after-profile-look.patch b/0013-apparmor-move-new_null_profile-to-after-profile-look.patch
deleted file mode 100644
index f1337f3c..00000000
--- a/0013-apparmor-move-new_null_profile-to-after-profile-look.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From 50d30adbef98a0b6cc531a9413d05f564eb633ee Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Wed, 16 Aug 2017 08:59:57 -0700
-Subject: [PATCH 13/17] apparmor: move new_null_profile to after profile lookup
- fns()
-
-new_null_profile will need to use some of the profile lookup fns()
-so move instead of doing forward fn declarations.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit cf1e50dfc6f627bc2989b57076b129c330fb3f0a)
----
- security/apparmor/policy.c | 158 ++++++++++++++++++++++-----------------------
- 1 file changed, 79 insertions(+), 79 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 244ea4a4a8f0..a81a384a63b1 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -289,85 +289,6 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
- 	return NULL;
- }
- 
--/**
-- * aa_new_null_profile - create or find a null-X learning profile
-- * @parent: profile that caused this profile to be created (NOT NULL)
-- * @hat: true if the null- learning profile is a hat
-- * @base: name to base the null profile off of
-- * @gfp: type of allocation
-- *
-- * Find/Create a null- complain mode profile used in learning mode.  The
-- * name of the profile is unique and follows the format of parent//null-XXX.
-- * where XXX is based on the @name or if that fails or is not supplied
-- * a unique number
-- *
-- * null profiles are added to the profile list but the list does not
-- * hold a count on them so that they are automatically released when
-- * not in use.
-- *
-- * Returns: new refcounted profile else NULL on failure
-- */
--struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
--				       const char *base, gfp_t gfp)
--{
--	struct aa_profile *profile;
--	char *name;
--
--	AA_BUG(!parent);
--
--	if (base) {
--		name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
--			       gfp);
--		if (name) {
--			sprintf(name, "%s//null-%s", parent->base.hname, base);
--			goto name;
--		}
--		/* fall through to try shorter uniq */
--	}
--
--	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
--	if (!name)
--		return NULL;
--	sprintf(name, "%s//null-%x", parent->base.hname,
--		atomic_inc_return(&parent->ns->uniq_null));
--
--name:
--	/* lookup to see if this is a dup creation */
--	profile = aa_find_child(parent, basename(name));
--	if (profile)
--		goto out;
--
--	profile = aa_alloc_profile(name, NULL, gfp);
--	if (!profile)
--		goto fail;
--
--	profile->mode = APPARMOR_COMPLAIN;
--	profile->label.flags |= FLAG_NULL;
--	if (hat)
--		profile->label.flags |= FLAG_HAT;
--	profile->path_flags = parent->path_flags;
--
--	/* released on free_profile */
--	rcu_assign_pointer(profile->parent, aa_get_profile(parent));
--	profile->ns = aa_get_ns(parent->ns);
--	profile->file.dfa = aa_get_dfa(nulldfa);
--	profile->policy.dfa = aa_get_dfa(nulldfa);
--
--	mutex_lock(&profile->ns->lock);
--	__add_profile(&parent->base.profiles, profile);
--	mutex_unlock(&profile->ns->lock);
--
--	/* refcount released by caller */
--out:
--	kfree(name);
--
--	return profile;
--
--fail:
--	aa_free_profile(profile);
--	return NULL;
--}
--
- /* TODO: profile accounting - setup in remove */
- 
- /**
-@@ -559,6 +480,85 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- }
- 
- /**
-+ * aa_new_null_profile - create or find a null-X learning profile
-+ * @parent: profile that caused this profile to be created (NOT NULL)
-+ * @hat: true if the null- learning profile is a hat
-+ * @base: name to base the null profile off of
-+ * @gfp: type of allocation
-+ *
-+ * Find/Create a null- complain mode profile used in learning mode.  The
-+ * name of the profile is unique and follows the format of parent//null-XXX.
-+ * where XXX is based on the @name or if that fails or is not supplied
-+ * a unique number
-+ *
-+ * null profiles are added to the profile list but the list does not
-+ * hold a count on them so that they are automatically released when
-+ * not in use.
-+ *
-+ * Returns: new refcounted profile else NULL on failure
-+ */
-+struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
-+				       const char *base, gfp_t gfp)
-+{
-+	struct aa_profile *profile;
-+	char *name;
-+
-+	AA_BUG(!parent);
-+
-+	if (base) {
-+		name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
-+			       gfp);
-+		if (name) {
-+			sprintf(name, "%s//null-%s", parent->base.hname, base);
-+			goto name;
-+		}
-+		/* fall through to try shorter uniq */
-+	}
-+
-+	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
-+	if (!name)
-+		return NULL;
-+	sprintf(name, "%s//null-%x", parent->base.hname,
-+		atomic_inc_return(&parent->ns->uniq_null));
-+
-+name:
-+	/* lookup to see if this is a dup creation */
-+	profile = aa_find_child(parent, basename(name));
-+	if (profile)
-+		goto out;
-+
-+	profile = aa_alloc_profile(name, NULL, gfp);
-+	if (!profile)
-+		goto fail;
-+
-+	profile->mode = APPARMOR_COMPLAIN;
-+	profile->label.flags |= FLAG_NULL;
-+	if (hat)
-+		profile->label.flags |= FLAG_HAT;
-+	profile->path_flags = parent->path_flags;
-+
-+	/* released on free_profile */
-+	rcu_assign_pointer(profile->parent, aa_get_profile(parent));
-+	profile->ns = aa_get_ns(parent->ns);
-+	profile->file.dfa = aa_get_dfa(nulldfa);
-+	profile->policy.dfa = aa_get_dfa(nulldfa);
-+
-+	mutex_lock(&profile->ns->lock);
-+	__add_profile(&parent->base.profiles, profile);
-+	mutex_unlock(&profile->ns->lock);
-+
-+	/* refcount released by caller */
-+out:
-+	kfree(name);
-+
-+	return profile;
-+
-+fail:
-+	aa_free_profile(profile);
-+	return NULL;
-+}
-+
-+/**
-  * replacement_allowed - test to see if replacement is allowed
-  * @profile: profile to test if it can be replaced  (MAYBE NULL)
-  * @noreplace: true if replacement shouldn't be allowed but addition is okay
--- 
-2.11.0
-
diff --git a/0014-apparmor-fix-race-condition-in-null-profile-creation.patch b/0014-apparmor-fix-race-condition-in-null-profile-creation.patch
deleted file mode 100644
index ae57b4bd..00000000
--- a/0014-apparmor-fix-race-condition-in-null-profile-creation.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From ab3b869791b6122c7be7e68ca4c08e2c2e8815ac Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Wed, 16 Aug 2017 05:40:49 -0700
-Subject: [PATCH 14/17] apparmor: fix race condition in null profile creation
-
-There is a race when null- profile is being created between the
-initial lookup/creation of the profile and lock/addition of the
-profile. This could result in multiple version of a profile being
-added to the list which need to be removed/replaced.
-
-Since these are learning profile their is no affect on mediation.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit 3aa3de2a4fb8f33ec62b00998bc6b6c6850d41b1)
----
- security/apparmor/policy.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index a81a384a63b1..4243b0c3f0e4 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -500,7 +500,8 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- 				       const char *base, gfp_t gfp)
- {
--	struct aa_profile *profile;
-+	struct aa_profile *p, *profile;
-+	const char *bname;
- 	char *name;
- 
- 	AA_BUG(!parent);
-@@ -523,7 +524,8 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- 
- name:
- 	/* lookup to see if this is a dup creation */
--	profile = aa_find_child(parent, basename(name));
-+	bname = basename(name);
-+	profile = aa_find_child(parent, bname);
- 	if (profile)
- 		goto out;
- 
-@@ -544,7 +546,13 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- 	profile->policy.dfa = aa_get_dfa(nulldfa);
- 
- 	mutex_lock(&profile->ns->lock);
--	__add_profile(&parent->base.profiles, profile);
-+	p = __find_child(&parent->base.profiles, bname);
-+	if (p) {
-+		aa_free_profile(profile);
-+		profile = aa_get_profile(p);
-+	} else {
-+		__add_profile(&parent->base.profiles, profile);
-+	}
- 	mutex_unlock(&profile->ns->lock);
- 
- 	/* refcount released by caller */
--- 
-2.11.0
-
diff --git a/0015-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch b/0015-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch
deleted file mode 100644
index 1ceb9900..00000000
--- a/0015-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 7f2cdd6453518ff76c3855255c91306a2b928c9a Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Wed, 16 Aug 2017 05:48:06 -0700
-Subject: [PATCH 15/17] apparmor: ensure unconfined profiles have dfas
- initialized
-
-Generally unconfined has early bailout tests and does not need the
-dfas initialized, however if an early bailout test is ever missed
-it will result in an oops.
-
-Be defensive and initialize the unconfined profile to have null dfas
-(no permission) so if an early bailout test is missed we fail
-closed (no perms granted) instead of oopsing.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit 034ad2d248927722bdcd1aedb62634cdc2049113)
----
- security/apparmor/policy_ns.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index 351d3bab3a3d..62a3589c62ab 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -112,6 +112,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
- 	ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
- 		FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
- 	ns->unconfined->mode = APPARMOR_UNCONFINED;
-+	ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
-+	ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
- 
- 	/* ns and ns->unconfined share ns->unconfined refcount */
- 	ns->unconfined->ns = ns;
--- 
-2.11.0
-
diff --git a/0016-apparmor-fix-incorrect-type-assignment-when-freeing-.patch b/0016-apparmor-fix-incorrect-type-assignment-when-freeing-.patch
deleted file mode 100644
index 9ff09f80..00000000
--- a/0016-apparmor-fix-incorrect-type-assignment-when-freeing-.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 8daf877473653c06a28c86bf72d63ce7e5c1d542 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Wed, 16 Aug 2017 09:33:48 -0700
-Subject: [PATCH 16/17] apparmor: fix incorrect type assignment when freeing
- proxies
-
-sparse reports
-
-poisoning the proxy->label before freeing the struct is resulting in
-a sparse build warning.
-../security/apparmor/label.c:52:30: warning: incorrect type in assignment (different address spaces)
-../security/apparmor/label.c:52:30:    expected struct aa_label [noderef] <asn:4>*label
-../security/apparmor/label.c:52:30:    got struct aa_label *<noident>
-
-fix with RCU_INIT_POINTER as this is one of those cases where
-rcu_assign_pointer() is not needed.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
-(cherry picked from commit 76e22e212a850bbd16cf49f9c586d4635507e0b5)
----
- security/apparmor/label.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index 52b4ef14840d..c5b99b954580 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -49,7 +49,7 @@ static void free_proxy(struct aa_proxy *proxy)
- 		/* p->label will not updated any more as p is dead */
- 		aa_put_label(rcu_dereference_protected(proxy->label, true));
- 		memset(proxy, 0, sizeof(*proxy));
--		proxy->label = (struct aa_label *) PROXY_POISON;
-+		RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON);
- 		kfree(proxy);
- 	}
- }
--- 
-2.11.0
-
diff --git a/kernel-aufs4.patch b/kernel-aufs4.patch
index e0eb9ca1..d11a0aa1 100644
--- a/kernel-aufs4.patch
+++ b/kernel-aufs4.patch
@@ -24,10 +24,10 @@ index 7bbaca9..a026491 100644
 aufs4.x-rcN base patch
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 1c3feff..1a12137 100644
+index af0cb69..d360d2e 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -2392,6 +2392,19 @@ F:	include/linux/audit.h
+@@ -2465,6 +2465,19 @@ F:	include/linux/audit.h
  F:	include/uapi/linux/audit.h
  F:	kernel/audit*
  
@@ -48,10 +48,10 @@ index 1c3feff..1a12137 100644
  M:	Miguel Ojeda Sandonis <miguel.ojeda.sandonis at gmail.com>
  W:	http://miguelojeda.es/auxdisplay.htm
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
-index f321b96..10707c3 100644
+index 85de673..d44de9d 100644
 --- a/drivers/block/loop.c
 +++ b/drivers/block/loop.c
-@@ -700,6 +700,24 @@ static inline int is_loop_device(struct file *file)
+@@ -686,6 +686,24 @@ static inline int is_loop_device(struct file *file)
  	return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
  }
  
@@ -90,7 +90,7 @@ index f901413..e3719a5 100644
  		   void (*finish)(void *))
  {
 diff --git a/fs/fcntl.c b/fs/fcntl.c
-index 3b01b64..659760e 100644
+index 448a111..f51c2cf 100644
 --- a/fs/fcntl.c
 +++ b/fs/fcntl.c
 @@ -31,7 +31,7 @@
@@ -112,10 +112,10 @@ index 3b01b64..659760e 100644
  		return error;
  
 diff --git a/fs/inode.c b/fs/inode.c
-index 5037059..73820bf 100644
+index d1e35b5..f7800d6 100644
 --- a/fs/inode.c
 +++ b/fs/inode.c
-@@ -1641,7 +1641,7 @@ EXPORT_SYMBOL(generic_update_time);
+@@ -1655,7 +1655,7 @@ EXPORT_SYMBOL(generic_update_time);
   * This does the actual work of updating an inodes time or version.  Must have
   * had called mnt_want_write() before calling this.
   */
@@ -124,13 +124,30 @@ index 5037059..73820bf 100644
  {
  	int (*update_time)(struct inode *, struct timespec *, int);
  
+diff --git a/fs/namespace.c b/fs/namespace.c
+index d18deb4..e5a4a7f 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -846,6 +846,12 @@ static inline int check_mnt(struct mount *mnt)
+ 	return mnt->mnt_ns == current->nsproxy->mnt_ns;
+ }
+ 
++/* for aufs, CONFIG_AUFS_BR_FUSE */
++int is_current_mnt_ns(struct vfsmount *mnt)
++{
++	return check_mnt(real_mount(mnt));
++}
++
+ /*
+  * vfsmount lock must be held for write
+  */
 diff --git a/fs/read_write.c b/fs/read_write.c
-index 0cc7033..6e542f0 100644
+index f0d4b16..6aa8c7a 100644
 --- a/fs/read_write.c
 +++ b/fs/read_write.c
-@@ -473,6 +473,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+@@ -483,6 +483,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+ 		return -EINVAL;
  }
- EXPORT_SYMBOL(__vfs_write);
  
 +vfs_readf_t vfs_readf(struct file *file)
 +{
@@ -154,14 +171,14 @@ index 0cc7033..6e542f0 100644
 +	return ERR_PTR(-ENOSYS);
 +}
 +
- ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
  {
  	mm_segment_t old_fs;
 diff --git a/fs/splice.c b/fs/splice.c
-index ae41201..9753304 100644
+index f3084cc..eb888c6 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -853,8 +853,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -837,8 +837,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -172,7 +189,7 @@ index ae41201..9753304 100644
  {
  	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  				loff_t *, size_t, unsigned int);
-@@ -870,9 +870,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -854,9 +854,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  /*
   * Attempt to initiate a splice from a file to a pipe.
   */
@@ -186,7 +203,7 @@ index ae41201..9753304 100644
  	ssize_t (*splice_read)(struct file *, loff_t *,
  			       struct pipe_inode_info *, size_t, unsigned int);
 diff --git a/fs/sync.c b/fs/sync.c
-index 2a54c1f..7a5fa3f 100644
+index a576aa2..eb61780 100644
 --- a/fs/sync.c
 +++ b/fs/sync.c
 @@ -27,7 +27,7 @@
@@ -211,10 +228,10 @@ index 61eb82c..e700888 100644
  static inline void fput_light(struct file *file, int fput_needed)
  {
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index cbfe127..9b21bb5 100644
+index 13dab19..8ab6566 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
-@@ -1262,6 +1262,7 @@ extern void fasync_free(struct fasync_struct *);
+@@ -1264,6 +1264,7 @@ extern void fasync_free(struct fasync_struct *);
  /* can be called from interrupts */
  extern void kill_fasync(struct fasync_struct **, int, int);
  
@@ -222,7 +239,7 @@ index cbfe127..9b21bb5 100644
  extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
  extern int f_setown(struct file *filp, unsigned long arg, int force);
  extern void f_delown(struct file *filp);
-@@ -1683,6 +1684,7 @@ struct file_operations {
+@@ -1710,6 +1711,7 @@ struct file_operations {
  	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
  	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
  	int (*check_flags)(int);
@@ -230,7 +247,7 @@ index cbfe127..9b21bb5 100644
  	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);
-@@ -1753,6 +1755,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+@@ -1780,6 +1782,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
  			      struct iovec *fast_pointer,
  			      struct iovec **ret_pointer);
  
@@ -241,9 +258,9 @@ index cbfe127..9b21bb5 100644
 +vfs_writef_t vfs_writef(struct file *file);
 +
  extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
- extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
  extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
-@@ -2157,6 +2165,7 @@ extern int current_umask(void);
+ extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
+@@ -2182,6 +2190,7 @@ extern int current_umask(void);
  extern void ihold(struct inode * inode);
  extern void iput(struct inode *);
  extern int generic_update_time(struct inode *, struct timespec *, int);
@@ -251,7 +268,7 @@ index cbfe127..9b21bb5 100644
  
  /* /sys/fs */
  extern struct kobject *fs_kobj;
-@@ -2437,6 +2446,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
+@@ -2462,6 +2471,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
  	return false;
  }
  #endif
@@ -259,6 +276,46 @@ index cbfe127..9b21bb5 100644
  extern int sync_filesystem(struct super_block *);
  extern const struct file_operations def_blk_fops;
  extern const struct file_operations def_chr_fops;
+diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
+index bfa8e0b..728d810 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -405,6 +405,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);
++
+ /*
+  * Acquire a lock.
+  *
+@@ -529,6 +531,7 @@ struct lock_class_key { };
+ 
+ #define lockdep_depth(tsk)	(0)
+ 
++#define lockdep_is_held(lock)			(1)
+ #define lockdep_is_held_type(l, r)		(1)
+ 
+ #define lockdep_assert_held(l)			do { (void)(l); } while (0)
+diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
+index 12b2ab5..8b810d1 100644
+--- a/include/linux/mnt_namespace.h
++++ b/include/linux/mnt_namespace.h
+@@ -5,11 +5,14 @@
+ struct mnt_namespace;
+ struct fs_struct;
+ struct user_namespace;
++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 int is_current_mnt_ns(struct vfsmount *mnt);
++
+ 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 db42746..12f3a5a 100644
 --- a/include/linux/splice.h
@@ -274,13 +331,34 @@ index db42746..12f3a5a 100644
 +			 struct pipe_inode_info *pipe, size_t len,
 +			 unsigned int flags);
  #endif
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index e36e652..bc97a97 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -144,7 +144,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+ unsigned long nr_lock_classes;
+ static struct lock_class lock_classes[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)
+ {
+ 	if (!hlock->class_idx) {
+ 		/*
+@@ -155,6 +155,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
+ 	}
+ 	return lock_classes + hlock->class_idx - 1;
+ }
++#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);
 aufs4.x-rcN mmap patch
 
 diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 719c2e9..a1b7968 100644
+index ad3b076..ad4a50d 100644
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
-@@ -1986,7 +1986,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
+@@ -1987,7 +1987,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
  	down_read(&mm->mmap_sem);
  	vma = find_exact_vma(mm, vm_start, vm_end);
  	if (vma && vma->vm_file) {
@@ -306,10 +384,10 @@ index 7563437..7c0dc0f 100644
  		ino = inode->i_ino;
  	}
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index fe8f326..b2f7f1a 100644
+index 5589b4b..f60aea2 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
-@@ -293,7 +293,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+@@ -309,7 +309,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
  	const char *name = NULL;
  
  	if (file) {
@@ -321,7 +399,7 @@ index fe8f326..b2f7f1a 100644
  		dev = inode->i_sb->s_dev;
  		ino = inode->i_ino;
  		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
-@@ -1640,7 +1643,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+@@ -1734,7 +1737,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
  	struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
  	struct vm_area_struct *vma = v;
  	struct numa_maps *md = &numa_priv->md;
@@ -331,10 +409,10 @@ index fe8f326..b2f7f1a 100644
  	struct mm_walk walk = {
  		.hugetlb_entry = gather_hugetlb_stats,
 diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
-index 23266694..58e59b6 100644
+index b00b7660..93e8a86 100644
 --- a/fs/proc/task_nommu.c
 +++ b/fs/proc/task_nommu.c
-@@ -157,7 +157,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
+@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
  	file = vma->vm_file;
  
  	if (file) {
@@ -347,10 +425,10 @@ index 23266694..58e59b6 100644
  		ino = inode->i_ino;
  		pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
 diff --git a/include/linux/mm.h b/include/linux/mm.h
-index 46b9ac5..62ba1c3 100644
+index 065d99d..04486c3 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
-@@ -1306,6 +1306,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -1348,6 +1348,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
  }
  #endif
  
@@ -380,10 +458,10 @@ index 46b9ac5..62ba1c3 100644
  		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 3cadee0..d0142c1 100644
+index 1861ea8..d85a914 100644
 --- a/include/linux/mm_types.h
 +++ b/include/linux/mm_types.h
-@@ -259,6 +259,7 @@ struct vm_region {
+@@ -260,6 +260,7 @@ 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 */
@@ -391,19 +469,19 @@ index 3cadee0..d0142c1 100644
  
  	int		vm_usage;	/* region usage count (access under nommu_region_sem) */
  	bool		vm_icache_flushed : 1; /* true if the icache has been flushed for
-@@ -333,6 +334,7 @@ struct vm_area_struct {
+@@ -334,6 +335,7 @@ 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). */
 +	struct file *vm_prfile;		/* shadow of vm_file */
  	void * vm_private_data;		/* was vm_pte (shared mem) */
  
- #ifndef CONFIG_MMU
+ 	atomic_long_t swap_readahead_info;
 diff --git a/kernel/fork.c b/kernel/fork.c
-index cbbea27..f0fd8a1 100644
+index 07cc743..b1d2b43 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -663,7 +663,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
+@@ -676,7 +676,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
  			struct inode *inode = file_inode(file);
  			struct address_space *mapping = file->f_mapping;
  
@@ -413,7 +491,7 @@ index cbbea27..f0fd8a1 100644
  				atomic_dec(&inode->i_writecount);
  			i_mmap_lock_write(mapping);
 diff --git a/mm/Makefile b/mm/Makefile
-index 411bd24..e7de927 100644
+index e3ac3ae..745b26c 100644
 --- a/mm/Makefile
 +++ b/mm/Makefile
 @@ -39,7 +39,7 @@ obj-y			:= filemap.o mempool.o oom_kill.o \
@@ -426,10 +504,10 @@ index 411bd24..e7de927 100644
  obj-y += init-mm.o
  
 diff --git a/mm/filemap.c b/mm/filemap.c
-index 0b41c8c..c5262ff 100644
+index 594d73f..7183aef 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
-@@ -2543,7 +2543,7 @@ int filemap_page_mkwrite(struct vm_fault *vmf)
+@@ -2590,7 +2590,7 @@ int filemap_page_mkwrite(struct vm_fault *vmf)
  	int ret = VM_FAULT_LOCKED;
  
  	sb_start_pagefault(inode->i_sb);
@@ -439,10 +517,10 @@ index 0b41c8c..c5262ff 100644
  	if (page->mapping != inode->i_mapping) {
  		unlock_page(page);
 diff --git a/mm/mmap.c b/mm/mmap.c
-index f19efcf..7fdd59e 100644
+index 680506f..081406a 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
-@@ -170,7 +170,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+@@ -171,7 +171,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
  	if (vma->vm_ops && vma->vm_ops->close)
  		vma->vm_ops->close(vma);
  	if (vma->vm_file)
@@ -451,7 +529,7 @@ index f19efcf..7fdd59e 100644
  	mpol_put(vma_policy(vma));
  	kmem_cache_free(vm_area_cachep, vma);
  	return next;
-@@ -895,7 +895,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
+@@ -896,7 +896,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
  	if (remove_next) {
  		if (file) {
  			uprobe_munmap(next, next->vm_start, next->vm_end);
@@ -460,7 +538,7 @@ index f19efcf..7fdd59e 100644
  		}
  		if (next->anon_vma)
  			anon_vma_merge(vma, next);
-@@ -1745,8 +1745,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+@@ -1746,8 +1746,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
  	return addr;
  
  unmap_and_free_vma:
@@ -470,7 +548,7 @@ index f19efcf..7fdd59e 100644
  
  	/* Undo any partial mapping done by a device driver. */
  	unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
-@@ -2568,7 +2568,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2569,7 +2569,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
  		goto out_free_mpol;
  
  	if (new->vm_file)
@@ -479,7 +557,7 @@ index f19efcf..7fdd59e 100644
  
  	if (new->vm_ops && new->vm_ops->open)
  		new->vm_ops->open(new);
-@@ -2587,7 +2587,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2588,7 +2588,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
  	if (new->vm_ops && new->vm_ops->close)
  		new->vm_ops->close(new);
  	if (new->vm_file)
@@ -488,7 +566,7 @@ index f19efcf..7fdd59e 100644
  	unlink_anon_vmas(new);
   out_free_mpol:
  	mpol_put(vma_policy(new));
-@@ -2741,7 +2741,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+@@ -2750,7 +2750,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
  	struct vm_area_struct *vma;
  	unsigned long populate = 0;
  	unsigned long ret = -EINVAL;
@@ -497,7 +575,7 @@ index f19efcf..7fdd59e 100644
  
  	pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n",
  		     current->comm, current->pid);
-@@ -2816,10 +2816,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+@@ -2825,10 +2825,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
  		}
  	}
  
@@ -526,7 +604,7 @@ index f19efcf..7fdd59e 100644
  out:
  	up_write(&mm->mmap_sem);
  	if (populate)
-@@ -3110,7 +3127,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -3136,7 +3153,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)
@@ -536,7 +614,7 @@ index f19efcf..7fdd59e 100644
  			new_vma->vm_ops->open(new_vma);
  		vma_link(mm, new_vma, prev, rb_link, rb_parent);
 diff --git a/mm/nommu.c b/mm/nommu.c
-index fc184f5..637ea81 100644
+index 17c00d9..4bcdf94 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
 @@ -641,7 +641,7 @@ static void __put_nommu_region(struct vm_region *region)
@@ -557,7 +635,7 @@ index fc184f5..637ea81 100644
  	put_nommu_region(vma->vm_region);
  	kmem_cache_free(vm_area_cachep, vma);
  }
-@@ -1326,7 +1326,7 @@ unsigned long do_mmap(struct file *file,
+@@ -1321,7 +1321,7 @@ unsigned long do_mmap(struct file *file,
  					goto error_just_free;
  				}
  			}
@@ -566,7 +644,7 @@ index fc184f5..637ea81 100644
  			kmem_cache_free(vm_region_jar, region);
  			region = pregion;
  			result = start;
-@@ -1401,10 +1401,10 @@ unsigned long do_mmap(struct file *file,
+@@ -1396,10 +1396,10 @@ unsigned long do_mmap(struct file *file,
  	up_write(&nommu_region_sem);
  error:
  	if (region->vm_file)
@@ -693,7 +771,7 @@ index e3719a5..3203470 100644
  /**
   * d_ancestor - search for an ancestor
 diff --git a/fs/exec.c b/fs/exec.c
-index 62175cb..f0b6fdd 100644
+index 3e14ba2..6818b01 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -109,6 +109,7 @@ bool path_noexec(const struct path *path)
@@ -705,7 +783,7 @@ index 62175cb..f0b6fdd 100644
  #ifdef CONFIG_USELIB
  /*
 diff --git a/fs/fcntl.c b/fs/fcntl.c
-index 659760e..5c37087 100644
+index f51c2cf..58bf222 100644
 --- a/fs/fcntl.c
 +++ b/fs/fcntl.c
 @@ -84,6 +84,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
@@ -717,7 +795,7 @@ index 659760e..5c37087 100644
  static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
                       int force)
 diff --git a/fs/file_table.c b/fs/file_table.c
-index 72e861a..01ae52f 100644
+index 61517f5..c6bab39c 100644
 --- a/fs/file_table.c
 +++ b/fs/file_table.c
 @@ -148,6 +148,7 @@ struct file *get_empty_filp(void)
@@ -728,7 +806,7 @@ index 72e861a..01ae52f 100644
  
  /**
   * alloc_file - allocate and initialize a 'struct file'
-@@ -260,6 +261,7 @@ void flush_delayed_fput(void)
+@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
  {
  	delayed_fput(NULL);
  }
@@ -736,7 +814,7 @@ index 72e861a..01ae52f 100644
  
  static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
  
-@@ -302,6 +304,7 @@ void __fput_sync(struct file *file)
+@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
  }
  
  EXPORT_SYMBOL(fput);
@@ -744,19 +822,19 @@ index 72e861a..01ae52f 100644
  
  void put_filp(struct file *file)
  {
-@@ -310,6 +313,7 @@ void put_filp(struct file *file)
+@@ -308,6 +311,7 @@ void put_filp(struct file *file)
  		file_free(file);
  	}
  }
 +EXPORT_SYMBOL_GPL(put_filp);
  
  void __init files_init(void)
- { 
+ {
 diff --git a/fs/inode.c b/fs/inode.c
-index 73820bf..7db829e 100644
+index f7800d6..f31a6c7 100644
 --- a/fs/inode.c
 +++ b/fs/inode.c
-@@ -1650,6 +1650,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
+@@ -1664,6 +1664,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
  
  	return update_time(inode, time, flags);
  }
@@ -765,10 +843,10 @@ index 73820bf..7db829e 100644
  /**
   *	touch_atime	-	update the access time
 diff --git a/fs/namespace.c b/fs/namespace.c
-index f8893dc..c55d949 100644
+index e5a4a7f..6d0c376 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
-@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
+@@ -517,6 +517,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
  	mnt_dec_writers(real_mount(mnt));
  	preempt_enable();
  }
@@ -776,7 +854,15 @@ index f8893dc..c55d949 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1823,6 +1824,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -851,6 +852,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
+ {
+ 	return check_mnt(real_mount(mnt));
+ }
++EXPORT_SYMBOL_GPL(is_current_mnt_ns);
+ 
+ /*
+  * vfsmount lock must be held for write
+@@ -1887,6 +1889,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
  	}
  	return 0;
  }
@@ -857,7 +943,7 @@ index 9991f88..117042c 100644
  /*
   * Destroy all marks in destroy_list, waits for SRCU period to finish before
 diff --git a/fs/open.c b/fs/open.c
-index 35bb784..92e08c5 100644
+index 7ea1184..6e2e241 100644
 --- a/fs/open.c
 +++ b/fs/open.c
 @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
@@ -877,10 +963,18 @@ index 35bb784..92e08c5 100644
  static int do_dentry_open(struct file *f,
  			  struct inode *inode,
 diff --git a/fs/read_write.c b/fs/read_write.c
-index 6e542f0..c6fa090 100644
+index 6aa8c7a..b5d392e 100644
 --- a/fs/read_write.c
 +++ b/fs/read_write.c
-@@ -483,6 +483,7 @@ vfs_readf_t vfs_readf(struct file *file)
+@@ -453,6 +453,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
+ 
+ 	return ret;
+ }
++EXPORT_SYMBOL_GPL(vfs_read);
+ 
+ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+ {
+@@ -493,6 +494,7 @@ vfs_readf_t vfs_readf(struct file *file)
  		return new_sync_read;
  	return ERR_PTR(-ENOSYS);
  }
@@ -888,19 +982,27 @@ index 6e542f0..c6fa090 100644
  
  vfs_writef_t vfs_writef(struct file *file)
  {
-@@ -494,6 +495,7 @@ vfs_writef_t vfs_writef(struct file *file)
+@@ -504,6 +506,7 @@ vfs_writef_t vfs_writef(struct file *file)
  		return new_sync_write;
  	return ERR_PTR(-ENOSYS);
  }
 +EXPORT_SYMBOL_GPL(vfs_writef);
  
- ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+ {
+@@ -573,6 +576,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
+ 
+ 	return ret;
+ }
++EXPORT_SYMBOL_GPL(vfs_write);
+ 
+ static inline loff_t file_pos_read(struct file *file)
  {
 diff --git a/fs/splice.c b/fs/splice.c
-index 9753304..b38e036 100644
+index eb888c6..7ab89d2 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -866,6 +866,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -850,6 +850,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
  	return splice_write(pipe, out, ppos, len, flags);
  }
@@ -908,7 +1010,7 @@ index 9753304..b38e036 100644
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
-@@ -895,6 +896,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+@@ -879,6 +880,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
  
  	return splice_read(in, ppos, pipe, len, flags);
  }
@@ -917,7 +1019,7 @@ index 9753304..b38e036 100644
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
 diff --git a/fs/sync.c b/fs/sync.c
-index 7a5fa3f..c9b9d46 100644
+index eb61780..32c5a05 100644
 --- a/fs/sync.c
 +++ b/fs/sync.c
 @@ -38,6 +38,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
@@ -929,10 +1031,10 @@ index 7a5fa3f..c9b9d46 100644
  /*
   * Write out and wait upon all dirty data associated with this
 diff --git a/fs/xattr.c b/fs/xattr.c
-index 464c94b..0234d49 100644
+index 61cd28b..35570cd 100644
 --- a/fs/xattr.c
 +++ b/fs/xattr.c
-@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
+@@ -297,6 +297,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
  	*xattr_value = value;
  	return error;
  }
@@ -940,20 +1042,32 @@ index 464c94b..0234d49 100644
  
  ssize_t
  __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index bc97a97..895a1ba 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -155,6 +155,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
+ 	}
+ 	return lock_classes + hlock->class_idx - 1;
+ }
++EXPORT_SYMBOL_GPL(lockdep_hlock_class);
+ #define hlock_class(hlock) lockdep_hlock_class(hlock)
+ 
+ #ifdef CONFIG_LOCK_STAT
 diff --git a/kernel/task_work.c b/kernel/task_work.c
-index d513051..e056d54 100644
+index 836a72a..aa00d49 100644
 --- a/kernel/task_work.c
 +++ b/kernel/task_work.c
-@@ -119,3 +119,4 @@ void task_work_run(void)
+@@ -115,3 +115,4 @@ void task_work_run(void)
  		} while (work);
  	}
  }
 +EXPORT_SYMBOL_GPL(task_work_run);
 diff --git a/security/commoncap.c b/security/commoncap.c
-index 7abebd7..c079ce4 100644
+index fc46f5b..90543ef 100644
 --- a/security/commoncap.c
 +++ b/security/commoncap.c
-@@ -1062,12 +1062,14 @@ int cap_mmap_addr(unsigned long addr)
+@@ -1270,12 +1270,14 @@ int cap_mmap_addr(unsigned long addr)
  	}
  	return ret;
  }
@@ -989,10 +1103,10 @@ index 03c1652..f88c84b 100644
  int devcgroup_inode_mknod(int mode, dev_t dev)
  {
 diff --git a/security/security.c b/security/security.c
-index 3013237..342ce8b 100644
+index 4bf0f57..b30d1e1 100644
 --- a/security/security.c
 +++ b/security/security.c
-@@ -535,6 +535,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
+@@ -530,6 +530,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
  		return 0;
  	return call_int_hook(path_rmdir, 0, dir, dentry);
  }
@@ -1000,7 +1114,7 @@ index 3013237..342ce8b 100644
  
  int security_path_unlink(const struct path *dir, struct dentry *dentry)
  {
-@@ -551,6 +552,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
+@@ -546,6 +547,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
  		return 0;
  	return call_int_hook(path_symlink, 0, dir, dentry, old_name);
  }
@@ -1008,7 +1122,7 @@ index 3013237..342ce8b 100644
  
  int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
  		       struct dentry *new_dentry)
-@@ -559,6 +561,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
+@@ -554,6 +556,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
  		return 0;
  	return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
  }
@@ -1016,7 +1130,7 @@ index 3013237..342ce8b 100644
  
  int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
  			 const struct path *new_dir, struct dentry *new_dentry,
-@@ -586,6 +589,7 @@ int security_path_truncate(const struct path *path)
+@@ -581,6 +584,7 @@ int security_path_truncate(const struct path *path)
  		return 0;
  	return call_int_hook(path_truncate, 0, path);
  }
@@ -1024,7 +1138,7 @@ index 3013237..342ce8b 100644
  
  int security_path_chmod(const struct path *path, umode_t mode)
  {
-@@ -593,6 +597,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
+@@ -588,6 +592,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
  		return 0;
  	return call_int_hook(path_chmod, 0, path, mode);
  }
@@ -1032,7 +1146,7 @@ index 3013237..342ce8b 100644
  
  int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
  {
-@@ -600,6 +605,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
+@@ -595,6 +600,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
  		return 0;
  	return call_int_hook(path_chown, 0, path, uid, gid);
  }
@@ -1040,7 +1154,7 @@ index 3013237..342ce8b 100644
  
  int security_path_chroot(const struct path *path)
  {
-@@ -685,6 +691,7 @@ int security_inode_readlink(struct dentry *dentry)
+@@ -680,6 +686,7 @@ int security_inode_readlink(struct dentry *dentry)
  		return 0;
  	return call_int_hook(inode_readlink, 0, dentry);
  }
@@ -1048,7 +1162,7 @@ index 3013237..342ce8b 100644
  
  int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
  			       bool rcu)
-@@ -700,6 +707,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -695,6 +702,7 @@ int security_inode_permission(struct inode *inode, int mask)
  		return 0;
  	return call_int_hook(inode_permission, 0, inode, mask);
  }
@@ -1056,7 +1170,7 @@ index 3013237..342ce8b 100644
  
  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  {
-@@ -871,6 +879,7 @@ int security_file_permission(struct file *file, int mask)
+@@ -866,6 +874,7 @@ int security_file_permission(struct file *file, int mask)
  
  	return fsnotify_perm(file, mask);
  }
@@ -1064,7 +1178,7 @@ index 3013237..342ce8b 100644
  
  int security_file_alloc(struct file *file)
  {
-@@ -930,6 +939,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
+@@ -925,6 +934,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
  		return ret;
  	return ima_file_mmap(file, prot);
  }
@@ -1163,7 +1277,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentat
 +		will be empty. About XINO files, see the aufs manual.
 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt	1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/filesystems/aufs/design/01intro.txt	2017-09-05 10:42:11.038754821 +0200
++++ linux/Documentation/filesystems/aufs/design/01intro.txt	2017-11-12 22:24:42.257509799 +0100
 @@ -0,0 +1,171 @@
 +
 +# Copyright (C) 2005-2017 Junjiro R. Okajima
@@ -1950,6 +2064,147 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx
 +  where the source and the target exists and selects the higher
 +  one. If the selected branch is readonly, then aufs follows the
 +  copyup policy.
+diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
+--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot	1970-01-01 01:00:00.000000000 +0100
++++ linux/Documentation/filesystems/aufs/design/06dirren.dot	2017-11-12 22:24:44.694244127 +0100
+@@ -0,0 +1,31 @@
++
++// to view this graph, run dot(1) command in GRAPHVIZ.
++
++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 -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
+--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt	1970-01-01 01:00:00.000000000 +0100
++++ linux/Documentation/filesystems/aufs/design/06dirren.txt	2017-11-12 22:24:44.694244127 +0100
+@@ -0,0 +1,102 @@
++
++# Copyright (C) 2017 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 refered 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 -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
 --- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt	1970-01-01 01:00:00.000000000 +0100
 +++ linux/Documentation/filesystems/aufs/design/06fhsm.txt	2017-07-29 12:14:25.896375188 +0200
@@ -2818,8 +3073,8 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta
 +# End: ;
 diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
 --- /usr/share/empty/fs/aufs/aufs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/aufs.h	2017-07-29 12:14:25.896375188 +0200
-@@ -0,0 +1,59 @@
++++ linux/fs/aufs/aufs.h	2017-11-12 22:24:44.697577553 +0100
+@@ -0,0 +1,60 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -2862,15 +3117,16 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.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 "loop.h"
 +#include "module.h"
 +#include "opts.h"
 +#include "rwsem.h"
-+#include "spl.h"
 +#include "super.h"
 +#include "sysaufs.h"
 +#include "vfsub.h"
@@ -2881,8 +3137,8 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
 +#endif /* __AUFS_H__ */
 diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 --- /usr/share/empty/fs/aufs/branch.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/branch.c	2017-07-29 12:14:25.896375188 +0200
-@@ -0,0 +1,1422 @@
++++ linux/fs/aufs/branch.c	2017-11-12 22:24:44.697577553 +0100
+@@ -0,0 +1,1432 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -2918,6 +3174,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	struct au_dykey **key;
 +
 +	au_hnotify_fin_br(br);
++	/* always, regardless the mount option */
++	au_dr_hino_free(&br->br_dirren);
 +
 +	if (br->br_xino.xi_file)
 +		fput(br->br_xino.xi_file);
@@ -3022,7 +3280,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +		goto out;
 +	add_branch->br_xino.xi_nondir.total = 8; /* initial size */
 +	add_branch->br_xino.xi_nondir.array
-+		= kzalloc(sizeof(ino_t) * add_branch->br_xino.xi_nondir.total,
++		= kcalloc(add_branch->br_xino.xi_nondir.total, sizeof(ino_t),
 +			  GFP_NOFS);
 +	if (unlikely(!add_branch->br_xino.xi_nondir.array))
 +		goto out_br;
@@ -3286,6 +3544,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	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))
@@ -3452,14 +3715,15 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +{
 +	unsigned long long n;
 +	struct file **p, *f;
-+	struct au_sphlhead *files;
++	struct hlist_bl_head *files;
++	struct hlist_bl_node *pos;
 +	struct au_finfo *finfo;
 +
 +	n = 0;
 +	p = a;
 +	files = &au_sbi(sb)->si_files;
-+	spin_lock(&files->spin);
-+	hlist_for_each_entry(finfo, &files->head, fi_hlist) {
++	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)) {
@@ -3469,7 +3733,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +			AuDebugOn(n > max);
 +		}
 +	}
-+	spin_unlock(&files->spin);
++	hlist_bl_unlock(files);
 +
 +	return n;
 +}
@@ -3872,6 +4136,9 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	au_br_do_del_hip(au_ii(inode), bindex, bbot);
 +	au_sbilist_unlock();
 +
++	/* ignore an error */
++	au_dr_br_fin(sb, br); /* always, regardless the mount option */
++
 +	dput(h_root);
 +	iput(h_inode);
 +	au_br_do_free(br);
@@ -4281,8 +4548,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +	goto out; /* success */
 +
 +out_bf:
-+	if (bf)
-+		kfree(bf);
++	kfree(bf);
 +out:
 +	AuTraceErr(err);
 +	return err;
@@ -4307,8 +4573,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +}
 diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 --- /usr/share/empty/fs/aufs/branch.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/branch.h	2017-07-29 12:14:25.896375188 +0200
-@@ -0,0 +1,321 @@
++++ linux/fs/aufs/branch.h	2017-11-12 22:24:44.697577553 +0100
+@@ -0,0 +1,333 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -4336,6 +4602,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +#ifdef __KERNEL__
 +
 +#include <linux/mount.h>
++#include "dirren.h"
 +#include "dynop.h"
 +#include "rwsem.h"
 +#include "super.h"
@@ -4433,6 +4700,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +	/* entries under sysfs per mount-point */
 +	struct au_brsysfs	br_sysfs[AuBrSysfs_Last];
 +#endif
++
++	struct au_dr_br		br_dirren;
 +};
 +
 +/* ---------------------------------------------------------------------- */
@@ -4479,7 +4748,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +
 +static inline int au_br_rdonly(struct au_branch *br)
 +{
-+	return ((au_br_sb(br)->s_flags & MS_RDONLY)
++	return (sb_rdonly(au_br_sb(br))
 +		|| !au_br_writable(br->br_perm))
 +		? -EROFS : 0;
 +}
@@ -4599,15 +4868,24 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +
 +/* ---------------------------------------------------------------------- */
 +
++#define wbr_wh_read_lock(wbr)	au_rw_read_lock(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_write_lock(wbr)	au_rw_write_lock(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_read_trylock(wbr)	au_rw_read_trylock(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem)
 +/*
-+ * wbr_wh_read_lock, wbr_wh_write_lock
-+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
-+ */
-+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
++#define wbr_wh_read_trylock_nested(wbr) \
++	au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_write_trylock_nested(wbr) \
++	au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem)
++*/
 +
-+#define WbrWhMustNoWaiters(wbr)	AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
-+#define WbrWhMustAnyLock(wbr)	AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
-+#define WbrWhMustWriteLock(wbr)	AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
++#define wbr_wh_read_unlock(wbr)	au_rw_read_unlock(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_write_unlock(wbr)	au_rw_write_unlock(&(wbr)->wbr_wh_rwsem)
++#define wbr_wh_downgrade_lock(wbr)	au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem)
++
++#define WbrWhMustNoWaiters(wbr)	AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem)
++#define WbrWhMustAnyLock(wbr)	AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem)
++#define WbrWhMustWriteLock(wbr)	AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem)
 +
 +/* ---------------------------------------------------------------------- */
 +
@@ -4632,8 +4910,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
 +#endif /* __AUFS_BRANCH_H__ */
 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 --- /usr/share/empty/fs/aufs/conf.mk	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/conf.mk	2017-07-29 12:14:25.899708630 +0200
-@@ -0,0 +1,38 @@
++++ linux/fs/aufs/conf.mk	2017-11-12 22:24:44.704244405 +0100
+@@ -0,0 +1,39 @@
 +
 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
 +
@@ -4650,6 +4928,7 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 +	XATTR \
 +	FHSM \
 +	RDU \
++	DIRREN \
 +	SHWH \
 +	BR_RAMFS \
 +	BR_FUSE POLL \
@@ -4674,8 +4953,8 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
 +-include ${srctree}/${src}/conf_priv.mk
 diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 --- /usr/share/empty/fs/aufs/cpup.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/cpup.c	2017-09-05 10:42:11.055421928 +0200
-@@ -0,0 +1,1442 @@
++++ linux/fs/aufs/cpup.c	2017-11-12 22:24:44.704244405 +0100
+@@ -0,0 +1,1443 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -5197,7 +5476,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +		else {
 +			inode_unlock_shared(h_src_inode);
 +			err = vfsub_getattr(&h_path, &h_src_attr->st);
-+			vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
++			vfsub_inode_lock_shared_nested(h_src_inode,
++						       AuLsc_I_CHILD);
 +		}
 +		if (unlikely(err)) {
 +			inode_unlock_shared(h_src_inode);
@@ -6120,8 +6400,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +}
 diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
 --- /usr/share/empty/fs/aufs/cpup.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/cpup.h	2017-07-29 12:14:25.899708630 +0200
-@@ -0,0 +1,94 @@
++++ linux/fs/aufs/cpup.h	2017-11-12 22:24:44.704244405 +0100
+@@ -0,0 +1,99 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -6183,6 +6463,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
 +#define AuCpup_RWDST		(1 << 5)	/* force write target even if
 +						   the branch is marked as RO */
 +
++#ifndef CONFIG_AUFS_BR_HFSPLUS
++#undef AuCpup_HOPEN
++#define AuCpup_HOPEN		0
++#endif
++
 +#define au_ftest_cpup(flags, name)	((flags) & AuCpup_##name)
 +#define au_fset_cpup(flags, name) \
 +	do { (flags) |= AuCpup_##name; } while (0)
@@ -6218,8 +6503,8 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
 +#endif /* __AUFS_CPUP_H__ */
 diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 --- /usr/share/empty/fs/aufs/dbgaufs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dbgaufs.c	2017-07-29 12:14:25.899708630 +0200
-@@ -0,0 +1,438 @@
++++ linux/fs/aufs/dbgaufs.c	2017-11-12 22:24:44.704244405 +0100
+@@ -0,0 +1,437 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -6336,7 +6621,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +	struct dbgaufs_plink_arg *p;
 +	struct au_sbinfo *sbinfo;
 +	struct super_block *sb;
-+	struct au_sphlhead *sphl;
++	struct hlist_bl_head *hbl;
 +
 +	err = -ENOMEM;
 +	p = (void *)get_zeroed_page(GFP_NOFS);
@@ -6356,10 +6641,9 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +		limit -= n;
 +
 +		sum = 0;
-+		for (i = 0, sphl = sbinfo->si_plink;
-+		     i < AuPlink_NHASH;
-+		     i++, sphl++) {
-+			n = au_sphl_count(sphl);
++		for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH;
++		     i++, hbl++) {
++			n = au_hbl_count(hbl);
 +			sum += n;
 +
 +			n = snprintf(p->a + p->n, limit, "%lu ", n);
@@ -6712,7 +6996,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
 +#endif /* __DBGAUFS_H__ */
 diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
 --- /usr/share/empty/fs/aufs/dcsub.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dcsub.c	2017-07-29 12:14:25.899708630 +0200
++++ linux/fs/aufs/dcsub.c	2017-11-12 22:24:42.267510077 +0100
 @@ -0,0 +1,225 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
@@ -7081,7 +7365,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
 +#endif /* __AUFS_DCSUB_H__ */
 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 --- /usr/share/empty/fs/aufs/debug.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/debug.c	2017-07-29 12:14:25.899708630 +0200
++++ linux/fs/aufs/debug.c	2017-11-12 22:24:42.267510077 +0100
 @@ -0,0 +1,440 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
@@ -7754,8 +8038,8 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
 +#endif /* __AUFS_DEBUG_H__ */
 diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 --- /usr/share/empty/fs/aufs/dentry.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/aufs/dentry.c	2017-09-05 10:42:11.055421928 +0200
-@@ -0,0 +1,1130 @@
++++ linux/fs/aufs/dentry.c	2017-11-12 22:24:44.704244405 +0100
+@@ -0,0 +1,1152 @@
 +/*
 + * Copyright (C) 2005-2017 Junjiro R. Okajima
 + *
@@ -7780,19 +8064,13 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +#include <linux/namei.h>
 +#include "aufs.h"
 +
-+struct au_do_lookup_args {
-+	unsigned int		flags;
-+	mode_t			type;
-+};
-+
 +/*
 + * returns positive/negative dentry, NULL or an error.
 + * NULL means whiteout-ed or not-found.
 + */
 +static struct dentry*
 +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
-+	     aufs_bindex_t bindex, struct qstr *wh_name,
-+	     struct au_do_lookup_args *args)
++	     aufs_bindex_t bindex, struct au_do_lookup_args *args)
 +{
 +	struct dentry *h_dentry;
 +	struct inode *h_inode;
@@ -7807,7 +8085,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	br = au_sbr(dentry->d_sb, bindex);
 +	wh_able = !!au_br_whable(br->br_perm);
 +	if (wh_able)
-+		wh_found = au_wh_test(h_parent, wh_name, ignore_perm);
++		wh_found = au_wh_test(h_parent, &args->whname, ignore_perm);
 +	h_dentry = ERR_PTR(wh_found);
 +	if (!wh_found)
 +		goto real_lookup;
@@ -7822,9 +8100,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +real_lookup:
 +	if (!ignore_perm)
-+		h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
++		h_dentry = vfsub_lkup_one(args->name, h_parent);
 +	else
-+		h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
++		h_dentry = au_sio_lkup_one(args->name, h_parent);
 +	if (IS_ERR(h_dentry)) {
 +		if (PTR_ERR(h_dentry) == -ENAMETOOLONG
 +		    && !allow_neg)
@@ -7839,6 +8117,13 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	} else if (wh_found
 +		   || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
 +		goto out_neg;
++	else if (au_ftest_lkup(args->flags, DIRREN)
++		 /* && h_inode */
++		 && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) {
++		AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry,
++		      (unsigned long long)h_inode->i_ino);
++		goto out_neg;
++	}
 +
 +	if (au_dbbot(dentry) <= bindex)
 +		au_set_dbbot(dentry, bindex);
@@ -7887,26 +8172,28 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +{
 +	int npositive, err;
 +	aufs_bindex_t bindex, btail, bdiropq;
-+	unsigned char isdir, dirperm1;
-+	struct qstr whname;
++	unsigned char isdir, dirperm1, dirren;
 +	struct au_do_lookup_args args = {
-+		.flags		= flags
++		.flags		= flags,
++		.name		= &dentry->d_name
 +	};
-+	const struct qstr *name = &dentry->d_name;
 +	struct dentry *parent;
 +	struct super_block *sb;
 +
 +	sb = dentry->d_sb;
-+	err = au_test_shwh(sb, name);
++	err = au_test_shwh(sb, args.name);
 +	if (unlikely(err))
 +		goto out;
 +
-+	err = au_wh_name_alloc(&whname, name);
++	err = au_wh_name_alloc(&args.whname, args.name);
 +	if (unlikely(err))
 +		goto out;
 +
 +	isdir = !!d_is_dir(dentry);
 +	dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
++	dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
++	if (dirren)
++		au_fset_lkup(args.flags, DIRREN);
 +
 +	npositive = 0;
 +	parent = dget_parent(dentry);
@@ -7914,6 +8201,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +	for (bindex = btop; bindex <= btail; bindex++) {
 +		struct dentry *h_parent, *h_dentry;
 +		struct inode *h_inode, *h_dir;
++		struct au_branch *br;
 +
 +		h_dentry = au_h_dptr(dentry, bindex);
 +		if (h_dentry) {
@@ -7925,10 +8213,16 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +		if (!h_parent || !d_is_dir(h_parent))
 +			continue;
 +
++		if (dirren) {
++			/* if the inum matches, then use the prepared name */
++			err = au_dr_lkup_name(&args, bindex);
++			if (unlikely(err))
++				goto out_parent;
++		}
++
 +		h_dir = d_inode(h_parent);
 +		vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
-+		h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
-+					&args);
++		h_dentry = au_do_lookup(h_parent, dentry, bindex, &args);
 +		inode_unlock_shared(h_dir);
 +		err = PTR_ERR(h_dentry);
 +		if (IS_ERR(h_dentry))
@@ -7956,6 +8250,15 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +			if (bdiropq >= 0 && bdiropq <= bindex)
 +				break;
 +		}
++		br = au_sbr(sb, bindex);
++		if (dirren
++		    && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino,
++					   /*add_ent*/NULL)) {
++			/* prepare next name to lookup */
++			err = au_dr_lkup(&args, dentry, bindex);
++			if (unlikely(err))
++				goto out_parent;
++		}
 +	}
 +
 +	if (npositive) {
@@ -7972,7 +8275,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +out_parent:
 +	dput(parent);
-+	kfree(whname.name);
++	kfree(args.whname.name);
++	if (dirren)
++		au_dr_lkup_fin(&args);
 +out:
 +	return err;
 +}
@@ -8581,7 +8886,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +/* todo: remove this */
 +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
-+			  unsigned int flags, int do_udba)
++			  unsigned int flags, int do_udba, int dirren)
 +{
 +	int err;
 +	umode_t mode, h_mode;
@@ -8632,7 +8937,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +			     && !is_root
 +			     && ((!h_nfs
 +				  && (unhashed != !!d_unhashed(h_dentry)
-+				      || (!tmpfile
++				      || (!tmpfile && !dirren
 +					  && !au_qstreq(name, h_name))
 +					  ))
 +				 || (h_nfs
@@ -8773,7 +9078,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +{
 +	int valid, err;
 +	unsigned int sigen;
<Skipped 4357 lines>
================================================================

---- gitweb:

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




More information about the pld-cvs-commit mailing list