summaryrefslogtreecommitdiff
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-03-28 07:30:41 +0300
committerDave Airlie <airlied@redhat.com>2018-03-28 07:30:41 +0300
commit2b4f44eec2be2688511c2b617d0e1b4f94c45ba4 (patch)
tree533c03602f4ae6d6404db6fa56c88e6f83e1bebe /fs/btrfs/backref.c
parent33d009cd889490838c5db9b9339856c9e3d3facc (diff)
parent3eb2ce825ea1ad89d20f7a3b5780df850e4be274 (diff)
downloadlinux-2b4f44eec2be2688511c2b617d0e1b4f94c45ba4.tar.xz
Backmerge tag 'v4.16-rc7' into drm-next
Linux 4.16-rc7 This was requested by Daniel, and things were getting a bit hard to reconcile, most of the conflicts were trivial though.
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index e4054e533f6d..26484648d090 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) {
@@ -1510,6 +1519,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr)
if (!node)
break;
bytenr = node->val;
+ shared.share_count = 0;
cond_resched();
}