Anthony Iliopoulos 5299c9
From b17164e258e3888d376a7434415013175d637377 Mon Sep 17 00:00:00 2001
Anthony Iliopoulos 5299c9
From: Mikulas Patocka <mpatocka@redhat.com>
Anthony Iliopoulos 5299c9
Date: Sat, 5 Sep 2020 08:13:02 -0400
Anthony Iliopoulos 5299c9
Subject: [PATCH] xfs: don't update mtime on COW faults
Anthony Iliopoulos 5299c9
Git-commit: b17164e258e3888d376a7434415013175d637377
Anthony Iliopoulos 5299c9
Patch-mainline: v5.9-rc4
Anthony Iliopoulos 5299c9
References: bsc#1167030
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
When running in a dax mode, if the user maps a page with MAP_PRIVATE and
Anthony Iliopoulos 5299c9
PROT_WRITE, the xfs filesystem would incorrectly update ctime and mtime
Anthony Iliopoulos 5299c9
when the user hits a COW fault.
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
This breaks building of the Linux kernel.  How to reproduce:
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
 1. extract the Linux kernel tree on dax-mounted xfs filesystem
Anthony Iliopoulos 5299c9
 2. run make clean
Anthony Iliopoulos 5299c9
 3. run make -j12
Anthony Iliopoulos 5299c9
 4. run make -j12
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
at step 4, make would incorrectly rebuild the whole kernel (although it
Anthony Iliopoulos 5299c9
was already built in step 3).
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
The reason for the breakage is that almost all object files depend on
Anthony Iliopoulos 5299c9
objtool.  When we run objtool, it takes COW page fault on its .data
Anthony Iliopoulos 5299c9
section, and these faults will incorrectly update the timestamp of the
Anthony Iliopoulos 5299c9
objtool binary.  The updated timestamp causes make to rebuild the whole
Anthony Iliopoulos 5299c9
tree.
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Anthony Iliopoulos 5299c9
Cc: stable@vger.kernel.org
Anthony Iliopoulos 5299c9
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Anthony Iliopoulos 5299c9
Acked-by: Anthony Iliopoulos <ailiop@suse.com>
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
---
Anthony Iliopoulos 5299c9
 fs/xfs/xfs_file.c |   12 ++++++++++--
Anthony Iliopoulos 5299c9
 1 file changed, 10 insertions(+), 2 deletions(-)
Anthony Iliopoulos 5299c9
Anthony Iliopoulos 5299c9
--- a/fs/xfs/xfs_file.c
Anthony Iliopoulos 5299c9
+++ b/fs/xfs/xfs_file.c
Anthony Iliopoulos 5299c9
@@ -1109,6 +1109,14 @@
Anthony Iliopoulos 5299c9
 	return ret;
Anthony Iliopoulos 5299c9
 }
Anthony Iliopoulos 5299c9
 
Anthony Iliopoulos 5299c9
+static inline bool
Anthony Iliopoulos 5299c9
+xfs_is_write_fault(
Anthony Iliopoulos 5299c9
+	struct vm_fault		*vmf)
Anthony Iliopoulos 5299c9
+{
Anthony Iliopoulos 5299c9
+	return (vmf->flags & FAULT_FLAG_WRITE) &&
Anthony Iliopoulos 5299c9
+	       (vmf->vma->vm_flags & VM_SHARED);
Anthony Iliopoulos 5299c9
+}
Anthony Iliopoulos 5299c9
+
Anthony Iliopoulos 5299c9
 static int
Anthony Iliopoulos 5299c9
 xfs_filemap_fault(
Anthony Iliopoulos 5299c9
 	struct vm_fault		*vmf)
Anthony Iliopoulos 5299c9
@@ -1116,7 +1124,7 @@
Anthony Iliopoulos 5299c9
 	/* DAX can shortcut the normal fault path on write faults! */
Anthony Iliopoulos 5299c9
 	return __xfs_filemap_fault(vmf, PE_SIZE_PTE,
Anthony Iliopoulos 5299c9
 			IS_DAX(file_inode(vmf->vma->vm_file)) &&
Anthony Iliopoulos 5299c9
-			(vmf->flags & FAULT_FLAG_WRITE));
Anthony Iliopoulos 5299c9
+			xfs_is_write_fault(vmf));
Anthony Iliopoulos 5299c9
 }
Anthony Iliopoulos 5299c9
 
Anthony Iliopoulos 5299c9
 static int
Anthony Iliopoulos 5299c9
@@ -1129,7 +1137,7 @@
Anthony Iliopoulos 5299c9
 
Anthony Iliopoulos 5299c9
 	/* DAX can shortcut the normal fault path on write faults! */
Anthony Iliopoulos 5299c9
 	return __xfs_filemap_fault(vmf, pe_size,
Anthony Iliopoulos 5299c9
-			(vmf->flags & FAULT_FLAG_WRITE));
Anthony Iliopoulos 5299c9
+			xfs_is_write_fault(vmf));
Anthony Iliopoulos 5299c9
 }
Anthony Iliopoulos 5299c9
 
Anthony Iliopoulos 5299c9
 static int