Commit a929904c authored by David Sterba's avatar David Sterba
Browse files

btrfs: add unlikely annotations to branches leading to transaction abort



The unlikely() annotation is a static prediction hint that compiler may
use to reorder code out of hot path. We use it elsewhere (namely
tree-checker.c) for error branches that almost never happen.

Transaction abort is one such error, the btrfs_abort_transaction()
inlines code to check the state and print a warning, this ought to be
out of the hot path.

The most common pattern is when transaction abort is called after
checking a return value and the control flow leads to a quick return.
In other cases it may not be necessary to add unlikely() e.g. when the
function returns anyway or the control flow is not changed noticeably.

Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent cc53bd20
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -3248,7 +3248,7 @@ static int cache_save_setup(struct btrfs_block_group *block_group,
	 */
	BTRFS_I(inode)->generation = 0;
	ret = btrfs_update_inode(trans, BTRFS_I(inode));
	if (ret) {
	if (unlikely(ret)) {
		/*
		 * So theoretically we could recover from this, simply set the
		 * super cache generation to 0 so we know to invalidate the
@@ -3995,7 +3995,7 @@ static struct btrfs_block_group *do_chunk_alloc(struct btrfs_trans_handle *trans
		struct btrfs_space_info *sys_space_info;

		sys_space_info = btrfs_find_space_info(trans->fs_info, sys_flags);
		if (!sys_space_info) {
		if (unlikely(!sys_space_info)) {
			ret = -EINVAL;
			btrfs_abort_transaction(trans, ret);
			goto out;
@@ -4009,17 +4009,17 @@ static struct btrfs_block_group *do_chunk_alloc(struct btrfs_trans_handle *trans
		}

		ret = btrfs_chunk_alloc_add_chunk_item(trans, sys_bg);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}

		ret = btrfs_chunk_alloc_add_chunk_item(trans, bg);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}
	} else if (ret) {
	} else if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto out;
	}
+25 −25
Original line number Diff line number Diff line
@@ -293,11 +293,11 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,

	if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) {
		ret = btrfs_inc_ref(trans, root, cow, 1);
		if (ret)
		if (unlikely(ret))
			btrfs_abort_transaction(trans, ret);
	} else {
		ret = btrfs_inc_ref(trans, root, cow, 0);
		if (ret)
		if (unlikely(ret))
			btrfs_abort_transaction(trans, ret);
	}
	if (ret) {
@@ -536,14 +536,14 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
	write_extent_buffer_fsid(cow, fs_info->fs_devices->metadata_uuid);

	ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto error_unlock_cow;
	}

	if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
		ret = btrfs_reloc_cow_block(trans, root, buf, cow);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto error_unlock_cow;
		}
@@ -556,7 +556,7 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
			parent_start = buf->start;

		ret = btrfs_tree_mod_log_insert_root(root->node, cow, true);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto error_unlock_cow;
		}
@@ -567,7 +567,7 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
					    parent_start, last_ref);
		free_extent_buffer(buf);
		add_root_to_dirty_list(root);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto error_unlock_cow;
		}
@@ -575,7 +575,7 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
		WARN_ON(trans->transid != btrfs_header_generation(parent));
		ret = btrfs_tree_mod_log_insert_key(parent, parent_slot,
						    BTRFS_MOD_LOG_KEY_REPLACE);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto error_unlock_cow;
		}
@@ -586,14 +586,14 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
		btrfs_mark_buffer_dirty(trans, parent);
		if (last_ref) {
			ret = btrfs_tree_mod_log_free_eb(buf);
			if (ret) {
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto error_unlock_cow;
			}
		}
		ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
					    parent_start, last_ref);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto error_unlock_cow;
		}
@@ -922,7 +922,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
		}

		ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_tree_unlock(child);
			free_extent_buffer(child);
			btrfs_abort_transaction(trans, ret);
@@ -944,7 +944,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
		ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
		/* once for the root ptr */
		free_extent_buffer_stale(mid);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}
@@ -1019,7 +1019,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
						    right, 0, 1);
			free_extent_buffer_stale(right);
			right = NULL;
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
@@ -1028,7 +1028,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
			btrfs_node_key(right, &right_key, 0);
			ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
					BTRFS_MOD_LOG_KEY_REPLACE);
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
@@ -1080,7 +1080,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
		ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
		free_extent_buffer_stale(mid);
		mid = NULL;
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}
@@ -1090,7 +1090,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
		btrfs_node_key(mid, &mid_key, 0);
		ret = btrfs_tree_mod_log_insert_key(parent, pslot,
						    BTRFS_MOD_LOG_KEY_REPLACE);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}
@@ -1195,7 +1195,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
			btrfs_node_key(mid, &disk_key, 0);
			ret = btrfs_tree_mod_log_insert_key(parent, pslot,
					BTRFS_MOD_LOG_KEY_REPLACE);
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_tree_unlock(left);
				free_extent_buffer(left);
				btrfs_abort_transaction(trans, ret);
@@ -1255,7 +1255,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
			btrfs_node_key(right, &disk_key, 0);
			ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
					BTRFS_MOD_LOG_KEY_REPLACE);
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_tree_unlock(right);
				free_extent_buffer(right);
				btrfs_abort_transaction(trans, ret);
@@ -2737,7 +2737,7 @@ static int push_node_left(struct btrfs_trans_handle *trans,
		return ret;
	}
	ret = btrfs_tree_mod_log_eb_copy(dst, src, dst_nritems, 0, push_items);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		return ret;
	}
@@ -2822,7 +2822,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans,

	ret = btrfs_tree_mod_log_eb_copy(dst, src, 0, src_nritems - push_items,
					 push_items);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		return ret;
	}
@@ -2892,7 +2892,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,

		btrfs_clear_buffer_dirty(trans, c);
		ret2 = btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1);
		if (ret2 < 0)
		if (unlikely(ret2 < 0))
			btrfs_abort_transaction(trans, ret2);
		btrfs_tree_unlock(c);
		free_extent_buffer(c);
@@ -2937,7 +2937,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans,
		if (level) {
			ret = btrfs_tree_mod_log_insert_move(lower, slot + 1,
					slot, nritems - slot);
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_abort_transaction(trans, ret);
				return ret;
			}
@@ -2950,7 +2950,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans,
	if (level) {
		ret = btrfs_tree_mod_log_insert_key(lower, slot,
						    BTRFS_MOD_LOG_KEY_ADD);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
@@ -3026,7 +3026,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
	ASSERT(btrfs_header_level(c) == level);

	ret = btrfs_tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_tree_unlock(split);
		free_extent_buffer(split);
		btrfs_abort_transaction(trans, ret);
@@ -4383,7 +4383,7 @@ int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		if (level) {
			ret = btrfs_tree_mod_log_insert_move(parent, slot,
					slot + 1, nritems - slot - 1);
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_abort_transaction(trans, ret);
				return ret;
			}
@@ -4396,7 +4396,7 @@ int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
	} else if (level) {
		ret = btrfs_tree_mod_log_insert_key(parent, slot,
						    BTRFS_MOD_LOG_KEY_REMOVE);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
+3 −3
Original line number Diff line number Diff line
@@ -1038,7 +1038,7 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
		 * transaction, because we could leave the inode with the
		 * improper counts behind.
		 */
		if (ret != -ENOENT)
		if (unlikely(ret != -ENOENT))
			btrfs_abort_transaction(trans, ret);
		goto out;
	}
@@ -1066,7 +1066,7 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,

		btrfs_release_path(path);
		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto err_out;
		}
@@ -1175,7 +1175,7 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr)
	while (curr_node && (!count || nr--)) {
		ret = __btrfs_commit_inode_delayed_items(trans, path,
							 curr_node);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}
+19 −19
Original line number Diff line number Diff line
@@ -2157,7 +2157,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, u64 min_bytes)
	delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
#endif
	ret = __btrfs_run_delayed_refs(trans, min_bytes);
	if (ret < 0) {
	if (unlikely(ret < 0)) {
		btrfs_abort_transaction(trans, ret);
		return ret;
	}
@@ -2982,26 +2982,26 @@ static int do_free_extent_accounting(struct btrfs_trans_handle *trans,

		csum_root = btrfs_csum_root(trans->fs_info, bytenr);
		ret = btrfs_del_csums(trans, csum_root, bytenr, num_bytes);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}

		ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
	}

	ret = btrfs_record_squota_delta(trans->fs_info, delta);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		return ret;
	}

	ret = btrfs_add_to_free_space_tree(trans, bytenr, num_bytes);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		return ret;
	}
@@ -3115,7 +3115,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,

	is_data = owner_objectid >= BTRFS_FIRST_FREE_OBJECTID;

	if (!is_data && refs_to_drop != 1) {
	if (unlikely(!is_data && refs_to_drop != 1)) {
		btrfs_crit(info,
"invalid refs_to_drop, dropping more than 1 refs for tree block %llu refs_to_drop %u",
			   node->bytenr, refs_to_drop);
@@ -3172,7 +3172,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
			/* Must be SHARED_* item, remove the backref first */
			ret = remove_extent_backref(trans, extent_root, path,
						    NULL, refs_to_drop, is_data);
			if (ret) {
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
@@ -3221,7 +3221,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
			"umm, got %d back from search, was looking for %llu, slot %d",
					  ret, bytenr, path->slots[0]);
			}
			if (ret < 0) {
			if (unlikely(ret < 0)) {
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
@@ -3298,7 +3298,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
		if (found_extent) {
			ret = remove_extent_backref(trans, extent_root, path,
						    iref, refs_to_drop, is_data);
			if (ret) {
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
@@ -3363,7 +3363,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,

		ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
				      num_to_del);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			goto out;
		}
@@ -5472,17 +5472,17 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
	if (!(wc->flags[level] & flag)) {
		ASSERT(path->locks[level]);
		ret = btrfs_inc_ref(trans, root, eb, 1);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
		ret = btrfs_dec_ref(trans, root, eb, 0);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
		ret = btrfs_set_disk_extent_flags(trans, eb, flag);
		if (ret) {
		if (unlikely(ret)) {
			btrfs_abort_transaction(trans, ret);
			return ret;
		}
@@ -5885,7 +5885,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
				}
			} else {
				ret = btrfs_dec_ref(trans, root, eb, 0);
				if (ret) {
				if (unlikely(ret)) {
					btrfs_abort_transaction(trans, ret);
					return ret;
				}
@@ -6180,13 +6180,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, bool update_ref, bool for_reloc
	while (1) {

		ret = walk_down_tree(trans, root, path, wc);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}

		ret = walk_up_tree(trans, root, path, wc, BTRFS_MAX_LEVEL);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			break;
		}
@@ -6213,7 +6213,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, bool update_ref, bool for_reloc
			ret = btrfs_update_root(trans, tree_root,
						&root->root_key,
						root_item);
			if (ret) {
			if (unlikely(ret)) {
				btrfs_abort_transaction(trans, ret);
				goto out_end_trans;
			}
@@ -6249,7 +6249,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, bool update_ref, bool for_reloc
		goto out_end_trans;

	ret = btrfs_del_root(trans, &root->root_key);
	if (ret) {
	if (unlikely(ret)) {
		btrfs_abort_transaction(trans, ret);
		goto out_end_trans;
	}
@@ -6257,7 +6257,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, bool update_ref, bool for_reloc
	if (!is_reloc_root) {
		ret = btrfs_find_root(tree_root, &root->root_key, path,
				      NULL, NULL);
		if (ret < 0) {
		if (unlikely(ret < 0)) {
			btrfs_abort_transaction(trans, ret);
			goto out_end_trans;
		} else if (ret > 0) {
+1 −1
Original line number Diff line number Diff line
@@ -1011,7 +1011,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
			 * item changed size or key
			 */
			ret = btrfs_split_item(trans, root, path, &key, offset);
			if (ret && ret != -EAGAIN) {
			if (unlikely(ret && ret != -EAGAIN)) {
				btrfs_abort_transaction(trans, ret);
				break;
			}
Loading