aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index c7e47e77723f..ee1ae00d2827 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -99,7 +99,6 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
99 if (ret) 99 if (ret)
100 return ret; 100 return ret;
101 } else { 101 } else {
102 WARN_ON(!root->ref_cows);
103 clean_tree_block(trans, root, buf); 102 clean_tree_block(trans, root, buf);
104 } 103 }
105 104
@@ -162,13 +161,14 @@ static int close_blocks(u64 blocknr, u64 other)
162 161
163int btrfs_realloc_node(struct btrfs_trans_handle *trans, 162int btrfs_realloc_node(struct btrfs_trans_handle *trans,
164 struct btrfs_root *root, struct buffer_head *parent, 163 struct btrfs_root *root, struct buffer_head *parent,
165 int cache_only) 164 int cache_only, u64 *last_ret)
166{ 165{
167 struct btrfs_node *parent_node; 166 struct btrfs_node *parent_node;
168 struct buffer_head *cur_bh; 167 struct buffer_head *cur_bh;
169 struct buffer_head *tmp_bh; 168 struct buffer_head *tmp_bh;
170 u64 blocknr; 169 u64 blocknr;
171 u64 search_start = 0; 170 u64 search_start = *last_ret;
171 u64 last_block = 0;
172 u64 other; 172 u64 other;
173 u32 parent_nritems; 173 u32 parent_nritems;
174 int start_slot; 174 int start_slot;
@@ -198,6 +198,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
198 for (i = start_slot; i < end_slot; i++) { 198 for (i = start_slot; i < end_slot; i++) {
199 int close = 1; 199 int close = 1;
200 blocknr = btrfs_node_blockptr(parent_node, i); 200 blocknr = btrfs_node_blockptr(parent_node, i);
201 if (last_block == 0)
202 last_block = blocknr;
201 if (i > 0) { 203 if (i > 0) {
202 other = btrfs_node_blockptr(parent_node, i - 1); 204 other = btrfs_node_blockptr(parent_node, i - 1);
203 close = close_blocks(blocknr, other); 205 close = close_blocks(blocknr, other);
@@ -206,8 +208,10 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
206 other = btrfs_node_blockptr(parent_node, i + 1); 208 other = btrfs_node_blockptr(parent_node, i + 1);
207 close = close_blocks(blocknr, other); 209 close = close_blocks(blocknr, other);
208 } 210 }
209 if (close) 211 if (close) {
212 last_block = blocknr;
210 continue; 213 continue;
214 }
211 215
212 cur_bh = btrfs_find_tree_block(root, blocknr); 216 cur_bh = btrfs_find_tree_block(root, blocknr);
213 if (!cur_bh || !buffer_uptodate(cur_bh) || 217 if (!cur_bh || !buffer_uptodate(cur_bh) ||
@@ -219,9 +223,9 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
219 brelse(cur_bh); 223 brelse(cur_bh);
220 cur_bh = read_tree_block(root, blocknr); 224 cur_bh = read_tree_block(root, blocknr);
221 } 225 }
222 if (search_start == 0) { 226 if (search_start == 0)
223 search_start = bh_blocknr(cur_bh) & ~((u64)65535); 227 search_start = last_block & ~((u64)65535);
224 } 228
225 err = __btrfs_cow_block(trans, root, cur_bh, parent, i, 229 err = __btrfs_cow_block(trans, root, cur_bh, parent, i,
226 &tmp_bh, search_start, 230 &tmp_bh, search_start,
227 min(8, end_slot - i)); 231 min(8, end_slot - i));