diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index a82f0340744f..c45bd52cc1d7 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -64,6 +64,7 @@ static void nfs_clear_inode(struct inode *); | |||
64 | static void nfs_umount_begin(struct super_block *); | 64 | static void nfs_umount_begin(struct super_block *); |
65 | static int nfs_statfs(struct super_block *, struct kstatfs *); | 65 | static int nfs_statfs(struct super_block *, struct kstatfs *); |
66 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 66 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
67 | static void nfs_zap_acl_cache(struct inode *); | ||
67 | 68 | ||
68 | static struct rpc_program nfs_program; | 69 | static struct rpc_program nfs_program; |
69 | 70 | ||
@@ -153,6 +154,7 @@ nfs_clear_inode(struct inode *inode) | |||
153 | 154 | ||
154 | nfs_wb_all(inode); | 155 | nfs_wb_all(inode); |
155 | BUG_ON (!list_empty(&nfsi->open_files)); | 156 | BUG_ON (!list_empty(&nfsi->open_files)); |
157 | nfs_zap_acl_cache(inode); | ||
156 | cred = nfsi->cache_access.cred; | 158 | cred = nfsi->cache_access.cred; |
157 | if (cred) | 159 | if (cred) |
158 | put_rpccred(cred); | 160 | put_rpccred(cred); |
@@ -587,9 +589,19 @@ nfs_zap_caches(struct inode *inode) | |||
587 | 589 | ||
588 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | 590 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); |
589 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) | 591 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
590 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; | 592 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
591 | else | 593 | else |
592 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; | 594 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
595 | } | ||
596 | |||
597 | static void nfs_zap_acl_cache(struct inode *inode) | ||
598 | { | ||
599 | void (*clear_acl_cache)(struct inode *); | ||
600 | |||
601 | clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache; | ||
602 | if (clear_acl_cache != NULL) | ||
603 | clear_acl_cache(inode); | ||
604 | NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL; | ||
593 | } | 605 | } |
594 | 606 | ||
595 | /* | 607 | /* |
@@ -789,7 +801,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
789 | } | 801 | } |
790 | } | 802 | } |
791 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) | 803 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) |
792 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; | 804 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
793 | nfs_end_data_update(inode); | 805 | nfs_end_data_update(inode); |
794 | unlock_kernel(); | 806 | unlock_kernel(); |
795 | return error; | 807 | return error; |
@@ -1033,6 +1045,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1033 | /* This ensures we revalidate dentries */ | 1045 | /* This ensures we revalidate dentries */ |
1034 | nfsi->cache_change_attribute++; | 1046 | nfsi->cache_change_attribute++; |
1035 | } | 1047 | } |
1048 | if (flags & NFS_INO_INVALID_ACL) | ||
1049 | nfs_zap_acl_cache(inode); | ||
1036 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 1050 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", |
1037 | inode->i_sb->s_id, | 1051 | inode->i_sb->s_id, |
1038 | (long long)NFS_FILEID(inode)); | 1052 | (long long)NFS_FILEID(inode)); |
@@ -1183,7 +1197,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1183 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) | 1197 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) |
1184 | || inode->i_uid != fattr->uid | 1198 | || inode->i_uid != fattr->uid |
1185 | || inode->i_gid != fattr->gid) | 1199 | || inode->i_gid != fattr->gid) |
1186 | nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | 1200 | nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1187 | 1201 | ||
1188 | /* Has the link count changed? */ | 1202 | /* Has the link count changed? */ |
1189 | if (inode->i_nlink != fattr->nlink) | 1203 | if (inode->i_nlink != fattr->nlink) |
@@ -1292,16 +1306,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1292 | #endif | 1306 | #endif |
1293 | nfsi->change_attr = fattr->change_attr; | 1307 | nfsi->change_attr = fattr->change_attr; |
1294 | if (!data_unstable) | 1308 | if (!data_unstable) |
1295 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; | 1309 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1296 | } | 1310 | } |
1297 | 1311 | ||
1298 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1312 | /* If ctime has changed we should definitely clear access+acl caches */ |
1313 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | ||
1314 | if (!data_unstable) | ||
1315 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
1316 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1317 | } | ||
1299 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1318 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1300 | 1319 | ||
1301 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || | 1320 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || |
1302 | inode->i_uid != fattr->uid || | 1321 | inode->i_uid != fattr->uid || |
1303 | inode->i_gid != fattr->gid) | 1322 | inode->i_gid != fattr->gid) |
1304 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; | 1323 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1305 | 1324 | ||
1306 | inode->i_mode = fattr->mode; | 1325 | inode->i_mode = fattr->mode; |
1307 | inode->i_nlink = fattr->nlink; | 1326 | inode->i_nlink = fattr->nlink; |