diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c496f8a74639..9927913c97c2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -147,6 +147,17 @@ int nfs_sync_mapping(struct address_space *mapping) | |||
147 | return ret; | 147 | return ret; |
148 | } | 148 | } |
149 | 149 | ||
150 | static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) | ||
151 | { | ||
152 | struct nfs_inode *nfsi = NFS_I(inode); | ||
153 | |||
154 | if (inode->i_mapping->nrpages == 0) | ||
155 | flags &= ~NFS_INO_INVALID_DATA; | ||
156 | nfsi->cache_validity |= flags; | ||
157 | if (flags & NFS_INO_INVALID_DATA) | ||
158 | nfs_fscache_invalidate(inode); | ||
159 | } | ||
160 | |||
150 | /* | 161 | /* |
151 | * Invalidate the local caches | 162 | * Invalidate the local caches |
152 | */ | 163 | */ |
@@ -162,17 +173,16 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
162 | 173 | ||
163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); | 174 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 175 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { |
165 | nfs_fscache_invalidate(inode); | 176 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
167 | | NFS_INO_INVALID_DATA | 177 | | NFS_INO_INVALID_DATA |
168 | | NFS_INO_INVALID_ACCESS | 178 | | NFS_INO_INVALID_ACCESS |
169 | | NFS_INO_INVALID_ACL | 179 | | NFS_INO_INVALID_ACL |
170 | | NFS_INO_REVAL_PAGECACHE; | 180 | | NFS_INO_REVAL_PAGECACHE); |
171 | } else | 181 | } else |
172 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 182 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
173 | | NFS_INO_INVALID_ACCESS | 183 | | NFS_INO_INVALID_ACCESS |
174 | | NFS_INO_INVALID_ACL | 184 | | NFS_INO_INVALID_ACL |
175 | | NFS_INO_REVAL_PAGECACHE; | 185 | | NFS_INO_REVAL_PAGECACHE); |
176 | nfs_zap_label_cache_locked(nfsi); | 186 | nfs_zap_label_cache_locked(nfsi); |
177 | } | 187 | } |
178 | 188 | ||
@@ -187,8 +197,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) | |||
187 | { | 197 | { |
188 | if (mapping->nrpages != 0) { | 198 | if (mapping->nrpages != 0) { |
189 | spin_lock(&inode->i_lock); | 199 | spin_lock(&inode->i_lock); |
190 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | 200 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
191 | nfs_fscache_invalidate(inode); | ||
192 | spin_unlock(&inode->i_lock); | 201 | spin_unlock(&inode->i_lock); |
193 | } | 202 | } |
194 | } | 203 | } |
@@ -209,7 +218,7 @@ EXPORT_SYMBOL_GPL(nfs_zap_acl_cache); | |||
209 | void nfs_invalidate_atime(struct inode *inode) | 218 | void nfs_invalidate_atime(struct inode *inode) |
210 | { | 219 | { |
211 | spin_lock(&inode->i_lock); | 220 | spin_lock(&inode->i_lock); |
212 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | 221 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME); |
213 | spin_unlock(&inode->i_lock); | 222 | spin_unlock(&inode->i_lock); |
214 | } | 223 | } |
215 | EXPORT_SYMBOL_GPL(nfs_invalidate_atime); | 224 | EXPORT_SYMBOL_GPL(nfs_invalidate_atime); |
@@ -369,7 +378,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
369 | inode->i_mode = fattr->mode; | 378 | inode->i_mode = fattr->mode; |
370 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 | 379 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 |
371 | && nfs_server_capable(inode, NFS_CAP_MODE)) | 380 | && nfs_server_capable(inode, NFS_CAP_MODE)) |
372 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 381 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
373 | /* Why so? Because we want revalidate for devices/FIFOs, and | 382 | /* Why so? Because we want revalidate for devices/FIFOs, and |
374 | * that's precisely what we have in nfs_file_inode_operations. | 383 | * that's precisely what we have in nfs_file_inode_operations. |
375 | */ | 384 | */ |
@@ -415,36 +424,36 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
415 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) | 424 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
416 | inode->i_atime = fattr->atime; | 425 | inode->i_atime = fattr->atime; |
417 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) | 426 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) |
418 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 427 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
419 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) | 428 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
420 | inode->i_mtime = fattr->mtime; | 429 | inode->i_mtime = fattr->mtime; |
421 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) | 430 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) |
422 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 431 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
423 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) | 432 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
424 | inode->i_ctime = fattr->ctime; | 433 | inode->i_ctime = fattr->ctime; |
425 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) | 434 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) |
426 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 435 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
427 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) | 436 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
428 | inode->i_version = fattr->change_attr; | 437 | inode->i_version = fattr->change_attr; |
429 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) | 438 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) |
430 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 439 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
431 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) | 440 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) |
432 | inode->i_size = nfs_size_to_loff_t(fattr->size); | 441 | inode->i_size = nfs_size_to_loff_t(fattr->size); |
433 | else | 442 | else |
434 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 443 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
435 | | NFS_INO_REVAL_PAGECACHE; | 444 | | NFS_INO_REVAL_PAGECACHE); |
436 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) | 445 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) |
437 | set_nlink(inode, fattr->nlink); | 446 | set_nlink(inode, fattr->nlink); |
438 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) | 447 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) |
439 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 448 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
440 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) | 449 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) |
441 | inode->i_uid = fattr->uid; | 450 | inode->i_uid = fattr->uid; |
442 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) | 451 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) |
443 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 452 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
444 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) | 453 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) |
445 | inode->i_gid = fattr->gid; | 454 | inode->i_gid = fattr->gid; |
446 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) | 455 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) |
447 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 456 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
448 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) | 457 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
449 | inode->i_blocks = fattr->du.nfs2.blocks; | 458 | inode->i_blocks = fattr->du.nfs2.blocks; |
450 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 459 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
@@ -550,6 +559,9 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset) | |||
550 | 559 | ||
551 | spin_lock(&inode->i_lock); | 560 | spin_lock(&inode->i_lock); |
552 | i_size_write(inode, offset); | 561 | i_size_write(inode, offset); |
562 | /* Optimisation */ | ||
563 | if (offset == 0) | ||
564 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; | ||
553 | spin_unlock(&inode->i_lock); | 565 | spin_unlock(&inode->i_lock); |
554 | 566 | ||
555 | truncate_pagecache(inode, offset); | 567 | truncate_pagecache(inode, offset); |
@@ -578,7 +590,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) | |||
578 | inode->i_uid = attr->ia_uid; | 590 | inode->i_uid = attr->ia_uid; |
579 | if ((attr->ia_valid & ATTR_GID) != 0) | 591 | if ((attr->ia_valid & ATTR_GID) != 0) |
580 | inode->i_gid = attr->ia_gid; | 592 | inode->i_gid = attr->ia_gid; |
581 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 593 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS |
594 | | NFS_INO_INVALID_ACL); | ||
582 | spin_unlock(&inode->i_lock); | 595 | spin_unlock(&inode->i_lock); |
583 | } | 596 | } |
584 | if ((attr->ia_valid & ATTR_SIZE) != 0) { | 597 | if ((attr->ia_valid & ATTR_SIZE) != 0) { |
@@ -1101,7 +1114,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
1101 | && inode->i_version == fattr->pre_change_attr) { | 1114 | && inode->i_version == fattr->pre_change_attr) { |
1102 | inode->i_version = fattr->change_attr; | 1115 | inode->i_version = fattr->change_attr; |
1103 | if (S_ISDIR(inode->i_mode)) | 1116 | if (S_ISDIR(inode->i_mode)) |
1104 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1117 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
1105 | ret |= NFS_INO_INVALID_ATTR; | 1118 | ret |= NFS_INO_INVALID_ATTR; |
1106 | } | 1119 | } |
1107 | /* If we have atomic WCC data, we may update some attributes */ | 1120 | /* If we have atomic WCC data, we may update some attributes */ |
@@ -1117,7 +1130,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
1117 | && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { | 1130 | && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { |
1118 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1131 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1119 | if (S_ISDIR(inode->i_mode)) | 1132 | if (S_ISDIR(inode->i_mode)) |
1120 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1133 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
1121 | ret |= NFS_INO_INVALID_ATTR; | 1134 | ret |= NFS_INO_INVALID_ATTR; |
1122 | } | 1135 | } |
1123 | if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) | 1136 | if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) |
@@ -1128,9 +1141,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
1128 | ret |= NFS_INO_INVALID_ATTR; | 1141 | ret |= NFS_INO_INVALID_ATTR; |
1129 | } | 1142 | } |
1130 | 1143 | ||
1131 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
1132 | nfs_fscache_invalidate(inode); | ||
1133 | |||
1134 | return ret; | 1144 | return ret; |
1135 | } | 1145 | } |
1136 | 1146 | ||
@@ -1189,7 +1199,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1189 | invalid |= NFS_INO_INVALID_ATIME; | 1199 | invalid |= NFS_INO_INVALID_ATIME; |
1190 | 1200 | ||
1191 | if (invalid != 0) | 1201 | if (invalid != 0) |
1192 | nfsi->cache_validity |= invalid; | 1202 | nfs_set_cache_invalid(inode, invalid); |
1193 | 1203 | ||
1194 | nfsi->read_cache_jiffies = fattr->time_start; | 1204 | nfsi->read_cache_jiffies = fattr->time_start; |
1195 | return 0; | 1205 | return 0; |
@@ -1402,13 +1412,11 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode); | |||
1402 | 1412 | ||
1403 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) | 1413 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) |
1404 | { | 1414 | { |
1405 | struct nfs_inode *nfsi = NFS_I(inode); | 1415 | unsigned long invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
1406 | 1416 | ||
1407 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; | 1417 | if (S_ISDIR(inode->i_mode)) |
1408 | if (S_ISDIR(inode->i_mode)) { | 1418 | invalid |= NFS_INO_INVALID_DATA; |
1409 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1419 | nfs_set_cache_invalid(inode, invalid); |
1410 | nfs_fscache_invalidate(inode); | ||
1411 | } | ||
1412 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1420 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
1413 | return 0; | 1421 | return 0; |
1414 | return nfs_refresh_inode_locked(inode, fattr); | 1422 | return nfs_refresh_inode_locked(inode, fattr); |
@@ -1601,6 +1609,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1601 | if ((nfsi->npages == 0) || new_isize > cur_isize) { | 1609 | if ((nfsi->npages == 0) || new_isize > cur_isize) { |
1602 | i_size_write(inode, new_isize); | 1610 | i_size_write(inode, new_isize); |
1603 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1611 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1612 | invalid &= ~NFS_INO_REVAL_PAGECACHE; | ||
1604 | } | 1613 | } |
1605 | dprintk("NFS: isize change on server for file %s/%ld " | 1614 | dprintk("NFS: isize change on server for file %s/%ld " |
1606 | "(%Ld to %Ld)\n", | 1615 | "(%Ld to %Ld)\n", |
@@ -1702,10 +1711,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1702 | invalid &= ~NFS_INO_INVALID_DATA; | 1711 | invalid &= ~NFS_INO_INVALID_DATA; |
1703 | if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) || | 1712 | if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) || |
1704 | (save_cache_validity & NFS_INO_REVAL_FORCED)) | 1713 | (save_cache_validity & NFS_INO_REVAL_FORCED)) |
1705 | nfsi->cache_validity |= invalid; | 1714 | nfs_set_cache_invalid(inode, invalid); |
1706 | |||
1707 | if (invalid & NFS_INO_INVALID_DATA) | ||
1708 | nfs_fscache_invalidate(inode); | ||
1709 | 1715 | ||
1710 | return 0; | 1716 | return 0; |
1711 | out_err: | 1717 | out_err: |