Commit ada70d94 authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] NFS: Add hooks to allow common NFS attribute code to clear cached acls

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 92cfc62c
...@@ -64,6 +64,7 @@ static void nfs_clear_inode(struct inode *); ...@@ -64,6 +64,7 @@ static void nfs_clear_inode(struct inode *);
static void nfs_umount_begin(struct super_block *); static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct super_block *, struct kstatfs *); static int nfs_statfs(struct super_block *, struct kstatfs *);
static int nfs_show_options(struct seq_file *, struct vfsmount *); static int nfs_show_options(struct seq_file *, struct vfsmount *);
static void nfs_zap_acl_cache(struct inode *);
static struct rpc_program nfs_program; static struct rpc_program nfs_program;
...@@ -153,6 +154,7 @@ nfs_clear_inode(struct inode *inode) ...@@ -153,6 +154,7 @@ nfs_clear_inode(struct inode *inode)
nfs_wb_all(inode); nfs_wb_all(inode);
BUG_ON (!list_empty(&nfsi->open_files)); BUG_ON (!list_empty(&nfsi->open_files));
nfs_zap_acl_cache(inode);
cred = nfsi->cache_access.cred; cred = nfsi->cache_access.cred;
if (cred) if (cred)
put_rpccred(cred); put_rpccred(cred);
...@@ -587,9 +589,19 @@ nfs_zap_caches(struct inode *inode) ...@@ -587,9 +589,19 @@ 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|NFS_INO_INVALID_ACCESS; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
else else
nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
}
static void nfs_zap_acl_cache(struct inode *inode)
{
void (*clear_acl_cache)(struct inode *);
clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
if (clear_acl_cache != NULL)
clear_acl_cache(inode);
NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL;
} }
/* /*
...@@ -789,7 +801,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -789,7 +801,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
} }
} }
if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
nfs_end_data_update(inode); nfs_end_data_update(inode);
unlock_kernel(); unlock_kernel();
return error; return error;
...@@ -1033,6 +1045,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -1033,6 +1045,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
/* This ensures we revalidate dentries */ /* This ensures we revalidate dentries */
nfsi->cache_change_attribute++; nfsi->cache_change_attribute++;
} }
if (flags & NFS_INO_INVALID_ACL)
nfs_zap_acl_cache(inode);
dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
inode->i_sb->s_id, inode->i_sb->s_id,
(long long)NFS_FILEID(inode)); (long long)NFS_FILEID(inode));
...@@ -1183,7 +1197,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1183,7 +1197,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 | NFS_INO_INVALID_ACCESS; nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
/* Has the link count changed? */ /* Has the link count changed? */
if (inode->i_nlink != fattr->nlink) if (inode->i_nlink != fattr->nlink)
...@@ -1292,16 +1306,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign ...@@ -1292,16 +1306,21 @@ 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|NFS_INO_INVALID_ACCESS; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
} }
memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); /* If ctime has changed we should definitely clear access+acl caches */
if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
if (!data_unstable)
invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
}
memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
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)
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
inode->i_mode = fattr->mode; inode->i_mode = fattr->mode;
inode->i_nlink = fattr->nlink; inode->i_nlink = fattr->nlink;
......
...@@ -189,6 +189,7 @@ struct nfs_inode { ...@@ -189,6 +189,7 @@ struct nfs_inode {
#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 */ #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */
#define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */
static inline struct nfs_inode *NFS_I(struct inode *inode) static inline struct nfs_inode *NFS_I(struct inode *inode)
{ {
......
...@@ -714,6 +714,7 @@ struct nfs_rpc_ops { ...@@ -714,6 +714,7 @@ struct nfs_rpc_ops {
int (*file_open) (struct inode *, struct file *); int (*file_open) (struct inode *, struct file *);
int (*file_release) (struct inode *, struct file *); int (*file_release) (struct inode *, struct file *);
int (*lock)(struct file *, int, struct file_lock *); int (*lock)(struct file *, int, struct file_lock *);
void (*clear_acl_cache)(struct inode *);
}; };
/* /*
......
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