From: Boris Burkov Date: Fri, 13 Dec 2024 20:33:22 +0000 (-0800) Subject: btrfs: check folio mapping after unlock in put_file_data() X-Git-Tag: v6.13-rc5~7^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0fba7be1ca6df2881e68386e5575fe096f33c4ca;p=thirdparty%2Flinux.git btrfs: check folio mapping after unlock in put_file_data() When we call btrfs_read_folio() we get an unlocked folio, so it is possible for a different thread to concurrently modify folio->mapping. We must check that this hasn't happened once we do have the lock. CC: stable@vger.kernel.org # 6.12+ Reviewed-by: Qu Wenruo Signed-off-by: Boris Burkov Signed-off-by: David Sterba --- diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 7254279c3cc92..498c843232536 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5280,6 +5280,7 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len) unsigned cur_len = min_t(unsigned, len, PAGE_SIZE - pg_offset); +again: folio = filemap_lock_folio(mapping, index); if (IS_ERR(folio)) { page_cache_sync_readahead(mapping, @@ -5312,6 +5313,11 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len) ret = -EIO; break; } + if (folio->mapping != mapping) { + folio_unlock(folio); + folio_put(folio); + goto again; + } } memcpy_from_folio(sctx->send_buf + sctx->send_size, folio,