diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 304 |
1 files changed, 180 insertions, 124 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6391d8964214..a77ee95b7efb 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | 41 | ||
42 | #include "nfs4_fs.h" | 42 | #include "nfs4_fs.h" |
43 | #include "callback.h" | ||
43 | #include "delegation.h" | 44 | #include "delegation.h" |
44 | 45 | ||
45 | #define NFSDBG_FACILITY NFSDBG_VFS | 46 | #define NFSDBG_FACILITY NFSDBG_VFS |
@@ -54,7 +55,7 @@ | |||
54 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) | 55 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) |
55 | 56 | ||
56 | static void nfs_invalidate_inode(struct inode *); | 57 | static void nfs_invalidate_inode(struct inode *); |
57 | static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); | 58 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); |
58 | 59 | ||
59 | static struct inode *nfs_alloc_inode(struct super_block *sb); | 60 | static struct inode *nfs_alloc_inode(struct super_block *sb); |
60 | static void nfs_destroy_inode(struct inode *); | 61 | static void nfs_destroy_inode(struct inode *); |
@@ -221,10 +222,10 @@ nfs_calc_block_size(u64 tsize) | |||
221 | static inline unsigned long | 222 | static inline unsigned long |
222 | nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) | 223 | nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) |
223 | { | 224 | { |
224 | if (bsize < 1024) | 225 | if (bsize < NFS_MIN_FILE_IO_SIZE) |
225 | bsize = NFS_DEF_FILE_IO_BUFFER_SIZE; | 226 | bsize = NFS_DEF_FILE_IO_SIZE; |
226 | else if (bsize >= NFS_MAX_FILE_IO_BUFFER_SIZE) | 227 | else if (bsize >= NFS_MAX_FILE_IO_SIZE) |
227 | bsize = NFS_MAX_FILE_IO_BUFFER_SIZE; | 228 | bsize = NFS_MAX_FILE_IO_SIZE; |
228 | 229 | ||
229 | return nfs_block_bits(bsize, nrbitsp); | 230 | return nfs_block_bits(bsize, nrbitsp); |
230 | } | 231 | } |
@@ -307,20 +308,15 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) | |||
307 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); | 308 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); |
308 | if (server->rsize > max_rpc_payload) | 309 | if (server->rsize > max_rpc_payload) |
309 | server->rsize = max_rpc_payload; | 310 | server->rsize = max_rpc_payload; |
310 | if (server->wsize > max_rpc_payload) | 311 | if (server->rsize > NFS_MAX_FILE_IO_SIZE) |
311 | server->wsize = max_rpc_payload; | 312 | server->rsize = NFS_MAX_FILE_IO_SIZE; |
312 | |||
313 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 313 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
314 | if (server->rpages > NFS_READ_MAXIOV) { | ||
315 | server->rpages = NFS_READ_MAXIOV; | ||
316 | server->rsize = server->rpages << PAGE_CACHE_SHIFT; | ||
317 | } | ||
318 | 314 | ||
315 | if (server->wsize > max_rpc_payload) | ||
316 | server->wsize = max_rpc_payload; | ||
317 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) | ||
318 | server->wsize = NFS_MAX_FILE_IO_SIZE; | ||
319 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 319 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
320 | if (server->wpages > NFS_WRITE_MAXIOV) { | ||
321 | server->wpages = NFS_WRITE_MAXIOV; | ||
322 | server->wsize = server->wpages << PAGE_CACHE_SHIFT; | ||
323 | } | ||
324 | 320 | ||
325 | if (sb->s_blocksize == 0) | 321 | if (sb->s_blocksize == 0) |
326 | sb->s_blocksize = nfs_block_bits(server->wsize, | 322 | sb->s_blocksize = nfs_block_bits(server->wsize, |
@@ -417,7 +413,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
417 | 413 | ||
418 | clnt->cl_intr = 1; | 414 | clnt->cl_intr = 1; |
419 | clnt->cl_softrtry = 1; | 415 | clnt->cl_softrtry = 1; |
420 | clnt->cl_chatty = 1; | ||
421 | 416 | ||
422 | return clnt; | 417 | return clnt; |
423 | 418 | ||
@@ -575,11 +570,10 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf) | |||
575 | buf->f_namelen = server->namelen; | 570 | buf->f_namelen = server->namelen; |
576 | out: | 571 | out: |
577 | unlock_kernel(); | 572 | unlock_kernel(); |
578 | |||
579 | return 0; | 573 | return 0; |
580 | 574 | ||
581 | out_err: | 575 | out_err: |
582 | printk(KERN_WARNING "nfs_statfs: statfs error = %d\n", -error); | 576 | dprintk("%s: statfs error = %d\n", __FUNCTION__, -error); |
583 | buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; | 577 | buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; |
584 | goto out; | 578 | goto out; |
585 | 579 | ||
@@ -640,17 +634,32 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
640 | return 0; | 634 | return 0; |
641 | } | 635 | } |
642 | 636 | ||
637 | /** | ||
638 | * nfs_sync_mapping - helper to flush all mmapped dirty data to disk | ||
639 | */ | ||
640 | int nfs_sync_mapping(struct address_space *mapping) | ||
641 | { | ||
642 | int ret; | ||
643 | |||
644 | if (mapping->nrpages == 0) | ||
645 | return 0; | ||
646 | unmap_mapping_range(mapping, 0, 0, 0); | ||
647 | ret = filemap_write_and_wait(mapping); | ||
648 | if (ret != 0) | ||
649 | goto out; | ||
650 | ret = nfs_wb_all(mapping->host); | ||
651 | out: | ||
652 | return ret; | ||
653 | } | ||
654 | |||
643 | /* | 655 | /* |
644 | * Invalidate the local caches | 656 | * Invalidate the local caches |
645 | */ | 657 | */ |
646 | void | 658 | static void nfs_zap_caches_locked(struct inode *inode) |
647 | nfs_zap_caches(struct inode *inode) | ||
648 | { | 659 | { |
649 | struct nfs_inode *nfsi = NFS_I(inode); | 660 | struct nfs_inode *nfsi = NFS_I(inode); |
650 | int mode = inode->i_mode; | 661 | int mode = inode->i_mode; |
651 | 662 | ||
652 | spin_lock(&inode->i_lock); | ||
653 | |||
654 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); | 663 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); |
655 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; | 664 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; |
656 | 665 | ||
@@ -659,7 +668,12 @@ nfs_zap_caches(struct inode *inode) | |||
659 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 668 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
660 | else | 669 | else |
661 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 670 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
671 | } | ||
662 | 672 | ||
673 | void nfs_zap_caches(struct inode *inode) | ||
674 | { | ||
675 | spin_lock(&inode->i_lock); | ||
676 | nfs_zap_caches_locked(inode); | ||
663 | spin_unlock(&inode->i_lock); | 677 | spin_unlock(&inode->i_lock); |
664 | } | 678 | } |
665 | 679 | ||
@@ -676,16 +690,13 @@ static void nfs_zap_acl_cache(struct inode *inode) | |||
676 | } | 690 | } |
677 | 691 | ||
678 | /* | 692 | /* |
679 | * Invalidate, but do not unhash, the inode | 693 | * Invalidate, but do not unhash, the inode. |
694 | * NB: must be called with inode->i_lock held! | ||
680 | */ | 695 | */ |
681 | static void | 696 | static void nfs_invalidate_inode(struct inode *inode) |
682 | nfs_invalidate_inode(struct inode *inode) | ||
683 | { | 697 | { |
684 | umode_t save_mode = inode->i_mode; | 698 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); |
685 | 699 | nfs_zap_caches_locked(inode); | |
686 | make_bad_inode(inode); | ||
687 | inode->i_mode = save_mode; | ||
688 | nfs_zap_caches(inode); | ||
689 | } | 700 | } |
690 | 701 | ||
691 | struct nfs_find_desc { | 702 | struct nfs_find_desc { |
@@ -850,8 +861,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
850 | nfs_begin_data_update(inode); | 861 | nfs_begin_data_update(inode); |
851 | /* Write all dirty data if we're changing file permissions or size */ | 862 | /* Write all dirty data if we're changing file permissions or size */ |
852 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) { | 863 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) { |
853 | if (filemap_fdatawrite(inode->i_mapping) == 0) | 864 | filemap_write_and_wait(inode->i_mapping); |
854 | filemap_fdatawait(inode->i_mapping); | ||
855 | nfs_wb_all(inode); | 865 | nfs_wb_all(inode); |
856 | } | 866 | } |
857 | /* | 867 | /* |
@@ -938,11 +948,22 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
938 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; | 948 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
939 | int err; | 949 | int err; |
940 | 950 | ||
941 | if (__IS_FLG(inode, MS_NOATIME)) | 951 | /* Flush out writes to the server in order to update c/mtime */ |
942 | need_atime = 0; | 952 | nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT); |
943 | else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) | 953 | |
954 | /* | ||
955 | * We may force a getattr if the user cares about atime. | ||
956 | * | ||
957 | * Note that we only have to check the vfsmount flags here: | ||
958 | * - NFS always sets S_NOATIME by so checking it would give a | ||
959 | * bogus result | ||
960 | * - NFS never sets MS_NOATIME or MS_NODIRATIME so there is | ||
961 | * no point in checking those. | ||
962 | */ | ||
963 | if ((mnt->mnt_flags & MNT_NOATIME) || | ||
964 | ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
944 | need_atime = 0; | 965 | need_atime = 0; |
945 | /* We may force a getattr if the user cares about atime */ | 966 | |
946 | if (need_atime) | 967 | if (need_atime) |
947 | err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); | 968 | err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); |
948 | else | 969 | else |
@@ -1081,8 +1102,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1081 | int status = -ESTALE; | 1102 | int status = -ESTALE; |
1082 | struct nfs_fattr fattr; | 1103 | struct nfs_fattr fattr; |
1083 | struct nfs_inode *nfsi = NFS_I(inode); | 1104 | struct nfs_inode *nfsi = NFS_I(inode); |
1084 | unsigned long verifier; | ||
1085 | unsigned long cache_validity; | ||
1086 | 1105 | ||
1087 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", | 1106 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", |
1088 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 1107 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); |
@@ -1107,8 +1126,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1107 | } | 1126 | } |
1108 | } | 1127 | } |
1109 | 1128 | ||
1110 | /* Protect against RPC races by saving the change attribute */ | ||
1111 | verifier = nfs_save_change_attribute(inode); | ||
1112 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); | 1129 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); |
1113 | if (status != 0) { | 1130 | if (status != 0) { |
1114 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", | 1131 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", |
@@ -1123,7 +1140,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1123 | } | 1140 | } |
1124 | 1141 | ||
1125 | spin_lock(&inode->i_lock); | 1142 | spin_lock(&inode->i_lock); |
1126 | status = nfs_update_inode(inode, &fattr, verifier); | 1143 | status = nfs_update_inode(inode, &fattr); |
1127 | if (status) { | 1144 | if (status) { |
1128 | spin_unlock(&inode->i_lock); | 1145 | spin_unlock(&inode->i_lock); |
1129 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", | 1146 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", |
@@ -1131,20 +1148,11 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1131 | (long long)NFS_FILEID(inode), status); | 1148 | (long long)NFS_FILEID(inode), status); |
1132 | goto out; | 1149 | goto out; |
1133 | } | 1150 | } |
1134 | cache_validity = nfsi->cache_validity; | ||
1135 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | ||
1136 | |||
1137 | /* | ||
1138 | * We may need to keep the attributes marked as invalid if | ||
1139 | * we raced with nfs_end_attr_update(). | ||
1140 | */ | ||
1141 | if (time_after_eq(verifier, nfsi->cache_change_attribute)) | ||
1142 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1143 | spin_unlock(&inode->i_lock); | 1151 | spin_unlock(&inode->i_lock); |
1144 | 1152 | ||
1145 | nfs_revalidate_mapping(inode, inode->i_mapping); | 1153 | nfs_revalidate_mapping(inode, inode->i_mapping); |
1146 | 1154 | ||
1147 | if (cache_validity & NFS_INO_INVALID_ACL) | 1155 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) |
1148 | nfs_zap_acl_cache(inode); | 1156 | nfs_zap_acl_cache(inode); |
1149 | 1157 | ||
1150 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 1158 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", |
@@ -1193,11 +1201,8 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
1193 | struct nfs_inode *nfsi = NFS_I(inode); | 1201 | struct nfs_inode *nfsi = NFS_I(inode); |
1194 | 1202 | ||
1195 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { | 1203 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { |
1196 | if (S_ISREG(inode->i_mode)) { | 1204 | if (S_ISREG(inode->i_mode)) |
1197 | if (filemap_fdatawrite(mapping) == 0) | 1205 | nfs_sync_mapping(mapping); |
1198 | filemap_fdatawait(mapping); | ||
1199 | nfs_wb_all(inode); | ||
1200 | } | ||
1201 | invalidate_inode_pages2(mapping); | 1206 | invalidate_inode_pages2(mapping); |
1202 | 1207 | ||
1203 | spin_lock(&inode->i_lock); | 1208 | spin_lock(&inode->i_lock); |
@@ -1248,6 +1253,33 @@ void nfs_end_data_update(struct inode *inode) | |||
1248 | atomic_dec(&nfsi->data_updates); | 1253 | atomic_dec(&nfsi->data_updates); |
1249 | } | 1254 | } |
1250 | 1255 | ||
1256 | static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) | ||
1257 | { | ||
1258 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1259 | |||
1260 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 | ||
1261 | && nfsi->change_attr == fattr->pre_change_attr) { | ||
1262 | nfsi->change_attr = fattr->change_attr; | ||
1263 | nfsi->cache_change_attribute = jiffies; | ||
1264 | } | ||
1265 | |||
1266 | /* If we have atomic WCC data, we may update some attributes */ | ||
1267 | if ((fattr->valid & NFS_ATTR_WCC) != 0) { | ||
1268 | if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) { | ||
1269 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1270 | nfsi->cache_change_attribute = jiffies; | ||
1271 | } | ||
1272 | if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { | ||
1273 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | ||
1274 | nfsi->cache_change_attribute = jiffies; | ||
1275 | } | ||
1276 | if (inode->i_size == fattr->pre_size && nfsi->npages == 0) { | ||
1277 | inode->i_size = fattr->size; | ||
1278 | nfsi->cache_change_attribute = jiffies; | ||
1279 | } | ||
1280 | } | ||
1281 | } | ||
1282 | |||
1251 | /** | 1283 | /** |
1252 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache | 1284 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache |
1253 | * @inode - pointer to inode | 1285 | * @inode - pointer to inode |
@@ -1264,22 +1296,20 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1264 | int data_unstable; | 1296 | int data_unstable; |
1265 | 1297 | ||
1266 | 1298 | ||
1299 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | ||
1300 | return 0; | ||
1301 | |||
1267 | /* Are we in the process of updating data on the server? */ | 1302 | /* Are we in the process of updating data on the server? */ |
1268 | data_unstable = nfs_caches_unstable(inode); | 1303 | data_unstable = nfs_caches_unstable(inode); |
1269 | 1304 | ||
1270 | if (fattr->valid & NFS_ATTR_FATTR_V4) { | 1305 | /* Do atomic weak cache consistency updates */ |
1271 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 | 1306 | nfs_wcc_update_inode(inode, fattr); |
1272 | && nfsi->change_attr == fattr->pre_change_attr) | ||
1273 | nfsi->change_attr = fattr->change_attr; | ||
1274 | if (nfsi->change_attr != fattr->change_attr) { | ||
1275 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1276 | if (!data_unstable) | ||
1277 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; | ||
1278 | } | ||
1279 | } | ||
1280 | 1307 | ||
1281 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) { | 1308 | if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 && |
1282 | return 0; | 1309 | nfsi->change_attr != fattr->change_attr) { |
1310 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1311 | if (!data_unstable) | ||
1312 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; | ||
1283 | } | 1313 | } |
1284 | 1314 | ||
1285 | /* Has the inode gone and changed behind our back? */ | 1315 | /* Has the inode gone and changed behind our back? */ |
@@ -1291,14 +1321,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1291 | cur_size = i_size_read(inode); | 1321 | cur_size = i_size_read(inode); |
1292 | new_isize = nfs_size_to_loff_t(fattr->size); | 1322 | new_isize = nfs_size_to_loff_t(fattr->size); |
1293 | 1323 | ||
1294 | /* If we have atomic WCC data, we may update some attributes */ | ||
1295 | if ((fattr->valid & NFS_ATTR_WCC) != 0) { | ||
1296 | if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) | ||
1297 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1298 | if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) | ||
1299 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | ||
1300 | } | ||
1301 | |||
1302 | /* Verify a few of the more important attributes */ | 1324 | /* Verify a few of the more important attributes */ |
1303 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { | 1325 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { |
1304 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 1326 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
@@ -1347,10 +1369,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1347 | return 0; | 1369 | return 0; |
1348 | spin_lock(&inode->i_lock); | 1370 | spin_lock(&inode->i_lock); |
1349 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | 1371 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; |
1350 | if (nfs_verify_change_attribute(inode, fattr->time_start)) | ||
1351 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1352 | if (time_after(fattr->time_start, nfsi->last_updated)) | 1372 | if (time_after(fattr->time_start, nfsi->last_updated)) |
1353 | status = nfs_update_inode(inode, fattr, fattr->time_start); | 1373 | status = nfs_update_inode(inode, fattr); |
1354 | else | 1374 | else |
1355 | status = nfs_check_inode_attributes(inode, fattr); | 1375 | status = nfs_check_inode_attributes(inode, fattr); |
1356 | 1376 | ||
@@ -1376,10 +1396,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1376 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | 1396 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; |
1377 | goto out; | 1397 | goto out; |
1378 | } | 1398 | } |
1379 | status = nfs_update_inode(inode, fattr, fattr->time_start); | 1399 | status = nfs_update_inode(inode, fattr); |
1380 | if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute)) | ||
1381 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); | ||
1382 | nfsi->cache_change_attribute = jiffies; | ||
1383 | out: | 1400 | out: |
1384 | spin_unlock(&inode->i_lock); | 1401 | spin_unlock(&inode->i_lock); |
1385 | return status; | 1402 | return status; |
@@ -1397,12 +1414,12 @@ out: | |||
1397 | * | 1414 | * |
1398 | * A very similar scenario holds for the dir cache. | 1415 | * A very similar scenario holds for the dir cache. |
1399 | */ | 1416 | */ |
1400 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) | 1417 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) |
1401 | { | 1418 | { |
1402 | struct nfs_inode *nfsi = NFS_I(inode); | 1419 | struct nfs_inode *nfsi = NFS_I(inode); |
1403 | loff_t cur_isize, new_isize; | 1420 | loff_t cur_isize, new_isize; |
1404 | unsigned int invalid = 0; | 1421 | unsigned int invalid = 0; |
1405 | int data_unstable; | 1422 | int data_stable; |
1406 | 1423 | ||
1407 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1424 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1408 | __FUNCTION__, inode->i_sb->s_id, inode->i_ino, | 1425 | __FUNCTION__, inode->i_sb->s_id, inode->i_ino, |
@@ -1411,14 +1428,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1411 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1428 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
1412 | return 0; | 1429 | return 0; |
1413 | 1430 | ||
1414 | if (nfsi->fileid != fattr->fileid) { | 1431 | if (nfsi->fileid != fattr->fileid) |
1415 | printk(KERN_ERR "%s: inode number mismatch\n" | 1432 | goto out_fileid; |
1416 | "expected (%s/0x%Lx), got (%s/0x%Lx)\n", | ||
1417 | __FUNCTION__, | ||
1418 | inode->i_sb->s_id, (long long)nfsi->fileid, | ||
1419 | inode->i_sb->s_id, (long long)fattr->fileid); | ||
1420 | goto out_err; | ||
1421 | } | ||
1422 | 1433 | ||
1423 | /* | 1434 | /* |
1424 | * Make sure the inode's type hasn't changed. | 1435 | * Make sure the inode's type hasn't changed. |
@@ -1433,8 +1444,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1433 | nfsi->last_updated = jiffies; | 1444 | nfsi->last_updated = jiffies; |
1434 | 1445 | ||
1435 | /* Are we racing with known updates of the metadata on the server? */ | 1446 | /* Are we racing with known updates of the metadata on the server? */ |
1436 | data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || | 1447 | data_stable = nfs_verify_change_attribute(inode, fattr->time_start); |
1437 | (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)); | 1448 | if (data_stable) |
1449 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1450 | |||
1451 | /* Do atomic weak cache consistency updates */ | ||
1452 | nfs_wcc_update_inode(inode, fattr); | ||
1438 | 1453 | ||
1439 | /* Check if our cached file size is stale */ | 1454 | /* Check if our cached file size is stale */ |
1440 | new_isize = nfs_size_to_loff_t(fattr->size); | 1455 | new_isize = nfs_size_to_loff_t(fattr->size); |
@@ -1443,7 +1458,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1443 | /* Do we perhaps have any outstanding writes? */ | 1458 | /* Do we perhaps have any outstanding writes? */ |
1444 | if (nfsi->npages == 0) { | 1459 | if (nfsi->npages == 0) { |
1445 | /* No, but did we race with nfs_end_data_update()? */ | 1460 | /* No, but did we race with nfs_end_data_update()? */ |
1446 | if (time_after_eq(verifier, nfsi->cache_change_attribute)) { | 1461 | if (data_stable) { |
1447 | inode->i_size = new_isize; | 1462 | inode->i_size = new_isize; |
1448 | invalid |= NFS_INO_INVALID_DATA; | 1463 | invalid |= NFS_INO_INVALID_DATA; |
1449 | } | 1464 | } |
@@ -1452,6 +1467,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1452 | inode->i_size = new_isize; | 1467 | inode->i_size = new_isize; |
1453 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1468 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1454 | } | 1469 | } |
1470 | nfsi->cache_change_attribute = jiffies; | ||
1455 | dprintk("NFS: isize change on server for file %s/%ld\n", | 1471 | dprintk("NFS: isize change on server for file %s/%ld\n", |
1456 | inode->i_sb->s_id, inode->i_ino); | 1472 | inode->i_sb->s_id, inode->i_ino); |
1457 | } | 1473 | } |
@@ -1461,8 +1477,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1461 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1477 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1462 | dprintk("NFS: mtime change on server for file %s/%ld\n", | 1478 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1463 | inode->i_sb->s_id, inode->i_ino); | 1479 | inode->i_sb->s_id, inode->i_ino); |
1464 | if (!data_unstable) | 1480 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1465 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1481 | nfsi->cache_change_attribute = jiffies; |
1466 | } | 1482 | } |
1467 | 1483 | ||
1468 | if ((fattr->valid & NFS_ATTR_FATTR_V4) | 1484 | if ((fattr->valid & NFS_ATTR_FATTR_V4) |
@@ -1470,15 +1486,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1470 | dprintk("NFS: change_attr change on server for file %s/%ld\n", | 1486 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1471 | inode->i_sb->s_id, inode->i_ino); | 1487 | inode->i_sb->s_id, inode->i_ino); |
1472 | nfsi->change_attr = fattr->change_attr; | 1488 | nfsi->change_attr = fattr->change_attr; |
1473 | if (!data_unstable) | 1489 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1474 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1490 | nfsi->cache_change_attribute = jiffies; |
1475 | } | 1491 | } |
1476 | 1492 | ||
1477 | /* If ctime has changed we should definitely clear access+acl caches */ | 1493 | /* If ctime has changed we should definitely clear access+acl caches */ |
1478 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | 1494 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { |
1479 | if (!data_unstable) | 1495 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1480 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
1481 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1496 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); |
1497 | nfsi->cache_change_attribute = jiffies; | ||
1482 | } | 1498 | } |
1483 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1499 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1484 | 1500 | ||
@@ -1516,6 +1532,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1516 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1532 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1517 | || S_ISLNK(inode->i_mode))) | 1533 | || S_ISLNK(inode->i_mode))) |
1518 | invalid &= ~NFS_INO_INVALID_DATA; | 1534 | invalid &= ~NFS_INO_INVALID_DATA; |
1535 | if (data_stable) | ||
1536 | invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); | ||
1519 | if (!nfs_have_delegation(inode, FMODE_READ)) | 1537 | if (!nfs_have_delegation(inode, FMODE_READ)) |
1520 | nfsi->cache_validity |= invalid; | 1538 | nfsi->cache_validity |= invalid; |
1521 | 1539 | ||
@@ -1528,15 +1546,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1528 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", | 1546 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", |
1529 | __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); | 1547 | __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); |
1530 | #endif | 1548 | #endif |
1549 | out_err: | ||
1531 | /* | 1550 | /* |
1532 | * No need to worry about unhashing the dentry, as the | 1551 | * No need to worry about unhashing the dentry, as the |
1533 | * lookup validation will know that the inode is bad. | 1552 | * lookup validation will know that the inode is bad. |
1534 | * (But we fall through to invalidate the caches.) | 1553 | * (But we fall through to invalidate the caches.) |
1535 | */ | 1554 | */ |
1536 | nfs_invalidate_inode(inode); | 1555 | nfs_invalidate_inode(inode); |
1537 | out_err: | ||
1538 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); | ||
1539 | return -ESTALE; | 1556 | return -ESTALE; |
1557 | |||
1558 | out_fileid: | ||
1559 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | ||
1560 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | ||
1561 | NFS_SERVER(inode)->hostname, inode->i_sb->s_id, | ||
1562 | (long long)nfsi->fileid, (long long)fattr->fileid); | ||
1563 | goto out_err; | ||
1540 | } | 1564 | } |
1541 | 1565 | ||
1542 | /* | 1566 | /* |
@@ -1818,25 +1842,10 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1818 | } | 1842 | } |
1819 | clnt->cl_intr = 1; | 1843 | clnt->cl_intr = 1; |
1820 | clnt->cl_softrtry = 1; | 1844 | clnt->cl_softrtry = 1; |
1821 | clnt->cl_chatty = 1; | ||
1822 | clp->cl_rpcclient = clnt; | 1845 | clp->cl_rpcclient = clnt; |
1823 | clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0); | ||
1824 | if (IS_ERR(clp->cl_cred)) { | ||
1825 | up_write(&clp->cl_sem); | ||
1826 | err = PTR_ERR(clp->cl_cred); | ||
1827 | clp->cl_cred = NULL; | ||
1828 | goto out_fail; | ||
1829 | } | ||
1830 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); | 1846 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); |
1831 | nfs_idmap_new(clp); | 1847 | nfs_idmap_new(clp); |
1832 | } | 1848 | } |
1833 | if (list_empty(&clp->cl_superblocks)) { | ||
1834 | err = nfs4_init_client(clp); | ||
1835 | if (err != 0) { | ||
1836 | up_write(&clp->cl_sem); | ||
1837 | goto out_fail; | ||
1838 | } | ||
1839 | } | ||
1840 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | 1849 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); |
1841 | clnt = rpc_clone_client(clp->cl_rpcclient); | 1850 | clnt = rpc_clone_client(clp->cl_rpcclient); |
1842 | if (!IS_ERR(clnt)) | 1851 | if (!IS_ERR(clnt)) |
@@ -2031,6 +2040,35 @@ static struct file_system_type nfs4_fs_type = { | |||
2031 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 2040 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
2032 | }; | 2041 | }; |
2033 | 2042 | ||
2043 | static const int nfs_set_port_min = 0; | ||
2044 | static const int nfs_set_port_max = 65535; | ||
2045 | static int param_set_port(const char *val, struct kernel_param *kp) | ||
2046 | { | ||
2047 | char *endp; | ||
2048 | int num = simple_strtol(val, &endp, 0); | ||
2049 | if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max) | ||
2050 | return -EINVAL; | ||
2051 | *((int *)kp->arg) = num; | ||
2052 | return 0; | ||
2053 | } | ||
2054 | |||
2055 | module_param_call(callback_tcpport, param_set_port, param_get_int, | ||
2056 | &nfs_callback_set_tcpport, 0644); | ||
2057 | |||
2058 | static int param_set_idmap_timeout(const char *val, struct kernel_param *kp) | ||
2059 | { | ||
2060 | char *endp; | ||
2061 | int num = simple_strtol(val, &endp, 0); | ||
2062 | int jif = num * HZ; | ||
2063 | if (endp == val || *endp || num < 0 || jif < num) | ||
2064 | return -EINVAL; | ||
2065 | *((int *)kp->arg) = jif; | ||
2066 | return 0; | ||
2067 | } | ||
2068 | |||
2069 | module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int, | ||
2070 | &nfs_idmap_cache_timeout, 0644); | ||
2071 | |||
2034 | #define nfs4_init_once(nfsi) \ | 2072 | #define nfs4_init_once(nfsi) \ |
2035 | do { \ | 2073 | do { \ |
2036 | INIT_LIST_HEAD(&(nfsi)->open_states); \ | 2074 | INIT_LIST_HEAD(&(nfsi)->open_states); \ |
@@ -2038,8 +2076,25 @@ static struct file_system_type nfs4_fs_type = { | |||
2038 | nfsi->delegation_state = 0; \ | 2076 | nfsi->delegation_state = 0; \ |
2039 | init_rwsem(&nfsi->rwsem); \ | 2077 | init_rwsem(&nfsi->rwsem); \ |
2040 | } while(0) | 2078 | } while(0) |
2041 | #define register_nfs4fs() register_filesystem(&nfs4_fs_type) | 2079 | |
2042 | #define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type) | 2080 | static inline int register_nfs4fs(void) |
2081 | { | ||
2082 | int ret; | ||
2083 | |||
2084 | ret = nfs_register_sysctl(); | ||
2085 | if (ret != 0) | ||
2086 | return ret; | ||
2087 | ret = register_filesystem(&nfs4_fs_type); | ||
2088 | if (ret != 0) | ||
2089 | nfs_unregister_sysctl(); | ||
2090 | return ret; | ||
2091 | } | ||
2092 | |||
2093 | static inline void unregister_nfs4fs(void) | ||
2094 | { | ||
2095 | unregister_filesystem(&nfs4_fs_type); | ||
2096 | nfs_unregister_sysctl(); | ||
2097 | } | ||
2043 | #else | 2098 | #else |
2044 | #define nfs4_init_once(nfsi) \ | 2099 | #define nfs4_init_once(nfsi) \ |
2045 | do { } while (0) | 2100 | do { } while (0) |
@@ -2068,6 +2123,7 @@ static struct inode *nfs_alloc_inode(struct super_block *sb) | |||
2068 | return NULL; | 2123 | return NULL; |
2069 | nfsi->flags = 0UL; | 2124 | nfsi->flags = 0UL; |
2070 | nfsi->cache_validity = 0UL; | 2125 | nfsi->cache_validity = 0UL; |
2126 | nfsi->cache_change_attribute = jiffies; | ||
2071 | #ifdef CONFIG_NFS_V3_ACL | 2127 | #ifdef CONFIG_NFS_V3_ACL |
2072 | nfsi->acl_access = ERR_PTR(-EAGAIN); | 2128 | nfsi->acl_access = ERR_PTR(-EAGAIN); |
2073 | nfsi->acl_default = ERR_PTR(-EAGAIN); | 2129 | nfsi->acl_default = ERR_PTR(-EAGAIN); |
@@ -2163,11 +2219,11 @@ out: | |||
2163 | #ifdef CONFIG_PROC_FS | 2219 | #ifdef CONFIG_PROC_FS |
2164 | rpc_proc_unregister("nfs"); | 2220 | rpc_proc_unregister("nfs"); |
2165 | #endif | 2221 | #endif |
2166 | nfs_destroy_writepagecache(); | ||
2167 | #ifdef CONFIG_NFS_DIRECTIO | 2222 | #ifdef CONFIG_NFS_DIRECTIO |
2168 | out0: | ||
2169 | nfs_destroy_directcache(); | 2223 | nfs_destroy_directcache(); |
2224 | out0: | ||
2170 | #endif | 2225 | #endif |
2226 | nfs_destroy_writepagecache(); | ||
2171 | out1: | 2227 | out1: |
2172 | nfs_destroy_readpagecache(); | 2228 | nfs_destroy_readpagecache(); |
2173 | out2: | 2229 | out2: |