diff options
author | Luís Henriques <lhenriques@suse.de> | 2022-08-25 15:31:27 +0200 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2023-08-24 11:24:36 +0200 |
commit | b422f115044328e1753d6c1e3bb4955b4ca5df27 (patch) | |
tree | 61c761bbadc64b3dbe98f758d4f1254aafb3dd3a /fs | |
parent | ceph: plumb in decryption during reads (diff) | |
download | linux-b422f115044328e1753d6c1e3bb4955b4ca5df27.tar.xz linux-b422f115044328e1753d6c1e3bb4955b4ca5df27.zip |
ceph: invalidate pages when doing direct/sync writes
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: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Milind Changire <mchangir@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/file.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 9d1a77cdc494..e58787233e42 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1636,11 +1636,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; @@ -1968,6 +1963,20 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, } 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); |