aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-24 14:04:53 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commit0ef3e66b6700eb8f052daa8b89443ff872fbbdfc (patch)
tree26bce57770b4f093199b6f87ab8ed3a54e951337
parent515dc3228c568f9df8b634f82b3471e20205ac16 (diff)
Btrfs: Allocator fix variety pack
* Force chunk allocation when find_free_extent has to do a full scan * Record the max key at the start of defrag so it doesn't run forever * Block groups might not be contiguous, make a forward search for the next block group in extent-tree.c * Get rid of extra checks for total fs size * Fix relocate_one_reference to avoid relocating the same file data block twice when referenced by an older transaction * Use the open device count when allocating chunks so that we don't try to allocate from devices that don't exist Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c2
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/extent-tree.c273
-rw-r--r--fs/btrfs/tree-defrag.c17
-rw-r--r--fs/btrfs/volumes.c12
5 files changed, 209 insertions, 97 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 02e571e6ee62..1d404bde3cfa 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -363,7 +363,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
363 other = btrfs_node_blockptr(parent, i - 1); 363 other = btrfs_node_blockptr(parent, i - 1);
364 close = close_blocks(blocknr, other, blocksize); 364 close = close_blocks(blocknr, other, blocksize);
365 } 365 }
366 if (close && i < end_slot - 2) { 366 if (!close && i < end_slot - 2) {
367 other = btrfs_node_blockptr(parent, i + 1); 367 other = btrfs_node_blockptr(parent, i + 1);
368 close = close_blocks(blocknr, other, blocksize); 368 close = close_blocks(blocknr, other, blocksize);
369 } 369 }
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 293464c0c6ba..7b73a9c3d868 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -464,6 +464,7 @@ struct btrfs_space_info {
464 u64 bytes_used; 464 u64 bytes_used;
465 u64 bytes_pinned; 465 u64 bytes_pinned;
466 int full; 466 int full;
467 int force_alloc;
467 struct list_head list; 468 struct list_head list;
468}; 469};
469 470
@@ -589,6 +590,7 @@ struct btrfs_root {
589 int ref_cows; 590 int ref_cows;
590 int track_dirty; 591 int track_dirty;
591 struct btrfs_key defrag_progress; 592 struct btrfs_key defrag_progress;
593 struct btrfs_key defrag_max;
592 int defrag_running; 594 int defrag_running;
593 int defrag_level; 595 int defrag_level;
594 char *name; 596 char *name;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 605018c6045c..41a63462d3eb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -136,6 +136,35 @@ err:
136 return 0; 136 return 0;
137} 137}
138 138
139struct btrfs_block_group_cache *btrfs_lookup_first_block_group(struct
140 btrfs_fs_info *info,
141 u64 bytenr)
142{
143 struct extent_io_tree *block_group_cache;
144 struct btrfs_block_group_cache *block_group = NULL;
145 u64 ptr;
146 u64 start;
147 u64 end;
148 int ret;
149
150 bytenr = max_t(u64, bytenr,
151 BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE);
152 block_group_cache = &info->block_group_cache;
153 ret = find_first_extent_bit(block_group_cache,
154 bytenr, &start, &end,
155 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA |
156 BLOCK_GROUP_SYSTEM);
157 if (ret) {
158 return NULL;
159 }
160 ret = get_state_private(block_group_cache, start, &ptr);
161 if (ret)
162 return NULL;
163
164 block_group = (struct btrfs_block_group_cache *)(unsigned long)ptr;
165 return block_group;
166}
167
139struct btrfs_block_group_cache *btrfs_lookup_block_group(struct 168struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
140 btrfs_fs_info *info, 169 btrfs_fs_info *info,
141 u64 bytenr) 170 u64 bytenr)
@@ -175,7 +204,7 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits)
175 204
176static int noinline find_search_start(struct btrfs_root *root, 205static int noinline find_search_start(struct btrfs_root *root,
177 struct btrfs_block_group_cache **cache_ret, 206 struct btrfs_block_group_cache **cache_ret,
178 u64 *start_ret, int num, int data) 207 u64 *start_ret, u64 num, int data)
179{ 208{
180 int ret; 209 int ret;
181 struct btrfs_block_group_cache *cache = *cache_ret; 210 struct btrfs_block_group_cache *cache = *cache_ret;
@@ -188,21 +217,21 @@ static int noinline find_search_start(struct btrfs_root *root,
188 u64 search_start = *start_ret; 217 u64 search_start = *start_ret;
189 int wrapped = 0; 218 int wrapped = 0;
190 219
191 if (!cache)
192 goto out;
193
194 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); 220 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
195 free_space_cache = &root->fs_info->free_space_cache; 221 free_space_cache = &root->fs_info->free_space_cache;
196 222
223 if (!cache)
224 goto out;
225
197again: 226again:
198 ret = cache_block_group(root, cache); 227 ret = cache_block_group(root, cache);
199 if (ret) 228 if (ret) {
200 goto out; 229 goto out;
230 }
201 231
202 last = max(search_start, cache->key.objectid); 232 last = max(search_start, cache->key.objectid);
203 if (!block_group_bits(cache, data) || cache->ro) { 233 if (!block_group_bits(cache, data) || cache->ro)
204 goto new_group; 234 goto new_group;
205 }
206 235
207 spin_lock_irq(&free_space_cache->lock); 236 spin_lock_irq(&free_space_cache->lock);
208 state = find_first_extent_bit_state(free_space_cache, last, EXTENT_DIRTY); 237 state = find_first_extent_bit_state(free_space_cache, last, EXTENT_DIRTY);
@@ -217,20 +246,17 @@ again:
217 start = max(last, state->start); 246 start = max(last, state->start);
218 last = state->end + 1; 247 last = state->end + 1;
219 if (last - start < num) { 248 if (last - start < num) {
220 if (last == cache->key.objectid + cache->key.offset)
221 cache_miss = start;
222 do { 249 do {
223 state = extent_state_next(state); 250 state = extent_state_next(state);
224 } while(state && !(state->state & EXTENT_DIRTY)); 251 } while(state && !(state->state & EXTENT_DIRTY));
225 continue; 252 continue;
226 } 253 }
227 spin_unlock_irq(&free_space_cache->lock); 254 spin_unlock_irq(&free_space_cache->lock);
228 if (cache->ro) 255 if (cache->ro) {
229 goto new_group; 256 goto new_group;
257 }
230 if (start + num > cache->key.objectid + cache->key.offset) 258 if (start + num > cache->key.objectid + cache->key.offset)
231 goto new_group; 259 goto new_group;
232 if (start + num > total_fs_bytes)
233 goto new_group;
234 if (!block_group_bits(cache, data)) { 260 if (!block_group_bits(cache, data)) {
235 printk("block group bits don't match %Lu %d\n", cache->flags, data); 261 printk("block group bits don't match %Lu %d\n", cache->flags, data);
236 } 262 }
@@ -248,7 +274,7 @@ out:
248new_group: 274new_group:
249 last = cache->key.objectid + cache->key.offset; 275 last = cache->key.objectid + cache->key.offset;
250wrapped: 276wrapped:
251 cache = btrfs_lookup_block_group(root->fs_info, last); 277 cache = btrfs_lookup_first_block_group(root->fs_info, last);
252 if (!cache || cache->key.objectid >= total_fs_bytes) { 278 if (!cache || cache->key.objectid >= total_fs_bytes) {
253no_cache: 279no_cache:
254 if (!wrapped) { 280 if (!wrapped) {
@@ -261,13 +287,13 @@ no_cache:
261 if (cache_miss && !cache->cached) { 287 if (cache_miss && !cache->cached) {
262 cache_block_group(root, cache); 288 cache_block_group(root, cache);
263 last = cache_miss; 289 last = cache_miss;
264 cache = btrfs_lookup_block_group(root->fs_info, last); 290 cache = btrfs_lookup_first_block_group(root->fs_info, last);
265 } 291 }
292 cache_miss = 0;
266 cache = btrfs_find_block_group(root, cache, last, data, 0); 293 cache = btrfs_find_block_group(root, cache, last, data, 0);
267 if (!cache) 294 if (!cache)
268 goto no_cache; 295 goto no_cache;
269 *cache_ret = cache; 296 *cache_ret = cache;
270 cache_miss = 0;
271 goto again; 297 goto again;
272} 298}
273 299
@@ -303,28 +329,26 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
303 struct btrfs_fs_info *info = root->fs_info; 329 struct btrfs_fs_info *info = root->fs_info;
304 u64 used; 330 u64 used;
305 u64 last = 0; 331 u64 last = 0;
306 u64 hint_last;
307 u64 start; 332 u64 start;
308 u64 end; 333 u64 end;
309 u64 free_check; 334 u64 free_check;
310 u64 ptr; 335 u64 ptr;
311 u64 total_fs_bytes;
312 int bit; 336 int bit;
313 int ret; 337 int ret;
314 int full_search = 0; 338 int full_search = 0;
315 int factor = 10; 339 int factor = 10;
340 int wrapped = 0;
316 341
317 block_group_cache = &info->block_group_cache; 342 block_group_cache = &info->block_group_cache;
318 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
319 343
320 if (data & BTRFS_BLOCK_GROUP_METADATA) 344 if (data & BTRFS_BLOCK_GROUP_METADATA)
321 factor = 9; 345 factor = 9;
322 346
323 bit = block_group_state_bits(data); 347 bit = block_group_state_bits(data);
324 348
325 if (search_start && search_start < total_fs_bytes) { 349 if (search_start) {
326 struct btrfs_block_group_cache *shint; 350 struct btrfs_block_group_cache *shint;
327 shint = btrfs_lookup_block_group(info, search_start); 351 shint = btrfs_lookup_first_block_group(info, search_start);
328 if (shint && block_group_bits(shint, data) && !shint->ro) { 352 if (shint && block_group_bits(shint, data) && !shint->ro) {
329 used = btrfs_block_group_used(&shint->item); 353 used = btrfs_block_group_used(&shint->item);
330 if (used + shint->pinned < 354 if (used + shint->pinned <
@@ -333,24 +357,18 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
333 } 357 }
334 } 358 }
335 } 359 }
336 if (hint && !hint->ro && block_group_bits(hint, data) && 360 if (hint && !hint->ro && block_group_bits(hint, data)) {
337 hint->key.objectid < total_fs_bytes) {
338 used = btrfs_block_group_used(&hint->item); 361 used = btrfs_block_group_used(&hint->item);
339 if (used + hint->pinned < 362 if (used + hint->pinned <
340 div_factor(hint->key.offset, factor)) { 363 div_factor(hint->key.offset, factor)) {
341 return hint; 364 return hint;
342 } 365 }
343 last = hint->key.objectid + hint->key.offset; 366 last = hint->key.objectid + hint->key.offset;
344 hint_last = last;
345 } else { 367 } else {
346 if (hint) 368 if (hint)
347 hint_last = max(hint->key.objectid, search_start); 369 last = max(hint->key.objectid, search_start);
348 else 370 else
349 hint_last = search_start; 371 last = search_start;
350
351 if (hint_last >= total_fs_bytes)
352 hint_last = search_start;
353 last = hint_last;
354 } 372 }
355again: 373again:
356 while(1) { 374 while(1) {
@@ -360,23 +378,17 @@ again:
360 break; 378 break;
361 379
362 ret = get_state_private(block_group_cache, start, &ptr); 380 ret = get_state_private(block_group_cache, start, &ptr);
363 if (ret) 381 if (ret) {
364 break; 382 last = end + 1;
383 continue;
384 }
365 385
366 cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; 386 cache = (struct btrfs_block_group_cache *)(unsigned long)ptr;
367 last = cache->key.objectid + cache->key.offset; 387 last = cache->key.objectid + cache->key.offset;
368 used = btrfs_block_group_used(&cache->item); 388 used = btrfs_block_group_used(&cache->item);
369 389
370 if (cache->key.objectid > total_fs_bytes)
371 break;
372
373 if (!cache->ro && block_group_bits(cache, data)) { 390 if (!cache->ro && block_group_bits(cache, data)) {
374 if (full_search) 391 free_check = div_factor(cache->key.offset, factor);
375 free_check = cache->key.offset;
376 else
377 free_check = div_factor(cache->key.offset,
378 factor);
379
380 if (used + cache->pinned < free_check) { 392 if (used + cache->pinned < free_check) {
381 found_group = cache; 393 found_group = cache;
382 goto found; 394 goto found;
@@ -384,9 +396,15 @@ again:
384 } 396 }
385 cond_resched(); 397 cond_resched();
386 } 398 }
387 if (!full_search) { 399 if (!wrapped) {
400 last = search_start;
401 wrapped = 1;
402 goto again;
403 }
404 if (!full_search && factor < 10) {
388 last = search_start; 405 last = search_start;
389 full_search = 1; 406 full_search = 1;
407 factor = 10;
390 goto again; 408 goto again;
391 } 409 }
392found: 410found:
@@ -1070,6 +1088,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1070 found->bytes_used = bytes_used; 1088 found->bytes_used = bytes_used;
1071 found->bytes_pinned = 0; 1089 found->bytes_pinned = 0;
1072 found->full = 0; 1090 found->full = 0;
1091 found->force_alloc = 0;
1073 *space_info = found; 1092 *space_info = found;
1074 return 0; 1093 return 0;
1075} 1094}
@@ -1120,7 +1139,7 @@ static u64 reduce_alloc_profile(struct btrfs_root *root, u64 flags)
1120 1139
1121static int do_chunk_alloc(struct btrfs_trans_handle *trans, 1140static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1122 struct btrfs_root *extent_root, u64 alloc_bytes, 1141 struct btrfs_root *extent_root, u64 alloc_bytes,
1123 u64 flags) 1142 u64 flags, int force)
1124{ 1143{
1125 struct btrfs_space_info *space_info; 1144 struct btrfs_space_info *space_info;
1126 u64 thresh; 1145 u64 thresh;
@@ -1138,11 +1157,16 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1138 } 1157 }
1139 BUG_ON(!space_info); 1158 BUG_ON(!space_info);
1140 1159
1160 if (space_info->force_alloc) {
1161 force = 1;
1162 space_info->force_alloc = 0;
1163 }
1141 if (space_info->full) 1164 if (space_info->full)
1142 return 0; 1165 return 0;
1143 1166
1144 thresh = div_factor(space_info->total_bytes, 6); 1167 thresh = div_factor(space_info->total_bytes, 6);
1145 if ((space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) < 1168 if (!force &&
1169 (space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) <
1146 thresh) 1170 thresh)
1147 return 0; 1171 return 0;
1148 1172
@@ -1152,7 +1176,6 @@ printk("space info full %Lu\n", flags);
1152 space_info->full = 1; 1176 space_info->full = 1;
1153 return 0; 1177 return 0;
1154 } 1178 }
1155
1156 BUG_ON(ret); 1179 BUG_ON(ret);
1157 1180
1158 ret = btrfs_make_block_group(trans, extent_root, 0, flags, 1181 ret = btrfs_make_block_group(trans, extent_root, 0, flags,
@@ -1619,11 +1642,16 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1619 struct btrfs_block_group_cache *block_group; 1642 struct btrfs_block_group_cache *block_group;
1620 int full_scan = 0; 1643 int full_scan = 0;
1621 int wrapped = 0; 1644 int wrapped = 0;
1645 int chunk_alloc_done = 0;
1622 int empty_cluster = 2 * 1024 * 1024; 1646 int empty_cluster = 2 * 1024 * 1024;
1647 int allowed_chunk_alloc = 0;
1623 1648
1624 WARN_ON(num_bytes < root->sectorsize); 1649 WARN_ON(num_bytes < root->sectorsize);
1625 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 1650 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
1626 1651
1652 if (orig_root->ref_cows || empty_size)
1653 allowed_chunk_alloc = 1;
1654
1627 if (data & BTRFS_BLOCK_GROUP_METADATA) { 1655 if (data & BTRFS_BLOCK_GROUP_METADATA) {
1628 last_ptr = &root->fs_info->last_alloc; 1656 last_ptr = &root->fs_info->last_alloc;
1629 empty_cluster = 256 * 1024; 1657 empty_cluster = 256 * 1024;
@@ -1648,7 +1676,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1648 search_end = btrfs_super_total_bytes(&info->super_copy); 1676 search_end = btrfs_super_total_bytes(&info->super_copy);
1649 1677
1650 if (hint_byte) { 1678 if (hint_byte) {
1651 block_group = btrfs_lookup_block_group(info, hint_byte); 1679 block_group = btrfs_lookup_first_block_group(info, hint_byte);
1652 if (!block_group) 1680 if (!block_group)
1653 hint_byte = search_start; 1681 hint_byte = search_start;
1654 block_group = btrfs_find_block_group(root, block_group, 1682 block_group = btrfs_find_block_group(root, block_group,
@@ -1666,17 +1694,28 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1666 1694
1667check_failed: 1695check_failed:
1668 if (!block_group) { 1696 if (!block_group) {
1669 block_group = btrfs_lookup_block_group(info, search_start); 1697 block_group = btrfs_lookup_first_block_group(info,
1698 search_start);
1670 if (!block_group) 1699 if (!block_group)
1671 block_group = btrfs_lookup_block_group(info, 1700 block_group = btrfs_lookup_first_block_group(info,
1672 orig_search_start); 1701 orig_search_start);
1673 } 1702 }
1703 if (full_scan && !chunk_alloc_done) {
1704 if (allowed_chunk_alloc) {
1705 do_chunk_alloc(trans, root,
1706 num_bytes + 2 * 1024 * 1024, data, 1);
1707 allowed_chunk_alloc = 0;
1708 } else if (block_group && block_group_bits(block_group, data)) {
1709 block_group->space_info->force_alloc = 1;
1710 }
1711 chunk_alloc_done = 1;
1712 }
1674 ret = find_search_start(root, &block_group, &search_start, 1713 ret = find_search_start(root, &block_group, &search_start,
1675 total_needed, data); 1714 total_needed, data);
1676 if (ret == -ENOSPC && last_ptr && *last_ptr) { 1715 if (ret == -ENOSPC && last_ptr && *last_ptr) {
1677 *last_ptr = 0; 1716 *last_ptr = 0;
1678 block_group = btrfs_lookup_block_group(info, 1717 block_group = btrfs_lookup_first_block_group(info,
1679 orig_search_start); 1718 orig_search_start);
1680 search_start = orig_search_start; 1719 search_start = orig_search_start;
1681 ret = find_search_start(root, &block_group, &search_start, 1720 ret = find_search_start(root, &block_group, &search_start,
1682 total_needed, data); 1721 total_needed, data);
@@ -1692,7 +1731,7 @@ check_failed:
1692 empty_size += empty_cluster; 1731 empty_size += empty_cluster;
1693 total_needed += empty_size; 1732 total_needed += empty_size;
1694 } 1733 }
1695 block_group = btrfs_lookup_block_group(info, 1734 block_group = btrfs_lookup_first_block_group(info,
1696 orig_search_start); 1735 orig_search_start);
1697 search_start = orig_search_start; 1736 search_start = orig_search_start;
1698 ret = find_search_start(root, &block_group, 1737 ret = find_search_start(root, &block_group,
@@ -1765,7 +1804,7 @@ enospc:
1765 } else 1804 } else
1766 wrapped = 1; 1805 wrapped = 1;
1767 } 1806 }
1768 block_group = btrfs_lookup_block_group(info, search_start); 1807 block_group = btrfs_lookup_first_block_group(info, search_start);
1769 cond_resched(); 1808 cond_resched();
1770 block_group = btrfs_find_block_group(root, block_group, 1809 block_group = btrfs_find_block_group(root, block_group,
1771 search_start, data, 0); 1810 search_start, data, 0);
@@ -1819,17 +1858,21 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1819 } 1858 }
1820again: 1859again:
1821 data = reduce_alloc_profile(root, data); 1860 data = reduce_alloc_profile(root, data);
1822 if (root->ref_cows) { 1861 /*
1862 * the only place that sets empty_size is btrfs_realloc_node, which
1863 * is not called recursively on allocations
1864 */
1865 if (empty_size || root->ref_cows) {
1823 if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { 1866 if (!(data & BTRFS_BLOCK_GROUP_METADATA)) {
1824 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1867 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1825 2 * 1024 * 1024, 1868 2 * 1024 * 1024,
1826 BTRFS_BLOCK_GROUP_METADATA | 1869 BTRFS_BLOCK_GROUP_METADATA |
1827 (info->metadata_alloc_profile & 1870 (info->metadata_alloc_profile &
1828 info->avail_metadata_alloc_bits)); 1871 info->avail_metadata_alloc_bits), 0);
1829 BUG_ON(ret); 1872 BUG_ON(ret);
1830 } 1873 }
1831 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1874 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1832 num_bytes + 2 * 1024 * 1024, data); 1875 num_bytes + 2 * 1024 * 1024, data, 0);
1833 BUG_ON(ret); 1876 BUG_ON(ret);
1834 } 1877 }
1835 1878
@@ -1842,6 +1885,8 @@ again:
1842 if (ret == -ENOSPC && num_bytes > min_alloc_size) { 1885 if (ret == -ENOSPC && num_bytes > min_alloc_size) {
1843 num_bytes = num_bytes >> 1; 1886 num_bytes = num_bytes >> 1;
1844 num_bytes = max(num_bytes, min_alloc_size); 1887 num_bytes = max(num_bytes, min_alloc_size);
1888 do_chunk_alloc(trans, root->fs_info->extent_root,
1889 num_bytes, data, 1);
1845 goto again; 1890 goto again;
1846 } 1891 }
1847 if (ret) { 1892 if (ret) {
@@ -2537,7 +2582,11 @@ out:
2537 */ 2582 */
2538static int noinline relocate_one_reference(struct btrfs_root *extent_root, 2583static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2539 struct btrfs_path *path, 2584 struct btrfs_path *path,
2540 struct btrfs_key *extent_key) 2585 struct btrfs_key *extent_key,
2586 u64 *last_file_objectid,
2587 u64 *last_file_offset,
2588 u64 *last_file_root,
2589 u64 last_extent)
2541{ 2590{
2542 struct inode *inode; 2591 struct inode *inode;
2543 struct btrfs_root *found_root; 2592 struct btrfs_root *found_root;
@@ -2576,6 +2625,12 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2576 found_key.offset = ref_offset; 2625 found_key.offset = ref_offset;
2577 level = 0; 2626 level = 0;
2578 2627
2628 if (last_extent == extent_key->objectid &&
2629 *last_file_objectid == ref_objectid &&
2630 *last_file_offset == ref_offset &&
2631 *last_file_root == ref_root)
2632 goto out;
2633
2579 ret = find_root_for_ref(extent_root, path, &found_key, 2634 ret = find_root_for_ref(extent_root, path, &found_key,
2580 level, 1, &found_root, 2635 level, 1, &found_root,
2581 extent_key->objectid); 2636 extent_key->objectid);
@@ -2583,6 +2638,12 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2583 if (ret) 2638 if (ret)
2584 goto out; 2639 goto out;
2585 2640
2641 if (last_extent == extent_key->objectid &&
2642 *last_file_objectid == ref_objectid &&
2643 *last_file_offset == ref_offset &&
2644 *last_file_root == ref_root)
2645 goto out;
2646
2586 mutex_unlock(&extent_root->fs_info->fs_mutex); 2647 mutex_unlock(&extent_root->fs_info->fs_mutex);
2587 inode = btrfs_iget_locked(extent_root->fs_info->sb, 2648 inode = btrfs_iget_locked(extent_root->fs_info->sb,
2588 ref_objectid, found_root); 2649 ref_objectid, found_root);
@@ -2603,6 +2664,10 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2603 mutex_lock(&extent_root->fs_info->fs_mutex); 2664 mutex_lock(&extent_root->fs_info->fs_mutex);
2604 goto out; 2665 goto out;
2605 } 2666 }
2667 *last_file_objectid = inode->i_ino;
2668 *last_file_root = found_root->root_key.objectid;
2669 *last_file_offset = ref_offset;
2670
2606 relocate_inode_pages(inode, ref_offset, extent_key->offset); 2671 relocate_inode_pages(inode, ref_offset, extent_key->offset);
2607 iput(inode); 2672 iput(inode);
2608 mutex_lock(&extent_root->fs_info->fs_mutex); 2673 mutex_lock(&extent_root->fs_info->fs_mutex);
@@ -2643,6 +2708,8 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2643 path->nodes[i] = NULL; 2708 path->nodes[i] = NULL;
2644 } 2709 }
2645 btrfs_release_path(found_root, path); 2710 btrfs_release_path(found_root, path);
2711 if (found_root == found_root->fs_info->extent_root)
2712 btrfs_extent_post_op(trans, found_root);
2646 btrfs_end_transaction(trans, found_root); 2713 btrfs_end_transaction(trans, found_root);
2647 } 2714 }
2648 2715
@@ -2678,6 +2745,10 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
2678 struct btrfs_key key; 2745 struct btrfs_key key;
2679 struct btrfs_key found_key; 2746 struct btrfs_key found_key;
2680 struct extent_buffer *leaf; 2747 struct extent_buffer *leaf;
2748 u64 last_file_objectid = 0;
2749 u64 last_file_root = 0;
2750 u64 last_file_offset = (u64)-1;
2751 u64 last_extent = 0;
2681 u32 nritems; 2752 u32 nritems;
2682 u32 item_size; 2753 u32 item_size;
2683 int ret = 0; 2754 int ret = 0;
@@ -2722,9 +2793,13 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
2722 key.offset = found_key.offset + 1; 2793 key.offset = found_key.offset + 1;
2723 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 2794 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
2724 2795
2725 ret = relocate_one_reference(extent_root, path, extent_key); 2796 ret = relocate_one_reference(extent_root, path, extent_key,
2797 &last_file_objectid,
2798 &last_file_offset,
2799 &last_file_root, last_extent);
2726 if (ret) 2800 if (ret)
2727 goto out; 2801 goto out;
2802 last_extent = extent_key->objectid;
2728 } 2803 }
2729 ret = 0; 2804 ret = 0;
2730out: 2805out:
@@ -2770,6 +2845,32 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
2770 return flags; 2845 return flags;
2771} 2846}
2772 2847
2848int __alloc_chunk_for_shrink(struct btrfs_root *root,
2849 struct btrfs_block_group_cache *shrink_block_group,
2850 int force)
2851{
2852 struct btrfs_trans_handle *trans;
2853 u64 new_alloc_flags;
2854 u64 calc;
2855
2856 if (btrfs_block_group_used(&shrink_block_group->item) > 0) {
2857
2858 trans = btrfs_start_transaction(root, 1);
2859 new_alloc_flags = update_block_group_flags(root,
2860 shrink_block_group->flags);
2861 if (new_alloc_flags != shrink_block_group->flags) {
2862 calc =
2863 btrfs_block_group_used(&shrink_block_group->item);
2864 } else {
2865 calc = shrink_block_group->key.offset;
2866 }
2867 do_chunk_alloc(trans, root->fs_info->extent_root,
2868 calc + 2 * 1024 * 1024, new_alloc_flags, force);
2869 btrfs_end_transaction(trans, root);
2870 }
2871 return 0;
2872}
2873
2773int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start) 2874int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
2774{ 2875{
2775 struct btrfs_trans_handle *trans; 2876 struct btrfs_trans_handle *trans;
@@ -2778,7 +2879,6 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
2778 u64 cur_byte; 2879 u64 cur_byte;
2779 u64 total_found; 2880 u64 total_found;
2780 u64 shrink_last_byte; 2881 u64 shrink_last_byte;
2781 u64 new_alloc_flags;
2782 struct btrfs_block_group_cache *shrink_block_group; 2882 struct btrfs_block_group_cache *shrink_block_group;
2783 struct btrfs_fs_info *info = root->fs_info; 2883 struct btrfs_fs_info *info = root->fs_info;
2784 struct btrfs_key key; 2884 struct btrfs_key key;
@@ -2792,7 +2892,8 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
2792 shrink_start); 2892 shrink_start);
2793 BUG_ON(!shrink_block_group); 2893 BUG_ON(!shrink_block_group);
2794 2894
2795 shrink_last_byte = shrink_start + shrink_block_group->key.offset; 2895 shrink_last_byte = shrink_block_group->key.objectid +
2896 shrink_block_group->key.offset;
2796 2897
2797 shrink_block_group->space_info->total_bytes -= 2898 shrink_block_group->space_info->total_bytes -=
2798 shrink_block_group->key.offset; 2899 shrink_block_group->key.offset;
@@ -2804,23 +2905,10 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
2804 (unsigned long long)shrink_start, 2905 (unsigned long long)shrink_start,
2805 (unsigned long long)shrink_block_group->flags); 2906 (unsigned long long)shrink_block_group->flags);
2806 2907
2908 __alloc_chunk_for_shrink(root, shrink_block_group, 1);
2909
2807again: 2910again:
2808 if (btrfs_block_group_used(&shrink_block_group->item) > 0) {
2809 u64 calc;
2810 2911
2811 trans = btrfs_start_transaction(root, 1);
2812 new_alloc_flags = update_block_group_flags(root,
2813 shrink_block_group->flags);
2814 if (new_alloc_flags != shrink_block_group->flags) {
2815 calc =
2816 btrfs_block_group_used(&shrink_block_group->item);
2817 } else {
2818 calc = shrink_block_group->key.offset;
2819 }
2820 do_chunk_alloc(trans, root->fs_info->extent_root,
2821 calc + 2 * 1024 * 1024, new_alloc_flags);
2822 btrfs_end_transaction(trans, root);
2823 }
2824 shrink_block_group->ro = 1; 2912 shrink_block_group->ro = 1;
2825 2913
2826 total_found = 0; 2914 total_found = 0;
@@ -2888,6 +2976,8 @@ next:
2888 2976
2889 if (btrfs_key_type(&found_key) != BTRFS_EXTENT_ITEM_KEY || 2977 if (btrfs_key_type(&found_key) != BTRFS_EXTENT_ITEM_KEY ||
2890 found_key.objectid + found_key.offset <= cur_byte) { 2978 found_key.objectid + found_key.offset <= cur_byte) {
2979 memcpy(&key, &found_key, sizeof(key));
2980 key.offset++;
2891 path->slots[0]++; 2981 path->slots[0]++;
2892 goto next; 2982 goto next;
2893 } 2983 }
@@ -2897,6 +2987,7 @@ next:
2897 key.objectid = cur_byte; 2987 key.objectid = cur_byte;
2898 btrfs_release_path(root, path); 2988 btrfs_release_path(root, path);
2899 ret = relocate_one_extent(root, path, &found_key); 2989 ret = relocate_one_extent(root, path, &found_key);
2990 __alloc_chunk_for_shrink(root, shrink_block_group, 0);
2900 } 2991 }
2901 2992
2902 btrfs_release_path(root, path); 2993 btrfs_release_path(root, path);
@@ -2930,20 +3021,27 @@ next:
2930 if (ret < 0) 3021 if (ret < 0)
2931 goto out; 3022 goto out;
2932 3023
2933 leaf = path->nodes[0]; 3024 clear_extent_bits(&info->block_group_cache, key.objectid,
2934 nritems = btrfs_header_nritems(leaf); 3025 key.objectid + key.offset - 1,
2935 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
2936 kfree(shrink_block_group);
2937
2938 clear_extent_bits(&info->block_group_cache, found_key.objectid,
2939 found_key.objectid + found_key.offset - 1,
2940 (unsigned int)-1, GFP_NOFS); 3026 (unsigned int)-1, GFP_NOFS);
2941 3027
3028
3029 clear_extent_bits(&info->free_space_cache,
3030 key.objectid, key.objectid + key.offset - 1,
3031 (unsigned int)-1, GFP_NOFS);
3032
3033 memset(shrink_block_group, 0, sizeof(*shrink_block_group));
3034 kfree(shrink_block_group);
3035
2942 btrfs_del_item(trans, root, path); 3036 btrfs_del_item(trans, root, path);
2943 clear_extent_dirty(&info->free_space_cache,
2944 shrink_start, shrink_last_byte - 1,
2945 GFP_NOFS);
2946 btrfs_commit_transaction(trans, root); 3037 btrfs_commit_transaction(trans, root);
3038
3039 /* the code to unpin extents might set a few bits in the free
3040 * space cache for this range again
3041 */
3042 clear_extent_bits(&info->free_space_cache,
3043 key.objectid, key.objectid + key.offset - 1,
3044 (unsigned int)-1, GFP_NOFS);
2947out: 3045out:
2948 btrfs_free_path(path); 3046 btrfs_free_path(path);
2949 return ret; 3047 return ret;
@@ -3081,9 +3179,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
3081 BUG_ON(!cache); 3179 BUG_ON(!cache);
3082 cache->key.objectid = chunk_offset; 3180 cache->key.objectid = chunk_offset;
3083 cache->key.offset = size; 3181 cache->key.offset = size;
3084
3085 btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY); 3182 btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
3086 memset(&cache->item, 0, sizeof(cache->item)); 3183
3087 btrfs_set_block_group_used(&cache->item, bytes_used); 3184 btrfs_set_block_group_used(&cache->item, bytes_used);
3088 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); 3185 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
3089 cache->flags = type; 3186 cache->flags = type;
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));
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 333e5269577a..722eb4550154 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -750,10 +750,6 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
750 if (bdev == fs_devices->latest_bdev) 750 if (bdev == fs_devices->latest_bdev)
751 fs_devices->latest_bdev = next_dev->bdev; 751 fs_devices->latest_bdev = next_dev->bdev;
752 752
753 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
754 btrfs_set_super_total_bytes(&root->fs_info->super_copy,
755 total_bytes - device->total_bytes);
756
757 total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy); 753 total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy);
758 btrfs_set_super_num_devices(&root->fs_info->super_copy, 754 btrfs_set_super_num_devices(&root->fs_info->super_copy,
759 total_bytes - 1); 755 total_bytes - 1);
@@ -849,6 +845,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
849 845
850 } 846 }
851 root->fs_info->fs_devices->num_devices--; 847 root->fs_info->fs_devices->num_devices--;
848 root->fs_info->fs_devices->open_devices--;
852 849
853 ret = btrfs_shrink_device(device, 0); 850 ret = btrfs_shrink_device(device, 0);
854 if (ret) 851 if (ret)
@@ -873,7 +870,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
873 if (device->bdev) { 870 if (device->bdev) {
874 /* one close for the device struct or super_block */ 871 /* one close for the device struct or super_block */
875 close_bdev_excl(device->bdev); 872 close_bdev_excl(device->bdev);
876 root->fs_info->fs_devices->open_devices--;
877 } 873 }
878 if (bdev) { 874 if (bdev) {
879 /* one close for us */ 875 /* one close for us */
@@ -1450,7 +1446,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
1450 return -ENOSPC; 1446 return -ENOSPC;
1451 1447
1452 if (type & (BTRFS_BLOCK_GROUP_RAID0)) { 1448 if (type & (BTRFS_BLOCK_GROUP_RAID0)) {
1453 num_stripes = btrfs_super_num_devices(&info->super_copy); 1449 num_stripes = extent_root->fs_info->fs_devices->open_devices;
1454 min_stripes = 2; 1450 min_stripes = 2;
1455 } 1451 }
1456 if (type & (BTRFS_BLOCK_GROUP_DUP)) { 1452 if (type & (BTRFS_BLOCK_GROUP_DUP)) {
@@ -1459,13 +1455,13 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
1459 } 1455 }
1460 if (type & (BTRFS_BLOCK_GROUP_RAID1)) { 1456 if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
1461 num_stripes = min_t(u64, 2, 1457 num_stripes = min_t(u64, 2,
1462 btrfs_super_num_devices(&info->super_copy)); 1458 extent_root->fs_info->fs_devices->open_devices);
1463 if (num_stripes < 2) 1459 if (num_stripes < 2)
1464 return -ENOSPC; 1460 return -ENOSPC;
1465 min_stripes = 2; 1461 min_stripes = 2;
1466 } 1462 }
1467 if (type & (BTRFS_BLOCK_GROUP_RAID10)) { 1463 if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
1468 num_stripes = btrfs_super_num_devices(&info->super_copy); 1464 num_stripes = extent_root->fs_info->fs_devices->open_devices;
1469 if (num_stripes < 4) 1465 if (num_stripes < 4)
1470 return -ENOSPC; 1466 return -ENOSPC;
1471 num_stripes &= ~(u32)1; 1467 num_stripes &= ~(u32)1;