diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 37401cc04a6b..df02ed25b7db 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -982,14 +982,26 @@ void btrfs_lock_and_flush_ordered_range(struct extent_io_tree *tree, struct extent_state **cached_state) { struct btrfs_ordered_extent *ordered; + struct extent_state *cachedp = NULL; + + if (cached_state) + cachedp = *cached_state; while (1) { - lock_extent_bits(tree, start, end, cached_state); + lock_extent_bits(tree, start, end, &cachedp); ordered = btrfs_lookup_ordered_range(inode, start, end - start + 1); - if (!ordered) + if (!ordered) { + /* + * If no external cached_state has been passed then + * decrement the extra ref taken for cachedp since we + * aren't exposing it outside of this function + */ + if (!cached_state) + refcount_dec(&cachedp->refs); break; - unlock_extent_cached(tree, start, end, cached_state); + } + unlock_extent_cached(tree, start, end, &cachedp); btrfs_start_ordered_extent(&inode->vfs_inode, ordered, 1); btrfs_put_ordered_extent(ordered); }