btrfs: don't hold an extra reference for redirtied buffers
authorChristoph Hellwig <hch@lst.de>
Mon, 8 May 2023 14:58:39 +0000 (07:58 -0700)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2023 11:59:26 +0000 (13:59 +0200)
When btrfs_redirty_list_add redirties a buffer, it also acquires
an extra reference that is released on transaction commit.  But
this is not required as buffers that are dirty or under writeback
are never freed (look for calls to extent_buffer_under_io())).

Remove the extra reference and the infrastructure used to drop it
again.

History behind redirty logic:

In the first place, it used releasing_list to hold all the
to-be-released extent buffers, and decided which buffers to re-dirty at
the commit time. Then, in a later version, the behaviour got changed to
re-dirty a necessary buffer and add re-dirtied one to the list in
btrfs_free_tree_block(). In short, the list was there mostly for the
patch series' historical reason.

Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
[ add Naohiro's comment regarding history ]
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/zoned.c
fs/btrfs/zoned.h

index 112c99dde57f50f988bb6db7e85188b6e5b57063..16224fd8298723de9c48fd12dd70255158ee99c1 100644 (file)
@@ -5073,8 +5073,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
                                     EXTENT_DIRTY);
        btrfs_destroy_pinned_extent(fs_info, &cur_trans->pinned_extents);
 
-       btrfs_free_redirty_list(cur_trans);
-
        cur_trans->state =TRANS_STATE_COMPLETED;
        wake_up(&cur_trans->commit_wait);
 }
index a829390632a538e081c732a2dbc955c908968e87..d8becf1cdbc09e44c14e3d100302bece0b35b8de 100644 (file)
@@ -3557,7 +3557,6 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
        init_rwsem(&eb->lock);
 
        btrfs_leak_debug_add_eb(eb);
-       INIT_LIST_HEAD(&eb->release_list);
 
        spin_lock_init(&eb->refs_lock);
        atomic_set(&eb->refs, 1);
index f937654230d3c5f77f1de6cf98d0008400c8e3a6..6f3cfadd232c957eb620783b25cc0a62178c116a 100644 (file)
@@ -89,7 +89,6 @@ struct extent_buffer {
        struct rw_semaphore lock;
 
        struct page *pages[INLINE_EXTENT_BUFFER_PAGES];
-       struct list_head release_list;
 #ifdef CONFIG_BTRFS_DEBUG
        struct list_head leak_list;
 #endif
index 27c616fdfae274908d9312ed0305086068e81ebf..fe0f00e717a8345666af35eea7af25cc9edf34f5 100644 (file)
@@ -374,8 +374,6 @@ loop:
        spin_lock_init(&cur_trans->dirty_bgs_lock);
        INIT_LIST_HEAD(&cur_trans->deleted_bgs);
        spin_lock_init(&cur_trans->dropped_roots_lock);
-       INIT_LIST_HEAD(&cur_trans->releasing_ebs);
-       spin_lock_init(&cur_trans->releasing_ebs_lock);
        list_add_tail(&cur_trans->list, &fs_info->trans_list);
        extent_io_tree_init(fs_info, &cur_trans->dirty_pages,
                        IO_TREE_TRANS_DIRTY_PAGES);
@@ -2482,13 +2480,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
                goto scrub_continue;
        }
 
-       /*
-        * At this point, we should have written all the tree blocks allocated
-        * in this transaction. So it's now safe to free the redirtyied extent
-        * buffers.
-        */
-       btrfs_free_redirty_list(cur_trans);
-
        ret = write_all_supers(fs_info, 0);
        /*
         * the super is written, we can safely allow the tree-loggers
index fa728ab8082614e0ada67307faa6ac11f8fe6536..8e9fa23bd7fed73acffeafc4b3655c6b64c7a58f 100644 (file)
@@ -94,9 +94,6 @@ struct btrfs_transaction {
         */
        atomic_t pending_ordered;
        wait_queue_head_t pending_wait;
-
-       spinlock_t releasing_ebs_lock;
-       struct list_head releasing_ebs;
 };
 
 enum {
index dac879fe28710bf6402f4e72d6f3ef14c2a8bca0..bda301a55cbe3b265098356256838310178ac65f 100644 (file)
@@ -1602,37 +1602,17 @@ void btrfs_calc_zone_unusable(struct btrfs_block_group *cache)
 void btrfs_redirty_list_add(struct btrfs_transaction *trans,
                            struct extent_buffer *eb)
 {
-       struct btrfs_fs_info *fs_info = eb->fs_info;
-
-       if (!btrfs_is_zoned(fs_info) ||
-           btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN) ||
-           !list_empty(&eb->release_list))
+       if (!btrfs_is_zoned(eb->fs_info) ||
+           btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN))
                return;
 
+       ASSERT(!test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
+
        memzero_extent_buffer(eb, 0, eb->len);
        set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
        set_extent_buffer_dirty(eb);
        set_extent_bits_nowait(&trans->dirty_pages, eb->start,
                               eb->start + eb->len - 1, EXTENT_DIRTY);
-
-       spin_lock(&trans->releasing_ebs_lock);
-       list_add_tail(&eb->release_list, &trans->releasing_ebs);
-       spin_unlock(&trans->releasing_ebs_lock);
-       atomic_inc(&eb->refs);
-}
-
-void btrfs_free_redirty_list(struct btrfs_transaction *trans)
-{
-       spin_lock(&trans->releasing_ebs_lock);
-       while (!list_empty(&trans->releasing_ebs)) {
-               struct extent_buffer *eb;
-
-               eb = list_first_entry(&trans->releasing_ebs,
-                                     struct extent_buffer, release_list);
-               list_del_init(&eb->release_list);
-               free_extent_buffer(eb);
-       }
-       spin_unlock(&trans->releasing_ebs_lock);
 }
 
 bool btrfs_use_zone_append(struct btrfs_bio *bbio)
index c0570d35fea291ccd0bc2295396917db53961291..3058ef559c98135b9f875b6128af2bb09be3189c 100644 (file)
@@ -54,7 +54,6 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new);
 void btrfs_calc_zone_unusable(struct btrfs_block_group *cache);
 void btrfs_redirty_list_add(struct btrfs_transaction *trans,
                            struct extent_buffer *eb);
-void btrfs_free_redirty_list(struct btrfs_transaction *trans);
 bool btrfs_use_zone_append(struct btrfs_bio *bbio);
 void btrfs_record_physical_zoned(struct btrfs_bio *bbio);
 void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered);
@@ -179,7 +178,6 @@ static inline void btrfs_calc_zone_unusable(struct btrfs_block_group *cache) { }
 
 static inline void btrfs_redirty_list_add(struct btrfs_transaction *trans,
                                          struct extent_buffer *eb) { }
-static inline void btrfs_free_redirty_list(struct btrfs_transaction *trans) { }
 
 static inline bool btrfs_use_zone_append(struct btrfs_bio *bbio)
 {