The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <stable@xxxxxxxxxxxxxxx>. To reproduce the conflict and resubmit, you may use the following commands: git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f18cc97845aa4ae0e795c088c979fe1642b3b8e5 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to '<stable@xxxxxxxxxxxxxxx>' --in-reply-to '2023071617-same-snowbird-770b@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^.. Possible dependencies: f18cc97845aa ("btrfs: fix dirty_metadata_bytes for redirtied buffers") 98c8d683c291 ("btrfs: combine btrfs_clear_buffer_dirty and clear_extent_buffer_dirty") 190a83391bc4 ("btrfs: rename btrfs_clean_tree_block to btrfs_clear_buffer_dirty") c4e54a657116 ("btrfs: replace clearing extent buffer dirty bit with btrfs_clean_block") ed25dab3a0d1 ("btrfs: add trans argument to btrfs_clean_tree_block") d3fb66150c05 ("btrfs: always lock the block before calling btrfs_clean_tree_block") 7f0add250f82 ("btrfs: move super_block specific helpers into super.h") c03b22076bd2 ("btrfs: move super prototypes into super.h") 5c11adcc383a ("btrfs: move verity prototypes into verity.h") 77407dc032e2 ("btrfs: move dev-replace prototypes into dev-replace.h") 2fc6822c99d7 ("btrfs: move scrub prototypes into scrub.h") 677074792a1d ("btrfs: move relocation prototypes into relocation.h") 33cf97a7b658 ("btrfs: move acl prototypes into acl.h") b538a271ae9b ("btrfs: move the 32bit warn defines into messages.h") af142b6f44d3 ("btrfs: move file prototypes to file.h") 7572dec8f522 ("btrfs: move ioctl prototypes into ioctl.h") c7a03b524d30 ("btrfs: move uuid tree prototypes to uuid-tree.h") 7c8ede162805 ("btrfs: move file-item prototypes into their own header") f2b39277b87d ("btrfs: move dir-item prototypes into dir-item.h") 59b818e064ab ("btrfs: move defrag related prototypes to their own header") thanks, greg k-h ------------------ original commit in Linus's tree ------------------ >From f18cc97845aa4ae0e795c088c979fe1642b3b8e5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <hch@xxxxxx> Date: Mon, 8 May 2023 07:58:38 -0700 Subject: [PATCH] btrfs: fix dirty_metadata_bytes for redirtied buffers dirty_metadata_bytes is decremented in both places that clear the dirty bit in a buffer, but only incremented in btrfs_mark_buffer_dirty, which means that a buffer that is redirtied using btrfs_redirty_list_add won't be added to dirty_metadata_bytes, but it will be subtracted when written out, leading an inconsistency in the counter. Move the dirty_metadata_bytes from btrfs_mark_buffer_dirty into set_extent_buffer_dirty to also account for the redirty case, and remove the now unused set_extent_buffer_dirty return value. Fixes: d3575156f662 ("btrfs: zoned: redirty released extent buffers") CC: stable@xxxxxxxxxxxxxxx # 5.15+ Reviewed-by: Naohiro Aota <naohiro.aota@xxxxxxx> Signed-off-by: Christoph Hellwig <hch@xxxxxx> Signed-off-by: David Sterba <dsterba@xxxxxxxx> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 83518ed71bfd..112c99dde57f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -4621,7 +4621,6 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) { struct btrfs_fs_info *fs_info = buf->fs_info; u64 transid = btrfs_header_generation(buf); - int was_dirty; #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS /* @@ -4636,11 +4635,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) if (transid != fs_info->generation) WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n", buf->start, transid, fs_info->generation); - was_dirty = set_extent_buffer_dirty(buf); - if (!was_dirty) - percpu_counter_add_batch(&fs_info->dirty_metadata_bytes, - buf->len, - fs_info->dirty_metadata_batch); + set_extent_buffer_dirty(buf); #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY /* * btrfs_check_leaf() won't check item data if we don't have WRITTEN diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index a1adadd5d25d..a829390632a5 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4148,7 +4148,7 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, WARN_ON(atomic_read(&eb->refs) == 0); } -bool set_extent_buffer_dirty(struct extent_buffer *eb) +void set_extent_buffer_dirty(struct extent_buffer *eb) { int i; int num_pages; @@ -4183,13 +4183,14 @@ bool set_extent_buffer_dirty(struct extent_buffer *eb) eb->start, eb->len); if (subpage) unlock_page(eb->pages[0]); + percpu_counter_add_batch(&eb->fs_info->dirty_metadata_bytes, + eb->len, + eb->fs_info->dirty_metadata_batch); } #ifdef CONFIG_BTRFS_DEBUG for (i = 0; i < num_pages; i++) ASSERT(PageDirty(eb->pages[i])); #endif - - return was_dirty; } void clear_extent_buffer_uptodate(struct extent_buffer *eb) diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4341ad978fb8..f937654230d3 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -262,7 +262,7 @@ void extent_buffer_bitmap_set(const struct extent_buffer *eb, unsigned long star void extent_buffer_bitmap_clear(const struct extent_buffer *eb, unsigned long start, unsigned long pos, unsigned long len); -bool set_extent_buffer_dirty(struct extent_buffer *eb); +void set_extent_buffer_dirty(struct extent_buffer *eb); void set_extent_buffer_uptodate(struct extent_buffer *eb); void clear_extent_buffer_uptodate(struct extent_buffer *eb); int extent_buffer_under_io(const struct extent_buffer *eb);