Re: [PATCH 2/5] btrfs: zoned: drop stale dirty btree buffers at close_ctree()
Qu Wenruo <[email protected]>
| Newsgroups | org.kernel.vger.linux-btrfs |
|---|---|
| Message-ID | <[email protected]> |
在 2026/7/17 23:47, Johannes Thumshirn 写道: > On 17.07.26 00:49, Qu Wenruo wrote: >> >> >> 在 2026/7/16 21:26, Johannes Thumshirn 写道: >>> On a zoned filesystem btrfs_clear_buffer_dirty() keeps a freed-but-dirty >>> tree block dirty (EXTENT_BUFFER_ZONED_ZEROOUT) so its zero-out keeps the >>> zone write pointer moving. A block left ahead of the block group's >>> meta_write_pointer (e.g. a tree-log block freed before being written) >>> can >>> never be written by btree_writepages() and survives to unmount. >>> >>> close_ctree() stops the endio workqueues before the final iput() of the >>> btree inode but frees the block groups only afterwards. Once the block >>> group is gone btrfs_check_meta_write_pointer() no longer defers the >>> buffer, >>> so the iput() submits it for writeback; its completion can no longer be >>> queued on the destroyed endio_meta_workers and umount hangs on writeback >>> that never finishes. >> >> Can we just trigger a btree inode write back for zoned cases? >> >> That sounds much simpler and less hacky. > I tried freeing the stale ebs in btrfs_reset_unused_block_groups() > before actually resetting the bg, but then the WARN() in > invalidate_and_check_btree_folios() triggered again. So that doesn't > work sorry. > Sorry I'm not familiar with zoned metadata writeback. But it still doesn't sound correctly to me. To me, this seems to be a problem that btrfs_check_meta_write_pointer() can skip some ebs from being written back, and in that case those ebs should be properly handled (e.g. clearing dirty etc) but that's not the case. Yes, btrfs_clear_buffer_dirty() will not clear the EXTENT_BUFFER_DIRTY flag, but only set EXTENT_BUFFER_ZEROOUT flag. But still that dirty eb will go through writeback, as they still have the folio dirty flag and page cache tags, being properly submitted and got its EXTENT_BUFFER_DIRTY cleared, in the regular lock_extent_buffer_for_io() path, then go through the write_one_eb() to be submitted. However if btrfs_check_meta_write_pointer() returns non-zero values, we skip the writeback for that eb completely, so that eb stays dirty forever. Shouldn't we do something to clean up those ebs in the first place? So to me, this seems to be a problem in the zoned metadata writeback behavior, just being exposed by the newly introduced sanity checks. Thanks, Qu