summaryrefslogtreecommitdiff
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2018-02-21 08:21:41 -0800
committerJames Morris <jmorris@namei.org>2018-02-21 08:21:41 -0800
commita02633e9b13dcb9b1a656b08f81bc8ba2d4d2294 (patch)
tree3d5ef56eee3117cd61812759a255fa293d8044b8 /fs/btrfs/backref.c
parentd21bd6898336a7892914d308d5e0868f0b863571 (diff)
parent91ab883eb21325ad80f3473633f794c78ac87f51 (diff)
Merge tag 'v4.16-rc2' into next-general
Sync to Linux 4.16-rc2 for developers to work against.
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 7d0dc100a09a..f94b2d8c744a 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -216,7 +216,8 @@ static int prelim_ref_compare(struct prelim_ref *ref1,
return 0;
}
-void update_share_count(struct share_check *sc, int oldcount, int newcount)
+static void update_share_count(struct share_check *sc, int oldcount,
+ int newcount)
{
if ((!sc) || (oldcount == 0 && newcount < 1))
return;
@@ -1263,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) {