diff options
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 161 |
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 | } |
844 | EXPORT_SYMBOL(mount_bdev); | 845 | EXPORT_SYMBOL(mount_bdev); |
845 | 846 | ||
846 | int 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 | |||
861 | EXPORT_SYMBOL(get_sb_bdev); | ||
862 | |||
863 | void kill_block_super(struct super_block *sb) | 847 | void 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 | } |
898 | EXPORT_SYMBOL(mount_nodev); | 882 | EXPORT_SYMBOL(mount_nodev); |
899 | 883 | ||
900 | int 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 | } | ||
914 | EXPORT_SYMBOL(get_sb_nodev); | ||
915 | |||
916 | static int compare_single(struct super_block *s, void *p) | 884 | static 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 | } |
944 | EXPORT_SYMBOL(mount_single); | 912 | EXPORT_SYMBOL(mount_single); |
945 | 913 | ||
946 | int get_sb_single(struct file_system_type *fs_type, | 914 | struct dentry * |
947 | int flags, void *data, | 915 | mount_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 | |||
960 | EXPORT_SYMBOL(get_sb_single); | ||
961 | |||
962 | struct vfsmount * | ||
963 | vfs_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; |
1027 | out_sb: | 960 | out_sb: |
1028 | dput(mnt->mnt_root); | 961 | dput(root); |
1029 | deactivate_locked_super(mnt->mnt_sb); | 962 | deactivate_locked_super(sb); |
1030 | out_free_secdata: | 963 | out_free_secdata: |
1031 | free_secdata(secdata); | 964 | free_secdata(secdata); |
1032 | out_mnt: | ||
1033 | free_vfsmnt(mnt); | ||
1034 | out: | 965 | out: |
1035 | return ERR_PTR(error); | 966 | return ERR_PTR(error); |
1036 | } | 967 | } |
1037 | 968 | ||
1038 | EXPORT_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 | } |
1128 | EXPORT_SYMBOL(thaw_super); | 1057 | EXPORT_SYMBOL(thaw_super); |
1129 | |||
1130 | static 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 | |||
1153 | struct vfsmount * | ||
1154 | do_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 | } | ||
1167 | EXPORT_SYMBOL_GPL(do_kern_mount); | ||
1168 | |||
1169 | struct 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 | |||
1174 | EXPORT_SYMBOL_GPL(kern_mount_data); | ||