diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-04-20 12:04:26 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-04-20 12:04:26 -0400 |
commit | cfec36d75b460843403c9e1392fddedf08288c9f (patch) | |
tree | c2680c2627772aead51327fb3b21bf06ee66f72a /fs/btrfs/backref.c | |
parent | 3b7c824e9330a640312fce1b04537c684c1d602c (diff) | |
parent | b22a1fa1b34f17ef3a5cc6007e0705375de3d5dd (diff) |
Merge remote-tracking branch 'linux-stable/linux-4.15.y' into bcachefs-buffered-io-2
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 7d0dc100a09a..8a9df8003345 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1263,7 +1263,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) { @@ -1509,6 +1518,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(); } |