Unverified Commit 64f44b27 authored by Christian Brauner's avatar Christian Brauner
Browse files

fs: use a for loop when locking a mount



Currently, lock_mount() uses a goto to retry the lookup until it
succeeded in acquiring the namespace_lock() preventing the top mount
from being overmounted. While that's perfectly fine we want to lookup
the mountpoint on the parent of the top mount in later patches. So adapt
the code to make this easier to implement. Also, the for loop is
arguably a little cleaner and makes the code easier to follow. No
functional changes intended.

Reviewed-by: default avatarSeth Forshee (DigitalOcean) <sforshee@kernel.org>
Message-Id: <20230202-fs-move-mount-replace-v4-3-98f3d80d7eaa@kernel.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 104026c2
Loading
Loading
Loading
Loading
+28 −21
Original line number Diff line number Diff line
@@ -2318,31 +2318,38 @@ static int attach_recursive_mnt(struct mount *source_mnt,
static struct mountpoint *lock_mount(struct path *path)
{
	struct vfsmount *mnt;
	struct dentry *dentry = path->dentry;
retry:
	struct dentry *dentry;
	struct mountpoint *mp;

	for (;;) {
		dentry = path->dentry;
		inode_lock(dentry->d_inode);
		if (unlikely(cant_mount(dentry))) {
			inode_unlock(dentry->d_inode);
			return ERR_PTR(-ENOENT);
		}

		namespace_lock();

		mnt = lookup_mnt(path);
	if (likely(!mnt)) {
		struct mountpoint *mp = get_mountpoint(dentry);
		if (likely(!mnt))
			break;

		namespace_unlock();
		inode_unlock(dentry->d_inode);
		path_put(path);
		path->mnt = mnt;
		path->dentry = dget(mnt->mnt_root);
	}

	mp = get_mountpoint(dentry);
	if (IS_ERR(mp)) {
		namespace_unlock();
		inode_unlock(dentry->d_inode);
			return mp;
	}

	return mp;
}
	namespace_unlock();
	inode_unlock(path->dentry->d_inode);
	path_put(path);
	path->mnt = mnt;
	dentry = path->dentry = dget(mnt->mnt_root);
	goto retry;
}

static void unlock_mount(struct mountpoint *where)
{