Skip to content

Commit

Permalink
Take the completion of automount into new helper
Browse files Browse the repository at this point in the history
... and shift it from namei.c to namespace.c

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro committed Jan 17, 2011
1 parent e78bf5e commit 19a167a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
1 change: 1 addition & 0 deletions fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
extern void release_mounts(struct list_head *);
extern void umount_tree(struct vfsmount *, int, struct list_head *);
extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
extern int finish_automount(struct vfsmount *, struct path *);
extern int do_add_mount(struct vfsmount *, struct path *, int);
extern void mnt_clear_expiry(struct vfsmount *);

Expand Down
31 changes: 5 additions & 26 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,45 +923,24 @@ static int follow_automount(struct path *path, unsigned flags,
if (!mnt) /* mount collision */
return 0;

/* The new mount record should have at least 2 refs to prevent it being
* expired before we get a chance to add it
*/
BUG_ON(mnt_get_count(mnt) < 2);

if (mnt->mnt_sb == path->mnt->mnt_sb &&
mnt->mnt_root == path->dentry) {
mnt_clear_expiry(mnt);
mntput(mnt);
mntput(mnt);
return -ELOOP;
}
err = finish_automount(mnt, path);

/* We need to add the mountpoint to the parent. The filesystem may
* have placed it on an expiry list, and so we need to make sure it
* won't be expired under us if do_add_mount() fails (do_add_mount()
* will eat a reference unconditionally).
*/
mntget(mnt);
err = do_add_mount(mnt, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
switch (err) {
case -EBUSY:
/* Someone else made a mount here whilst we were busy */
err = 0;
default:
mnt_clear_expiry(mnt);
mntput(mnt);
mntput(mnt);
return err;
return 0;
case 0:
mntput(mnt);
dput(path->dentry);
if (*need_mntput)
mntput(path->mnt);
path->mnt = mnt;
path->dentry = dget(mnt->mnt_root);
*need_mntput = true;
return 0;
default:
return err;
}

}

/*
Expand Down
33 changes: 33 additions & 0 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,39 @@ static int do_new_mount(struct path *path, char *type, int flags,
return do_add_mount(mnt, path, mnt_flags);
}

int finish_automount(struct vfsmount *m, struct path *path)
{
int err;
/* The new mount record should have at least 2 refs to prevent it being
* expired before we get a chance to add it
*/
BUG_ON(mnt_get_count(m) < 2);

if (m->mnt_sb == path->mnt->mnt_sb &&
m->mnt_root == path->dentry) {
mnt_clear_expiry(m);
mntput(m);
mntput(m);
return -ELOOP;
}

/* We need to add the mountpoint to the parent. The filesystem may
* have placed it on an expiry list, and so we need to make sure it
* won't be expired under us if do_add_mount() fails (do_add_mount()
* will eat a reference unconditionally).
*/
mntget(m);
err = do_add_mount(m, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
if (err) {
mnt_clear_expiry(m);
mntput(m);
mntput(m);
} else {
mntput(m);
}
return err;
}

/*
* add a mount into a namespace's mount tree
* - this unconditionally eats one of the caller's references to newmnt.
Expand Down

0 comments on commit 19a167a

Please sign in to comment.