Commit 64f44b27 authored by Christian Brauner's avatar Christian Brauner

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
...@@ -2318,30 +2318,37 @@ static int attach_recursive_mnt(struct mount *source_mnt, ...@@ -2318,30 +2318,37 @@ static int attach_recursive_mnt(struct mount *source_mnt,
static struct mountpoint *lock_mount(struct path *path) static struct mountpoint *lock_mount(struct path *path)
{ {
struct vfsmount *mnt; struct vfsmount *mnt;
struct dentry *dentry = path->dentry; struct dentry *dentry;
retry: struct mountpoint *mp;
for (;;) {
dentry = path->dentry;
inode_lock(dentry->d_inode); inode_lock(dentry->d_inode);
if (unlikely(cant_mount(dentry))) { if (unlikely(cant_mount(dentry))) {
inode_unlock(dentry->d_inode); inode_unlock(dentry->d_inode);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
namespace_lock(); namespace_lock();
mnt = lookup_mnt(path); mnt = lookup_mnt(path);
if (likely(!mnt)) { if (likely(!mnt))
struct mountpoint *mp = get_mountpoint(dentry); 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)) { if (IS_ERR(mp)) {
namespace_unlock(); namespace_unlock();
inode_unlock(dentry->d_inode); inode_unlock(dentry->d_inode);
return mp;
} }
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) static void unlock_mount(struct mountpoint *where)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment