Skip to content

Commit a57c2d4

Browse files
fdmananakdave
authored andcommitted
btrfs: assert delayed node locked when removing delayed item
When removing a delayed item, or releasing which will remove it as well, we will modify one of the delayed node's rbtrees and item counter if the delayed item is in one of the rbtrees. This require having the delayed node's mutex locked, otherwise we will race with other tasks modifying the rbtrees and the counter. This is motivated by a previous version of another patch actually calling btrfs_release_delayed_item() after unlocking the delayed node's mutex and against a delayed item that is in a rbtree. So assert at __btrfs_remove_delayed_item() that the delayed node's mutex is locked. Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 2c58c39 commit a57c2d4

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

fs/btrfs/delayed-inode.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,25 +412,29 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root)
412412

413413
static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
414414
{
415+
struct btrfs_delayed_node *delayed_node = delayed_item->delayed_node;
415416
struct rb_root_cached *root;
416417
struct btrfs_delayed_root *delayed_root;
417418

418419
/* Not inserted, ignore it. */
419420
if (RB_EMPTY_NODE(&delayed_item->rb_node))
420421
return;
421422

422-
delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
423+
/* If it's in a rbtree, then we need to have delayed node locked. */
424+
lockdep_assert_held(&delayed_node->mutex);
425+
426+
delayed_root = delayed_node->root->fs_info->delayed_root;
423427

424428
BUG_ON(!delayed_root);
425429

426430
if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM)
427-
root = &delayed_item->delayed_node->ins_root;
431+
root = &delayed_node->ins_root;
428432
else
429-
root = &delayed_item->delayed_node->del_root;
433+
root = &delayed_node->del_root;
430434

431435
rb_erase_cached(&delayed_item->rb_node, root);
432436
RB_CLEAR_NODE(&delayed_item->rb_node);
433-
delayed_item->delayed_node->count--;
437+
delayed_node->count--;
434438

435439
finish_one_item(delayed_root);
436440
}

0 commit comments

Comments
 (0)