aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c119
1 files changed, 84 insertions, 35 deletions
diff --git a/fs/super.c b/fs/super.c
index 8819e3a7ff20..ca696155cd9a 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -273,14 +273,14 @@ void generic_shutdown_super(struct super_block *sb)
273 get_fs_excl(); 273 get_fs_excl();
274 sb->s_flags &= ~MS_ACTIVE; 274 sb->s_flags &= ~MS_ACTIVE;
275 275
276 /* bad name - it should be evict_inodes() */ 276 fsnotify_unmount_inodes(&sb->s_inodes);
277 invalidate_inodes(sb); 277
278 evict_inodes(sb);
278 279
279 if (sop->put_super) 280 if (sop->put_super)
280 sop->put_super(sb); 281 sop->put_super(sb);
281 282
282 /* Forget any remaining inodes */ 283 if (!list_empty(&sb->s_inodes)) {
283 if (invalidate_inodes(sb)) {
284 printk("VFS: Busy inodes after unmount of %s. " 284 printk("VFS: Busy inodes after unmount of %s. "
285 "Self-destruct in 5 seconds. Have a nice day...\n", 285 "Self-destruct in 5 seconds. Have a nice day...\n",
286 sb->s_id); 286 sb->s_id);
@@ -715,15 +715,14 @@ static int ns_set_super(struct super_block *sb, void *data)
715 return set_anon_super(sb, NULL); 715 return set_anon_super(sb, NULL);
716} 716}
717 717
718int get_sb_ns(struct file_system_type *fs_type, int flags, void *data, 718struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
719 int (*fill_super)(struct super_block *, void *, int), 719 void *data, int (*fill_super)(struct super_block *, void *, int))
720 struct vfsmount *mnt)
721{ 720{
722 struct super_block *sb; 721 struct super_block *sb;
723 722
724 sb = sget(fs_type, ns_test_super, ns_set_super, data); 723 sb = sget(fs_type, ns_test_super, ns_set_super, data);
725 if (IS_ERR(sb)) 724 if (IS_ERR(sb))
726 return PTR_ERR(sb); 725 return ERR_CAST(sb);
727 726
728 if (!sb->s_root) { 727 if (!sb->s_root) {
729 int err; 728 int err;
@@ -731,17 +730,16 @@ int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
731 err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 730 err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
732 if (err) { 731 if (err) {
733 deactivate_locked_super(sb); 732 deactivate_locked_super(sb);
734 return err; 733 return ERR_PTR(err);
735 } 734 }
736 735
737 sb->s_flags |= MS_ACTIVE; 736 sb->s_flags |= MS_ACTIVE;
738 } 737 }
739 738
740 simple_set_mnt(mnt, sb); 739 return dget(sb->s_root);
741 return 0;
742} 740}
743 741
744EXPORT_SYMBOL(get_sb_ns); 742EXPORT_SYMBOL(mount_ns);
745 743
746#ifdef CONFIG_BLOCK 744#ifdef CONFIG_BLOCK
747static int set_bdev_super(struct super_block *s, void *data) 745static int set_bdev_super(struct super_block *s, void *data)
@@ -762,10 +760,9 @@ static int test_bdev_super(struct super_block *s, void *data)
762 return (void *)s->s_bdev == data; 760 return (void *)s->s_bdev == data;
763} 761}
764 762
765int get_sb_bdev(struct file_system_type *fs_type, 763struct dentry *mount_bdev(struct file_system_type *fs_type,
766 int flags, const char *dev_name, void *data, 764 int flags, const char *dev_name, void *data,
767 int (*fill_super)(struct super_block *, void *, int), 765 int (*fill_super)(struct super_block *, void *, int))
768 struct vfsmount *mnt)
769{ 766{
770 struct block_device *bdev; 767 struct block_device *bdev;
771 struct super_block *s; 768 struct super_block *s;
@@ -777,7 +774,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
777 774
778 bdev = open_bdev_exclusive(dev_name, mode, fs_type); 775 bdev = open_bdev_exclusive(dev_name, mode, fs_type);
779 if (IS_ERR(bdev)) 776 if (IS_ERR(bdev))
780 return PTR_ERR(bdev); 777 return ERR_CAST(bdev);
781 778
782 /* 779 /*
783 * once the super is inserted into the list by sget, s_umount 780 * once the super is inserted into the list by sget, s_umount
@@ -829,15 +826,30 @@ int get_sb_bdev(struct file_system_type *fs_type,
829 bdev->bd_super = s; 826 bdev->bd_super = s;
830 } 827 }
831 828
832 simple_set_mnt(mnt, s); 829 return dget(s->s_root);
833 return 0;
834 830
835error_s: 831error_s:
836 error = PTR_ERR(s); 832 error = PTR_ERR(s);
837error_bdev: 833error_bdev:
838 close_bdev_exclusive(bdev, mode); 834 close_bdev_exclusive(bdev, mode);
839error: 835error:
840 return error; 836 return ERR_PTR(error);
837}
838EXPORT_SYMBOL(mount_bdev);
839
840int get_sb_bdev(struct file_system_type *fs_type,
841 int flags, const char *dev_name, void *data,
842 int (*fill_super)(struct super_block *, void *, int),
843 struct vfsmount *mnt)
844{
845 struct dentry *root;
846
847 root = mount_bdev(fs_type, flags, dev_name, data, fill_super);
848 if (IS_ERR(root))
849 return PTR_ERR(root);
850 mnt->mnt_root = root;
851 mnt->mnt_sb = root->d_sb;
852 return 0;
841} 853}
842 854
843EXPORT_SYMBOL(get_sb_bdev); 855EXPORT_SYMBOL(get_sb_bdev);
@@ -856,29 +868,42 @@ void kill_block_super(struct super_block *sb)
856EXPORT_SYMBOL(kill_block_super); 868EXPORT_SYMBOL(kill_block_super);
857#endif 869#endif
858 870
859int get_sb_nodev(struct file_system_type *fs_type, 871struct dentry *mount_nodev(struct file_system_type *fs_type,
860 int flags, void *data, 872 int flags, void *data,
861 int (*fill_super)(struct super_block *, void *, int), 873 int (*fill_super)(struct super_block *, void *, int))
862 struct vfsmount *mnt)
863{ 874{
864 int error; 875 int error;
865 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); 876 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
866 877
867 if (IS_ERR(s)) 878 if (IS_ERR(s))
868 return PTR_ERR(s); 879 return ERR_CAST(s);
869 880
870 s->s_flags = flags; 881 s->s_flags = flags;
871 882
872 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 883 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
873 if (error) { 884 if (error) {
874 deactivate_locked_super(s); 885 deactivate_locked_super(s);
875 return error; 886 return ERR_PTR(error);
876 } 887 }
877 s->s_flags |= MS_ACTIVE; 888 s->s_flags |= MS_ACTIVE;
878 simple_set_mnt(mnt, s); 889 return dget(s->s_root);
879 return 0;
880} 890}
891EXPORT_SYMBOL(mount_nodev);
892
893int get_sb_nodev(struct file_system_type *fs_type,
894 int flags, void *data,
895 int (*fill_super)(struct super_block *, void *, int),
896 struct vfsmount *mnt)
897{
898 struct dentry *root;
881 899
900 root = mount_nodev(fs_type, flags, data, fill_super);
901 if (IS_ERR(root))
902 return PTR_ERR(root);
903 mnt->mnt_root = root;
904 mnt->mnt_sb = root->d_sb;
905 return 0;
906}
882EXPORT_SYMBOL(get_sb_nodev); 907EXPORT_SYMBOL(get_sb_nodev);
883 908
884static int compare_single(struct super_block *s, void *p) 909static int compare_single(struct super_block *s, void *p)
@@ -886,29 +911,42 @@ static int compare_single(struct super_block *s, void *p)
886 return 1; 911 return 1;
887} 912}
888 913
889int get_sb_single(struct file_system_type *fs_type, 914struct dentry *mount_single(struct file_system_type *fs_type,
890 int flags, void *data, 915 int flags, void *data,
891 int (*fill_super)(struct super_block *, void *, int), 916 int (*fill_super)(struct super_block *, void *, int))
892 struct vfsmount *mnt)
893{ 917{
894 struct super_block *s; 918 struct super_block *s;
895 int error; 919 int error;
896 920
897 s = sget(fs_type, compare_single, set_anon_super, NULL); 921 s = sget(fs_type, compare_single, set_anon_super, NULL);
898 if (IS_ERR(s)) 922 if (IS_ERR(s))
899 return PTR_ERR(s); 923 return ERR_CAST(s);
900 if (!s->s_root) { 924 if (!s->s_root) {
901 s->s_flags = flags; 925 s->s_flags = flags;
902 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 926 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
903 if (error) { 927 if (error) {
904 deactivate_locked_super(s); 928 deactivate_locked_super(s);
905 return error; 929 return ERR_PTR(error);
906 } 930 }
907 s->s_flags |= MS_ACTIVE; 931 s->s_flags |= MS_ACTIVE;
908 } else { 932 } else {
909 do_remount_sb(s, flags, data, 0); 933 do_remount_sb(s, flags, data, 0);
910 } 934 }
911 simple_set_mnt(mnt, s); 935 return dget(s->s_root);
936}
937EXPORT_SYMBOL(mount_single);
938
939int get_sb_single(struct file_system_type *fs_type,
940 int flags, void *data,
941 int (*fill_super)(struct super_block *, void *, int),
942 struct vfsmount *mnt)
943{
944 struct dentry *root;
945 root = mount_single(fs_type, flags, data, fill_super);
946 if (IS_ERR(root))
947 return PTR_ERR(root);
948 mnt->mnt_root = root;
949 mnt->mnt_sb = root->d_sb;
912 return 0; 950 return 0;
913} 951}
914 952
@@ -918,6 +956,7 @@ struct vfsmount *
918vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) 956vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
919{ 957{
920 struct vfsmount *mnt; 958 struct vfsmount *mnt;
959 struct dentry *root;
921 char *secdata = NULL; 960 char *secdata = NULL;
922 int error; 961 int error;
923 962
@@ -942,9 +981,19 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
942 goto out_free_secdata; 981 goto out_free_secdata;
943 } 982 }
944 983
945 error = type->get_sb(type, flags, name, data, mnt); 984 if (type->mount) {
946 if (error < 0) 985 root = type->mount(type, flags, name, data);
947 goto out_free_secdata; 986 if (IS_ERR(root)) {
987 error = PTR_ERR(root);
988 goto out_free_secdata;
989 }
990 mnt->mnt_root = root;
991 mnt->mnt_sb = root->d_sb;
992 } else {
993 error = type->get_sb(type, flags, name, data, mnt);
994 if (error < 0)
995 goto out_free_secdata;
996 }
948 BUG_ON(!mnt->mnt_sb); 997 BUG_ON(!mnt->mnt_sb);
949 WARN_ON(!mnt->mnt_sb->s_bdi); 998 WARN_ON(!mnt->mnt_sb->s_bdi);
950 mnt->mnt_sb->s_flags |= MS_BORN; 999 mnt->mnt_sb->s_flags |= MS_BORN;