summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorFilipe Manana2014-11-03 15:12:57 +0100
committerChris Mason2014-11-21 02:20:06 +0100
commitc7bc6319c59cc791743cf1b6e98f86be69444495 (patch)
treeab6180b41c0dab292280b217fe88e3c24fbcf531 /fs/btrfs/extent_io.c
parentBtrfs: don't take the chunk_mutex/dev_list mutex in statfs V2 (diff)
downloadkernel-qcow2-linux-c7bc6319c59cc791743cf1b6e98f86be69444495.tar.gz
kernel-qcow2-linux-c7bc6319c59cc791743cf1b6e98f86be69444495.tar.xz
kernel-qcow2-linux-c7bc6319c59cc791743cf1b6e98f86be69444495.zip
Btrfs: avoid premature -ENOMEM in clear_extent_bit()
We try to allocate an extent state structure before acquiring the extent state tree's spinlock as we might need a new one later and therefore avoid doing later an atomic allocation while holding the tree's spinlock. However we returned -ENOMEM if that initial non-atomic allocation failed, which is a bit excessive since we might end up not needing the pre-allocated extent state at all - for the case where the tree doesn't have any extent states that cover the input range and cover too any other range. Therefore don't return -ENOMEM if that pre-allocation fails. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 654ed3de0054..4ebabd237153 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -595,9 +595,14 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
clear = 1;
again:
if (!prealloc && (mask & __GFP_WAIT)) {
+ /*
+ * Don't care for allocation failure here because we might end
+ * up not needing the pre-allocated extent state at all, which
+ * is the case if we only have in the tree extent states that
+ * cover our input range and don't cover too any other range.
+ * If we end up needing a new extent state we allocate it later.
+ */
prealloc = alloc_extent_state(mask);
- if (!prealloc)
- return -ENOMEM;
}
spin_lock(&tree->lock);