u64 log_root_level;
mutex_lock(&root->log_mutex);
+ trace_btrfs_sync_log_enter(trans, root, ctx);
log_transid = ctx->log_transid;
if (root->log_transid_committed >= log_transid) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ctx->log_ret);
mutex_unlock(&root->log_mutex);
return ctx->log_ret;
}
index1 = log_transid % 2;
if (atomic_read(&root->log_commit[index1])) {
wait_log_commit(root, log_transid);
+ trace_btrfs_sync_log_exit(trans, root, ctx, ctx->log_ret);
mutex_unlock(&root->log_mutex);
return ctx->log_ret;
}
/* bail out if we need to do a full commit */
if (btrfs_need_log_full_commit(trans)) {
ret = BTRFS_LOG_FORCE_COMMIT;
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
mutex_unlock(&root->log_mutex);
goto out;
}
if (ret == -EAGAIN && btrfs_is_zoned(fs_info))
ret = 0;
if (ret) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
blk_finish_plug(&plug);
btrfs_set_log_full_commit(trans);
mutex_unlock(&root->log_mutex);
if (!log_root_tree->node) {
ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
if (ret) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
mutex_unlock(&fs_info->tree_root->log_mutex);
blk_finish_plug(&plug);
goto out;
*/
ret = update_log_root(trans, log, &new_root_item);
if (ret) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
list_del_init(&root_log_ctx.list);
blk_finish_plug(&plug);
btrfs_set_log_full_commit(trans);
list_del_init(&root_log_ctx.list);
mutex_unlock(&log_root_tree->log_mutex);
ret = root_log_ctx.log_ret;
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
goto out;
}
mutex_unlock(&log_root_tree->log_mutex);
if (!ret)
ret = root_log_ctx.log_ret;
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
goto out;
}
ASSERT(root_log_ctx.log_transid == log_root_tree->log_transid,
btrfs_wait_tree_log_extents(log, mark);
mutex_unlock(&log_root_tree->log_mutex);
ret = BTRFS_LOG_FORCE_COMMIT;
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
goto out_wake_log_root;
}
* deadlock. Bail out to the full commit instead.
*/
if (ret == -EAGAIN && btrfs_is_zoned(fs_info)) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
btrfs_set_log_full_commit(trans);
btrfs_wait_tree_log_extents(log, mark);
mutex_unlock(&log_root_tree->log_mutex);
goto out_wake_log_root;
} else if (ret) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
btrfs_set_log_full_commit(trans);
mutex_unlock(&log_root_tree->log_mutex);
goto out_wake_log_root;
ret = btrfs_wait_tree_log_extents(log_root_tree,
EXTENT_DIRTY_LOG1 | EXTENT_DIRTY_LOG2);
if (ret) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
btrfs_set_log_full_commit(trans);
mutex_unlock(&log_root_tree->log_mutex);
goto out_wake_log_root;
*/
if (unlikely(BTRFS_FS_ERROR(fs_info))) {
ret = -EIO;
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
btrfs_set_log_full_commit(trans);
btrfs_abort_transaction(trans, ret);
mutex_unlock(&fs_info->tree_log_mutex);
ret = write_all_supers(trans);
mutex_unlock(&fs_info->tree_log_mutex);
if (unlikely(ret)) {
+ trace_btrfs_sync_log_exit(trans, root, ctx, ret);
btrfs_set_log_full_commit(trans);
btrfs_abort_transaction(trans, ret);
goto out_wake_log_root;
__entry->ino, __entry->old_dir_ino, __entry->ret)
);
+/* Ideally call this while under root->log_mutex (but not always possible). */
+TRACE_EVENT(btrfs_sync_log_enter,
+
+ TP_PROTO(const struct btrfs_trans_handle *trans,
+ const struct btrfs_root *root,
+ const struct btrfs_log_ctx *ctx),
+
+ TP_ARGS(trans, root, ctx),
+
+ TP_STRUCT__entry_btrfs(
+ __field( u64, root_objectid )
+ __field( u64, transid )
+ __field( int, ctx_log_transid )
+ __field( int, root_log_transid )
+ __field( int, log_transid_committed )
+ __field( bool, log_committing )
+ __field( bool, log_committing_prev )
+ __field( int, log_writers )
+ ),
+
+ TP_fast_assign(
+ TP_fast_assign_fsid(trans->fs_info);
+ __entry->root_objectid = btrfs_root_id(root);
+ __entry->transid = trans->transid;
+ __entry->ctx_log_transid = ctx->log_transid;
+ __entry->root_log_transid = btrfs_get_root_log_transid(root);
+ __entry->log_transid_committed =
+ data_race(root->log_transid_committed);
+ __entry->log_committing =
+ atomic_read(&root->log_commit[ctx->log_transid % 2]);
+ __entry->log_committing_prev =
+ atomic_read(&root->log_commit[(ctx->log_transid + 1) % 2]);
+ __entry->log_writers = atomic_read(&root->log_writers);
+ ),
+
+ TP_printk_btrfs("root=%llu(%s) transid=%llu ctx_log_transid=%d"
+ " root_log_transid=%d log_transid_committed=%d"
+ " log_committing=%d log_committing_prev=%d log_writers=%d",
+ show_root_type(__entry->root_objectid), __entry->transid,
+ __entry->ctx_log_transid, __entry->root_log_transid,
+ __entry->log_transid_committed, __entry->log_committing,
+ __entry->log_committing_prev, __entry->log_writers)
+);
+
+/*
+ * Ideally call this while under root->log_mutex and in the same critical
+ * section that calls the btrfs_sync_log_enter() trace event (though it's not
+ * always possible).
+ */
+TRACE_EVENT(btrfs_sync_log_exit,
+
+ TP_PROTO(const struct btrfs_trans_handle *trans,
+ const struct btrfs_root *root,
+ const struct btrfs_log_ctx *ctx,
+ int ret),
+
+ TP_ARGS(trans, root, ctx, ret),
+
+ TP_STRUCT__entry_btrfs(
+ __field( u64, root_objectid )
+ __field( u64, transid )
+ __field( int, ctx_log_transid )
+ __field( int, root_log_transid )
+ __field( int, log_transid_committed )
+ __field( int, ret )
+ ),
+
+ TP_fast_assign(
+ TP_fast_assign_fsid(trans->fs_info);
+ __entry->root_objectid = btrfs_root_id(root);
+ __entry->transid = trans->transid;
+ __entry->ctx_log_transid = ctx->log_transid;
+ __entry->root_log_transid = btrfs_get_root_log_transid(root);
+ __entry->log_transid_committed =
+ data_race(root->log_transid_committed);
+ __entry->ret = ret;
+ ),
+
+ TP_printk_btrfs("root=%llu(%s) transid=%llu ctx_log_transid=%d"
+ " root_log_transid=%d log_transid_committed=%d ret=%d",
+ show_root_type(__entry->root_objectid), __entry->transid,
+ __entry->ctx_log_transid, __entry->root_log_transid,
+ __entry->log_transid_committed, __entry->ret)
+);
+
TRACE_EVENT(btrfs_sync_fs,
TP_PROTO(const struct btrfs_fs_info *fs_info, int wait),