Merge branch 'cleanup' into for-linus
[firefly-linux-kernel-4.4.55.git] / fs / inode.c
index 006c85ca06ebe05ad8eb7438040bddd3af64968d..ac8d904b3f1624bfa945ba088d2909e740e16a6c 100644 (file)
@@ -1542,18 +1542,24 @@ void touch_atime(struct path *path)
        if (timespec_equal(&inode->i_atime, &now))
                return;
 
-       if (mnt_want_write(mnt))
+       if (!sb_start_write_trylock(inode->i_sb))
                return;
 
+       if (__mnt_want_write(mnt))
+               goto skip_update;
        /*
         * File systems can error out when updating inodes if they need to
         * allocate new space to modify an inode (such is the case for
         * Btrfs), but since we touch atime while walking down the path we
         * really don't care if we failed to update the atime of the file,
         * so just ignore the return value.
+        * We may also fail on filesystems that have the ability to make parts
+        * of the fs read only, e.g. subvolumes in Btrfs.
         */
        update_time(inode, &now, S_ATIME);
-       mnt_drop_write(mnt);
+       __mnt_drop_write(mnt);
+skip_update:
+       sb_end_write(inode->i_sb);
 }
 EXPORT_SYMBOL(touch_atime);