aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/dir.c15
-rw-r--r--fs/nfs/inode.c6
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--include/linux/nfs_fs.h1
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 */
651void 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;
366extern const struct file_operations nfs_dir_operations; 366extern const struct file_operations nfs_dir_operations;
367extern struct dentry_operations nfs_dentry_operations; 367extern struct dentry_operations nfs_dentry_operations;
368 368
369extern void nfs_force_lookup_revalidate(struct inode *dir);
369extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); 370extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
370extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); 371extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags);
371extern void nfs_access_zap_cache(struct inode *inode); 372extern void nfs_access_zap_cache(struct inode *inode);