diff options
Diffstat (limited to 'fs/btrfs/backref.c')
| -rw-r--r-- | fs/btrfs/backref.c | 11 | 
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) { |