]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: invalidate pages when doing direct/sync writes
authorLuís Henriques <lhenriques@suse.de>
Thu, 7 Apr 2022 15:15:21 +0000 (16:15 +0100)
committerJeff Layton <jlayton@kernel.org>
Tue, 31 May 2022 15:50:02 +0000 (11:50 -0400)
When doing a direct/sync write, we need to invalidate the page cache in
the range being written to. If we don't do this, the cache will include
invalid data as we just did a write that avoided the page cache.

In the event that invalidation fails, just ignore the error. That likely
just means that we raced with another task doing a buffered write, in
which case we want to leave the page intact anyway.

[ jlayton: minor comment update ]

Signed-off-by: Luís Henriques <lhenriques@suse.de>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
fs/ceph/file.c

index 4de25a0723adff1b6589334a79324f9b67257558..f4356ed2f93312eb7a6e8c98f3ff1c802bee2ac8 100644 (file)
@@ -1619,11 +1619,6 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
                return ret;
 
        ceph_fscache_invalidate(inode, false);
-       ret = invalidate_inode_pages2_range(inode->i_mapping,
-                                           pos >> PAGE_SHIFT,
-                                           (pos + count - 1) >> PAGE_SHIFT);
-       if (ret < 0)
-               dout("invalidate_inode_pages2_range returned %d\n", ret);
 
        while ((len = iov_iter_count(from)) > 0) {
                size_t left;
@@ -1950,6 +1945,20 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
                        break;
                }
                ceph_clear_error_write(ci);
+
+               /*
+                * We successfully wrote to a range of the file. Declare
+                * that region of the pagecache invalid.
+                */
+               ret = invalidate_inode_pages2_range(
+                               inode->i_mapping,
+                               pos >> PAGE_SHIFT,
+                               (pos + len - 1) >> PAGE_SHIFT);
+               if (ret < 0) {
+                       dout("invalidate_inode_pages2_range returned %d\n",
+                            ret);
+                       ret = 0;
+               }
                pos += len;
                written += len;
                dout("sync_write written %d\n", written);