aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/dir.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 062e108fac50..37c1dd642184 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -637,7 +637,7 @@ int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
637 * In the case it has, we assume that the dentries are untrustworthy 637 * In the case it has, we assume that the dentries are untrustworthy
638 * and may need to be looked up again. 638 * and may need to be looked up again.
639 */ 639 */
640static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry) 640static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
641{ 641{
642 if (IS_ROOT(dentry)) 642 if (IS_ROOT(dentry))
643 return 1; 643 return 1;
@@ -652,6 +652,12 @@ static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
652 dentry->d_fsdata = (void *)verf; 652 dentry->d_fsdata = (void *)verf;
653} 653}
654 654
655static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
656{
657 if (time_after(verf, (unsigned long)dentry->d_fsdata))
658 nfs_set_verifier(dentry, verf);
659}
660
655/* 661/*
656 * Whenever an NFS operation succeeds, we know that the dentry 662 * Whenever an NFS operation succeeds, we know that the dentry
657 * is valid, so we update the revalidation timestamp. 663 * is valid, so we update the revalidation timestamp.
@@ -785,7 +791,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
785 goto out_bad; 791 goto out_bad;
786 792
787 nfs_renew_times(dentry); 793 nfs_renew_times(dentry);
788 nfs_set_verifier(dentry, verifier); 794 nfs_refresh_verifier(dentry, verifier);
789 out_valid: 795 out_valid:
790 unlock_kernel(); 796 unlock_kernel();
791 dput(parent); 797 dput(parent);
@@ -1085,7 +1091,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1085 verifier = nfs_save_change_attribute(dir); 1091 verifier = nfs_save_change_attribute(dir);
1086 ret = nfs4_open_revalidate(dir, dentry, openflags, nd); 1092 ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
1087 if (!ret) 1093 if (!ret)
1088 nfs_set_verifier(dentry, verifier); 1094 nfs_refresh_verifier(dentry, verifier);
1089 unlock_kernel(); 1095 unlock_kernel();
1090out: 1096out:
1091 dput(parent); 1097 dput(parent);
@@ -1159,10 +1165,13 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
1159 dentry = alias; 1165 dentry = alias;
1160 } 1166 }
1161 1167
1162out_renew:
1163 nfs_renew_times(dentry); 1168 nfs_renew_times(dentry);
1164 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1169 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1165 return dentry; 1170 return dentry;
1171out_renew:
1172 nfs_renew_times(dentry);
1173 nfs_refresh_verifier(dentry, nfs_save_change_attribute(dir));
1174 return dentry;
1166} 1175}
1167 1176
1168/* 1177/*
@@ -1700,7 +1709,7 @@ out:
1700 if (!error) { 1709 if (!error) {
1701 d_move(old_dentry, new_dentry); 1710 d_move(old_dentry, new_dentry);
1702 nfs_renew_times(new_dentry); 1711 nfs_renew_times(new_dentry);
1703 nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); 1712 nfs_refresh_verifier(new_dentry, nfs_save_change_attribute(new_dir));
1704 } 1713 }
1705 1714
1706 /* new dentry created? */ 1715 /* new dentry created? */