|
@@ -637,7 +637,7 @@ int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
|
|
* In the case it has, we assume that the dentries are untrustworthy
|
|
* In the case it has, we assume that the dentries are untrustworthy
|
|
* and may need to be looked up again.
|
|
* and may need to be looked up again.
|
|
*/
|
|
*/
|
|
-static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
|
|
|
|
|
|
+static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
|
|
{
|
|
{
|
|
if (IS_ROOT(dentry))
|
|
if (IS_ROOT(dentry))
|
|
return 1;
|
|
return 1;
|
|
@@ -652,6 +652,12 @@ static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
|
|
dentry->d_fsdata = (void *)verf;
|
|
dentry->d_fsdata = (void *)verf;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
|
|
|
|
+{
|
|
|
|
+ if (time_after(verf, (unsigned long)dentry->d_fsdata))
|
|
|
|
+ nfs_set_verifier(dentry, verf);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Whenever an NFS operation succeeds, we know that the dentry
|
|
* Whenever an NFS operation succeeds, we know that the dentry
|
|
* is valid, so we update the revalidation timestamp.
|
|
* is valid, so we update the revalidation timestamp.
|
|
@@ -785,7 +791,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
|
|
goto out_bad;
|
|
goto out_bad;
|
|
|
|
|
|
nfs_renew_times(dentry);
|
|
nfs_renew_times(dentry);
|
|
- nfs_set_verifier(dentry, verifier);
|
|
|
|
|
|
+ nfs_refresh_verifier(dentry, verifier);
|
|
out_valid:
|
|
out_valid:
|
|
unlock_kernel();
|
|
unlock_kernel();
|
|
dput(parent);
|
|
dput(parent);
|
|
@@ -1085,7 +1091,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|
verifier = nfs_save_change_attribute(dir);
|
|
verifier = nfs_save_change_attribute(dir);
|
|
ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
|
|
ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
|
|
if (!ret)
|
|
if (!ret)
|
|
- nfs_set_verifier(dentry, verifier);
|
|
|
|
|
|
+ nfs_refresh_verifier(dentry, verifier);
|
|
unlock_kernel();
|
|
unlock_kernel();
|
|
out:
|
|
out:
|
|
dput(parent);
|
|
dput(parent);
|
|
@@ -1159,10 +1165,13 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
|
|
dentry = alias;
|
|
dentry = alias;
|
|
}
|
|
}
|
|
|
|
|
|
-out_renew:
|
|
|
|
nfs_renew_times(dentry);
|
|
nfs_renew_times(dentry);
|
|
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
|
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
|
return dentry;
|
|
return dentry;
|
|
|
|
+out_renew:
|
|
|
|
+ nfs_renew_times(dentry);
|
|
|
|
+ nfs_refresh_verifier(dentry, nfs_save_change_attribute(dir));
|
|
|
|
+ return dentry;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1700,7 +1709,7 @@ out:
|
|
if (!error) {
|
|
if (!error) {
|
|
d_move(old_dentry, new_dentry);
|
|
d_move(old_dentry, new_dentry);
|
|
nfs_renew_times(new_dentry);
|
|
nfs_renew_times(new_dentry);
|
|
- nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir));
|
|
|
|
|
|
+ nfs_refresh_verifier(new_dentry, nfs_save_change_attribute(new_dir));
|
|
}
|
|
}
|
|
|
|
|
|
/* new dentry created? */
|
|
/* new dentry created? */
|