On 12/20/16 1:00 PM, David Sterba wrote: > On Tue, Dec 13, 2016 at 02:33:33PM -0500, Jeff Mahoney wrote: >> In __btrfs_run_delayed_refs, the error path when run_delayed_extent_op >> fails sets locked_ref->processing = 0 but doesn't re-increment >> delayed_refs->num_heads_ready. As a result, we can end up triggering >> the WARN_ON in btrfs_select_ref_head since the head remains in the tree >> with ->processing = 0 and the ready count is off. >> >> Fixes: d7df2c796d7 (Btrfs: attach delayed ref updates to delayed ref heads) >> Reported-by: Jon Nelson <jnelson-suse@xxxxxxxxxxx> >> Signed-off-by: Jeff Mahoney <jeffm@xxxxxxxx> >> --- >> fs/btrfs/extent-tree.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c >> index 4607af3..73a8d31 100644 >> --- a/fs/btrfs/extent-tree.c >> +++ b/fs/btrfs/extent-tree.c >> @@ -2588,6 +2588,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, >> if (must_insert_reserved) >> locked_ref->must_insert_reserved = 1; >> locked_ref->processing = 0; >> + delayed_refs->num_heads_ready++; > > I think this requires spin lock/unlock around the increment, as do other > similar places that fixup num_heads_ready after previous error. > Thanks, I'll fix that. It looks like the locking for the next block up is also broken -- we unlock the locked_ref and then set ->processing = 0. I'll send a patch for that as well. -Jeff -- Jeff Mahoney SUSE Labs
Attachment:
signature.asc
Description: OpenPGP digital signature
