Commit b422f115 authored by Luís Henriques's avatar Luís Henriques Committed by Ilya Dryomov
Browse files

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: default avatarLuís Henriques <lhenriques@suse.de>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarMilind Changire <mchangir@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent f0fe1e54
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -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);