[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210121131959.646623-30-christian.brauner@ubuntu.com>
Date: Thu, 21 Jan 2021 14:19:48 +0100
From: Christian Brauner <christian.brauner@...ntu.com>
To: Alexander Viro <viro@...iv.linux.org.uk>,
Christoph Hellwig <hch@....de>, linux-fsdevel@...r.kernel.org
Cc: John Johansen <john.johansen@...onical.com>,
James Morris <jmorris@...ei.org>,
Mimi Zohar <zohar@...ux.ibm.com>,
Dmitry Kasatkin <dmitry.kasatkin@...il.com>,
Stephen Smalley <stephen.smalley.work@...il.com>,
Casey Schaufler <casey@...aufler-ca.com>,
Arnd Bergmann <arnd@...db.de>,
Andreas Dilger <adilger.kernel@...ger.ca>,
OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>,
Geoffrey Thomas <geofft@...reload.com>,
Mrunal Patel <mpatel@...hat.com>,
Josh Triplett <josh@...htriplett.org>,
Andy Lutomirski <luto@...nel.org>,
Theodore Tso <tytso@....edu>, Alban Crequy <alban@...volk.io>,
Tycho Andersen <tycho@...ho.ws>,
David Howells <dhowells@...hat.com>,
James Bottomley <James.Bottomley@...senpartnership.com>,
Seth Forshee <seth.forshee@...onical.com>,
Stéphane Graber <stgraber@...ntu.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Aleksa Sarai <cyphar@...har.com>,
Lennart Poettering <lennart@...ttering.net>,
"Eric W. Biederman" <ebiederm@...ssion.com>, smbarber@...omium.org,
Phil Estes <estesp@...il.com>, Serge Hallyn <serge@...lyn.com>,
Kees Cook <keescook@...omium.org>,
Todd Kjos <tkjos@...gle.com>, Paul Moore <paul@...l-moore.com>,
Jonathan Corbet <corbet@....net>,
containers@...ts.linux-foundation.org,
linux-security-module@...r.kernel.org, linux-api@...r.kernel.org,
linux-ext4@...r.kernel.org, linux-xfs@...r.kernel.org,
linux-integrity@...r.kernel.org, selinux@...r.kernel.org,
Christian Brauner <christian.brauner@...ntu.com>
Subject: [PATCH v6 29/40] 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/20210112220124.837960-2-christian.brauner@ubuntu.com
Cc: David Howells <dhowells@...hat.com>
Cc: Al Viro <viro@...iv.linux.org.uk>
Cc: linux-fsdevel@...r.kernel.org
Reviewed-by: Christoph Hellwig <hch@....de>
Signed-off-by: Christian Brauner <christian.brauner@...ntu.com>
---
/* v2 */
- Christoph Hellwig <hch@....de>:
- Remove pointless __mnt_unmake_readonly() helper.
- Even though Christoph suggested to lockdep_assert_held() into places that
require {lock,unlock}_mount_hash() it seems that seqlock's don't support
it.
/* v3 */
unchanged
/* v4 */
unchanged
/* v5 */
unchanged
base-commit: 7c53f6b671f4aba70ff15e1b05148b10d58c2837
/* v6 */
unchanged
base-commit: 19c329f6808995b142b3966301f217c831e7cf31
---
fs/namespace.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index ecdc63ef881c..bdfb130f2c3c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -464,7 +464,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
@@ -498,18 +497,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;
@@ -2523,7 +2513,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;
}
/*
@@ -2532,11 +2523,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();
}
static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt)
@@ -2582,9 +2571,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);
mnt_warn_timestamp_expiry(path, &mnt->mnt);
@@ -2625,8 +2616,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 = reconfigure_super(fc);
- if (!err)
+ if (!err) {
+ lock_mount_hash();
set_mount_attributes(mnt, mnt_flags);
+ unlock_mount_hash();
+ }
}
up_write(&sb->s_umount);
}
--
2.30.0
Powered by blists - more mailing lists