Commit 5708b9591617486bf1aa5b1a97f2c0549ec87933

Authored by Chris Mason
1 parent 18f16f7ba6

Btrfs: Tune the automatic defrag code

1) Forced defrag wasn't working properly (btrfsctl -d) because some
cache only checks were incorrect.

2) Defrag only the leaves unless in forced defrag mode.

3) Don't use complex logic to figure out if a leaf is needs defrag

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Showing 2 changed files with 26 additions and 44 deletions Side-by-side Diff

... ... @@ -161,34 +161,6 @@
161 161 return 0;
162 162 }
163 163  
164   -static int should_defrag_leaf(struct extent_buffer *leaf)
165   -{
166   - struct btrfs_key key;
167   - u32 nritems;
168   -
169   - if (btrfs_buffer_defrag(leaf))
170   - return 1;
171   -
172   - nritems = btrfs_header_nritems(leaf);
173   - if (nritems == 0)
174   - return 0;
175   -
176   - btrfs_item_key_to_cpu(leaf, &key, 0);
177   - if (key.type == BTRFS_DIR_ITEM_KEY)
178   - return 1;
179   -
180   -
181   - btrfs_item_key_to_cpu(leaf, &key, nritems - 1);
182   - if (key.type == BTRFS_DIR_ITEM_KEY)
183   - return 1;
184   - if (nritems > 4) {
185   - btrfs_item_key_to_cpu(leaf, &key, nritems / 2);
186   - if (key.type == BTRFS_DIR_ITEM_KEY)
187   - return 1;
188   - }
189   - return 0;
190   -}
191   -
192 164 int btrfs_realloc_node(struct btrfs_trans_handle *trans,
193 165 struct btrfs_root *root, struct extent_buffer *parent,
194 166 int start_slot, int cache_only, u64 *last_ret,
... ... @@ -208,6 +180,10 @@
208 180 int uptodate;
209 181 u32 blocksize;
210 182  
  183 + parent_level = btrfs_header_level(parent);
  184 + if (cache_only && parent_level != 1)
  185 + return 0;
  186 +
211 187 if (trans->transaction != root->fs_info->running_transaction) {
212 188 printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
213 189 root->fs_info->running_transaction->transid);
... ... @@ -218,7 +194,6 @@
218 194 root->fs_info->generation);
219 195 WARN_ON(1);
220 196 }
221   - parent_level = btrfs_header_level(parent);
222 197  
223 198 parent_nritems = btrfs_header_nritems(parent);
224 199 blocksize = btrfs_level_size(root, parent_level - 1);
225 200  
226 201  
227 202  
... ... @@ -227,27 +202,26 @@
227 202 if (parent_nritems == 1)
228 203 return 0;
229 204  
230   - if (root != root->fs_info->extent_root) {
231   - struct btrfs_key first_key;
232   - struct btrfs_key last_key;
233   -
234   - btrfs_node_key_to_cpu(parent, &first_key, 0);
235   - btrfs_node_key_to_cpu(parent, &last_key, parent_nritems - 1);
236   - if (first_key.objectid != last_key.objectid)
237   - return 0;
238   - }
239   -
240 205 for (i = start_slot; i < end_slot; i++) {
241 206 int close = 1;
242 207  
  208 + if (!parent->map_token) {
  209 + map_extent_buffer(parent,
  210 + btrfs_node_key_ptr_offset(i),
  211 + sizeof(struct btrfs_key_ptr),
  212 + &parent->map_token, &parent->kaddr,
  213 + &parent->map_start, &parent->map_len,
  214 + KM_USER1);
  215 + }
243 216 blocknr = btrfs_node_blockptr(parent, i);
244 217 if (last_block == 0)
245 218 last_block = blocknr;
  219 +
246 220 if (i > 0) {
247 221 other = btrfs_node_blockptr(parent, i - 1);
248 222 close = close_blocks(blocknr, other, blocksize);
249 223 }
250   - if (close && i < end_slot - 1) {
  224 + if (close && i < end_slot - 2) {
251 225 other = btrfs_node_blockptr(parent, i + 1);
252 226 close = close_blocks(blocknr, other, blocksize);
253 227 }
254 228  
... ... @@ -255,15 +229,18 @@
255 229 last_block = blocknr;
256 230 continue;
257 231 }
  232 + if (parent->map_token) {
  233 + unmap_extent_buffer(parent, parent->map_token,
  234 + KM_USER1);
  235 + parent->map_token = NULL;
  236 + }
258 237  
259 238 cur = btrfs_find_tree_block(root, blocknr, blocksize);
260 239 if (cur)
261 240 uptodate = btrfs_buffer_uptodate(cur);
262 241 else
263 242 uptodate = 0;
264   - if (!cur || !uptodate ||
265   - (parent_level != 1 && !btrfs_buffer_defrag(cur)) ||
266   - (parent_level == 1 && !should_defrag_leaf(cur))) {
  243 + if (!cur || !uptodate) {
267 244 if (cache_only) {
268 245 free_extent_buffer(cur);
269 246 continue;
270 247  
... ... @@ -287,10 +264,16 @@
287 264 break;
288 265 }
289 266 search_start = tmp->start;
  267 + last_block = tmp->start;
290 268 *last_ret = search_start;
291 269 if (parent_level == 1)
292 270 btrfs_clear_buffer_defrag(tmp);
293 271 free_extent_buffer(tmp);
  272 + }
  273 + if (parent->map_token) {
  274 + unmap_extent_buffer(parent, parent->map_token,
  275 + KM_USER1);
  276 + parent->map_token = NULL;
294 277 }
295 278 return err;
296 279 }
fs/btrfs/tree-defrag.c
... ... @@ -183,7 +183,6 @@
183 183 if (level == 0) {
184 184 goto out;
185 185 }
186   -
187 186 if (root->defrag_progress.objectid == 0) {
188 187 extent_buffer_get(root->node);
189 188 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);