aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <piastryyy@gmail.com>2019-09-30 10:06:20 -0700
committerSteve French <stfrench@microsoft.com>2019-10-09 00:10:50 -0500
commit0b3d0ef9840f7be202393ca9116b857f6f793715 (patch)
tree3254e63a7496c708fb46004c542c1160e885b2f0
parentc82e5ac7fe3570a269c0929bf7899f62048e7dbc (diff)
downloadlinux-0b3d0ef9840f7be202393ca9116b857f6f793715.tar.gz
CIFS: Force reval dentry if LOOKUP_REVAL flag is set
Mark inode for force revalidation if LOOKUP_REVAL flag is set. This tells the client to actually send a QueryInfo request to the server to obtain the latest metadata in case a directory or a file were changed remotely. Only do that if the client doesn't have a lease for the file to avoid unneeded round trips to the server. Cc: <stable@vger.kernel.org> Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/cifs/dir.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index dd5ac841aefa7f..7ce689d31aa2d4 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -738,10 +738,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
static int
cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
{
+ struct inode *inode;
+
if (flags & LOOKUP_RCU)
return -ECHILD;
if (d_really_is_positive(direntry)) {
+ inode = d_inode(direntry);
+ if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
+ CIFS_I(inode)->time = 0; /* force reval */
+
if (cifs_revalidate_dentry(direntry))
return 0;
else {
@@ -752,7 +758,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
* attributes will have been updated by
* cifs_revalidate_dentry().
*/
- if (IS_AUTOMOUNT(d_inode(direntry)) &&
+ if (IS_AUTOMOUNT(inode) &&
!(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
spin_lock(&direntry->d_lock);
direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;