diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 427 |
1 files changed, 255 insertions, 172 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index f2317f3e29f9..4845911f1c63 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/system.h> | 39 | #include <asm/system.h> |
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | 41 | ||
42 | #include "nfs4_fs.h" | ||
42 | #include "delegation.h" | 43 | #include "delegation.h" |
43 | 44 | ||
44 | #define NFSDBG_FACILITY NFSDBG_VFS | 45 | #define NFSDBG_FACILITY NFSDBG_VFS |
@@ -63,6 +64,7 @@ static void nfs_clear_inode(struct inode *); | |||
63 | static void nfs_umount_begin(struct super_block *); | 64 | static void nfs_umount_begin(struct super_block *); |
64 | static int nfs_statfs(struct super_block *, struct kstatfs *); | 65 | static int nfs_statfs(struct super_block *, struct kstatfs *); |
65 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 66 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
67 | static void nfs_zap_acl_cache(struct inode *); | ||
66 | 68 | ||
67 | static struct rpc_program nfs_program; | 69 | static struct rpc_program nfs_program; |
68 | 70 | ||
@@ -106,6 +108,21 @@ static struct rpc_program nfs_program = { | |||
106 | .pipe_dir_name = "/nfs", | 108 | .pipe_dir_name = "/nfs", |
107 | }; | 109 | }; |
108 | 110 | ||
111 | #ifdef CONFIG_NFS_V3_ACL | ||
112 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | ||
113 | static struct rpc_version * nfsacl_version[] = { | ||
114 | [3] = &nfsacl_version3, | ||
115 | }; | ||
116 | |||
117 | struct rpc_program nfsacl_program = { | ||
118 | .name = "nfsacl", | ||
119 | .number = NFS_ACL_PROGRAM, | ||
120 | .nrvers = sizeof(nfsacl_version) / sizeof(nfsacl_version[0]), | ||
121 | .version = nfsacl_version, | ||
122 | .stats = &nfsacl_rpcstat, | ||
123 | }; | ||
124 | #endif /* CONFIG_NFS_V3_ACL */ | ||
125 | |||
109 | static inline unsigned long | 126 | static inline unsigned long |
110 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) | 127 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) |
111 | { | 128 | { |
@@ -118,7 +135,7 @@ nfs_write_inode(struct inode *inode, int sync) | |||
118 | int flags = sync ? FLUSH_WAIT : 0; | 135 | int flags = sync ? FLUSH_WAIT : 0; |
119 | int ret; | 136 | int ret; |
120 | 137 | ||
121 | ret = nfs_commit_inode(inode, 0, 0, flags); | 138 | ret = nfs_commit_inode(inode, flags); |
122 | if (ret < 0) | 139 | if (ret < 0) |
123 | return ret; | 140 | return ret; |
124 | return 0; | 141 | return 0; |
@@ -140,10 +157,6 @@ nfs_delete_inode(struct inode * inode) | |||
140 | clear_inode(inode); | 157 | clear_inode(inode); |
141 | } | 158 | } |
142 | 159 | ||
143 | /* | ||
144 | * For the moment, the only task for the NFS clear_inode method is to | ||
145 | * release the mmap credential | ||
146 | */ | ||
147 | static void | 160 | static void |
148 | nfs_clear_inode(struct inode *inode) | 161 | nfs_clear_inode(struct inode *inode) |
149 | { | 162 | { |
@@ -152,6 +165,7 @@ nfs_clear_inode(struct inode *inode) | |||
152 | 165 | ||
153 | nfs_wb_all(inode); | 166 | nfs_wb_all(inode); |
154 | BUG_ON (!list_empty(&nfsi->open_files)); | 167 | BUG_ON (!list_empty(&nfsi->open_files)); |
168 | nfs_zap_acl_cache(inode); | ||
155 | cred = nfsi->cache_access.cred; | 169 | cred = nfsi->cache_access.cred; |
156 | if (cred) | 170 | if (cred) |
157 | put_rpccred(cred); | 171 | put_rpccred(cred); |
@@ -161,11 +175,13 @@ nfs_clear_inode(struct inode *inode) | |||
161 | void | 175 | void |
162 | nfs_umount_begin(struct super_block *sb) | 176 | nfs_umount_begin(struct super_block *sb) |
163 | { | 177 | { |
164 | struct nfs_server *server = NFS_SB(sb); | 178 | struct rpc_clnt *rpc = NFS_SB(sb)->client; |
165 | struct rpc_clnt *rpc; | ||
166 | 179 | ||
167 | /* -EIO all pending I/O */ | 180 | /* -EIO all pending I/O */ |
168 | if ((rpc = server->client) != NULL) | 181 | if (!IS_ERR(rpc)) |
182 | rpc_killall_tasks(rpc); | ||
183 | rpc = NFS_SB(sb)->client_acl; | ||
184 | if (!IS_ERR(rpc)) | ||
169 | rpc_killall_tasks(rpc); | 185 | rpc_killall_tasks(rpc); |
170 | } | 186 | } |
171 | 187 | ||
@@ -366,13 +382,15 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
366 | xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, | 382 | xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, |
367 | &server->addr, &timeparms); | 383 | &server->addr, &timeparms); |
368 | if (IS_ERR(xprt)) { | 384 | if (IS_ERR(xprt)) { |
369 | printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); | 385 | dprintk("%s: cannot create RPC transport. Error = %ld\n", |
386 | __FUNCTION__, PTR_ERR(xprt)); | ||
370 | return (struct rpc_clnt *)xprt; | 387 | return (struct rpc_clnt *)xprt; |
371 | } | 388 | } |
372 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | 389 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, |
373 | server->rpc_ops->version, data->pseudoflavor); | 390 | server->rpc_ops->version, data->pseudoflavor); |
374 | if (IS_ERR(clnt)) { | 391 | if (IS_ERR(clnt)) { |
375 | printk(KERN_WARNING "NFS: cannot create RPC client.\n"); | 392 | dprintk("%s: cannot create RPC client. Error = %ld\n", |
393 | __FUNCTION__, PTR_ERR(xprt)); | ||
376 | goto out_fail; | 394 | goto out_fail; |
377 | } | 395 | } |
378 | 396 | ||
@@ -383,7 +401,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
383 | return clnt; | 401 | return clnt; |
384 | 402 | ||
385 | out_fail: | 403 | out_fail: |
386 | xprt_destroy(xprt); | ||
387 | return clnt; | 404 | return clnt; |
388 | } | 405 | } |
389 | 406 | ||
@@ -427,21 +444,16 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | |||
427 | 444 | ||
428 | /* Check NFS protocol revision and initialize RPC op vector | 445 | /* Check NFS protocol revision and initialize RPC op vector |
429 | * and file handle pool. */ | 446 | * and file handle pool. */ |
430 | if (server->flags & NFS_MOUNT_VER3) { | ||
431 | #ifdef CONFIG_NFS_V3 | 447 | #ifdef CONFIG_NFS_V3 |
448 | if (server->flags & NFS_MOUNT_VER3) { | ||
432 | server->rpc_ops = &nfs_v3_clientops; | 449 | server->rpc_ops = &nfs_v3_clientops; |
433 | server->caps |= NFS_CAP_READDIRPLUS; | 450 | server->caps |= NFS_CAP_READDIRPLUS; |
434 | if (data->version < 4) { | ||
435 | printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n"); | ||
436 | return -EIO; | ||
437 | } | ||
438 | #else | ||
439 | printk(KERN_NOTICE "NFS: NFSv3 not supported.\n"); | ||
440 | return -EIO; | ||
441 | #endif | ||
442 | } else { | 451 | } else { |
443 | server->rpc_ops = &nfs_v2_clientops; | 452 | server->rpc_ops = &nfs_v2_clientops; |
444 | } | 453 | } |
454 | #else | ||
455 | server->rpc_ops = &nfs_v2_clientops; | ||
456 | #endif | ||
445 | 457 | ||
446 | /* Fill in pseudoflavor for mount version < 5 */ | 458 | /* Fill in pseudoflavor for mount version < 5 */ |
447 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) | 459 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) |
@@ -455,17 +467,34 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | |||
455 | return PTR_ERR(server->client); | 467 | return PTR_ERR(server->client); |
456 | /* RFC 2623, sec 2.3.2 */ | 468 | /* RFC 2623, sec 2.3.2 */ |
457 | if (authflavor != RPC_AUTH_UNIX) { | 469 | if (authflavor != RPC_AUTH_UNIX) { |
470 | struct rpc_auth *auth; | ||
471 | |||
458 | server->client_sys = rpc_clone_client(server->client); | 472 | server->client_sys = rpc_clone_client(server->client); |
459 | if (IS_ERR(server->client_sys)) | 473 | if (IS_ERR(server->client_sys)) |
460 | return PTR_ERR(server->client_sys); | 474 | return PTR_ERR(server->client_sys); |
461 | if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys)) | 475 | auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys); |
462 | return -ENOMEM; | 476 | if (IS_ERR(auth)) |
477 | return PTR_ERR(auth); | ||
463 | } else { | 478 | } else { |
464 | atomic_inc(&server->client->cl_count); | 479 | atomic_inc(&server->client->cl_count); |
465 | server->client_sys = server->client; | 480 | server->client_sys = server->client; |
466 | } | 481 | } |
467 | |||
468 | if (server->flags & NFS_MOUNT_VER3) { | 482 | if (server->flags & NFS_MOUNT_VER3) { |
483 | #ifdef CONFIG_NFS_V3_ACL | ||
484 | if (!(server->flags & NFS_MOUNT_NOACL)) { | ||
485 | server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3); | ||
486 | /* No errors! Assume that Sun nfsacls are supported */ | ||
487 | if (!IS_ERR(server->client_acl)) | ||
488 | server->caps |= NFS_CAP_ACLS; | ||
489 | } | ||
490 | #else | ||
491 | server->flags &= ~NFS_MOUNT_NOACL; | ||
492 | #endif /* CONFIG_NFS_V3_ACL */ | ||
493 | /* | ||
494 | * The VFS shouldn't apply the umask to mode bits. We will | ||
495 | * do so ourselves when necessary. | ||
496 | */ | ||
497 | sb->s_flags |= MS_POSIXACL; | ||
469 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) | 498 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) |
470 | server->namelen = NFS3_MAXNAMLEN; | 499 | server->namelen = NFS3_MAXNAMLEN; |
471 | sb->s_time_gran = 1; | 500 | sb->s_time_gran = 1; |
@@ -549,6 +578,7 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
549 | { NFS_MOUNT_NOCTO, ",nocto", "" }, | 578 | { NFS_MOUNT_NOCTO, ",nocto", "" }, |
550 | { NFS_MOUNT_NOAC, ",noac", "" }, | 579 | { NFS_MOUNT_NOAC, ",noac", "" }, |
551 | { NFS_MOUNT_NONLM, ",nolock", ",lock" }, | 580 | { NFS_MOUNT_NONLM, ",nolock", ",lock" }, |
581 | { NFS_MOUNT_NOACL, ",noacl", "" }, | ||
552 | { 0, NULL, NULL } | 582 | { 0, NULL, NULL } |
553 | }; | 583 | }; |
554 | struct proc_nfs_info *nfs_infop; | 584 | struct proc_nfs_info *nfs_infop; |
@@ -590,9 +620,19 @@ nfs_zap_caches(struct inode *inode) | |||
590 | 620 | ||
591 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | 621 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); |
592 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) | 622 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
593 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; | 623 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
594 | else | 624 | else |
595 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; | 625 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
626 | } | ||
627 | |||
628 | static void nfs_zap_acl_cache(struct inode *inode) | ||
629 | { | ||
630 | void (*clear_acl_cache)(struct inode *); | ||
631 | |||
632 | clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache; | ||
633 | if (clear_acl_cache != NULL) | ||
634 | clear_acl_cache(inode); | ||
635 | NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL; | ||
596 | } | 636 | } |
597 | 637 | ||
598 | /* | 638 | /* |
@@ -689,7 +729,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
689 | /* Why so? Because we want revalidate for devices/FIFOs, and | 729 | /* Why so? Because we want revalidate for devices/FIFOs, and |
690 | * that's precisely what we have in nfs_file_inode_operations. | 730 | * that's precisely what we have in nfs_file_inode_operations. |
691 | */ | 731 | */ |
692 | inode->i_op = &nfs_file_inode_operations; | 732 | inode->i_op = NFS_SB(sb)->rpc_ops->file_inode_ops; |
693 | if (S_ISREG(inode->i_mode)) { | 733 | if (S_ISREG(inode->i_mode)) { |
694 | inode->i_fop = &nfs_file_operations; | 734 | inode->i_fop = &nfs_file_operations; |
695 | inode->i_data.a_ops = &nfs_file_aops; | 735 | inode->i_data.a_ops = &nfs_file_aops; |
@@ -792,7 +832,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
792 | } | 832 | } |
793 | } | 833 | } |
794 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) | 834 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) |
795 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; | 835 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
796 | nfs_end_data_update(inode); | 836 | nfs_end_data_update(inode); |
797 | unlock_kernel(); | 837 | unlock_kernel(); |
798 | return error; | 838 | return error; |
@@ -851,7 +891,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp | |||
851 | ctx->state = NULL; | 891 | ctx->state = NULL; |
852 | ctx->lockowner = current->files; | 892 | ctx->lockowner = current->files; |
853 | ctx->error = 0; | 893 | ctx->error = 0; |
854 | init_waitqueue_head(&ctx->waitq); | 894 | ctx->dir_cookie = 0; |
855 | } | 895 | } |
856 | return ctx; | 896 | return ctx; |
857 | } | 897 | } |
@@ -1015,6 +1055,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1015 | goto out; | 1055 | goto out; |
1016 | } | 1056 | } |
1017 | flags = nfsi->flags; | 1057 | flags = nfsi->flags; |
1058 | nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE; | ||
1018 | /* | 1059 | /* |
1019 | * We may need to keep the attributes marked as invalid if | 1060 | * We may need to keep the attributes marked as invalid if |
1020 | * we raced with nfs_end_attr_update(). | 1061 | * we raced with nfs_end_attr_update(). |
@@ -1022,21 +1063,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1022 | if (verifier == nfsi->cache_change_attribute) | 1063 | if (verifier == nfsi->cache_change_attribute) |
1023 | nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | 1064 | nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); |
1024 | /* Do the page cache invalidation */ | 1065 | /* Do the page cache invalidation */ |
1025 | if (flags & NFS_INO_INVALID_DATA) { | 1066 | nfs_revalidate_mapping(inode, inode->i_mapping); |
1026 | if (S_ISREG(inode->i_mode)) { | 1067 | if (flags & NFS_INO_INVALID_ACL) |
1027 | if (filemap_fdatawrite(inode->i_mapping) == 0) | 1068 | nfs_zap_acl_cache(inode); |
1028 | filemap_fdatawait(inode->i_mapping); | ||
1029 | nfs_wb_all(inode); | ||
1030 | } | ||
1031 | nfsi->flags &= ~NFS_INO_INVALID_DATA; | ||
1032 | invalidate_inode_pages2(inode->i_mapping); | ||
1033 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | ||
1034 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", | ||
1035 | inode->i_sb->s_id, | ||
1036 | (long long)NFS_FILEID(inode)); | ||
1037 | /* This ensures we revalidate dentries */ | ||
1038 | nfsi->cache_change_attribute++; | ||
1039 | } | ||
1040 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 1069 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", |
1041 | inode->i_sb->s_id, | 1070 | inode->i_sb->s_id, |
1042 | (long long)NFS_FILEID(inode)); | 1071 | (long long)NFS_FILEID(inode)); |
@@ -1074,6 +1103,34 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1074 | } | 1103 | } |
1075 | 1104 | ||
1076 | /** | 1105 | /** |
1106 | * nfs_revalidate_mapping - Revalidate the pagecache | ||
1107 | * @inode - pointer to host inode | ||
1108 | * @mapping - pointer to mapping | ||
1109 | */ | ||
1110 | void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | ||
1111 | { | ||
1112 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1113 | |||
1114 | if (nfsi->flags & NFS_INO_INVALID_DATA) { | ||
1115 | if (S_ISREG(inode->i_mode)) { | ||
1116 | if (filemap_fdatawrite(mapping) == 0) | ||
1117 | filemap_fdatawait(mapping); | ||
1118 | nfs_wb_all(inode); | ||
1119 | } | ||
1120 | invalidate_inode_pages2(mapping); | ||
1121 | nfsi->flags &= ~NFS_INO_INVALID_DATA; | ||
1122 | if (S_ISDIR(inode->i_mode)) { | ||
1123 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | ||
1124 | /* This ensures we revalidate child dentries */ | ||
1125 | nfsi->cache_change_attribute++; | ||
1126 | } | ||
1127 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", | ||
1128 | inode->i_sb->s_id, | ||
1129 | (long long)NFS_FILEID(inode)); | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | /** | ||
1077 | * nfs_begin_data_update | 1134 | * nfs_begin_data_update |
1078 | * @inode - pointer to inode | 1135 | * @inode - pointer to inode |
1079 | * Declare that a set of operations will update file data on the server | 1136 | * Declare that a set of operations will update file data on the server |
@@ -1106,27 +1163,6 @@ void nfs_end_data_update(struct inode *inode) | |||
1106 | } | 1163 | } |
1107 | 1164 | ||
1108 | /** | 1165 | /** |
1109 | * nfs_end_data_update_defer | ||
1110 | * @inode - pointer to inode | ||
1111 | * Declare end of the operations that will update file data | ||
1112 | * This will defer marking the inode as needing revalidation | ||
1113 | * unless there are no other pending updates. | ||
1114 | */ | ||
1115 | void nfs_end_data_update_defer(struct inode *inode) | ||
1116 | { | ||
1117 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1118 | |||
1119 | if (atomic_dec_and_test(&nfsi->data_updates)) { | ||
1120 | /* Mark the attribute cache for revalidation */ | ||
1121 | nfsi->flags |= NFS_INO_INVALID_ATTR; | ||
1122 | /* Directories and symlinks: invalidate page cache too */ | ||
1123 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | ||
1124 | nfsi->flags |= NFS_INO_INVALID_DATA; | ||
1125 | nfsi->cache_change_attribute ++; | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1130 | * nfs_refresh_inode - verify consistency of the inode attribute cache | 1166 | * nfs_refresh_inode - verify consistency of the inode attribute cache |
1131 | * @inode - pointer to inode | 1167 | * @inode - pointer to inode |
1132 | * @fattr - updated attributes | 1168 | * @fattr - updated attributes |
@@ -1152,8 +1188,11 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1152 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 | 1188 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 |
1153 | && nfsi->change_attr == fattr->pre_change_attr) | 1189 | && nfsi->change_attr == fattr->pre_change_attr) |
1154 | nfsi->change_attr = fattr->change_attr; | 1190 | nfsi->change_attr = fattr->change_attr; |
1155 | if (!data_unstable && nfsi->change_attr != fattr->change_attr) | 1191 | if (nfsi->change_attr != fattr->change_attr) { |
1156 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1192 | nfsi->flags |= NFS_INO_INVALID_ATTR; |
1193 | if (!data_unstable) | ||
1194 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; | ||
1195 | } | ||
1157 | } | 1196 | } |
1158 | 1197 | ||
1159 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1198 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
@@ -1176,18 +1215,22 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1176 | } | 1215 | } |
1177 | 1216 | ||
1178 | /* Verify a few of the more important attributes */ | 1217 | /* Verify a few of the more important attributes */ |
1179 | if (!data_unstable) { | 1218 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { |
1180 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime) | 1219 | nfsi->flags |= NFS_INO_INVALID_ATTR; |
1181 | || cur_size != new_isize) | 1220 | if (!data_unstable) |
1182 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1221 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; |
1183 | } else if (S_ISREG(inode->i_mode) && new_isize > cur_size) | 1222 | } |
1184 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1223 | if (cur_size != new_isize) { |
1224 | nfsi->flags |= NFS_INO_INVALID_ATTR; | ||
1225 | if (nfsi->npages == 0) | ||
1226 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; | ||
1227 | } | ||
1185 | 1228 | ||
1186 | /* Have any file permissions changed? */ | 1229 | /* Have any file permissions changed? */ |
1187 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) | 1230 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) |
1188 | || inode->i_uid != fattr->uid | 1231 | || inode->i_uid != fattr->uid |
1189 | || inode->i_gid != fattr->gid) | 1232 | || inode->i_gid != fattr->gid) |
1190 | nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | 1233 | nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1191 | 1234 | ||
1192 | /* Has the link count changed? */ | 1235 | /* Has the link count changed? */ |
1193 | if (inode->i_nlink != fattr->nlink) | 1236 | if (inode->i_nlink != fattr->nlink) |
@@ -1215,10 +1258,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1215 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) | 1258 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) |
1216 | { | 1259 | { |
1217 | struct nfs_inode *nfsi = NFS_I(inode); | 1260 | struct nfs_inode *nfsi = NFS_I(inode); |
1218 | __u64 new_size; | 1261 | loff_t cur_isize, new_isize; |
1219 | loff_t new_isize; | ||
1220 | unsigned int invalid = 0; | 1262 | unsigned int invalid = 0; |
1221 | loff_t cur_isize; | ||
1222 | int data_unstable; | 1263 | int data_unstable; |
1223 | 1264 | ||
1224 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1265 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
@@ -1251,61 +1292,56 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1251 | /* Are we racing with known updates of the metadata on the server? */ | 1292 | /* Are we racing with known updates of the metadata on the server? */ |
1252 | data_unstable = ! nfs_verify_change_attribute(inode, verifier); | 1293 | data_unstable = ! nfs_verify_change_attribute(inode, verifier); |
1253 | 1294 | ||
1254 | /* Check if the file size agrees */ | 1295 | /* Check if our cached file size is stale */ |
1255 | new_size = fattr->size; | ||
1256 | new_isize = nfs_size_to_loff_t(fattr->size); | 1296 | new_isize = nfs_size_to_loff_t(fattr->size); |
1257 | cur_isize = i_size_read(inode); | 1297 | cur_isize = i_size_read(inode); |
1258 | if (cur_isize != new_size) { | 1298 | if (new_isize != cur_isize) { |
1259 | #ifdef NFS_DEBUG_VERBOSE | 1299 | /* Do we perhaps have any outstanding writes? */ |
1260 | printk(KERN_DEBUG "NFS: isize change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); | 1300 | if (nfsi->npages == 0) { |
1261 | #endif | 1301 | /* No, but did we race with nfs_end_data_update()? */ |
1262 | /* | 1302 | if (verifier == nfsi->cache_change_attribute) { |
1263 | * If we have pending writebacks, things can get | ||
1264 | * messy. | ||
1265 | */ | ||
1266 | if (S_ISREG(inode->i_mode) && data_unstable) { | ||
1267 | if (new_isize > cur_isize) { | ||
1268 | inode->i_size = new_isize; | 1303 | inode->i_size = new_isize; |
1269 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1304 | invalid |= NFS_INO_INVALID_DATA; |
1270 | } | 1305 | } |
1271 | } else { | 1306 | invalid |= NFS_INO_INVALID_ATTR; |
1307 | } else if (new_isize > cur_isize) { | ||
1272 | inode->i_size = new_isize; | 1308 | inode->i_size = new_isize; |
1273 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1309 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1274 | } | 1310 | } |
1311 | dprintk("NFS: isize change on server for file %s/%ld\n", | ||
1312 | inode->i_sb->s_id, inode->i_ino); | ||
1275 | } | 1313 | } |
1276 | 1314 | ||
1277 | /* | 1315 | /* Check if the mtime agrees */ |
1278 | * Note: we don't check inode->i_mtime since pipes etc. | ||
1279 | * can change this value in VFS without requiring a | ||
1280 | * cache revalidation. | ||
1281 | */ | ||
1282 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { | 1316 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { |
1283 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1317 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1284 | #ifdef NFS_DEBUG_VERBOSE | 1318 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1285 | printk(KERN_DEBUG "NFS: mtime change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); | 1319 | inode->i_sb->s_id, inode->i_ino); |
1286 | #endif | ||
1287 | if (!data_unstable) | 1320 | if (!data_unstable) |
1288 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1321 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1289 | } | 1322 | } |
1290 | 1323 | ||
1291 | if ((fattr->valid & NFS_ATTR_FATTR_V4) | 1324 | if ((fattr->valid & NFS_ATTR_FATTR_V4) |
1292 | && nfsi->change_attr != fattr->change_attr) { | 1325 | && nfsi->change_attr != fattr->change_attr) { |
1293 | #ifdef NFS_DEBUG_VERBOSE | 1326 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1294 | printk(KERN_DEBUG "NFS: change_attr change on %s/%ld\n", | ||
1295 | inode->i_sb->s_id, inode->i_ino); | 1327 | inode->i_sb->s_id, inode->i_ino); |
1296 | #endif | ||
1297 | nfsi->change_attr = fattr->change_attr; | 1328 | nfsi->change_attr = fattr->change_attr; |
1298 | if (!data_unstable) | 1329 | if (!data_unstable) |
1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; | 1330 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1300 | } | 1331 | } |
1301 | 1332 | ||
1302 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1333 | /* If ctime has changed we should definitely clear access+acl caches */ |
1334 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | ||
1335 | if (!data_unstable) | ||
1336 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
1337 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1338 | } | ||
1303 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1339 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1304 | 1340 | ||
1305 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || | 1341 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || |
1306 | inode->i_uid != fattr->uid || | 1342 | inode->i_uid != fattr->uid || |
1307 | inode->i_gid != fattr->gid) | 1343 | inode->i_gid != fattr->gid) |
1308 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; | 1344 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1309 | 1345 | ||
1310 | inode->i_mode = fattr->mode; | 1346 | inode->i_mode = fattr->mode; |
1311 | inode->i_nlink = fattr->nlink; | 1347 | inode->i_nlink = fattr->nlink; |
@@ -1385,74 +1421,95 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1385 | int flags, const char *dev_name, void *raw_data) | 1421 | int flags, const char *dev_name, void *raw_data) |
1386 | { | 1422 | { |
1387 | int error; | 1423 | int error; |
1388 | struct nfs_server *server; | 1424 | struct nfs_server *server = NULL; |
1389 | struct super_block *s; | 1425 | struct super_block *s; |
1390 | struct nfs_fh *root; | 1426 | struct nfs_fh *root; |
1391 | struct nfs_mount_data *data = raw_data; | 1427 | struct nfs_mount_data *data = raw_data; |
1392 | 1428 | ||
1393 | if (!data) { | 1429 | s = ERR_PTR(-EINVAL); |
1394 | printk("nfs_read_super: missing data argument\n"); | 1430 | if (data == NULL) { |
1395 | return ERR_PTR(-EINVAL); | 1431 | dprintk("%s: missing data argument\n", __FUNCTION__); |
1432 | goto out_err; | ||
1433 | } | ||
1434 | if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { | ||
1435 | dprintk("%s: bad mount version\n", __FUNCTION__); | ||
1436 | goto out_err; | ||
1396 | } | 1437 | } |
1438 | switch (data->version) { | ||
1439 | case 1: | ||
1440 | data->namlen = 0; | ||
1441 | case 2: | ||
1442 | data->bsize = 0; | ||
1443 | case 3: | ||
1444 | if (data->flags & NFS_MOUNT_VER3) { | ||
1445 | dprintk("%s: mount structure version %d does not support NFSv3\n", | ||
1446 | __FUNCTION__, | ||
1447 | data->version); | ||
1448 | goto out_err; | ||
1449 | } | ||
1450 | data->root.size = NFS2_FHSIZE; | ||
1451 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); | ||
1452 | case 4: | ||
1453 | if (data->flags & NFS_MOUNT_SECFLAVOUR) { | ||
1454 | dprintk("%s: mount structure version %d does not support strong security\n", | ||
1455 | __FUNCTION__, | ||
1456 | data->version); | ||
1457 | goto out_err; | ||
1458 | } | ||
1459 | case 5: | ||
1460 | memset(data->context, 0, sizeof(data->context)); | ||
1461 | } | ||
1462 | #ifndef CONFIG_NFS_V3 | ||
1463 | /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ | ||
1464 | s = ERR_PTR(-EPROTONOSUPPORT); | ||
1465 | if (data->flags & NFS_MOUNT_VER3) { | ||
1466 | dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); | ||
1467 | goto out_err; | ||
1468 | } | ||
1469 | #endif /* CONFIG_NFS_V3 */ | ||
1397 | 1470 | ||
1471 | s = ERR_PTR(-ENOMEM); | ||
1398 | server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); | 1472 | server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); |
1399 | if (!server) | 1473 | if (!server) |
1400 | return ERR_PTR(-ENOMEM); | 1474 | goto out_err; |
1401 | memset(server, 0, sizeof(struct nfs_server)); | 1475 | memset(server, 0, sizeof(struct nfs_server)); |
1402 | /* Zero out the NFS state stuff */ | 1476 | /* Zero out the NFS state stuff */ |
1403 | init_nfsv4_state(server); | 1477 | init_nfsv4_state(server); |
1404 | 1478 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | |
1405 | if (data->version != NFS_MOUNT_VERSION) { | ||
1406 | printk("nfs warning: mount version %s than kernel\n", | ||
1407 | data->version < NFS_MOUNT_VERSION ? "older" : "newer"); | ||
1408 | if (data->version < 2) | ||
1409 | data->namlen = 0; | ||
1410 | if (data->version < 3) | ||
1411 | data->bsize = 0; | ||
1412 | if (data->version < 4) { | ||
1413 | data->flags &= ~NFS_MOUNT_VER3; | ||
1414 | data->root.size = NFS2_FHSIZE; | ||
1415 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); | ||
1416 | } | ||
1417 | if (data->version < 5) | ||
1418 | data->flags &= ~NFS_MOUNT_SECFLAVOUR; | ||
1419 | } | ||
1420 | 1479 | ||
1421 | root = &server->fh; | 1480 | root = &server->fh; |
1422 | if (data->flags & NFS_MOUNT_VER3) | 1481 | if (data->flags & NFS_MOUNT_VER3) |
1423 | root->size = data->root.size; | 1482 | root->size = data->root.size; |
1424 | else | 1483 | else |
1425 | root->size = NFS2_FHSIZE; | 1484 | root->size = NFS2_FHSIZE; |
1485 | s = ERR_PTR(-EINVAL); | ||
1426 | if (root->size > sizeof(root->data)) { | 1486 | if (root->size > sizeof(root->data)) { |
1427 | printk("nfs_get_sb: invalid root filehandle\n"); | 1487 | dprintk("%s: invalid root filehandle\n", __FUNCTION__); |
1428 | kfree(server); | 1488 | goto out_err; |
1429 | return ERR_PTR(-EINVAL); | ||
1430 | } | 1489 | } |
1431 | memcpy(root->data, data->root.data, root->size); | 1490 | memcpy(root->data, data->root.data, root->size); |
1432 | 1491 | ||
1433 | /* We now require that the mount process passes the remote address */ | 1492 | /* We now require that the mount process passes the remote address */ |
1434 | memcpy(&server->addr, &data->addr, sizeof(server->addr)); | 1493 | memcpy(&server->addr, &data->addr, sizeof(server->addr)); |
1435 | if (server->addr.sin_addr.s_addr == INADDR_ANY) { | 1494 | if (server->addr.sin_addr.s_addr == INADDR_ANY) { |
1436 | printk("NFS: mount program didn't pass remote address!\n"); | 1495 | dprintk("%s: mount program didn't pass remote address!\n", |
1437 | kfree(server); | 1496 | __FUNCTION__); |
1438 | return ERR_PTR(-EINVAL); | 1497 | goto out_err; |
1439 | } | 1498 | } |
1440 | 1499 | ||
1441 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | 1500 | /* Fire up rpciod if not yet running */ |
1442 | 1501 | s = ERR_PTR(rpciod_up()); | |
1443 | if (IS_ERR(s) || s->s_root) { | 1502 | if (IS_ERR(s)) { |
1444 | kfree(server); | 1503 | dprintk("%s: couldn't start rpciod! Error = %ld\n", |
1445 | return s; | 1504 | __FUNCTION__, PTR_ERR(s)); |
1505 | goto out_err; | ||
1446 | } | 1506 | } |
1447 | 1507 | ||
1448 | s->s_flags = flags; | 1508 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); |
1509 | if (IS_ERR(s) || s->s_root) | ||
1510 | goto out_rpciod_down; | ||
1449 | 1511 | ||
1450 | /* Fire up rpciod if not yet running */ | 1512 | s->s_flags = flags; |
1451 | if (rpciod_up() != 0) { | ||
1452 | printk(KERN_WARNING "NFS: couldn't start rpciod!\n"); | ||
1453 | kfree(server); | ||
1454 | return ERR_PTR(-EIO); | ||
1455 | } | ||
1456 | 1513 | ||
1457 | error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); | 1514 | error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); |
1458 | if (error) { | 1515 | if (error) { |
@@ -1462,6 +1519,11 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1462 | } | 1519 | } |
1463 | s->s_flags |= MS_ACTIVE; | 1520 | s->s_flags |= MS_ACTIVE; |
1464 | return s; | 1521 | return s; |
1522 | out_rpciod_down: | ||
1523 | rpciod_down(); | ||
1524 | out_err: | ||
1525 | kfree(server); | ||
1526 | return s; | ||
1465 | } | 1527 | } |
1466 | 1528 | ||
1467 | static void nfs_kill_super(struct super_block *s) | 1529 | static void nfs_kill_super(struct super_block *s) |
@@ -1470,10 +1532,12 @@ static void nfs_kill_super(struct super_block *s) | |||
1470 | 1532 | ||
1471 | kill_anon_super(s); | 1533 | kill_anon_super(s); |
1472 | 1534 | ||
1473 | if (server->client != NULL && !IS_ERR(server->client)) | 1535 | if (!IS_ERR(server->client)) |
1474 | rpc_shutdown_client(server->client); | 1536 | rpc_shutdown_client(server->client); |
1475 | if (server->client_sys != NULL && !IS_ERR(server->client_sys)) | 1537 | if (!IS_ERR(server->client_sys)) |
1476 | rpc_shutdown_client(server->client_sys); | 1538 | rpc_shutdown_client(server->client_sys); |
1539 | if (!IS_ERR(server->client_acl)) | ||
1540 | rpc_shutdown_client(server->client_acl); | ||
1477 | 1541 | ||
1478 | if (!(server->flags & NFS_MOUNT_NONLM)) | 1542 | if (!(server->flags & NFS_MOUNT_NONLM)) |
1479 | lockd_down(); /* release rpc.lockd */ | 1543 | lockd_down(); /* release rpc.lockd */ |
@@ -1594,15 +1658,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1594 | 1658 | ||
1595 | clp = nfs4_get_client(&server->addr.sin_addr); | 1659 | clp = nfs4_get_client(&server->addr.sin_addr); |
1596 | if (!clp) { | 1660 | if (!clp) { |
1597 | printk(KERN_WARNING "NFS: failed to create NFS4 client.\n"); | 1661 | dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__); |
1598 | return -EIO; | 1662 | return -EIO; |
1599 | } | 1663 | } |
1600 | 1664 | ||
1601 | /* Now create transport and client */ | 1665 | /* Now create transport and client */ |
1602 | authflavour = RPC_AUTH_UNIX; | 1666 | authflavour = RPC_AUTH_UNIX; |
1603 | if (data->auth_flavourlen != 0) { | 1667 | if (data->auth_flavourlen != 0) { |
1604 | if (data->auth_flavourlen > 1) | 1668 | if (data->auth_flavourlen != 1) { |
1605 | printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n"); | 1669 | dprintk("%s: Invalid number of RPC auth flavours %d.\n", |
1670 | __FUNCTION__, data->auth_flavourlen); | ||
1671 | err = -EINVAL; | ||
1672 | goto out_fail; | ||
1673 | } | ||
1606 | if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { | 1674 | if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { |
1607 | err = -EFAULT; | 1675 | err = -EFAULT; |
1608 | goto out_fail; | 1676 | goto out_fail; |
@@ -1610,21 +1678,22 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1610 | } | 1678 | } |
1611 | 1679 | ||
1612 | down_write(&clp->cl_sem); | 1680 | down_write(&clp->cl_sem); |
1613 | if (clp->cl_rpcclient == NULL) { | 1681 | if (IS_ERR(clp->cl_rpcclient)) { |
1614 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); | 1682 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); |
1615 | if (IS_ERR(xprt)) { | 1683 | if (IS_ERR(xprt)) { |
1616 | up_write(&clp->cl_sem); | 1684 | up_write(&clp->cl_sem); |
1617 | printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); | ||
1618 | err = PTR_ERR(xprt); | 1685 | err = PTR_ERR(xprt); |
1686 | dprintk("%s: cannot create RPC transport. Error = %d\n", | ||
1687 | __FUNCTION__, err); | ||
1619 | goto out_fail; | 1688 | goto out_fail; |
1620 | } | 1689 | } |
1621 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | 1690 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, |
1622 | server->rpc_ops->version, authflavour); | 1691 | server->rpc_ops->version, authflavour); |
1623 | if (IS_ERR(clnt)) { | 1692 | if (IS_ERR(clnt)) { |
1624 | up_write(&clp->cl_sem); | 1693 | up_write(&clp->cl_sem); |
1625 | printk(KERN_WARNING "NFS: cannot create RPC client.\n"); | ||
1626 | xprt_destroy(xprt); | ||
1627 | err = PTR_ERR(clnt); | 1694 | err = PTR_ERR(clnt); |
1695 | dprintk("%s: cannot create RPC client. Error = %d\n", | ||
1696 | __FUNCTION__, err); | ||
1628 | goto out_fail; | 1697 | goto out_fail; |
1629 | } | 1698 | } |
1630 | clnt->cl_intr = 1; | 1699 | clnt->cl_intr = 1; |
@@ -1656,21 +1725,26 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1656 | clp = NULL; | 1725 | clp = NULL; |
1657 | 1726 | ||
1658 | if (IS_ERR(clnt)) { | 1727 | if (IS_ERR(clnt)) { |
1659 | printk(KERN_WARNING "NFS: cannot create RPC client.\n"); | 1728 | err = PTR_ERR(clnt); |
1660 | return PTR_ERR(clnt); | 1729 | dprintk("%s: cannot create RPC client. Error = %d\n", |
1730 | __FUNCTION__, err); | ||
1731 | return err; | ||
1661 | } | 1732 | } |
1662 | 1733 | ||
1663 | server->client = clnt; | 1734 | server->client = clnt; |
1664 | 1735 | ||
1665 | if (server->nfs4_state->cl_idmap == NULL) { | 1736 | if (server->nfs4_state->cl_idmap == NULL) { |
1666 | printk(KERN_WARNING "NFS: failed to create idmapper.\n"); | 1737 | dprintk("%s: failed to create idmapper.\n", __FUNCTION__); |
1667 | return -ENOMEM; | 1738 | return -ENOMEM; |
1668 | } | 1739 | } |
1669 | 1740 | ||
1670 | if (clnt->cl_auth->au_flavor != authflavour) { | 1741 | if (clnt->cl_auth->au_flavor != authflavour) { |
1671 | if (rpcauth_create(authflavour, clnt) == NULL) { | 1742 | struct rpc_auth *auth; |
1672 | printk(KERN_WARNING "NFS: couldn't create credcache!\n"); | 1743 | |
1673 | return -ENOMEM; | 1744 | auth = rpcauth_create(authflavour, clnt); |
1745 | if (IS_ERR(auth)) { | ||
1746 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); | ||
1747 | return PTR_ERR(auth); | ||
1674 | } | 1748 | } |
1675 | } | 1749 | } |
1676 | 1750 | ||
@@ -1730,8 +1804,12 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1730 | struct nfs4_mount_data *data = raw_data; | 1804 | struct nfs4_mount_data *data = raw_data; |
1731 | void *p; | 1805 | void *p; |
1732 | 1806 | ||
1733 | if (!data) { | 1807 | if (data == NULL) { |
1734 | printk("nfs_read_super: missing data argument\n"); | 1808 | dprintk("%s: missing data argument\n", __FUNCTION__); |
1809 | return ERR_PTR(-EINVAL); | ||
1810 | } | ||
1811 | if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) { | ||
1812 | dprintk("%s: bad mount version\n", __FUNCTION__); | ||
1735 | return ERR_PTR(-EINVAL); | 1813 | return ERR_PTR(-EINVAL); |
1736 | } | 1814 | } |
1737 | 1815 | ||
@@ -1741,11 +1819,7 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1741 | memset(server, 0, sizeof(struct nfs_server)); | 1819 | memset(server, 0, sizeof(struct nfs_server)); |
1742 | /* Zero out the NFS state stuff */ | 1820 | /* Zero out the NFS state stuff */ |
1743 | init_nfsv4_state(server); | 1821 | init_nfsv4_state(server); |
1744 | 1822 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | |
1745 | if (data->version != NFS4_MOUNT_VERSION) { | ||
1746 | printk("nfs warning: mount version %s than kernel\n", | ||
1747 | data->version < NFS4_MOUNT_VERSION ? "older" : "newer"); | ||
1748 | } | ||
1749 | 1823 | ||
1750 | p = nfs_copy_user_string(NULL, &data->hostname, 256); | 1824 | p = nfs_copy_user_string(NULL, &data->hostname, 256); |
1751 | if (IS_ERR(p)) | 1825 | if (IS_ERR(p)) |
@@ -1773,11 +1847,20 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1773 | } | 1847 | } |
1774 | if (server->addr.sin_family != AF_INET || | 1848 | if (server->addr.sin_family != AF_INET || |
1775 | server->addr.sin_addr.s_addr == INADDR_ANY) { | 1849 | server->addr.sin_addr.s_addr == INADDR_ANY) { |
1776 | printk("NFS: mount program didn't pass remote IP address!\n"); | 1850 | dprintk("%s: mount program didn't pass remote IP address!\n", |
1851 | __FUNCTION__); | ||
1777 | s = ERR_PTR(-EINVAL); | 1852 | s = ERR_PTR(-EINVAL); |
1778 | goto out_free; | 1853 | goto out_free; |
1779 | } | 1854 | } |
1780 | 1855 | ||
1856 | /* Fire up rpciod if not yet running */ | ||
1857 | s = ERR_PTR(rpciod_up()); | ||
1858 | if (IS_ERR(s)) { | ||
1859 | dprintk("%s: couldn't start rpciod! Error = %ld\n", | ||
1860 | __FUNCTION__, PTR_ERR(s)); | ||
1861 | goto out_free; | ||
1862 | } | ||
1863 | |||
1781 | s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); | 1864 | s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); |
1782 | 1865 | ||
1783 | if (IS_ERR(s) || s->s_root) | 1866 | if (IS_ERR(s) || s->s_root) |
@@ -1785,13 +1868,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1785 | 1868 | ||
1786 | s->s_flags = flags; | 1869 | s->s_flags = flags; |
1787 | 1870 | ||
1788 | /* Fire up rpciod if not yet running */ | ||
1789 | if (rpciod_up() != 0) { | ||
1790 | printk(KERN_WARNING "NFS: couldn't start rpciod!\n"); | ||
1791 | s = ERR_PTR(-EIO); | ||
1792 | goto out_free; | ||
1793 | } | ||
1794 | |||
1795 | error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); | 1871 | error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); |
1796 | if (error) { | 1872 | if (error) { |
1797 | up_write(&s->s_umount); | 1873 | up_write(&s->s_umount); |
@@ -1875,6 +1951,13 @@ static struct inode *nfs_alloc_inode(struct super_block *sb) | |||
1875 | if (!nfsi) | 1951 | if (!nfsi) |
1876 | return NULL; | 1952 | return NULL; |
1877 | nfsi->flags = 0; | 1953 | nfsi->flags = 0; |
1954 | #ifdef CONFIG_NFS_V3_ACL | ||
1955 | nfsi->acl_access = ERR_PTR(-EAGAIN); | ||
1956 | nfsi->acl_default = ERR_PTR(-EAGAIN); | ||
1957 | #endif | ||
1958 | #ifdef CONFIG_NFS_V4 | ||
1959 | nfsi->nfs4_acl = NULL; | ||
1960 | #endif /* CONFIG_NFS_V4 */ | ||
1878 | return &nfsi->vfs_inode; | 1961 | return &nfsi->vfs_inode; |
1879 | } | 1962 | } |
1880 | 1963 | ||