mirror of
https://github.com/torvalds/linux.git
synced 2026-05-05 23:05:25 -04:00
finish_automount(): take the lock_mount() analogue into a helper
finish_automount() can't use lock_mount() - it treats finding something already mounted as "quitely drop our mount and return 0", not as "mount on top of whatever mounted there". It's been open-coded; let's take it into a helper similar to lock_mount(). "something's already mounted" => -EBUSY, finish_automount() needs to distinguish it from the normal case and it can't happen in other failure cases. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -3781,9 +3781,29 @@ static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
|
||||
return err;
|
||||
}
|
||||
|
||||
int finish_automount(struct vfsmount *m, const struct path *path)
|
||||
static int lock_mount_exact(const struct path *path,
|
||||
struct pinned_mountpoint *mp)
|
||||
{
|
||||
struct dentry *dentry = path->dentry;
|
||||
int err;
|
||||
|
||||
inode_lock(dentry->d_inode);
|
||||
namespace_lock();
|
||||
if (unlikely(cant_mount(dentry)))
|
||||
err = -ENOENT;
|
||||
else if (path_overmounted(path))
|
||||
err = -EBUSY;
|
||||
else
|
||||
err = get_mountpoint(dentry, mp);
|
||||
if (unlikely(err)) {
|
||||
namespace_unlock();
|
||||
inode_unlock(dentry->d_inode);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int finish_automount(struct vfsmount *m, const struct path *path)
|
||||
{
|
||||
struct pinned_mountpoint mp = {};
|
||||
struct mount *mnt;
|
||||
int err;
|
||||
@@ -3805,20 +3825,11 @@ int finish_automount(struct vfsmount *m, const struct path *path)
|
||||
* that overmounts our mountpoint to be means "quitely drop what we've
|
||||
* got", not "try to mount it on top".
|
||||
*/
|
||||
inode_lock(dentry->d_inode);
|
||||
namespace_lock();
|
||||
if (unlikely(cant_mount(dentry))) {
|
||||
err = -ENOENT;
|
||||
goto discard_locked;
|
||||
err = lock_mount_exact(path, &mp);
|
||||
if (unlikely(err)) {
|
||||
mntput(m);
|
||||
return err == -EBUSY ? 0 : err;
|
||||
}
|
||||
if (path_overmounted(path)) {
|
||||
err = 0;
|
||||
goto discard_locked;
|
||||
}
|
||||
err = get_mountpoint(dentry, &mp);
|
||||
if (err)
|
||||
goto discard_locked;
|
||||
|
||||
err = do_add_mount(mnt, mp.mp, path,
|
||||
path->mnt->mnt_flags | MNT_SHRINKABLE);
|
||||
unlock_mount(&mp);
|
||||
@@ -3826,9 +3837,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
|
||||
goto discard;
|
||||
return 0;
|
||||
|
||||
discard_locked:
|
||||
namespace_unlock();
|
||||
inode_unlock(dentry->d_inode);
|
||||
discard:
|
||||
mntput(m);
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user