From 06048c5b83fb7a1b064a755423c0ac2225e78e80 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lu=C3=ADs=20Henriques?= Date: Thu, 7 Apr 2022 16:15:21 +0100 Subject: [PATCH] ceph: invalidate pages when doing direct/sync writes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Xiubo Li Signed-off-by: Jeff Layton --- fs/ceph/file.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 4de25a0723adf..f4356ed2f9331 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -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); -- 2.39.5