]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: tracepoints: trace transaction states during commit phase
authorFilipe Manana <fdmanana@suse.com>
Thu, 23 Apr 2026 16:05:23 +0000 (17:05 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 8 Jun 2026 13:53:34 +0000 (15:53 +0200)
Currently the trace event is fired only when a transaction is fully
complete (its state is TRANS_STATE_COMPLETED). However during a
transaction commit we go through several states and as soon as the
state reaches TRANS_STATE_UNBLOCKED, another transaction can start.
Therefore it's useful to track every transaction state changed during
the commit of a transaction, so that we can see if a new transaction
is started before the current one is completed. Add the transaction
state to the transaction commit event and call the event everytime
we change the transaction state during commit.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/transaction.c
include/trace/events/btrfs.h

index 9ff8792d71820900287793e066c410b416f9c291..aef2462b25d891af0b9ff750e885ec26889566f9 100644 (file)
@@ -2321,6 +2321,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        }
 
        cur_trans->state = TRANS_STATE_COMMIT_PREP;
+       trace_btrfs_transaction_commit(trans);
        wake_up(&fs_info->transaction_blocked_wait);
        btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP);
 
@@ -2359,6 +2360,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        }
 
        cur_trans->state = TRANS_STATE_COMMIT_START;
+       trace_btrfs_transaction_commit(trans);
        wake_up(&fs_info->transaction_blocked_wait);
        spin_unlock(&fs_info->trans_lock);
 
@@ -2414,6 +2416,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        spin_lock(&fs_info->trans_lock);
        add_pending_snapshot(trans);
        cur_trans->state = TRANS_STATE_COMMIT_DOING;
+       trace_btrfs_transaction_commit(trans);
        spin_unlock(&fs_info->trans_lock);
 
        /*
@@ -2562,6 +2565,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
 
        spin_lock(&fs_info->trans_lock);
        cur_trans->state = TRANS_STATE_UNBLOCKED;
+       trace_btrfs_transaction_commit(trans);
        fs_info->running_transaction = NULL;
        spin_unlock(&fs_info->trans_lock);
        mutex_unlock(&fs_info->reloc_mutex);
@@ -2604,6 +2608,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * which can change it.
         */
        cur_trans->state = TRANS_STATE_SUPER_COMMITTED;
+       trace_btrfs_transaction_commit(trans);
        wake_up(&cur_trans->commit_wait);
        btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
 
@@ -2620,6 +2625,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * which can change it.
         */
        cur_trans->state = TRANS_STATE_COMPLETED;
+       trace_btrfs_transaction_commit(trans);
        wake_up(&cur_trans->commit_wait);
        btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED);
 
@@ -2633,8 +2639,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        if (trans->type & __TRANS_FREEZABLE)
                sb_end_intwrite(fs_info->sb);
 
-       trace_btrfs_transaction_commit(trans);
-
        btrfs_scrub_continue(fs_info);
 
        if (current->journal_info == trans)
index e43528003848e7729db047166bbb97cc7faefec4..801f4793e00265bef6063f5a577082bb6678ec1d 100644 (file)
@@ -105,6 +105,15 @@ struct btrfs_transaction;
        EM( COMMIT_TRANS,               "COMMIT_TRANS")                 \
        EMe(RESET_ZONES,                "RESET_ZONES")
 
+#define TRANSACTION_STATES                                                     \
+       EM( TRANS_STATE_RUNNING,                "TRANS_STATE_RUNNING")          \
+       EM( TRANS_STATE_COMMIT_PREP,            "TRANS_STATE_COMMIT_PREP")      \
+       EM( TRANS_STATE_COMMIT_START,           "TRANS_STATE_COMMIT_START")     \
+       EM( TRANS_STATE_COMMIT_DOING,           "TRANS_STATE_COMMIT_DOING")     \
+       EM( TRANS_STATE_UNBLOCKED,              "TRANS_STATE_UNBLOCKED")        \
+       EM( TRANS_STATE_SUPER_COMMITTED,        "TRANS_STATE_SUPER_COMMITTED")  \
+       EMe(TRANS_STATE_COMPLETED,              "TRANS_STATE_COMPLETED")
+
 /*
  * First define the enums in the above macros to be exported to userspace via
  * TRACE_DEFINE_ENUM().
@@ -120,6 +129,7 @@ FI_TYPES
 QGROUP_RSV_TYPES
 IO_TREE_OWNER
 FLUSH_STATES
+TRANSACTION_STATES
 
 /*
  * Now redefine the EM and EMe macros to map the enums to the strings that will
@@ -208,15 +218,18 @@ TRACE_EVENT(btrfs_transaction_commit,
        TP_STRUCT__entry_btrfs(
                __field(        u64,  generation                )
                __field(        bool, in_fsync                  )
+               __field(        int,  state                     )
        ),
 
        TP_fast_assign_btrfs(trans->fs_info,
                __entry->generation     = trans->transid;
                __entry->in_fsync       = trans->in_fsync;
+               __entry->state          = trans->transaction->state;
        ),
 
-       TP_printk_btrfs("gen=%llu in_fsync=%d", __entry->generation,
-                       __entry->in_fsync)
+       TP_printk_btrfs("gen=%llu in_fsync=%d state=%d(%s)", __entry->generation,
+                       __entry->in_fsync, __entry->state,
+                       __print_symbolic(__entry->state, TRANSACTION_STATES))
 );
 
 TRACE_EVENT(btrfs_transaction_abort,