diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/inode.c | 60 |
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 | ||
1251 | static 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); |