diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 08:41:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 13:07:53 -0400 |
commit | 816724e65c72a90a44fbad0ef0b59b186c85fa90 (patch) | |
tree | 421fa29aedff988e392f92780637553e275d37a0 /fs/nfs | |
parent | 70ac4385a13f78bc478f26d317511893741b05bd (diff) | |
parent | d384ea691fe4ea8c2dd5b9b8d9042eb181776f18 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts:
fs/nfs/inode.c
fs/super.c
Fix conflicts between patch 'NFS: Split fs/nfs/inode.c' and patch
'VFS: Permit filesystem to override root dentry on mount'
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/file.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 1 | ||||
-rw-r--r-- | fs/nfs/super.c | 168 |
3 files changed, 105 insertions, 68 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 106ef0dec04d..add289138836 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -43,7 +43,7 @@ static int nfs_file_mmap(struct file *, struct vm_area_struct *); | |||
43 | static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); | 43 | static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); |
44 | static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); | 44 | static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); |
45 | static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); | 45 | static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); |
46 | static int nfs_file_flush(struct file *); | 46 | static int nfs_file_flush(struct file *, fl_owner_t id); |
47 | static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); | 47 | static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); |
48 | static int nfs_check_flags(int flags); | 48 | static int nfs_check_flags(int flags); |
49 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 49 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
@@ -171,7 +171,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) | |||
171 | * | 171 | * |
172 | */ | 172 | */ |
173 | static int | 173 | static int |
174 | nfs_file_flush(struct file *file) | 174 | nfs_file_flush(struct file *file, fl_owner_t id) |
175 | { | 175 | { |
176 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 176 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
177 | struct inode *inode = file->f_dentry->d_inode; | 177 | struct inode *inode = file->f_dentry->d_inode; |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 4a006f81666b..67391eef6b93 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/nfs.h> | 23 | #include <linux/nfs.h> |
24 | #include <linux/nfs2.h> | 24 | #include <linux/nfs2.h> |
25 | #include <linux/nfs_fs.h> | 25 | #include <linux/nfs_fs.h> |
26 | #include "internal.h" | ||
26 | 27 | ||
27 | #define NFSDBG_FACILITY NFSDBG_XDR | 28 | #define NFSDBG_FACILITY NFSDBG_XDR |
28 | /* #define NFS_PARANOIA 1 */ | 29 | /* #define NFS_PARANOIA 1 */ |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 30f939bcb724..b977748553d3 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -107,12 +107,12 @@ struct rpc_program nfsacl_program = { | |||
107 | #endif /* CONFIG_NFS_V3_ACL */ | 107 | #endif /* CONFIG_NFS_V3_ACL */ |
108 | 108 | ||
109 | static void nfs_umount_begin(struct vfsmount *, int); | 109 | static void nfs_umount_begin(struct vfsmount *, int); |
110 | static int nfs_statfs(struct super_block *, struct kstatfs *); | 110 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
112 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); | 112 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); |
113 | static struct super_block *nfs_get_sb(struct file_system_type *, int, const char *, void *); | 113 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
114 | static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, | 114 | static int nfs_clone_nfs_sb(struct file_system_type *fs_type, |
115 | int flags, const char *dev_name, void *raw_data); | 115 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
116 | static void nfs_kill_super(struct super_block *); | 116 | static void nfs_kill_super(struct super_block *); |
117 | 117 | ||
118 | static struct file_system_type nfs_fs_type = { | 118 | static struct file_system_type nfs_fs_type = { |
@@ -143,12 +143,12 @@ static struct super_operations nfs_sops = { | |||
143 | }; | 143 | }; |
144 | 144 | ||
145 | #ifdef CONFIG_NFS_V4 | 145 | #ifdef CONFIG_NFS_V4 |
146 | static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | 146 | static int nfs4_get_sb(struct file_system_type *fs_type, |
147 | int flags, const char *dev_name, void *raw_data); | 147 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
148 | static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 148 | static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, |
149 | int flags, const char *dev_name, void *raw_data); | 149 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
150 | static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 150 | static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, |
151 | int flags, const char *dev_name, void *raw_data); | 151 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
152 | static void nfs4_kill_super(struct super_block *sb); | 152 | static void nfs4_kill_super(struct super_block *sb); |
153 | 153 | ||
154 | static struct file_system_type nfs4_fs_type = { | 154 | static struct file_system_type nfs4_fs_type = { |
@@ -263,8 +263,9 @@ void __exit unregister_nfs_fs(void) | |||
263 | /* | 263 | /* |
264 | * Deliver file system statistics to userspace | 264 | * Deliver file system statistics to userspace |
265 | */ | 265 | */ |
266 | static int nfs_statfs(struct super_block *sb, struct kstatfs *buf) | 266 | static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
267 | { | 267 | { |
268 | struct super_block *sb = dentry->d_sb; | ||
268 | struct nfs_server *server = NFS_SB(sb); | 269 | struct nfs_server *server = NFS_SB(sb); |
269 | unsigned char blockbits; | 270 | unsigned char blockbits; |
270 | unsigned long blockres; | 271 | unsigned long blockres; |
@@ -770,15 +771,16 @@ out: | |||
770 | /* | 771 | /* |
771 | * Copy an existing superblock and attach revised data | 772 | * Copy an existing superblock and attach revised data |
772 | */ | 773 | */ |
773 | static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data, | 774 | static int nfs_clone_generic_sb(struct nfs_clone_mount *data, |
774 | struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *), | 775 | struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *), |
775 | struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *)) | 776 | struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *), |
777 | struct vfsmount *mnt) | ||
776 | { | 778 | { |
777 | struct nfs_server *server; | 779 | struct nfs_server *server; |
778 | struct nfs_server *parent = NFS_SB(data->sb); | 780 | struct nfs_server *parent = NFS_SB(data->sb); |
779 | struct super_block *sb = ERR_PTR(-EINVAL); | 781 | struct super_block *sb = ERR_PTR(-EINVAL); |
780 | void *err = ERR_PTR(-ENOMEM); | ||
781 | char *hostname; | 782 | char *hostname; |
783 | int error = -ENOMEM; | ||
782 | int len; | 784 | int len; |
783 | 785 | ||
784 | server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); | 786 | server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); |
@@ -791,21 +793,34 @@ static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data, | |||
791 | if (server->hostname == NULL) | 793 | if (server->hostname == NULL) |
792 | goto free_server; | 794 | goto free_server; |
793 | memcpy(server->hostname, hostname, len); | 795 | memcpy(server->hostname, hostname, len); |
794 | if (rpciod_up() != 0) | 796 | error = rpciod_up(); |
797 | if (error != 0) | ||
795 | goto free_hostname; | 798 | goto free_hostname; |
796 | 799 | ||
797 | sb = fill_sb(server, data); | 800 | sb = fill_sb(server, data); |
798 | if (IS_ERR((err = sb)) || sb->s_root) | 801 | if (IS_ERR(sb)) { |
802 | error = PTR_ERR(sb); | ||
799 | goto kill_rpciod; | 803 | goto kill_rpciod; |
804 | } | ||
805 | |||
806 | if (sb->s_root) | ||
807 | goto out_rpciod_down; | ||
800 | 808 | ||
801 | server = fill_server(sb, data); | 809 | server = fill_server(sb, data); |
802 | if (IS_ERR((err = server))) | 810 | if (IS_ERR(server)) { |
811 | error = PTR_ERR(server); | ||
803 | goto out_deactivate; | 812 | goto out_deactivate; |
804 | return sb; | 813 | } |
814 | return simple_set_mnt(mnt, sb); | ||
805 | out_deactivate: | 815 | out_deactivate: |
806 | up_write(&sb->s_umount); | 816 | up_write(&sb->s_umount); |
807 | deactivate_super(sb); | 817 | deactivate_super(sb); |
808 | return (struct super_block *)err; | 818 | return error; |
819 | out_rpciod_down: | ||
820 | rpciod_down(); | ||
821 | kfree(server->hostname); | ||
822 | kfree(server); | ||
823 | return simple_set_mnt(mnt, sb); | ||
809 | kill_rpciod: | 824 | kill_rpciod: |
810 | rpciod_down(); | 825 | rpciod_down(); |
811 | free_hostname: | 826 | free_hostname: |
@@ -813,7 +828,7 @@ free_hostname: | |||
813 | free_server: | 828 | free_server: |
814 | kfree(server); | 829 | kfree(server); |
815 | out_err: | 830 | out_err: |
816 | return (struct super_block *)err; | 831 | return error; |
817 | } | 832 | } |
818 | 833 | ||
819 | /* | 834 | /* |
@@ -939,8 +954,8 @@ static int nfs_compare_super(struct super_block *sb, void *data) | |||
939 | return !nfs_compare_fh(&old->fh, &server->fh); | 954 | return !nfs_compare_fh(&old->fh, &server->fh); |
940 | } | 955 | } |
941 | 956 | ||
942 | static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | 957 | static int nfs_get_sb(struct file_system_type *fs_type, |
943 | int flags, const char *dev_name, void *raw_data) | 958 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
944 | { | 959 | { |
945 | int error; | 960 | int error; |
946 | struct nfs_server *server = NULL; | 961 | struct nfs_server *server = NULL; |
@@ -948,14 +963,14 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
948 | struct nfs_fh *root; | 963 | struct nfs_fh *root; |
949 | struct nfs_mount_data *data = raw_data; | 964 | struct nfs_mount_data *data = raw_data; |
950 | 965 | ||
951 | s = ERR_PTR(-EINVAL); | 966 | error = -EINVAL; |
952 | if (data == NULL) { | 967 | if (data == NULL) { |
953 | dprintk("%s: missing data argument\n", __FUNCTION__); | 968 | dprintk("%s: missing data argument\n", __FUNCTION__); |
954 | goto out_err; | 969 | goto out_err_noserver; |
955 | } | 970 | } |
956 | if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { | 971 | if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { |
957 | dprintk("%s: bad mount version\n", __FUNCTION__); | 972 | dprintk("%s: bad mount version\n", __FUNCTION__); |
958 | goto out_err; | 973 | goto out_err_noserver; |
959 | } | 974 | } |
960 | switch (data->version) { | 975 | switch (data->version) { |
961 | case 1: | 976 | case 1: |
@@ -967,7 +982,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
967 | dprintk("%s: mount structure version %d does not support NFSv3\n", | 982 | dprintk("%s: mount structure version %d does not support NFSv3\n", |
968 | __FUNCTION__, | 983 | __FUNCTION__, |
969 | data->version); | 984 | data->version); |
970 | goto out_err; | 985 | goto out_err_noserver; |
971 | } | 986 | } |
972 | data->root.size = NFS2_FHSIZE; | 987 | data->root.size = NFS2_FHSIZE; |
973 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); | 988 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); |
@@ -976,24 +991,24 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
976 | dprintk("%s: mount structure version %d does not support strong security\n", | 991 | dprintk("%s: mount structure version %d does not support strong security\n", |
977 | __FUNCTION__, | 992 | __FUNCTION__, |
978 | data->version); | 993 | data->version); |
979 | goto out_err; | 994 | goto out_err_noserver; |
980 | } | 995 | } |
981 | case 5: | 996 | case 5: |
982 | memset(data->context, 0, sizeof(data->context)); | 997 | memset(data->context, 0, sizeof(data->context)); |
983 | } | 998 | } |
984 | #ifndef CONFIG_NFS_V3 | 999 | #ifndef CONFIG_NFS_V3 |
985 | /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ | 1000 | /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ |
986 | s = ERR_PTR(-EPROTONOSUPPORT); | 1001 | error = -EPROTONOSUPPORT; |
987 | if (data->flags & NFS_MOUNT_VER3) { | 1002 | if (data->flags & NFS_MOUNT_VER3) { |
988 | dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); | 1003 | dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); |
989 | goto out_err; | 1004 | goto out_err_noserver; |
990 | } | 1005 | } |
991 | #endif /* CONFIG_NFS_V3 */ | 1006 | #endif /* CONFIG_NFS_V3 */ |
992 | 1007 | ||
993 | s = ERR_PTR(-ENOMEM); | 1008 | error = -ENOMEM; |
994 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); | 1009 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); |
995 | if (!server) | 1010 | if (!server) |
996 | goto out_err; | 1011 | goto out_err_noserver; |
997 | /* Zero out the NFS state stuff */ | 1012 | /* Zero out the NFS state stuff */ |
998 | init_nfsv4_state(server); | 1013 | init_nfsv4_state(server); |
999 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 1014 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); |
@@ -1003,7 +1018,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1003 | root->size = data->root.size; | 1018 | root->size = data->root.size; |
1004 | else | 1019 | else |
1005 | root->size = NFS2_FHSIZE; | 1020 | root->size = NFS2_FHSIZE; |
1006 | s = ERR_PTR(-EINVAL); | 1021 | error = -EINVAL; |
1007 | if (root->size > sizeof(root->data)) { | 1022 | if (root->size > sizeof(root->data)) { |
1008 | dprintk("%s: invalid root filehandle\n", __FUNCTION__); | 1023 | dprintk("%s: invalid root filehandle\n", __FUNCTION__); |
1009 | goto out_err; | 1024 | goto out_err; |
@@ -1019,15 +1034,20 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1019 | } | 1034 | } |
1020 | 1035 | ||
1021 | /* Fire up rpciod if not yet running */ | 1036 | /* Fire up rpciod if not yet running */ |
1022 | s = ERR_PTR(rpciod_up()); | 1037 | error = rpciod_up(); |
1023 | if (IS_ERR(s)) { | 1038 | if (error < 0) { |
1024 | dprintk("%s: couldn't start rpciod! Error = %ld\n", | 1039 | dprintk("%s: couldn't start rpciod! Error = %d\n", |
1025 | __FUNCTION__, PTR_ERR(s)); | 1040 | __FUNCTION__, error); |
1026 | goto out_err; | 1041 | goto out_err; |
1027 | } | 1042 | } |
1028 | 1043 | ||
1029 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | 1044 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); |
1030 | if (IS_ERR(s) || s->s_root) | 1045 | if (IS_ERR(s)) { |
1046 | error = PTR_ERR(s); | ||
1047 | goto out_err_rpciod; | ||
1048 | } | ||
1049 | |||
1050 | if (s->s_root) | ||
1031 | goto out_rpciod_down; | 1051 | goto out_rpciod_down; |
1032 | 1052 | ||
1033 | s->s_flags = flags; | 1053 | s->s_flags = flags; |
@@ -1036,15 +1056,22 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1036 | if (error) { | 1056 | if (error) { |
1037 | up_write(&s->s_umount); | 1057 | up_write(&s->s_umount); |
1038 | deactivate_super(s); | 1058 | deactivate_super(s); |
1039 | return ERR_PTR(error); | 1059 | return error; |
1040 | } | 1060 | } |
1041 | s->s_flags |= MS_ACTIVE; | 1061 | s->s_flags |= MS_ACTIVE; |
1042 | return s; | 1062 | return simple_set_mnt(mnt, s); |
1063 | |||
1043 | out_rpciod_down: | 1064 | out_rpciod_down: |
1044 | rpciod_down(); | 1065 | rpciod_down(); |
1066 | kfree(server); | ||
1067 | return simple_set_mnt(mnt, s); | ||
1068 | |||
1069 | out_err_rpciod: | ||
1070 | rpciod_down(); | ||
1045 | out_err: | 1071 | out_err: |
1046 | kfree(server); | 1072 | kfree(server); |
1047 | return s; | 1073 | out_err_noserver: |
1074 | return error; | ||
1048 | } | 1075 | } |
1049 | 1076 | ||
1050 | static void nfs_kill_super(struct super_block *s) | 1077 | static void nfs_kill_super(struct super_block *s) |
@@ -1083,11 +1110,11 @@ static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_cl | |||
1083 | return sb; | 1110 | return sb; |
1084 | } | 1111 | } |
1085 | 1112 | ||
1086 | static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, | 1113 | static int nfs_clone_nfs_sb(struct file_system_type *fs_type, |
1087 | int flags, const char *dev_name, void *raw_data) | 1114 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1088 | { | 1115 | { |
1089 | struct nfs_clone_mount *data = raw_data; | 1116 | struct nfs_clone_mount *data = raw_data; |
1090 | return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server); | 1117 | return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server, mnt); |
1091 | } | 1118 | } |
1092 | 1119 | ||
1093 | #ifdef CONFIG_NFS_V4 | 1120 | #ifdef CONFIG_NFS_V4 |
@@ -1266,8 +1293,8 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen) | |||
1266 | return dst; | 1293 | return dst; |
1267 | } | 1294 | } |
1268 | 1295 | ||
1269 | static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | 1296 | static int nfs4_get_sb(struct file_system_type *fs_type, |
1270 | int flags, const char *dev_name, void *raw_data) | 1297 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1271 | { | 1298 | { |
1272 | int error; | 1299 | int error; |
1273 | struct nfs_server *server; | 1300 | struct nfs_server *server; |
@@ -1277,16 +1304,16 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1277 | 1304 | ||
1278 | if (data == NULL) { | 1305 | if (data == NULL) { |
1279 | dprintk("%s: missing data argument\n", __FUNCTION__); | 1306 | dprintk("%s: missing data argument\n", __FUNCTION__); |
1280 | return ERR_PTR(-EINVAL); | 1307 | return -EINVAL; |
1281 | } | 1308 | } |
1282 | if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) { | 1309 | if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) { |
1283 | dprintk("%s: bad mount version\n", __FUNCTION__); | 1310 | dprintk("%s: bad mount version\n", __FUNCTION__); |
1284 | return ERR_PTR(-EINVAL); | 1311 | return -EINVAL; |
1285 | } | 1312 | } |
1286 | 1313 | ||
1287 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); | 1314 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); |
1288 | if (!server) | 1315 | if (!server) |
1289 | return ERR_PTR(-ENOMEM); | 1316 | return -ENOMEM; |
1290 | /* Zero out the NFS state stuff */ | 1317 | /* Zero out the NFS state stuff */ |
1291 | init_nfsv4_state(server); | 1318 | init_nfsv4_state(server); |
1292 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 1319 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); |
@@ -1308,33 +1335,42 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1308 | 1335 | ||
1309 | /* We now require that the mount process passes the remote address */ | 1336 | /* We now require that the mount process passes the remote address */ |
1310 | if (data->host_addrlen != sizeof(server->addr)) { | 1337 | if (data->host_addrlen != sizeof(server->addr)) { |
1311 | s = ERR_PTR(-EINVAL); | 1338 | error = -EINVAL; |
1312 | goto out_free; | 1339 | goto out_free; |
1313 | } | 1340 | } |
1314 | if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { | 1341 | if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { |
1315 | s = ERR_PTR(-EFAULT); | 1342 | error = -EFAULT; |
1316 | goto out_free; | 1343 | goto out_free; |
1317 | } | 1344 | } |
1318 | if (server->addr.sin_family != AF_INET || | 1345 | if (server->addr.sin_family != AF_INET || |
1319 | server->addr.sin_addr.s_addr == INADDR_ANY) { | 1346 | server->addr.sin_addr.s_addr == INADDR_ANY) { |
1320 | dprintk("%s: mount program didn't pass remote IP address!\n", | 1347 | dprintk("%s: mount program didn't pass remote IP address!\n", |
1321 | __FUNCTION__); | 1348 | __FUNCTION__); |
1322 | s = ERR_PTR(-EINVAL); | 1349 | error = -EINVAL; |
1323 | goto out_free; | 1350 | goto out_free; |
1324 | } | 1351 | } |
1325 | 1352 | ||
1326 | /* Fire up rpciod if not yet running */ | 1353 | /* Fire up rpciod if not yet running */ |
1327 | s = ERR_PTR(rpciod_up()); | 1354 | error = rpciod_up(); |
1328 | if (IS_ERR(s)) { | 1355 | if (error < 0) { |
1329 | dprintk("%s: couldn't start rpciod! Error = %ld\n", | 1356 | dprintk("%s: couldn't start rpciod! Error = %d\n", |
1330 | __FUNCTION__, PTR_ERR(s)); | 1357 | __FUNCTION__, error); |
1331 | goto out_free; | 1358 | goto out_free; |
1332 | } | 1359 | } |
1333 | 1360 | ||
1334 | s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); | 1361 | s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); |
1335 | 1362 | ||
1336 | if (IS_ERR(s) || s->s_root) | 1363 | if (IS_ERR(s)) { |
1364 | error = PTR_ERR(s); | ||
1337 | goto out_free; | 1365 | goto out_free; |
1366 | } | ||
1367 | |||
1368 | if (s->s_root) { | ||
1369 | kfree(server->mnt_path); | ||
1370 | kfree(server->hostname); | ||
1371 | kfree(server); | ||
1372 | return simple_set_mnt(mnt, s); | ||
1373 | } | ||
1338 | 1374 | ||
1339 | s->s_flags = flags; | 1375 | s->s_flags = flags; |
1340 | 1376 | ||
@@ -1342,17 +1378,17 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1342 | if (error) { | 1378 | if (error) { |
1343 | up_write(&s->s_umount); | 1379 | up_write(&s->s_umount); |
1344 | deactivate_super(s); | 1380 | deactivate_super(s); |
1345 | return ERR_PTR(error); | 1381 | return error; |
1346 | } | 1382 | } |
1347 | s->s_flags |= MS_ACTIVE; | 1383 | s->s_flags |= MS_ACTIVE; |
1348 | return s; | 1384 | return simple_set_mnt(mnt, s); |
1349 | out_err: | 1385 | out_err: |
1350 | s = (struct super_block *)p; | 1386 | error = PTR_ERR(p); |
1351 | out_free: | 1387 | out_free: |
1352 | kfree(server->mnt_path); | 1388 | kfree(server->mnt_path); |
1353 | kfree(server->hostname); | 1389 | kfree(server->hostname); |
1354 | kfree(server); | 1390 | kfree(server); |
1355 | return s; | 1391 | return error; |
1356 | } | 1392 | } |
1357 | 1393 | ||
1358 | static void nfs4_kill_super(struct super_block *sb) | 1394 | static void nfs4_kill_super(struct super_block *sb) |
@@ -1430,11 +1466,11 @@ err: | |||
1430 | return sb; | 1466 | return sb; |
1431 | } | 1467 | } |
1432 | 1468 | ||
1433 | static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 1469 | static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, |
1434 | int flags, const char *dev_name, void *raw_data) | 1470 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1435 | { | 1471 | { |
1436 | struct nfs_clone_mount *data = raw_data; | 1472 | struct nfs_clone_mount *data = raw_data; |
1437 | return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server); | 1473 | return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server, mnt); |
1438 | } | 1474 | } |
1439 | 1475 | ||
1440 | static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) | 1476 | static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) |
@@ -1487,11 +1523,11 @@ out_err: | |||
1487 | return (struct nfs_server *)err; | 1523 | return (struct nfs_server *)err; |
1488 | } | 1524 | } |
1489 | 1525 | ||
1490 | static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 1526 | static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, |
1491 | int flags, const char *dev_name, void *raw_data) | 1527 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1492 | { | 1528 | { |
1493 | struct nfs_clone_mount *data = raw_data; | 1529 | struct nfs_clone_mount *data = raw_data; |
1494 | return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server); | 1530 | return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server, mnt); |
1495 | } | 1531 | } |
1496 | 1532 | ||
1497 | #endif | 1533 | #endif |