aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c161
1 files changed, 22 insertions, 139 deletions
diff --git a/fs/super.c b/fs/super.c
index 7e9dd4cc2c01..8a06881b1920 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -71,6 +71,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
71#else 71#else
72 INIT_LIST_HEAD(&s->s_files); 72 INIT_LIST_HEAD(&s->s_files);
73#endif 73#endif
74 s->s_bdi = &default_backing_dev_info;
74 INIT_LIST_HEAD(&s->s_instances); 75 INIT_LIST_HEAD(&s->s_instances);
75 INIT_HLIST_BL_HEAD(&s->s_anon); 76 INIT_HLIST_BL_HEAD(&s->s_anon);
76 INIT_LIST_HEAD(&s->s_inodes); 77 INIT_LIST_HEAD(&s->s_inodes);
@@ -843,23 +844,6 @@ error:
843} 844}
844EXPORT_SYMBOL(mount_bdev); 845EXPORT_SYMBOL(mount_bdev);
845 846
846int get_sb_bdev(struct file_system_type *fs_type,
847 int flags, const char *dev_name, void *data,
848 int (*fill_super)(struct super_block *, void *, int),
849 struct vfsmount *mnt)
850{
851 struct dentry *root;
852
853 root = mount_bdev(fs_type, flags, dev_name, data, fill_super);
854 if (IS_ERR(root))
855 return PTR_ERR(root);
856 mnt->mnt_root = root;
857 mnt->mnt_sb = root->d_sb;
858 return 0;
859}
860
861EXPORT_SYMBOL(get_sb_bdev);
862
863void kill_block_super(struct super_block *sb) 847void kill_block_super(struct super_block *sb)
864{ 848{
865 struct block_device *bdev = sb->s_bdev; 849 struct block_device *bdev = sb->s_bdev;
@@ -897,22 +881,6 @@ struct dentry *mount_nodev(struct file_system_type *fs_type,
897} 881}
898EXPORT_SYMBOL(mount_nodev); 882EXPORT_SYMBOL(mount_nodev);
899 883
900int get_sb_nodev(struct file_system_type *fs_type,
901 int flags, void *data,
902 int (*fill_super)(struct super_block *, void *, int),
903 struct vfsmount *mnt)
904{
905 struct dentry *root;
906
907 root = mount_nodev(fs_type, flags, data, fill_super);
908 if (IS_ERR(root))
909 return PTR_ERR(root);
910 mnt->mnt_root = root;
911 mnt->mnt_sb = root->d_sb;
912 return 0;
913}
914EXPORT_SYMBOL(get_sb_nodev);
915
916static int compare_single(struct super_block *s, void *p) 884static int compare_single(struct super_block *s, void *p)
917{ 885{
918 return 1; 886 return 1;
@@ -943,69 +911,36 @@ struct dentry *mount_single(struct file_system_type *fs_type,
943} 911}
944EXPORT_SYMBOL(mount_single); 912EXPORT_SYMBOL(mount_single);
945 913
946int get_sb_single(struct file_system_type *fs_type, 914struct dentry *
947 int flags, void *data, 915mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
948 int (*fill_super)(struct super_block *, void *, int),
949 struct vfsmount *mnt)
950{
951 struct dentry *root;
952 root = mount_single(fs_type, flags, data, fill_super);
953 if (IS_ERR(root))
954 return PTR_ERR(root);
955 mnt->mnt_root = root;
956 mnt->mnt_sb = root->d_sb;
957 return 0;
958}
959
960EXPORT_SYMBOL(get_sb_single);
961
962struct vfsmount *
963vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
964{ 916{
965 struct vfsmount *mnt;
966 struct dentry *root; 917 struct dentry *root;
918 struct super_block *sb;
967 char *secdata = NULL; 919 char *secdata = NULL;
968 int error; 920 int error = -ENOMEM;
969
970 if (!type)
971 return ERR_PTR(-ENODEV);
972
973 error = -ENOMEM;
974 mnt = alloc_vfsmnt(name);
975 if (!mnt)
976 goto out;
977
978 if (flags & MS_KERNMOUNT)
979 mnt->mnt_flags = MNT_INTERNAL;
980 921
981 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 922 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
982 secdata = alloc_secdata(); 923 secdata = alloc_secdata();
983 if (!secdata) 924 if (!secdata)
984 goto out_mnt; 925 goto out;
985 926
986 error = security_sb_copy_data(data, secdata); 927 error = security_sb_copy_data(data, secdata);
987 if (error) 928 if (error)
988 goto out_free_secdata; 929 goto out_free_secdata;
989 } 930 }
990 931
991 if (type->mount) { 932 root = type->mount(type, flags, name, data);
992 root = type->mount(type, flags, name, data); 933 if (IS_ERR(root)) {
993 if (IS_ERR(root)) { 934 error = PTR_ERR(root);
994 error = PTR_ERR(root); 935 goto out_free_secdata;
995 goto out_free_secdata;
996 }
997 mnt->mnt_root = root;
998 mnt->mnt_sb = root->d_sb;
999 } else {
1000 error = type->get_sb(type, flags, name, data, mnt);
1001 if (error < 0)
1002 goto out_free_secdata;
1003 } 936 }
1004 BUG_ON(!mnt->mnt_sb); 937 sb = root->d_sb;
1005 WARN_ON(!mnt->mnt_sb->s_bdi); 938 BUG_ON(!sb);
1006 mnt->mnt_sb->s_flags |= MS_BORN; 939 WARN_ON(!sb->s_bdi);
940 WARN_ON(sb->s_bdi == &default_backing_dev_info);
941 sb->s_flags |= MS_BORN;
1007 942
1008 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); 943 error = security_sb_kern_mount(sb, flags, secdata);
1009 if (error) 944 if (error)
1010 goto out_sb; 945 goto out_sb;
1011 946
@@ -1016,27 +951,21 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
1016 * violate this rule. This warning should be either removed or 951 * violate this rule. This warning should be either removed or
1017 * converted to a BUG() in 2.6.34. 952 * converted to a BUG() in 2.6.34.
1018 */ 953 */
1019 WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " 954 WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
1020 "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); 955 "negative value (%lld)\n", type->name, sb->s_maxbytes);
1021 956
1022 mnt->mnt_mountpoint = mnt->mnt_root; 957 up_write(&sb->s_umount);
1023 mnt->mnt_parent = mnt;
1024 up_write(&mnt->mnt_sb->s_umount);
1025 free_secdata(secdata); 958 free_secdata(secdata);
1026 return mnt; 959 return root;
1027out_sb: 960out_sb:
1028 dput(mnt->mnt_root); 961 dput(root);
1029 deactivate_locked_super(mnt->mnt_sb); 962 deactivate_locked_super(sb);
1030out_free_secdata: 963out_free_secdata:
1031 free_secdata(secdata); 964 free_secdata(secdata);
1032out_mnt:
1033 free_vfsmnt(mnt);
1034out: 965out:
1035 return ERR_PTR(error); 966 return ERR_PTR(error);
1036} 967}
1037 968
1038EXPORT_SYMBOL_GPL(vfs_kern_mount);
1039
1040/** 969/**
1041 * freeze_super - lock the filesystem and force it into a consistent state 970 * freeze_super - lock the filesystem and force it into a consistent state
1042 * @sb: the super to lock 971 * @sb: the super to lock
@@ -1126,49 +1055,3 @@ out:
1126 return 0; 1055 return 0;
1127} 1056}
1128EXPORT_SYMBOL(thaw_super); 1057EXPORT_SYMBOL(thaw_super);
1129
1130static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
1131{
1132 int err;
1133 const char *subtype = strchr(fstype, '.');
1134 if (subtype) {
1135 subtype++;
1136 err = -EINVAL;
1137 if (!subtype[0])
1138 goto err;
1139 } else
1140 subtype = "";
1141
1142 mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
1143 err = -ENOMEM;
1144 if (!mnt->mnt_sb->s_subtype)
1145 goto err;
1146 return mnt;
1147
1148 err:
1149 mntput(mnt);
1150 return ERR_PTR(err);
1151}
1152
1153struct vfsmount *
1154do_kern_mount(const char *fstype, int flags, const char *name, void *data)
1155{
1156 struct file_system_type *type = get_fs_type(fstype);
1157 struct vfsmount *mnt;
1158 if (!type)
1159 return ERR_PTR(-ENODEV);
1160 mnt = vfs_kern_mount(type, flags, name, data);
1161 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1162 !mnt->mnt_sb->s_subtype)
1163 mnt = fs_set_subtype(mnt, fstype);
1164 put_filesystem(type);
1165 return mnt;
1166}
1167EXPORT_SYMBOL_GPL(do_kern_mount);
1168
1169struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
1170{
1171 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
1172}
1173
1174EXPORT_SYMBOL_GPL(kern_mount_data);