Skip to content

Commit 3adf8f1

Browse files
adam900710kdave
authored andcommitted
btrfs: do not touch page cache for encoded writes
[BUG] When running btrfs/284, the following ASSERT() will be triggered with 64K page size and 4K fs block size: assertion failed: folio_test_writeback(folio) :: 0, in subpage.c:476 ------------[ cut here ]------------ kernel BUG at subpage.c:476! Internal error: Oops - BUG: 00000000f2000800 [#1] SMP CPU: 4 UID: 0 PID: 2313 Comm: kworker/u37:2 Tainted: G OE 6.19.0-rc8-custom+ #185 PREEMPT(voluntary) Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022 Workqueue: btrfs-endio simple_end_io_work [btrfs] pc : btrfs_subpage_clear_writeback+0x148/0x160 [btrfs] lr : btrfs_subpage_clear_writeback+0x148/0x160 [btrfs] Call trace: btrfs_subpage_clear_writeback+0x148/0x160 [btrfs] (P) btrfs_folio_clamp_clear_writeback+0xb4/0xd0 [btrfs] end_compressed_writeback+0xe0/0x1e0 [btrfs] end_bbio_compressed_write+0x1e8/0x218 [btrfs] btrfs_bio_end_io+0x108/0x258 [btrfs] simple_end_io_work+0x68/0xa8 [btrfs] process_one_work+0x168/0x3f0 worker_thread+0x25c/0x398 kthread+0x154/0x250 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- [CAUSE] The offending bio is from an encoded write, where the compressed data is directly written as a data extent, without touching the page cache. However the encoded write still utilizes the regular buffered write path for compressed data, by setting the compressed_bio::writeback flag. When that flag is set, at end_bbio_compressed_write() btrfs will go clearing the writeback flag of the folios in the page cache. However for bs < ps cases, the subpage helper has one extra check to make sure the folio has a writeback flag set in the first place. But since it's an encoded write, we never go through page cache, thus the folio has no writeback flag and triggers the ASSERT(). [FIX] Do not set compressed_bio::writeback flag for encoded writes, and change the ASSERT() in btrfs_submit_compressed_write() to make sure that flag is not set. Fixes: e1bc83f ("btrfs: get rid of compressed_folios[] usage for encoded writes") Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 65ee606 commit 3adf8f1

1 file changed

Lines changed: 7 additions & 3 deletions

File tree

fs/btrfs/compression.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,12 @@ void btrfs_submit_compressed_write(struct btrfs_ordered_extent *ordered,
320320

321321
ASSERT(IS_ALIGNED(ordered->file_offset, fs_info->sectorsize));
322322
ASSERT(IS_ALIGNED(ordered->num_bytes, fs_info->sectorsize));
323-
ASSERT(cb->writeback);
323+
/*
324+
* This flag determines if we should clear the writeback flag from the
325+
* page cache. But this function is only utilized by encoded writes, it
326+
* never goes through the page cache.
327+
*/
328+
ASSERT(!cb->writeback);
324329

325330
cb->start = ordered->file_offset;
326331
cb->len = ordered->num_bytes;
@@ -346,8 +351,7 @@ struct compressed_bio *btrfs_alloc_compressed_write(struct btrfs_inode *inode,
346351
cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE, end_bbio_compressed_write);
347352
cb->start = start;
348353
cb->len = len;
349-
cb->writeback = true;
350-
354+
cb->writeback = false;
351355
return cb;
352356
}
353357

0 commit comments

Comments
 (0)