mirror of https://gitee.com/openkylin/linux.git
vfs: spread struct mount - alloc_vfsmnt/free_vfsmnt/mnt_alloc_id/mnt_free_id
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
cbbe362cd6
commit
b105e270b4
|
@ -78,16 +78,16 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
|
||||||
* allocation is serialized by namespace_sem, but we need the spinlock to
|
* allocation is serialized by namespace_sem, but we need the spinlock to
|
||||||
* serialize with freeing.
|
* serialize with freeing.
|
||||||
*/
|
*/
|
||||||
static int mnt_alloc_id(struct vfsmount *mnt)
|
static int mnt_alloc_id(struct mount *mnt)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ida_pre_get(&mnt_id_ida, GFP_KERNEL);
|
ida_pre_get(&mnt_id_ida, GFP_KERNEL);
|
||||||
spin_lock(&mnt_id_lock);
|
spin_lock(&mnt_id_lock);
|
||||||
res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
|
res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt.mnt_id);
|
||||||
if (!res)
|
if (!res)
|
||||||
mnt_id_start = mnt->mnt_id + 1;
|
mnt_id_start = mnt->mnt.mnt_id + 1;
|
||||||
spin_unlock(&mnt_id_lock);
|
spin_unlock(&mnt_id_lock);
|
||||||
if (res == -EAGAIN)
|
if (res == -EAGAIN)
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -95,9 +95,9 @@ static int mnt_alloc_id(struct vfsmount *mnt)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mnt_free_id(struct vfsmount *mnt)
|
static void mnt_free_id(struct mount *mnt)
|
||||||
{
|
{
|
||||||
int id = mnt->mnt_id;
|
int id = mnt->mnt.mnt_id;
|
||||||
spin_lock(&mnt_id_lock);
|
spin_lock(&mnt_id_lock);
|
||||||
ida_remove(&mnt_id_ida, id);
|
ida_remove(&mnt_id_ida, id);
|
||||||
if (mnt_id_start > id)
|
if (mnt_id_start > id)
|
||||||
|
@ -171,14 +171,14 @@ unsigned int mnt_get_count(struct vfsmount *mnt)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vfsmount *alloc_vfsmnt(const char *name)
|
static struct mount *alloc_vfsmnt(const char *name)
|
||||||
{
|
{
|
||||||
struct mount *p = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
|
struct mount *p = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
|
||||||
if (p) {
|
if (p) {
|
||||||
struct vfsmount *mnt = &p->mnt;
|
struct vfsmount *mnt = &p->mnt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = mnt_alloc_id(mnt);
|
err = mnt_alloc_id(p);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_free_cache;
|
goto out_free_cache;
|
||||||
|
|
||||||
|
@ -211,14 +211,14 @@ static struct vfsmount *alloc_vfsmnt(const char *name)
|
||||||
INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
|
INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return &p->mnt;
|
return p;
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
out_free_devname:
|
out_free_devname:
|
||||||
kfree(p->mnt.mnt_devname);
|
kfree(p->mnt.mnt_devname);
|
||||||
#endif
|
#endif
|
||||||
out_free_id:
|
out_free_id:
|
||||||
mnt_free_id(&p->mnt);
|
mnt_free_id(p);
|
||||||
out_free_cache:
|
out_free_cache:
|
||||||
kmem_cache_free(mnt_cache, p);
|
kmem_cache_free(mnt_cache, p);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -448,15 +448,14 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt)
|
||||||
br_write_unlock(vfsmount_lock);
|
br_write_unlock(vfsmount_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_vfsmnt(struct vfsmount *mnt)
|
static void free_vfsmnt(struct mount *mnt)
|
||||||
{
|
{
|
||||||
struct mount *p = real_mount(mnt);
|
kfree(mnt->mnt.mnt_devname);
|
||||||
kfree(mnt->mnt_devname);
|
|
||||||
mnt_free_id(mnt);
|
mnt_free_id(mnt);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
free_percpu(mnt->mnt_pcp);
|
free_percpu(mnt->mnt.mnt_pcp);
|
||||||
#endif
|
#endif
|
||||||
kmem_cache_free(mnt_cache, p);
|
kmem_cache_free(mnt_cache, mnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -661,7 +660,7 @@ static struct mount *skip_mnt_tree(struct mount *p)
|
||||||
struct vfsmount *
|
struct vfsmount *
|
||||||
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
|
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
|
||||||
{
|
{
|
||||||
struct vfsmount *mnt;
|
struct mount *mnt;
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
|
@ -672,7 +671,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
if (flags & MS_KERNMOUNT)
|
if (flags & MS_KERNMOUNT)
|
||||||
mnt->mnt_flags = MNT_INTERNAL;
|
mnt->mnt.mnt_flags = MNT_INTERNAL;
|
||||||
|
|
||||||
root = mount_fs(type, flags, name, data);
|
root = mount_fs(type, flags, name, data);
|
||||||
if (IS_ERR(root)) {
|
if (IS_ERR(root)) {
|
||||||
|
@ -680,11 +679,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
|
||||||
return ERR_CAST(root);
|
return ERR_CAST(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
mnt->mnt_root = root;
|
mnt->mnt.mnt_root = root;
|
||||||
mnt->mnt_sb = root->d_sb;
|
mnt->mnt.mnt_sb = root->d_sb;
|
||||||
mnt->mnt_mountpoint = mnt->mnt_root;
|
mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
|
||||||
mnt->mnt_parent = mnt;
|
mnt->mnt.mnt_parent = &mnt->mnt;
|
||||||
return mnt;
|
return &mnt->mnt;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vfs_kern_mount);
|
EXPORT_SYMBOL_GPL(vfs_kern_mount);
|
||||||
|
|
||||||
|
@ -692,49 +691,49 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
struct super_block *sb = old->mnt_sb;
|
struct super_block *sb = old->mnt_sb;
|
||||||
struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
|
struct mount *mnt = alloc_vfsmnt(old->mnt_devname);
|
||||||
|
|
||||||
if (mnt) {
|
if (mnt) {
|
||||||
if (flag & (CL_SLAVE | CL_PRIVATE))
|
if (flag & (CL_SLAVE | CL_PRIVATE))
|
||||||
mnt->mnt_group_id = 0; /* not a peer of original */
|
mnt->mnt.mnt_group_id = 0; /* not a peer of original */
|
||||||
else
|
else
|
||||||
mnt->mnt_group_id = old->mnt_group_id;
|
mnt->mnt.mnt_group_id = old->mnt_group_id;
|
||||||
|
|
||||||
if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) {
|
if ((flag & CL_MAKE_SHARED) && !mnt->mnt.mnt_group_id) {
|
||||||
int err = mnt_alloc_group_id(real_mount(mnt));
|
int err = mnt_alloc_group_id(mnt);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
mnt->mnt_flags = old->mnt_flags & ~MNT_WRITE_HOLD;
|
mnt->mnt.mnt_flags = old->mnt_flags & ~MNT_WRITE_HOLD;
|
||||||
atomic_inc(&sb->s_active);
|
atomic_inc(&sb->s_active);
|
||||||
mnt->mnt_sb = sb;
|
mnt->mnt.mnt_sb = sb;
|
||||||
mnt->mnt_root = dget(root);
|
mnt->mnt.mnt_root = dget(root);
|
||||||
mnt->mnt_mountpoint = mnt->mnt_root;
|
mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
|
||||||
mnt->mnt_parent = mnt;
|
mnt->mnt.mnt_parent = &mnt->mnt;
|
||||||
|
|
||||||
if (flag & CL_SLAVE) {
|
if (flag & CL_SLAVE) {
|
||||||
list_add(&mnt->mnt_slave, &old->mnt_slave_list);
|
list_add(&mnt->mnt.mnt_slave, &old->mnt_slave_list);
|
||||||
mnt->mnt_master = old;
|
mnt->mnt.mnt_master = old;
|
||||||
CLEAR_MNT_SHARED(mnt);
|
CLEAR_MNT_SHARED(&mnt->mnt);
|
||||||
} else if (!(flag & CL_PRIVATE)) {
|
} else if (!(flag & CL_PRIVATE)) {
|
||||||
if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
|
if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
|
||||||
list_add(&mnt->mnt_share, &old->mnt_share);
|
list_add(&mnt->mnt.mnt_share, &old->mnt_share);
|
||||||
if (IS_MNT_SLAVE(old))
|
if (IS_MNT_SLAVE(old))
|
||||||
list_add(&mnt->mnt_slave, &old->mnt_slave);
|
list_add(&mnt->mnt.mnt_slave, &old->mnt_slave);
|
||||||
mnt->mnt_master = old->mnt_master;
|
mnt->mnt.mnt_master = old->mnt_master;
|
||||||
}
|
}
|
||||||
if (flag & CL_MAKE_SHARED)
|
if (flag & CL_MAKE_SHARED)
|
||||||
set_mnt_shared(mnt);
|
set_mnt_shared(&mnt->mnt);
|
||||||
|
|
||||||
/* stick the duplicate mount on the same expiry list
|
/* stick the duplicate mount on the same expiry list
|
||||||
* as the original if that was on one */
|
* as the original if that was on one */
|
||||||
if (flag & CL_EXPIRE) {
|
if (flag & CL_EXPIRE) {
|
||||||
if (!list_empty(&old->mnt_expire))
|
if (!list_empty(&old->mnt_expire))
|
||||||
list_add(&mnt->mnt_expire, &old->mnt_expire);
|
list_add(&mnt->mnt.mnt_expire, &old->mnt_expire);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mnt;
|
return &mnt->mnt;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
free_vfsmnt(mnt);
|
free_vfsmnt(mnt);
|
||||||
|
@ -758,7 +757,7 @@ static inline void mntfree(struct vfsmount *mnt)
|
||||||
WARN_ON(mnt_get_writers(mnt));
|
WARN_ON(mnt_get_writers(mnt));
|
||||||
fsnotify_vfsmount_delete(mnt);
|
fsnotify_vfsmount_delete(mnt);
|
||||||
dput(mnt->mnt_root);
|
dput(mnt->mnt_root);
|
||||||
free_vfsmnt(mnt);
|
free_vfsmnt(real_mount(mnt));
|
||||||
deactivate_super(sb);
|
deactivate_super(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue