__cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
static struct list_head *mount_hashtable;
-static int hash_mask, hash_bits;
+static int hash_mask __read_mostly, hash_bits __read_mostly;
static kmem_cache_t *mnt_cache;
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
INIT_LIST_HEAD(&mnt->mnt_child);
INIT_LIST_HEAD(&mnt->mnt_mounts);
INIT_LIST_HEAD(&mnt->mnt_list);
- INIT_LIST_HEAD(&mnt->mnt_fslink);
+ INIT_LIST_HEAD(&mnt->mnt_expire);
if (name) {
int size = strlen(name)+1;
char *newname = kmalloc(size, GFP_KERNEL);
mnt->mnt_root = dget(root);
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
- mnt->mnt_namespace = old->mnt_namespace;
+ mnt->mnt_namespace = current->namespace;
/* stick the duplicate mount on the same expiry list
* as the original if that was on one */
spin_lock(&vfsmount_lock);
- if (!list_empty(&old->mnt_fslink))
- list_add(&mnt->mnt_fslink, &old->mnt_fslink);
+ if (!list_empty(&old->mnt_expire))
+ list_add(&mnt->mnt_expire, &old->mnt_expire);
spin_unlock(&vfsmount_lock);
}
return mnt;
while (!list_empty(&kill)) {
mnt = list_entry(kill.next, struct vfsmount, mnt_list);
list_del_init(&mnt->mnt_list);
- list_del_init(&mnt->mnt_fslink);
+ list_del_init(&mnt->mnt_expire);
if (mnt->mnt_parent == mnt) {
spin_unlock(&vfsmount_lock);
} else {
static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
{
struct vfsmount *res, *p, *q, *r, *s;
- struct list_head *h;
struct nameidata nd;
res = q = clone_mnt(mnt, dentry);
q->mnt_mountpoint = mnt->mnt_mountpoint;
p = mnt;
- for (h = mnt->mnt_mounts.next; h != &mnt->mnt_mounts; h = h->next) {
- r = list_entry(h, struct vfsmount, mnt_child);
+ list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
if (!lives_below_in_same_fs(r->mnt_mountpoint, dentry))
continue;
if (mnt) {
/* stop bind mounts from expiring */
spin_lock(&vfsmount_lock);
- list_del_init(&mnt->mnt_fslink);
+ list_del_init(&mnt->mnt_expire);
spin_unlock(&vfsmount_lock);
err = graft_tree(mnt, nd);
/* if the mount is moved, it should no longer be expire
* automatically */
- list_del_init(&old_nd.mnt->mnt_fslink);
+ list_del_init(&old_nd.mnt->mnt_expire);
out2:
spin_unlock(&vfsmount_lock);
out1:
goto unlock;
newmnt->mnt_flags = mnt_flags;
+ newmnt->mnt_namespace = current->namespace;
err = graft_tree(newmnt, nd);
if (err == 0 && fslist) {
/* add to the specified expiration list */
spin_lock(&vfsmount_lock);
- list_add_tail(&newmnt->mnt_fslink, fslist);
+ list_add_tail(&newmnt->mnt_expire, fslist);
spin_unlock(&vfsmount_lock);
}
* Someone brought it back to life whilst we didn't have any
* locks held so return it to the expiration list
*/
- list_add_tail(&mnt->mnt_fslink, mounts);
+ list_add_tail(&mnt->mnt_expire, mounts);
spin_unlock(&vfsmount_lock);
}
}
* - still marked for expiry (marked on the last call here; marks are
* cleared by mntput())
*/
- list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) {
+ list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
if (!xchg(&mnt->mnt_expiry_mark, 1) ||
atomic_read(&mnt->mnt_count) != 1)
continue;
mntget(mnt);
- list_move(&mnt->mnt_fslink, &graveyard);
+ list_move(&mnt->mnt_expire, &graveyard);
}
/*
* - dispose of the corpse
*/
while (!list_empty(&graveyard)) {
- mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink);
- list_del_init(&mnt->mnt_fslink);
+ mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
+ list_del_init(&mnt->mnt_expire);
/* don't do anything if the namespace is dead - all the
* vfsmounts from it are going away anyway */
error = -EINVAL;
if (user_nd.mnt->mnt_root != user_nd.dentry)
goto out2; /* not a mountpoint */
+ if (user_nd.mnt->mnt_parent == user_nd.mnt)
+ goto out2; /* not attached */
if (new_nd.mnt->mnt_root != new_nd.dentry)
goto out2; /* not a mountpoint */
+ if (new_nd.mnt->mnt_parent == new_nd.mnt)
+ goto out2; /* not attached */
tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
spin_lock(&vfsmount_lock);
if (tmp != new_nd.mnt) {