NFS: Ensure ACCESS caches are invalidated together with the attribute cache. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 3 ++- fs/nfs/inode.c | 27 ++++++++------------------- include/linux/nfs_fs.h | 3 ++- 3 files changed, 12 insertions(+), 21 deletions(-) Index: linux-2.6.10-rc1-NFS_ALL/fs/nfs/inode.c =================================================================== --- linux-2.6.10-rc1-NFS_ALL.orig/fs/nfs/inode.c 2004-10-25 15:58:05.142745194 -0400 +++ linux-2.6.10-rc1-NFS_ALL/fs/nfs/inode.c 2004-10-25 16:55:41.839997067 -0400 @@ -565,9 +565,9 @@ nfs_zap_caches(struct inode *inode) memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) - nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; else - nfsi->flags |= NFS_INO_INVALID_ATTR; + nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; } /* @@ -766,13 +766,8 @@ nfs_setattr(struct dentry *dentry, struc vmtruncate(inode, attr->ia_size); } } - if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { - struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; - if (*cred) { - put_rpccred(*cred); - *cred = NULL; - } - } + if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) + NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; nfs_end_data_update(inode); unlock_kernel(); return error; @@ -1160,7 +1155,7 @@ int nfs_refresh_inode(struct inode *inod if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || inode->i_uid != fattr->uid || inode->i_gid != fattr->gid) - nfsi->flags |= NFS_INO_INVALID_ATTR; + nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; /* Has the link count changed? */ if (inode->i_nlink != fattr->nlink) @@ -1269,7 +1264,7 @@ static int nfs_update_inode(struct inode #endif nfsi->change_attr = fattr->change_attr; if (!data_unstable) - invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; } memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); @@ -1277,14 +1272,8 @@ static int nfs_update_inode(struct inode if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || inode->i_uid != fattr->uid || - inode->i_gid != fattr->gid) { - struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; - if (*cred) { - put_rpccred(*cred); - *cred = NULL; - } - invalid |= NFS_INO_INVALID_ATTR; - } + inode->i_gid != fattr->gid) + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; Index: linux-2.6.10-rc1-NFS_ALL/fs/nfs/dir.c =================================================================== --- linux-2.6.10-rc1-NFS_ALL.orig/fs/nfs/dir.c 2004-10-25 15:58:05.140745460 -0400 +++ linux-2.6.10-rc1-NFS_ALL/fs/nfs/dir.c 2004-10-25 16:19:19.517634265 -0400 @@ -1452,7 +1452,7 @@ int nfs_access_get_cached(struct inode * if (cache->cred != cred || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) - || (NFS_FLAGS(inode) & NFS_INO_INVALID_ATTR)) + || (NFS_FLAGS(inode) & NFS_INO_INVALID_ACCESS)) return -ENOENT; memcpy(res, cache, sizeof(*res)); return 0; @@ -1466,6 +1466,7 @@ void nfs_access_add_cache(struct inode * if (cache->cred) put_rpccred(cache->cred); cache->cred = get_rpccred(set->cred); + NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS; } cache->jiffies = set->jiffies; cache->mask = set->mask; Index: linux-2.6.10-rc1-NFS_ALL/include/linux/nfs_fs.h =================================================================== --- linux-2.6.10-rc1-NFS_ALL.orig/include/linux/nfs_fs.h 2004-10-25 15:58:00.630344214 -0400 +++ linux-2.6.10-rc1-NFS_ALL/include/linux/nfs_fs.h 2004-10-25 16:12:11.994353827 -0400 @@ -201,6 +201,7 @@ struct nfs_inode { #define NFS_INO_INVALID_ATTR 0x0008 /* cached attrs are invalid */ #define NFS_INO_INVALID_DATA 0x0010 /* cached data is invalid */ #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ +#define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ static inline struct nfs_inode *NFS_I(struct inode *inode) { @@ -239,7 +240,7 @@ static inline int nfs_caches_unstable(st static inline void NFS_CACHEINV(struct inode *inode) { if (!nfs_caches_unstable(inode)) - NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR; + NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; } static inline int nfs_server_capable(struct inode *inode, int cap)