Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
[sfrench/cifs-2.6.git] / fs / inode.c
index 210054157a4998b901c366e5d27a211b39f23315..d1e35b53bb23b80db7077500f63eeec9bce6bb28 100644 (file)
@@ -1570,11 +1570,24 @@ EXPORT_SYMBOL(bmap);
 static void update_ovl_inode_times(struct dentry *dentry, struct inode *inode,
                               bool rcu)
 {
-       if (!rcu) {
-               struct inode *realinode = d_real_inode(dentry);
+       struct dentry *upperdentry;
 
-               if (unlikely(inode != realinode) &&
-                   (!timespec_equal(&inode->i_mtime, &realinode->i_mtime) ||
+       /*
+        * Nothing to do if in rcu or if non-overlayfs
+        */
+       if (rcu || likely(!(dentry->d_flags & DCACHE_OP_REAL)))
+               return;
+
+       upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER);
+
+       /*
+        * If file is on lower then we can't update atime, so no worries about
+        * stale mtime/ctime.
+        */
+       if (upperdentry) {
+               struct inode *realinode = d_inode(upperdentry);
+
+               if ((!timespec_equal(&inode->i_mtime, &realinode->i_mtime) ||
                     !timespec_equal(&inode->i_ctime, &realinode->i_ctime))) {
                        inode->i_mtime = realinode->i_mtime;
                        inode->i_ctime = realinode->i_ctime;