aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-03-17 22:08:28 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-17 22:10:41 -0400
commit9d412a43c3b26e1e549319e5eec26f0829f9f74d (patch)
treeb6522b693564fed172e9f8aee2e42aa2fdd95c8a /fs/namespace.c
parentfbe0aa1f3d16fac5b641c0c1697371dcbe45b569 (diff)
vfs: split off vfsmount-related parts of vfs_kern_mount()
new function: mount_fs(). Does all work done by vfs_kern_mount() except the allocation and filling of vfsmount; returns root dentry or ERR_PTR(). vfs_kern_mount() switched to using it and taken to fs/namespace.c, along with its wrappers. alloc_vfsmnt()/free_vfsmnt() made static. functions in namespace.c slightly reordered. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c153
1 files changed, 113 insertions, 40 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index a2a01a104ab0..453529f72dff 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -196,7 +196,7 @@ unsigned int mnt_get_count(struct vfsmount *mnt)
196#endif 196#endif
197} 197}
198 198
199struct vfsmount *alloc_vfsmnt(const char *name) 199static struct vfsmount *alloc_vfsmnt(const char *name)
200{ 200{
201 struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); 201 struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
202 if (mnt) { 202 if (mnt) {
@@ -466,7 +466,7 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt)
466 br_write_unlock(vfsmount_lock); 466 br_write_unlock(vfsmount_lock);
467} 467}
468 468
469void free_vfsmnt(struct vfsmount *mnt) 469static void free_vfsmnt(struct vfsmount *mnt)
470{ 470{
471 kfree(mnt->mnt_devname); 471 kfree(mnt->mnt_devname);
472 mnt_free_id(mnt); 472 mnt_free_id(mnt);
@@ -670,6 +670,36 @@ static struct vfsmount *skip_mnt_tree(struct vfsmount *p)
670 return p; 670 return p;
671} 671}
672 672
673struct vfsmount *
674vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
675{
676 struct vfsmount *mnt;
677 struct dentry *root;
678
679 if (!type)
680 return ERR_PTR(-ENODEV);
681
682 mnt = alloc_vfsmnt(name);
683 if (!mnt)
684 return ERR_PTR(-ENOMEM);
685
686 if (flags & MS_KERNMOUNT)
687 mnt->mnt_flags = MNT_INTERNAL;
688
689 root = mount_fs(type, flags, name, data);
690 if (IS_ERR(root)) {
691 free_vfsmnt(mnt);
692 return ERR_CAST(root);
693 }
694
695 mnt->mnt_root = root;
696 mnt->mnt_sb = root->d_sb;
697 mnt->mnt_mountpoint = mnt->mnt_root;
698 mnt->mnt_parent = mnt;
699 return mnt;
700}
701EXPORT_SYMBOL_GPL(vfs_kern_mount);
702
673static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, 703static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
674 int flag) 704 int flag)
675{ 705{
@@ -1905,7 +1935,81 @@ out:
1905 return err; 1935 return err;
1906} 1936}
1907 1937
1908static int do_add_mount(struct vfsmount *, struct path *, int); 1938static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
1939{
1940 int err;
1941 const char *subtype = strchr(fstype, '.');
1942 if (subtype) {
1943 subtype++;
1944 err = -EINVAL;
1945 if (!subtype[0])
1946 goto err;
1947 } else
1948 subtype = "";
1949
1950 mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
1951 err = -ENOMEM;
1952 if (!mnt->mnt_sb->s_subtype)
1953 goto err;
1954 return mnt;
1955
1956 err:
1957 mntput(mnt);
1958 return ERR_PTR(err);
1959}
1960
1961struct vfsmount *
1962do_kern_mount(const char *fstype, int flags, const char *name, void *data)
1963{
1964 struct file_system_type *type = get_fs_type(fstype);
1965 struct vfsmount *mnt;
1966 if (!type)
1967 return ERR_PTR(-ENODEV);
1968 mnt = vfs_kern_mount(type, flags, name, data);
1969 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1970 !mnt->mnt_sb->s_subtype)
1971 mnt = fs_set_subtype(mnt, fstype);
1972 put_filesystem(type);
1973 return mnt;
1974}
1975EXPORT_SYMBOL_GPL(do_kern_mount);
1976
1977/*
1978 * add a mount into a namespace's mount tree
1979 */
1980static int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1981{
1982 int err;
1983
1984 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
1985
1986 down_write(&namespace_sem);
1987 /* Something was mounted here while we slept */
1988 err = follow_down(path, true);
1989 if (err < 0)
1990 goto unlock;
1991
1992 err = -EINVAL;
1993 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
1994 goto unlock;
1995
1996 /* Refuse the same filesystem on the same mount point */
1997 err = -EBUSY;
1998 if (path->mnt->mnt_sb == newmnt->mnt_sb &&
1999 path->mnt->mnt_root == path->dentry)
2000 goto unlock;
2001
2002 err = -EINVAL;
2003 if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
2004 goto unlock;
2005
2006 newmnt->mnt_flags = mnt_flags;
2007 err = graft_tree(newmnt, path);
2008
2009unlock:
2010 up_write(&namespace_sem);
2011 return err;
2012}
1909 2013
1910/* 2014/*
1911 * create a new mount for userspace and request it to be added into the 2015 * create a new mount for userspace and request it to be added into the
@@ -1965,43 +2069,6 @@ fail:
1965 return err; 2069 return err;
1966} 2070}
1967 2071
1968/*
1969 * add a mount into a namespace's mount tree
1970 */
1971static int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1972{
1973 int err;
1974
1975 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
1976
1977 down_write(&namespace_sem);
1978 /* Something was mounted here while we slept */
1979 err = follow_down(path, true);
1980 if (err < 0)
1981 goto unlock;
1982
1983 err = -EINVAL;
1984 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
1985 goto unlock;
1986
1987 /* Refuse the same filesystem on the same mount point */
1988 err = -EBUSY;
1989 if (path->mnt->mnt_sb == newmnt->mnt_sb &&
1990 path->mnt->mnt_root == path->dentry)
1991 goto unlock;
1992
1993 err = -EINVAL;
1994 if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
1995 goto unlock;
1996
1997 newmnt->mnt_flags = mnt_flags;
1998 err = graft_tree(newmnt, path);
1999
2000unlock:
2001 up_write(&namespace_sem);
2002 return err;
2003}
2004
2005/** 2072/**
2006 * mnt_set_expiry - Put a mount on an expiration list 2073 * mnt_set_expiry - Put a mount on an expiration list
2007 * @mnt: The mount to list. 2074 * @mnt: The mount to list.
@@ -2660,3 +2727,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
2660 kfree(ns); 2727 kfree(ns);
2661} 2728}
2662EXPORT_SYMBOL(put_mnt_ns); 2729EXPORT_SYMBOL(put_mnt_ns);
2730
2731struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
2732{
2733 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
2734}
2735EXPORT_SYMBOL_GPL(kern_mount_data);