|
@@ -439,6 +439,15 @@ static int clear_state_bit(struct extent_io_tree *tree,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static struct extent_state *
|
|
|
+alloc_extent_state_atomic(struct extent_state *prealloc)
|
|
|
+{
|
|
|
+ if (!prealloc)
|
|
|
+ prealloc = alloc_extent_state(GFP_ATOMIC);
|
|
|
+
|
|
|
+ return prealloc;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* clear some bits on a range in the tree. This may require splitting
|
|
|
* or inserting elements in the tree, so the gfp mask is used to
|
|
@@ -476,8 +485,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
|
|
|
again:
|
|
|
if (!prealloc && (mask & __GFP_WAIT)) {
|
|
|
prealloc = alloc_extent_state(mask);
|
|
|
- if (!prealloc)
|
|
|
- return -ENOMEM;
|
|
|
+ BUG_ON(!prealloc);
|
|
|
}
|
|
|
|
|
|
spin_lock(&tree->lock);
|
|
@@ -529,8 +537,8 @@ hit_next:
|
|
|
*/
|
|
|
|
|
|
if (state->start < start) {
|
|
|
- if (!prealloc)
|
|
|
- prealloc = alloc_extent_state(GFP_ATOMIC);
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = split_state(tree, state, prealloc, start);
|
|
|
BUG_ON(err == -EEXIST);
|
|
|
prealloc = NULL;
|
|
@@ -551,8 +559,8 @@ hit_next:
|
|
|
* on the first half
|
|
|
*/
|
|
|
if (state->start <= end && state->end > end) {
|
|
|
- if (!prealloc)
|
|
|
- prealloc = alloc_extent_state(GFP_ATOMIC);
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = split_state(tree, state, prealloc, end + 1);
|
|
|
BUG_ON(err == -EEXIST);
|
|
|
if (wake)
|
|
@@ -725,8 +733,7 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
|
|
|
again:
|
|
|
if (!prealloc && (mask & __GFP_WAIT)) {
|
|
|
prealloc = alloc_extent_state(mask);
|
|
|
- if (!prealloc)
|
|
|
- return -ENOMEM;
|
|
|
+ BUG_ON(!prealloc);
|
|
|
}
|
|
|
|
|
|
spin_lock(&tree->lock);
|
|
@@ -743,6 +750,8 @@ again:
|
|
|
*/
|
|
|
node = tree_search(tree, start);
|
|
|
if (!node) {
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = insert_state(tree, prealloc, start, end, &bits);
|
|
|
prealloc = NULL;
|
|
|
BUG_ON(err == -EEXIST);
|
|
@@ -811,6 +820,9 @@ hit_next:
|
|
|
err = -EEXIST;
|
|
|
goto out;
|
|
|
}
|
|
|
+
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = split_state(tree, state, prealloc, start);
|
|
|
BUG_ON(err == -EEXIST);
|
|
|
prealloc = NULL;
|
|
@@ -841,6 +853,9 @@ hit_next:
|
|
|
this_end = end;
|
|
|
else
|
|
|
this_end = last_start - 1;
|
|
|
+
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = insert_state(tree, prealloc, start, this_end,
|
|
|
&bits);
|
|
|
BUG_ON(err == -EEXIST);
|
|
@@ -865,6 +880,9 @@ hit_next:
|
|
|
err = -EEXIST;
|
|
|
goto out;
|
|
|
}
|
|
|
+
|
|
|
+ prealloc = alloc_extent_state_atomic(prealloc);
|
|
|
+ BUG_ON(!prealloc);
|
|
|
err = split_state(tree, state, prealloc, end + 1);
|
|
|
BUG_ON(err == -EEXIST);
|
|
|
|