aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-defrag.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-06-25 16:01:31 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:04 -0400
commit3f157a2fd2ad731e1ed9964fecdc5f459f04a4a4 (patch)
treedf9421e7b1d0c06d5efb8659f4317438d3d511d7 /fs/btrfs/tree-defrag.c
parent1b1e2135dc1e4efbcf25ac9ac9979316d4e1193e (diff)
Btrfs: Online btree defragmentation fixes
The btree defragger wasn't making forward progress because the new key wasn't being saved by the btrfs_search_forward function. This also disables the automatic btree defrag, it wasn't scaling well to huge filesystems. The auto-defrag needs to be done differently. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/tree-defrag.c')
-rw-r--r--fs/btrfs/tree-defrag.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index b17693f61fbc..cc2650b06952 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -32,10 +32,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
32 int wret; 32 int wret;
33 int level; 33 int level;
34 int orig_level; 34 int orig_level;
35 int i;
36 int is_extent = 0; 35 int is_extent = 0;
37 int next_key_ret = 0; 36 int next_key_ret = 0;
38 u64 last_ret = 0; 37 u64 last_ret = 0;
38 u64 min_trans = 0;
39
40 if (cache_only)
41 goto out;
39 42
40 if (root->fs_info->extent_root == root) { 43 if (root->fs_info->extent_root == root) {
41 /* 44 /*
@@ -43,10 +46,6 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
43 * we can't defrag the extent root without deadlock 46 * we can't defrag the extent root without deadlock
44 */ 47 */
45 goto out; 48 goto out;
46#if 0
47 mutex_lock(&root->fs_info->alloc_mutex);
48 is_extent = 1;
49#endif
50 } 49 }
51 50
52 if (root->ref_cows == 0 && !is_extent) 51 if (root->ref_cows == 0 && !is_extent)
@@ -84,6 +83,17 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
84 83
85 path->lowest_level = 1; 84 path->lowest_level = 1;
86 path->keep_locks = 1; 85 path->keep_locks = 1;
86 if (cache_only)
87 min_trans = root->defrag_trans_start;
88
89 ret = btrfs_search_forward(root, &key, path, cache_only, min_trans);
90 if (ret < 0)
91 goto out;
92 if (ret > 0) {
93 ret = 0;
94 goto out;
95 }
96 btrfs_release_path(root, path);
87 wret = btrfs_search_slot(trans, root, &key, path, 0, 1); 97 wret = btrfs_search_slot(trans, root, &key, path, 0, 1);
88 98
89 if (wret < 0) { 99 if (wret < 0) {
@@ -95,7 +105,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
95 goto out; 105 goto out;
96 } 106 }
97 path->slots[1] = btrfs_header_nritems(path->nodes[1]); 107 path->slots[1] = btrfs_header_nritems(path->nodes[1]);
98 next_key_ret = btrfs_find_next_key(root, path, &key, 1); 108 next_key_ret = btrfs_find_next_key(root, path, &key, 1, cache_only,
109 min_trans);
99 ret = btrfs_realloc_node(trans, root, 110 ret = btrfs_realloc_node(trans, root,
100 path->nodes[1], 0, 111 path->nodes[1], 0,
101 cache_only, &last_ret, 112 cache_only, &last_ret,
@@ -106,19 +117,9 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
106 ret = -EAGAIN; 117 ret = -EAGAIN;
107 } 118 }
108 119
109 for (i = 1; i < BTRFS_MAX_LEVEL; i++) { 120 btrfs_release_path(root, path);
110 if (path->locks[i]) {
111 btrfs_tree_unlock(path->nodes[i]);
112 path->locks[i] = 0;
113 }
114 if (path->nodes[i]) {
115 free_extent_buffer(path->nodes[i]);
116 path->nodes[i] = NULL;
117 }
118 }
119 if (is_extent) 121 if (is_extent)
120 btrfs_extent_post_op(trans, root); 122 btrfs_extent_post_op(trans, root);
121
122out: 123out:
123 if (is_extent) 124 if (is_extent)
124 mutex_unlock(&root->fs_info->alloc_mutex); 125 mutex_unlock(&root->fs_info->alloc_mutex);
@@ -138,6 +139,7 @@ done:
138 if (ret != -EAGAIN) { 139 if (ret != -EAGAIN) {
139 memset(&root->defrag_progress, 0, 140 memset(&root->defrag_progress, 0,
140 sizeof(root->defrag_progress)); 141 sizeof(root->defrag_progress));
142 root->defrag_trans_start = trans->transid;
141 } 143 }
142 return ret; 144 return ret;
143} 145}