aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-defrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-defrag.c')
-rw-r--r--fs/btrfs/tree-defrag.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index c02e2bf2f028..155961c7b4d5 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -198,6 +198,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
198 goto out; 198 goto out;
199 } 199 }
200 if (root->defrag_progress.objectid == 0) { 200 if (root->defrag_progress.objectid == 0) {
201 u32 nritems;
202
203 nritems = btrfs_header_nritems(root->node);
204 root->defrag_max.objectid = 0;
205 /* from above we know this is not a leaf */
206 btrfs_node_key_to_cpu(root->node, &root->defrag_max,
207 nritems - 1);
201 extent_buffer_get(root->node); 208 extent_buffer_get(root->node);
202 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); 209 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
203 BUG_ON(ret); 210 BUG_ON(ret);
@@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
254out: 261out:
255 if (path) 262 if (path)
256 btrfs_free_path(path); 263 btrfs_free_path(path);
264 if (ret == -EAGAIN) {
265 if (root->defrag_max.objectid > root->defrag_progress.objectid)
266 goto done;
267 if (root->defrag_max.type > root->defrag_progress.type)
268 goto done;
269 if (root->defrag_max.offset > root->defrag_progress.offset)
270 goto done;
271 ret = 0;
272 }
273done:
257 if (ret != -EAGAIN) { 274 if (ret != -EAGAIN) {
258 memset(&root->defrag_progress, 0, 275 memset(&root->defrag_progress, 0,
259 sizeof(root->defrag_progress)); 276 sizeof(root->defrag_progress));