static struct list_head *mount_hashtable __read_mostly;
static struct list_head *mountpoint_hashtable __read_mostly;
static struct kmem_cache *mnt_cache __read_mostly;
-static struct rw_semaphore namespace_sem;
+static DECLARE_RWSEM(namespace_sem);
/* /sys/fs */
struct kobject *fs_kobj;
return retval;
}
+void detach_mounts(struct dentry *dentry)
+{
+ struct mountpoint *mp;
+ struct mount *mnt;
+
+ namespace_lock();
+ if (!d_mountpoint(dentry))
+ goto out_unlock;
+
+ mp = new_mountpoint(dentry);
+ if (IS_ERR(mp))
+ goto out_unlock;
+
+ br_write_lock(&vfsmount_lock);
+ while (!list_empty(&mp->m_list)) {
+ mnt = list_first_entry(&mp->m_list, struct mount, mnt_mp_list);
+ umount_tree(mnt, 1);
+ }
+ br_write_unlock(&vfsmount_lock);
+ put_mountpoint(mp);
+out_unlock:
+ namespace_unlock();
+}
+
/*
* Is the caller allowed to modify his namespace?
*/
br_write_lock(&vfsmount_lock);
mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK;
mnt->mnt.mnt_flags = mnt_flags;
- br_write_unlock(&vfsmount_lock);
- }
- up_write(&sb->s_umount);
- if (!err) {
- br_write_lock(&vfsmount_lock);
touch_mnt_namespace(mnt->mnt_ns);
br_write_unlock(&vfsmount_lock);
}
+ up_write(&sb->s_umount);
return err;
}
return ERR_CAST(new);
}
new_ns->root = new;
- br_write_lock(&vfsmount_lock);
list_add_tail(&new_ns->list, &new->mnt_list);
- br_write_unlock(&vfsmount_lock);
/*
* Second pass: switch the tsk->fs->* elements and mark new vfsmounts
unsigned u;
int err;
- init_rwsem(&namespace_sem);
-
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
{
if (!atomic_dec_and_test(&ns->count))
return;
- namespace_lock();
- br_write_lock(&vfsmount_lock);
- umount_tree(ns->root, 0);
- br_write_unlock(&vfsmount_lock);
- namespace_unlock();
+ drop_collected_mounts(&ns->root->mnt);
free_mnt_ns(ns);
}
if (unlikely(!ns))
return false;
- namespace_lock();
+ down_read(&namespace_sem);
list_for_each_entry(mnt, &ns->list, mnt_list) {
struct mount *child;
if (mnt->mnt.mnt_sb->s_type != type)
next: ;
}
found:
- namespace_unlock();
+ up_read(&namespace_sem);
return visible;
}