Skip to content

Commit 423e0ab

Browse files
pdxChenAl Viro
authored and
Al Viro
committed
VFS : mount lock scalability for internal mounts
For a number of file systems that don't have a mount point (e.g. sockfs and pipefs), they are not marked as long term. Therefore in mntput_no_expire, all locks in vfs_mount lock are taken instead of just local cpu's lock to aggregate reference counts when we release reference to file objects. In fact, only local lock need to have been taken to update ref counts as these file systems are in no danger of going away until we are ready to unregister them. The attached patch marks file systems using kern_mount without mount point as long term. The contentions of vfs_mount lock is now eliminated. Before un-registering such file system, kern_unmount should be called to remove the long term flag and make the mount point ready to be freed. Signed-off-by: Tim Chen <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent bbd9d6f commit 423e0ab

File tree

7 files changed

+26
-4
lines changed

7 files changed

+26
-4
lines changed

drivers/mtd/mtdchar.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,7 @@ static int __init init_mtdchar(void)
11921192
static void __exit cleanup_mtdchar(void)
11931193
{
11941194
unregister_mtd_user(&mtdchar_notifier);
1195-
mntput(mtd_inode_mnt);
1195+
kern_unmount(mtd_inode_mnt);
11961196
unregister_filesystem(&mtd_inodefs_type);
11971197
__unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
11981198
}

fs/anon_inodes.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static int __init anon_inode_init(void)
233233
return 0;
234234

235235
err_mntput:
236-
mntput(anon_inode_mnt);
236+
kern_unmount(anon_inode_mnt);
237237
err_unregister_filesystem:
238238
unregister_filesystem(&anon_inode_fs_type);
239239
err_exit:

fs/hugetlbfs/inode.c

+1
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ static int __init init_hugetlbfs_fs(void)
10301030
static void __exit exit_hugetlbfs_fs(void)
10311031
{
10321032
kmem_cache_destroy(hugetlbfs_inode_cachep);
1033+
kern_unmount(hugetlbfs_vfsmount);
10331034
unregister_filesystem(&hugetlbfs_fs_type);
10341035
bdi_destroy(&hugetlbfs_backing_dev_info);
10351036
}

fs/namespace.c

+20-1
Original file line numberDiff line numberDiff line change
@@ -2721,6 +2721,25 @@ EXPORT_SYMBOL(put_mnt_ns);
27212721

27222722
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
27232723
{
2724-
return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
2724+
struct vfsmount *mnt;
2725+
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
2726+
if (!IS_ERR(mnt)) {
2727+
/*
2728+
* it is a longterm mount, don't release mnt until
2729+
* we unmount before file sys is unregistered
2730+
*/
2731+
mnt_make_longterm(mnt);
2732+
}
2733+
return mnt;
27252734
}
27262735
EXPORT_SYMBOL_GPL(kern_mount_data);
2736+
2737+
void kern_unmount(struct vfsmount *mnt)
2738+
{
2739+
/* release long term mount so mount point can be released */
2740+
if (!IS_ERR_OR_NULL(mnt)) {
2741+
mnt_make_shortterm(mnt);
2742+
mntput(mnt);
2743+
}
2744+
}
2745+
EXPORT_SYMBOL(kern_unmount);

fs/pipe.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,8 +1291,8 @@ static int __init init_pipe_fs(void)
12911291

12921292
static void __exit exit_pipe_fs(void)
12931293
{
1294+
kern_unmount(pipe_mnt);
12941295
unregister_filesystem(&pipe_fs_type);
1295-
mntput(pipe_mnt);
12961296
}
12971297

12981298
fs_initcall(init_pipe_fs);

include/linux/fs.h

+1
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,7 @@ extern int register_filesystem(struct file_system_type *);
18851885
extern int unregister_filesystem(struct file_system_type *);
18861886
extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
18871887
#define kern_mount(type) kern_mount_data(type, NULL)
1888+
extern void kern_unmount(struct vfsmount *mnt);
18881889
extern int may_umount_tree(struct vfsmount *);
18891890
extern int may_umount(struct vfsmount *);
18901891
extern long do_mount(char *, char *, char *, unsigned long, void *);

security/selinux/selinuxfs.c

+1
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,7 @@ __initcall(init_sel_fs);
19841984
void exit_sel_fs(void)
19851985
{
19861986
kobject_put(selinuxfs_kobj);
1987+
kern_unmount(selinuxfs_mount);
19871988
unregister_filesystem(&sel_fs_type);
19881989
}
19891990
#endif

0 commit comments

Comments
 (0)