aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/file.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2021-04-22 16:38:26 +0200
committerJan Kara <jack@suse.cz>2021-07-13 14:29:01 +0200
commit057ba5b24532aca202cb1ae8c246bde27de12763 (patch)
tree3abff803cddcd5ef21b135f6c31cb1d05f908e6a /fs/ceph/file.c
parentfuse: Convert to using invalidate_lock (diff)
downloadlinux-dev-057ba5b24532aca202cb1ae8c246bde27de12763.tar.xz
linux-dev-057ba5b24532aca202cb1ae8c246bde27de12763.zip
ceph: Fix race between hole punch and page fault
Ceph has a following race between hole punching and page fault: CPU1 CPU2 ceph_fallocate() ... ceph_zero_pagecache_range() ceph_filemap_fault() faults in page in the range being punched ceph_zero_objects() And now we have a page in punched range with invalid data. Fix the problem by using mapping->invalidate_lock similarly to other filesystems. Note that using invalidate_lock also fixes a similar race wrt ->readpage(). CC: Jeff Layton <jlayton@kernel.org> CC: ceph-devel@vger.kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r--fs/ceph/file.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index d1755ac1d964..e1d605a02d4a 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -2088,6 +2088,7 @@ static long ceph_fallocate(struct file *file, int mode,
if (ret < 0)
goto unlock;
+ filemap_invalidate_lock(inode->i_mapping);
ceph_zero_pagecache_range(inode, offset, length);
ret = ceph_zero_objects(inode, offset, length);
@@ -2100,6 +2101,7 @@ static long ceph_fallocate(struct file *file, int mode,
if (dirty)
__mark_inode_dirty(inode, dirty);
}
+ filemap_invalidate_unlock(inode->i_mapping);
ceph_put_cap_refs(ci, got);
unlock: