[Devel] [PATCH RHEL7 COMMIT] ms/namespace: take lock_mount_hash() directly when changing flags

Konstantin Khorenko khorenko at virtuozzo.com
Thu Apr 20 21:00:50 MSK 2023


The commit is pushed to "branch-rh7-3.10.0-1160.88.1.vz7.195.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.88.1.vz7.195.2
------>
commit 059d77b2c5e41ea0b3397d9bd73132248e9452ed
Author: Christian Brauner <christian.brauner at ubuntu.com>
Date:   Thu Apr 13 18:47:19 2023 +0800

    ms/namespace: take lock_mount_hash() directly when changing flags
    
    Changing mount options always ends up taking lock_mount_hash() but when
    MNT_READONLY is requested and neither the mount nor the superblock are
    MNT_READONLY we end up taking the lock, dropping it, and retaking it to
    change the other mount attributes. Instead, let's acquire the lock once
    when changing the mount attributes. This simplifies the locking in these
    codepath, makes them easier to reason about and avoids having to
    reacquire the lock right after dropping it.
    
    Link: https://lore.kernel.org/r/20210121131959.646623-30-christian.brauner@ubuntu.com
    Cc: David Howells <dhowells at redhat.com>
    Cc: Al Viro <viro at zeniv.linux.org.uk>
    Cc: linux-fsdevel at vger.kernel.org
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
    
    (cherry picked from commit 68847c941700475575ced191108971d26e82ae29)
    https://jira.sw.ru/browse/PSBM-144416
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    =================
    Patchset description:
    mount: Port move_mount_set_group and mount_setattr
    
    We need this as in Virtuozzo criu after rebase to mainstream criu in u20
    we will switch to this new API for sharing group setting accross mounts.
    
    https://jira.vzint.dev/browse/PSBM-144416
---
 fs/namespace.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 1b7b71c46a22..52a879628aba 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -564,7 +564,6 @@ static int mnt_make_readonly(struct mount *mnt)
 {
 	int ret = 0;
 
-	lock_mount_hash();
 	mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;
 	/*
 	 * After storing MNT_WRITE_HOLD, we'll read the counters. This store
@@ -598,18 +597,9 @@ static int mnt_make_readonly(struct mount *mnt)
 	 */
 	smp_wmb();
 	mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;
-	unlock_mount_hash();
 	return ret;
 }
 
-static int __mnt_unmake_readonly(struct mount *mnt)
-{
-	lock_mount_hash();
-	mnt->mnt.mnt_flags &= ~MNT_READONLY;
-	unlock_mount_hash();
-	return 0;
-}
-
 int sb_prepare_remount_readonly(struct super_block *sb)
 {
 	struct mount *mnt;
@@ -2697,7 +2687,8 @@ static int change_mount_ro_state(struct mount *mnt, unsigned int mnt_flags)
 	if (readonly_request)
 		return mnt_make_readonly(mnt);
 
-	return __mnt_unmake_readonly(mnt);
+	mnt->mnt.mnt_flags &= ~MNT_READONLY;
+	return 0;
 }
 
 /*
@@ -2706,11 +2697,9 @@ static int change_mount_ro_state(struct mount *mnt, unsigned int mnt_flags)
  */
 static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags)
 {
-	lock_mount_hash();
 	mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
 	mnt->mnt.mnt_flags = mnt_flags;
 	touch_mnt_namespace(mnt->mnt_ns);
-	unlock_mount_hash();
 }
 
 /*
@@ -2734,9 +2723,11 @@ static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags)
 		return -EPERM;
 
 	down_write(&sb->s_umount);
+	lock_mount_hash();
 	ret = change_mount_ro_state(mnt, mnt_flags);
 	if (ret == 0)
 		set_mount_attributes(mnt, mnt_flags);
+	unlock_mount_hash();
 	up_write(&sb->s_umount);
 	return ret;
 }
@@ -2958,8 +2949,11 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
 	err = -EPERM;
 	if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
 		err = do_check_and_remount_sb(sb, sb_flags, data);
-		if (!err)
+		if (!err) {
+			lock_mount_hash();
 			set_mount_attributes(mnt, mnt_flags);
+			unlock_mount_hash();
+		}
 	}
 	up_write(&sb->s_umount);
 	return err;


More information about the Devel mailing list