Commit 74ce6fec authored by Trond Myklebust's avatar Trond Myklebust

NFS: Ensure ACCESS caches are invalidated together with the attribute

     cache.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent c256ae39
...@@ -1452,7 +1452,7 @@ int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs ...@@ -1452,7 +1452,7 @@ int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs
if (cache->cred != cred if (cache->cred != cred
|| time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))
|| (NFS_FLAGS(inode) & NFS_INO_INVALID_ATTR)) || (NFS_FLAGS(inode) & NFS_INO_INVALID_ACCESS))
return -ENOENT; return -ENOENT;
memcpy(res, cache, sizeof(*res)); memcpy(res, cache, sizeof(*res));
return 0; return 0;
...@@ -1466,6 +1466,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) ...@@ -1466,6 +1466,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
if (cache->cred) if (cache->cred)
put_rpccred(cache->cred); put_rpccred(cache->cred);
cache->cred = get_rpccred(set->cred); cache->cred = get_rpccred(set->cred);
NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS;
} }
cache->jiffies = set->jiffies; cache->jiffies = set->jiffies;
cache->mask = set->mask; cache->mask = set->mask;
......
...@@ -565,9 +565,9 @@ nfs_zap_caches(struct inode *inode) ...@@ -565,9 +565,9 @@ nfs_zap_caches(struct inode *inode)
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) 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 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, struct iattr *attr) ...@@ -766,13 +766,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
vmtruncate(inode, attr->ia_size); vmtruncate(inode, attr->ia_size);
} }
} }
if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS;
if (*cred) {
put_rpccred(*cred);
*cred = NULL;
}
}
nfs_end_data_update(inode); nfs_end_data_update(inode);
unlock_kernel(); unlock_kernel();
return error; return error;
...@@ -1160,7 +1155,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1160,7 +1155,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
|| inode->i_uid != fattr->uid || inode->i_uid != fattr->uid
|| inode->i_gid != fattr->gid) || 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? */ /* Has the link count changed? */
if (inode->i_nlink != fattr->nlink) if (inode->i_nlink != fattr->nlink)
...@@ -1269,7 +1264,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign ...@@ -1269,7 +1264,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
#endif #endif
nfsi->change_attr = fattr->change_attr; nfsi->change_attr = fattr->change_attr;
if (!data_unstable) 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)); memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
...@@ -1277,14 +1272,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign ...@@ -1277,14 +1272,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
inode->i_uid != fattr->uid || inode->i_uid != fattr->uid ||
inode->i_gid != fattr->gid) { inode->i_gid != fattr->gid)
struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
if (*cred) {
put_rpccred(*cred);
*cred = NULL;
}
invalid |= NFS_INO_INVALID_ATTR;
}
inode->i_mode = fattr->mode; inode->i_mode = fattr->mode;
inode->i_nlink = fattr->nlink; inode->i_nlink = fattr->nlink;
......
...@@ -202,6 +202,7 @@ struct nfs_inode { ...@@ -202,6 +202,7 @@ struct nfs_inode {
#define NFS_INO_INVALID_ATTR 0x0008 /* cached attrs are invalid */ #define NFS_INO_INVALID_ATTR 0x0008 /* cached attrs are invalid */
#define NFS_INO_INVALID_DATA 0x0010 /* cached data is 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_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) static inline struct nfs_inode *NFS_I(struct inode *inode)
{ {
...@@ -240,7 +241,7 @@ static inline int nfs_caches_unstable(struct inode *inode) ...@@ -240,7 +241,7 @@ static inline int nfs_caches_unstable(struct inode *inode)
static inline void NFS_CACHEINV(struct inode *inode) static inline void NFS_CACHEINV(struct inode *inode)
{ {
if (!nfs_caches_unstable(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) static inline int nfs_server_capable(struct inode *inode, int cap)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment