diff options
-rw-r--r-- | fs/nfs/dir.c | 15 | ||||
-rw-r--r-- | fs/nfs/inode.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 2 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 1 |
4 files changed, 21 insertions, 3 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 32c666c612a1..72d141a0dbd8 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -638,6 +638,21 @@ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) | |||
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
640 | 640 | ||
641 | /** | ||
642 | * nfs_force_lookup_revalidate - Mark the directory as having changed | ||
643 | * @dir - pointer to directory inode | ||
644 | * | ||
645 | * This forces the revalidation code in nfs_lookup_revalidate() to do a | ||
646 | * full lookup on all child dentries of 'dir' whenever a change occurs | ||
647 | * on the server that might have invalidated our dcache. | ||
648 | * | ||
649 | * The caller should be holding dir->i_lock | ||
650 | */ | ||
651 | void nfs_force_lookup_revalidate(struct inode *dir) | ||
652 | { | ||
653 | NFS_I(dir)->cache_change_attribute = jiffies; | ||
654 | } | ||
655 | |||
641 | /* | 656 | /* |
642 | * A check for whether or not the parent directory has changed. | 657 | * A check for whether or not the parent directory has changed. |
643 | * In the case it has, we assume that the dentries are untrustworthy | 658 | * In the case it has, we assume that the dentries are untrustworthy |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index cc3a09db41a9..5747d49bdd76 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1029,7 +1029,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1029 | dprintk("NFS: mtime change on server for file %s/%ld\n", | 1029 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1030 | inode->i_sb->s_id, inode->i_ino); | 1030 | inode->i_sb->s_id, inode->i_ino); |
1031 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1031 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1032 | nfsi->cache_change_attribute = now; | 1032 | if (S_ISDIR(inode->i_mode)) |
1033 | nfs_force_lookup_revalidate(inode); | ||
1033 | } | 1034 | } |
1034 | /* If ctime has changed we should definitely clear access+acl caches */ | 1035 | /* If ctime has changed we should definitely clear access+acl caches */ |
1035 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) | 1036 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) |
@@ -1038,7 +1039,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1038 | dprintk("NFS: change_attr change on server for file %s/%ld\n", | 1039 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1039 | inode->i_sb->s_id, inode->i_ino); | 1040 | inode->i_sb->s_id, inode->i_ino); |
1040 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1041 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1041 | nfsi->cache_change_attribute = now; | 1042 | if (S_ISDIR(inode->i_mode)) |
1043 | nfs_force_lookup_revalidate(inode); | ||
1042 | } | 1044 | } |
1043 | 1045 | ||
1044 | /* Check if our cached file size is stale */ | 1046 | /* Check if our cached file size is stale */ |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 826b445b8c70..26192a703129 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -210,7 +210,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) | |||
210 | spin_lock(&dir->i_lock); | 210 | spin_lock(&dir->i_lock); |
211 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; | 211 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; |
212 | if (!cinfo->atomic || cinfo->before != nfsi->change_attr) | 212 | if (!cinfo->atomic || cinfo->before != nfsi->change_attr) |
213 | nfsi->cache_change_attribute = jiffies; | 213 | nfs_force_lookup_revalidate(dir); |
214 | nfsi->change_attr = cinfo->after; | 214 | nfsi->change_attr = cinfo->after; |
215 | spin_unlock(&dir->i_lock); | 215 | spin_unlock(&dir->i_lock); |
216 | } | 216 | } |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 2d15d4aac094..7095aaa087d8 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -366,6 +366,7 @@ extern const struct inode_operations nfs3_dir_inode_operations; | |||
366 | extern const struct file_operations nfs_dir_operations; | 366 | extern const struct file_operations nfs_dir_operations; |
367 | extern struct dentry_operations nfs_dentry_operations; | 367 | extern struct dentry_operations nfs_dentry_operations; |
368 | 368 | ||
369 | extern void nfs_force_lookup_revalidate(struct inode *dir); | ||
369 | extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); | 370 | extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); |
370 | extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); | 371 | extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); |
371 | extern void nfs_access_zap_cache(struct inode *inode); | 372 | extern void nfs_access_zap_cache(struct inode *inode); |