diff options
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 |
