Message ID | cbbf1064-dc95-b1e2-94d9-b3b2879913d8@suse.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
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@jamponi.net> > Signed-off-by: Jeff Mahoney <jeffm@suse.com> > --- > 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. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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@jamponi.net> >> Signed-off-by: Jeff Mahoney <jeffm@suse.com> >> --- >> 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
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++; btrfs_debug(fs_info, "run_delayed_extent_op returned %d", ret);
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@jamponi.net> Signed-off-by: Jeff Mahoney <jeffm@suse.com> --- fs/btrfs/extent-tree.c | 1 + 1 file changed, 1 insertion(+)