summaryrefslogtreecommitdiff
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2018-03-08 09:21:07 -0600
committerRob Herring <robh@kernel.org>2018-03-08 09:21:07 -0600
commitc679fa6e3aaa5c58fc514b5b88cfa82774b8d390 (patch)
tree0c10b339368bd1795152a66a4e245e6f654fb3ec /fs/btrfs/backref.c
parentbdb7013df910681f84eff27b07791d4c160cb76f (diff)
parent4fd98e374fd377ae0458a9dc44aa779cf9631ddd (diff)
Merge branch 'dtc-update' into dt/next
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index e4054e533f6d..f94b2d8c744a 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1264,7 +1264,16 @@ again:
while (node) {
ref = rb_entry(node, struct prelim_ref, rbnode);
node = rb_next(&ref->rbnode);
- WARN_ON(ref->count < 0);
+ /*
+ * ref->count < 0 can happen here if there are delayed
+ * refs with a node->action of BTRFS_DROP_DELAYED_REF.
+ * prelim_ref_insert() relies on this when merging
+ * identical refs to keep the overall count correct.
+ * prelim_ref_insert() will merge only those refs
+ * which compare identically. Any refs having
+ * e.g. different offsets would not be merged,
+ * and would retain their original ref->count < 0.
+ */
if (roots && ref->count && ref->root_id && ref->parent == 0) {
if (sc && sc->root_objectid &&
ref->root_id != sc->root_objectid) {