aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 2c7f8aac1dec..7270b1d73d30 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1248,6 +1248,33 @@ void nfs_end_data_update(struct inode *inode)
1248 atomic_dec(&nfsi->data_updates); 1248 atomic_dec(&nfsi->data_updates);
1249} 1249}
1250 1250
1251static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1252{
1253 struct nfs_inode *nfsi = NFS_I(inode);
1254
1255 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
1256 && nfsi->change_attr == fattr->pre_change_attr) {
1257 nfsi->change_attr = fattr->change_attr;
1258 nfsi->cache_change_attribute = jiffies;
1259 }
1260
1261 /* If we have atomic WCC data, we may update some attributes */
1262 if ((fattr->valid & NFS_ATTR_WCC) != 0) {
1263 if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
1264 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1265 nfsi->cache_change_attribute = jiffies;
1266 }
1267 if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
1268 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1269 nfsi->cache_change_attribute = jiffies;
1270 }
1271 if (inode->i_size == fattr->pre_size && nfsi->npages == 0) {
1272 inode->i_size = fattr->size;
1273 nfsi->cache_change_attribute = jiffies;
1274 }
1275 }
1276}
1277
1251/** 1278/**
1252 * nfs_check_inode_attributes - verify consistency of the inode attribute cache 1279 * nfs_check_inode_attributes - verify consistency of the inode attribute cache
1253 * @inode - pointer to inode 1280 * @inode - pointer to inode
@@ -1264,22 +1291,20 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1264 int data_unstable; 1291 int data_unstable;
1265 1292
1266 1293
1294 if ((fattr->valid & NFS_ATTR_FATTR) == 0)
1295 return 0;
1296
1267 /* Are we in the process of updating data on the server? */ 1297 /* Are we in the process of updating data on the server? */
1268 data_unstable = nfs_caches_unstable(inode); 1298 data_unstable = nfs_caches_unstable(inode);
1269 1299
1270 if (fattr->valid & NFS_ATTR_FATTR_V4) { 1300 /* Do atomic weak cache consistency updates */
1271 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 1301 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 1302
1281 if ((fattr->valid & NFS_ATTR_FATTR) == 0) { 1303 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
1282 return 0; 1304 nfsi->change_attr != fattr->change_attr) {
1305 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1306 if (!data_unstable)
1307 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1283 } 1308 }
1284 1309
1285 /* Has the inode gone and changed behind our back? */ 1310 /* Has the inode gone and changed behind our back? */
@@ -1291,14 +1316,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1291 cur_size = i_size_read(inode); 1316 cur_size = i_size_read(inode);
1292 new_isize = nfs_size_to_loff_t(fattr->size); 1317 new_isize = nfs_size_to_loff_t(fattr->size);
1293 1318
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 */ 1319 /* Verify a few of the more important attributes */
1303 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { 1320 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
1304 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1321 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
@@ -1426,6 +1443,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1426 if (data_stable) 1443 if (data_stable)
1427 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1444 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1428 1445
1446 /* Do atomic weak cache consistency updates */
1447 nfs_wcc_update_inode(inode, fattr);
1448
1429 /* Check if our cached file size is stale */ 1449 /* Check if our cached file size is stale */
1430 new_isize = nfs_size_to_loff_t(fattr->size); 1450 new_isize = nfs_size_to_loff_t(fattr->size);
1431 cur_isize = i_size_read(inode); 1451 cur_isize = i_size_read(inode);