diff mbox series

[2/2] btrfs: fix btrfs_read_folio race in send

Message ID e55d48ca1bd763a232f9eb1b2d57585dfd598065.1734131353.git.boris@bur.io (mailing list archive)
State New
Headers show
Series fixes for btrfs_read_folio races | expand

Commit Message

Boris Burkov Dec. 13, 2024, 11:13 p.m. UTC
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.

Signed-off-by: Boris Burkov <boris@bur.io>
---
 fs/btrfs/send.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff mbox series

Patch

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index c5a318feb8ae..f437138fefbc 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,