diff options
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 172 |
1 files changed, 31 insertions, 141 deletions
diff --git a/fs/super.c b/fs/super.c index 74e149efed81..c75593953c52 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/backing-dev.h> | 32 | #include <linux/backing-dev.h> |
33 | #include <linux/rculist_bl.h> | 33 | #include <linux/rculist_bl.h> |
34 | #include <linux/cleancache.h> | ||
34 | #include "internal.h" | 35 | #include "internal.h" |
35 | 36 | ||
36 | 37 | ||
@@ -71,6 +72,7 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
71 | #else | 72 | #else |
72 | INIT_LIST_HEAD(&s->s_files); | 73 | INIT_LIST_HEAD(&s->s_files); |
73 | #endif | 74 | #endif |
75 | s->s_bdi = &default_backing_dev_info; | ||
74 | INIT_LIST_HEAD(&s->s_instances); | 76 | INIT_LIST_HEAD(&s->s_instances); |
75 | INIT_HLIST_BL_HEAD(&s->s_anon); | 77 | INIT_HLIST_BL_HEAD(&s->s_anon); |
76 | INIT_LIST_HEAD(&s->s_inodes); | 78 | INIT_LIST_HEAD(&s->s_inodes); |
@@ -111,6 +113,7 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
111 | s->s_maxbytes = MAX_NON_LFS; | 113 | s->s_maxbytes = MAX_NON_LFS; |
112 | s->s_op = &default_op; | 114 | s->s_op = &default_op; |
113 | s->s_time_gran = 1000000000; | 115 | s->s_time_gran = 1000000000; |
116 | s->cleancache_poolid = -1; | ||
114 | } | 117 | } |
115 | out: | 118 | out: |
116 | return s; | 119 | return s; |
@@ -176,7 +179,13 @@ void deactivate_locked_super(struct super_block *s) | |||
176 | { | 179 | { |
177 | struct file_system_type *fs = s->s_type; | 180 | struct file_system_type *fs = s->s_type; |
178 | if (atomic_dec_and_test(&s->s_active)) { | 181 | if (atomic_dec_and_test(&s->s_active)) { |
182 | cleancache_flush_fs(s); | ||
179 | fs->kill_sb(s); | 183 | fs->kill_sb(s); |
184 | /* | ||
185 | * We need to call rcu_barrier so all the delayed rcu free | ||
186 | * inodes are flushed before we release the fs module. | ||
187 | */ | ||
188 | rcu_barrier(); | ||
180 | put_filesystem(fs); | 189 | put_filesystem(fs); |
181 | put_super(s); | 190 | put_super(s); |
182 | } else { | 191 | } else { |
@@ -838,23 +847,6 @@ error: | |||
838 | } | 847 | } |
839 | EXPORT_SYMBOL(mount_bdev); | 848 | EXPORT_SYMBOL(mount_bdev); |
840 | 849 | ||
841 | int get_sb_bdev(struct file_system_type *fs_type, | ||
842 | int flags, const char *dev_name, void *data, | ||
843 | int (*fill_super)(struct super_block *, void *, int), | ||
844 | struct vfsmount *mnt) | ||
845 | { | ||
846 | struct dentry *root; | ||
847 | |||
848 | root = mount_bdev(fs_type, flags, dev_name, data, fill_super); | ||
849 | if (IS_ERR(root)) | ||
850 | return PTR_ERR(root); | ||
851 | mnt->mnt_root = root; | ||
852 | mnt->mnt_sb = root->d_sb; | ||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | EXPORT_SYMBOL(get_sb_bdev); | ||
857 | |||
858 | void kill_block_super(struct super_block *sb) | 850 | void kill_block_super(struct super_block *sb) |
859 | { | 851 | { |
860 | struct block_device *bdev = sb->s_bdev; | 852 | struct block_device *bdev = sb->s_bdev; |
@@ -892,22 +884,6 @@ struct dentry *mount_nodev(struct file_system_type *fs_type, | |||
892 | } | 884 | } |
893 | EXPORT_SYMBOL(mount_nodev); | 885 | EXPORT_SYMBOL(mount_nodev); |
894 | 886 | ||
895 | int get_sb_nodev(struct file_system_type *fs_type, | ||
896 | int flags, void *data, | ||
897 | int (*fill_super)(struct super_block *, void *, int), | ||
898 | struct vfsmount *mnt) | ||
899 | { | ||
900 | struct dentry *root; | ||
901 | |||
902 | root = mount_nodev(fs_type, flags, data, fill_super); | ||
903 | if (IS_ERR(root)) | ||
904 | return PTR_ERR(root); | ||
905 | mnt->mnt_root = root; | ||
906 | mnt->mnt_sb = root->d_sb; | ||
907 | return 0; | ||
908 | } | ||
909 | EXPORT_SYMBOL(get_sb_nodev); | ||
910 | |||
911 | static int compare_single(struct super_block *s, void *p) | 887 | static int compare_single(struct super_block *s, void *p) |
912 | { | 888 | { |
913 | return 1; | 889 | return 1; |
@@ -938,69 +914,36 @@ struct dentry *mount_single(struct file_system_type *fs_type, | |||
938 | } | 914 | } |
939 | EXPORT_SYMBOL(mount_single); | 915 | EXPORT_SYMBOL(mount_single); |
940 | 916 | ||
941 | int get_sb_single(struct file_system_type *fs_type, | 917 | struct dentry * |
942 | int flags, void *data, | 918 | mount_fs(struct file_system_type *type, int flags, const char *name, void *data) |
943 | int (*fill_super)(struct super_block *, void *, int), | ||
944 | struct vfsmount *mnt) | ||
945 | { | ||
946 | struct dentry *root; | ||
947 | root = mount_single(fs_type, flags, data, fill_super); | ||
948 | if (IS_ERR(root)) | ||
949 | return PTR_ERR(root); | ||
950 | mnt->mnt_root = root; | ||
951 | mnt->mnt_sb = root->d_sb; | ||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | EXPORT_SYMBOL(get_sb_single); | ||
956 | |||
957 | struct vfsmount * | ||
958 | vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) | ||
959 | { | 919 | { |
960 | struct vfsmount *mnt; | ||
961 | struct dentry *root; | 920 | struct dentry *root; |
921 | struct super_block *sb; | ||
962 | char *secdata = NULL; | 922 | char *secdata = NULL; |
963 | int error; | 923 | int error = -ENOMEM; |
964 | |||
965 | if (!type) | ||
966 | return ERR_PTR(-ENODEV); | ||
967 | |||
968 | error = -ENOMEM; | ||
969 | mnt = alloc_vfsmnt(name); | ||
970 | if (!mnt) | ||
971 | goto out; | ||
972 | |||
973 | if (flags & MS_KERNMOUNT) | ||
974 | mnt->mnt_flags = MNT_INTERNAL; | ||
975 | 924 | ||
976 | if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { | 925 | if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { |
977 | secdata = alloc_secdata(); | 926 | secdata = alloc_secdata(); |
978 | if (!secdata) | 927 | if (!secdata) |
979 | goto out_mnt; | 928 | goto out; |
980 | 929 | ||
981 | error = security_sb_copy_data(data, secdata); | 930 | error = security_sb_copy_data(data, secdata); |
982 | if (error) | 931 | if (error) |
983 | goto out_free_secdata; | 932 | goto out_free_secdata; |
984 | } | 933 | } |
985 | 934 | ||
986 | if (type->mount) { | 935 | root = type->mount(type, flags, name, data); |
987 | root = type->mount(type, flags, name, data); | 936 | if (IS_ERR(root)) { |
988 | if (IS_ERR(root)) { | 937 | error = PTR_ERR(root); |
989 | error = PTR_ERR(root); | 938 | goto out_free_secdata; |
990 | goto out_free_secdata; | ||
991 | } | ||
992 | mnt->mnt_root = root; | ||
993 | mnt->mnt_sb = root->d_sb; | ||
994 | } else { | ||
995 | error = type->get_sb(type, flags, name, data, mnt); | ||
996 | if (error < 0) | ||
997 | goto out_free_secdata; | ||
998 | } | 939 | } |
999 | BUG_ON(!mnt->mnt_sb); | 940 | sb = root->d_sb; |
1000 | WARN_ON(!mnt->mnt_sb->s_bdi); | 941 | BUG_ON(!sb); |
1001 | mnt->mnt_sb->s_flags |= MS_BORN; | 942 | WARN_ON(!sb->s_bdi); |
943 | WARN_ON(sb->s_bdi == &default_backing_dev_info); | ||
944 | sb->s_flags |= MS_BORN; | ||
1002 | 945 | ||
1003 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); | 946 | error = security_sb_kern_mount(sb, flags, secdata); |
1004 | if (error) | 947 | if (error) |
1005 | goto out_sb; | 948 | goto out_sb; |
1006 | 949 | ||
@@ -1008,30 +951,23 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
1008 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE | 951 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE |
1009 | * but s_maxbytes was an unsigned long long for many releases. Throw | 952 | * but s_maxbytes was an unsigned long long for many releases. Throw |
1010 | * this warning for a little while to try and catch filesystems that | 953 | * this warning for a little while to try and catch filesystems that |
1011 | * violate this rule. This warning should be either removed or | 954 | * violate this rule. |
1012 | * converted to a BUG() in 2.6.34. | ||
1013 | */ | 955 | */ |
1014 | WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " | 956 | WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " |
1015 | "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); | 957 | "negative value (%lld)\n", type->name, sb->s_maxbytes); |
1016 | 958 | ||
1017 | mnt->mnt_mountpoint = mnt->mnt_root; | 959 | up_write(&sb->s_umount); |
1018 | mnt->mnt_parent = mnt; | ||
1019 | up_write(&mnt->mnt_sb->s_umount); | ||
1020 | free_secdata(secdata); | 960 | free_secdata(secdata); |
1021 | return mnt; | 961 | return root; |
1022 | out_sb: | 962 | out_sb: |
1023 | dput(mnt->mnt_root); | 963 | dput(root); |
1024 | deactivate_locked_super(mnt->mnt_sb); | 964 | deactivate_locked_super(sb); |
1025 | out_free_secdata: | 965 | out_free_secdata: |
1026 | free_secdata(secdata); | 966 | free_secdata(secdata); |
1027 | out_mnt: | ||
1028 | free_vfsmnt(mnt); | ||
1029 | out: | 967 | out: |
1030 | return ERR_PTR(error); | 968 | return ERR_PTR(error); |
1031 | } | 969 | } |
1032 | 970 | ||
1033 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | ||
1034 | |||
1035 | /** | 971 | /** |
1036 | * freeze_super - lock the filesystem and force it into a consistent state | 972 | * freeze_super - lock the filesystem and force it into a consistent state |
1037 | * @sb: the super to lock | 973 | * @sb: the super to lock |
@@ -1121,49 +1057,3 @@ out: | |||
1121 | return 0; | 1057 | return 0; |
1122 | } | 1058 | } |
1123 | EXPORT_SYMBOL(thaw_super); | 1059 | EXPORT_SYMBOL(thaw_super); |
1124 | |||
1125 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) | ||
1126 | { | ||
1127 | int err; | ||
1128 | const char *subtype = strchr(fstype, '.'); | ||
1129 | if (subtype) { | ||
1130 | subtype++; | ||
1131 | err = -EINVAL; | ||
1132 | if (!subtype[0]) | ||
1133 | goto err; | ||
1134 | } else | ||
1135 | subtype = ""; | ||
1136 | |||
1137 | mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL); | ||
1138 | err = -ENOMEM; | ||
1139 | if (!mnt->mnt_sb->s_subtype) | ||
1140 | goto err; | ||
1141 | return mnt; | ||
1142 | |||
1143 | err: | ||
1144 | mntput(mnt); | ||
1145 | return ERR_PTR(err); | ||
1146 | } | ||
1147 | |||
1148 | struct vfsmount * | ||
1149 | do_kern_mount(const char *fstype, int flags, const char *name, void *data) | ||
1150 | { | ||
1151 | struct file_system_type *type = get_fs_type(fstype); | ||
1152 | struct vfsmount *mnt; | ||
1153 | if (!type) | ||
1154 | return ERR_PTR(-ENODEV); | ||
1155 | mnt = vfs_kern_mount(type, flags, name, data); | ||
1156 | if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && | ||
1157 | !mnt->mnt_sb->s_subtype) | ||
1158 | mnt = fs_set_subtype(mnt, fstype); | ||
1159 | put_filesystem(type); | ||
1160 | return mnt; | ||
1161 | } | ||
1162 | EXPORT_SYMBOL_GPL(do_kern_mount); | ||
1163 | |||
1164 | struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) | ||
1165 | { | ||
1166 | return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); | ||
1167 | } | ||
1168 | |||
1169 | EXPORT_SYMBOL_GPL(kern_mount_data); | ||