[Devel] [PATCH RHEL7 COMMIT] ext4: add prepare_mmap API

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jun 22 03:37:59 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.15
------>
commit 2be5fd8bdd9ac06d60f9bf2b342e79d355c3297f
Author: Dmitry Monakhov <dmonakhov at openvz.org>
Date:   Mon Jun 22 14:37:58 2015 +0400

    ext4: add prepare_mmap API
    
    Merge two patches
    diff-ext4-ext4_file_mmap-fix-i_mutex-vs-mmap_sem-wrong-lock-order
    diff-ext4-remove-file_operations-prepare_mmap-2
    
    https://jira.sw.ru/browse/PSBM-23133
    https://jira.sw.ru/browse/PCLIN-32299
    
    backport task: https://jira.sw.ru/browse/PSBM-34112
    
    Signed-off-by: Dmitry Monakhov <dmonakhov at openvz.org>
---
 fs/ext4/file.c     | 18 ++++++++++++------
 fs/ext4/super.c    |  2 +-
 include/linux/fs.h |  7 +++++++
 mm/util.c          |  4 ++++
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index fc94a2e..2ba3bec 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -213,12 +213,18 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
 
 	if (!mapping->a_ops->readpage)
 		return -ENOEXEC;
-
-	if ((vma->vm_flags & VM_SHARED) &&
-	    ext4_test_inode_state(inode, EXT4_STATE_PFCACHE_CSUM)) {
-		mutex_lock(&inode->i_mutex);
-		ext4_truncate_data_csum(inode, -1);
-		mutex_unlock(&inode->i_mutex);
+	/*
+	 * f_op->mmap must be called with vma=NULL before taking mmap_sem;
+	 * workaround for wrong i_mutex vs mmap_sem lock ordering in pfcache
+	 * (PSBM-23133) - vdavydov@
+	 */
+	if (!vma) {
+		if (ext4_test_inode_state(inode, EXT4_STATE_PFCACHE_CSUM)) {
+			mutex_lock(&inode->i_mutex);
+			ext4_truncate_data_csum(inode, -1);
+			mutex_unlock(&inode->i_mutex);
+		}
+		return 0;
 	}
 
 	file_accessed(file);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index cbcc684..a40e3c8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5526,7 +5526,7 @@ static struct file_system_type ext4_fs_type = {
 	.name		= "ext4",
 	.mount		= ext4_mount,
 	.kill_sb	= ext4_kill_sb,
-	.fs_flags	= FS_REQUIRES_DEV | FS_VIRTUALIZED,
+	.fs_flags	= FS_REQUIRES_DEV | FS_VIRTUALIZED | FS_HAS_MMAP_PREP,
 };
 MODULE_ALIAS_FS("ext4");
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e770944..845fb6ce 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1957,6 +1957,13 @@ struct file_system_type {
 #define FS_VIRTUALIZED		64	/* Can mount this fstype inside ve */
 #define FS_MANGLE_PROC		128	/* hide some /proc/mounts info inside VE */
 #define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move() during rename() internally. */
+/*
+ * f_op->mmap must be called with vma=NULL before taking mmap_sem;
+ * workaround for wrong i_mutex vs mmap_sem lock ordering in pfcache
+ * (PSBM-23133) - vdavydov@
+ */
+#define FS_HAS_MMAP_PREP	(1<<18)
+
 	struct dentry *(*mount) (struct file_system_type *, int,
 		       const char *, void *);
 	void (*kill_sb) (struct super_block *);
diff --git a/mm/util.c b/mm/util.c
index a9569b2..bfbd099 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -364,6 +364,10 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
 
 	ret = security_mmap_file(file, prot, flag);
 	if (!ret) {
+		/* Ugly fix for PSBM-23133 vdavydov@ */
+		if (file && file->f_op && (flag & MAP_TYPE) == MAP_SHARED &&
+		    (file_inode(file)->i_sb->s_type->fs_flags & FS_HAS_MMAP_PREP))
+			file->f_op->mmap(file, NULL);
 		down_write(&mm->mmap_sem);
 		ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff,
 				    &populate);



More information about the Devel mailing list