|
@@ -1653,6 +1653,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
unsigned long invalid = 0;
|
|
|
unsigned long now = jiffies;
|
|
|
unsigned long save_cache_validity;
|
|
|
+ bool cache_revalidated = true;
|
|
|
|
|
|
dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
|
|
|
__func__, inode->i_sb->s_id, inode->i_ino,
|
|
@@ -1714,22 +1715,28 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
nfs_force_lookup_revalidate(inode);
|
|
|
inode->i_version = fattr->change_attr;
|
|
|
}
|
|
|
- } else
|
|
|
+ } else {
|
|
|
nfsi->cache_validity |= save_cache_validity;
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
|
|
|
memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
|
|
|
- } else if (server->caps & NFS_CAP_MTIME)
|
|
|
+ } else if (server->caps & NFS_CAP_MTIME) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
|
|
|
memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
|
|
|
- } else if (server->caps & NFS_CAP_CTIME)
|
|
|
+ } else if (server->caps & NFS_CAP_CTIME) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
/* Check if our cached file size is stale */
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
|
@@ -1749,19 +1756,23 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
(long long)cur_isize,
|
|
|
(long long)new_isize);
|
|
|
}
|
|
|
- } else
|
|
|
+ } else {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_REVAL_PAGECACHE
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_ATIME)
|
|
|
memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
|
|
|
- else if (server->caps & NFS_CAP_ATIME)
|
|
|
+ else if (server->caps & NFS_CAP_ATIME) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATIME
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_MODE) {
|
|
|
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
|
|
@@ -1770,36 +1781,42 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
inode->i_mode = newmode;
|
|
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
|
|
}
|
|
|
- } else if (server->caps & NFS_CAP_MODE)
|
|
|
+ } else if (server->caps & NFS_CAP_MODE) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_INVALID_ACCESS
|
|
|
| NFS_INO_INVALID_ACL
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
|
|
|
if (!uid_eq(inode->i_uid, fattr->uid)) {
|
|
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
|
|
inode->i_uid = fattr->uid;
|
|
|
}
|
|
|
- } else if (server->caps & NFS_CAP_OWNER)
|
|
|
+ } else if (server->caps & NFS_CAP_OWNER) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_INVALID_ACCESS
|
|
|
| NFS_INO_INVALID_ACL
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
|
|
|
if (!gid_eq(inode->i_gid, fattr->gid)) {
|
|
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
|
|
inode->i_gid = fattr->gid;
|
|
|
}
|
|
|
- } else if (server->caps & NFS_CAP_OWNER_GROUP)
|
|
|
+ } else if (server->caps & NFS_CAP_OWNER_GROUP) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_INVALID_ACCESS
|
|
|
| NFS_INO_INVALID_ACL
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
|
|
|
if (inode->i_nlink != fattr->nlink) {
|
|
@@ -1808,19 +1825,22 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
invalid |= NFS_INO_INVALID_DATA;
|
|
|
set_nlink(inode, fattr->nlink);
|
|
|
}
|
|
|
- } else if (server->caps & NFS_CAP_NLINK)
|
|
|
+ } else if (server->caps & NFS_CAP_NLINK) {
|
|
|
nfsi->cache_validity |= save_cache_validity &
|
|
|
(NFS_INO_INVALID_ATTR
|
|
|
| NFS_INO_REVAL_FORCED);
|
|
|
+ cache_revalidated = false;
|
|
|
+ }
|
|
|
|
|
|
if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
|
|
|
/*
|
|
|
* report the blocks in 512byte units
|
|
|
*/
|
|
|
inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
|
|
|
- }
|
|
|
- if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
|
|
|
+ } else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
|
|
|
inode->i_blocks = fattr->du.nfs2.blocks;
|
|
|
+ else
|
|
|
+ cache_revalidated = false;
|
|
|
|
|
|
/* Update attrtimeo value if we're out of the unstable period */
|
|
|
if (invalid & NFS_INO_INVALID_ATTR) {
|
|
@@ -1830,9 +1850,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
/* Set barrier to be more recent than all outstanding updates */
|
|
|
nfsi->attr_gencount = nfs_inc_attr_generation_counter();
|
|
|
} else {
|
|
|
- if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
|
|
|
- if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
|
|
|
- nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
|
|
|
+ if (cache_revalidated) {
|
|
|
+ if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
|
|
|
+ nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
|
|
|
+ nfsi->attrtimeo <<= 1;
|
|
|
+ if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
|
|
|
+ nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
|
|
|
+ }
|
|
|
nfsi->attrtimeo_timestamp = now;
|
|
|
}
|
|
|
/* Set the barrier to be more recent than this fattr */
|
|
@@ -1841,7 +1865,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|
|
}
|
|
|
|
|
|
/* Don't declare attrcache up to date if there were no attrs! */
|
|
|
- if (fattr->valid != 0)
|
|
|
+ if (cache_revalidated)
|
|
|
invalid &= ~NFS_INO_INVALID_ATTR;
|
|
|
|
|
|
/* Don't invalidate the data if we were to blame */
|