diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 252 |
1 files changed, 164 insertions, 88 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 41a63462d3eb..7e40c516fe62 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "print-tree.h" | 25 | #include "print-tree.h" |
26 | #include "transaction.h" | 26 | #include "transaction.h" |
27 | #include "volumes.h" | 27 | #include "volumes.h" |
28 | #include "locking.h" | ||
28 | 29 | ||
29 | #define BLOCK_GROUP_DATA EXTENT_WRITEBACK | 30 | #define BLOCK_GROUP_DATA EXTENT_WRITEBACK |
30 | #define BLOCK_GROUP_METADATA EXTENT_UPTODATE | 31 | #define BLOCK_GROUP_METADATA EXTENT_UPTODATE |
@@ -36,7 +37,28 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
36 | btrfs_root *extent_root); | 37 | btrfs_root *extent_root); |
37 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 38 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
38 | btrfs_root *extent_root); | 39 | btrfs_root *extent_root); |
40 | static struct btrfs_block_group_cache * | ||
41 | __btrfs_find_block_group(struct btrfs_root *root, | ||
42 | struct btrfs_block_group_cache *hint, | ||
43 | u64 search_start, int data, int owner); | ||
39 | 44 | ||
45 | void maybe_lock_mutex(struct btrfs_root *root) | ||
46 | { | ||
47 | if (root != root->fs_info->extent_root && | ||
48 | root != root->fs_info->chunk_root && | ||
49 | root != root->fs_info->dev_root) { | ||
50 | mutex_lock(&root->fs_info->alloc_mutex); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | void maybe_unlock_mutex(struct btrfs_root *root) | ||
55 | { | ||
56 | if (root != root->fs_info->extent_root && | ||
57 | root != root->fs_info->chunk_root && | ||
58 | root != root->fs_info->dev_root) { | ||
59 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
60 | } | ||
61 | } | ||
40 | 62 | ||
41 | static int cache_block_group(struct btrfs_root *root, | 63 | static int cache_block_group(struct btrfs_root *root, |
42 | struct btrfs_block_group_cache *block_group) | 64 | struct btrfs_block_group_cache *block_group) |
@@ -66,6 +88,7 @@ static int cache_block_group(struct btrfs_root *root, | |||
66 | return -ENOMEM; | 88 | return -ENOMEM; |
67 | 89 | ||
68 | path->reada = 2; | 90 | path->reada = 2; |
91 | path->skip_locking = 1; | ||
69 | first_free = block_group->key.objectid; | 92 | first_free = block_group->key.objectid; |
70 | key.objectid = block_group->key.objectid; | 93 | key.objectid = block_group->key.objectid; |
71 | key.offset = 0; | 94 | key.offset = 0; |
@@ -290,7 +313,7 @@ no_cache: | |||
290 | cache = btrfs_lookup_first_block_group(root->fs_info, last); | 313 | cache = btrfs_lookup_first_block_group(root->fs_info, last); |
291 | } | 314 | } |
292 | cache_miss = 0; | 315 | cache_miss = 0; |
293 | cache = btrfs_find_block_group(root, cache, last, data, 0); | 316 | cache = __btrfs_find_block_group(root, cache, last, data, 0); |
294 | if (!cache) | 317 | if (!cache) |
295 | goto no_cache; | 318 | goto no_cache; |
296 | *cache_ret = cache; | 319 | *cache_ret = cache; |
@@ -318,10 +341,10 @@ static int block_group_state_bits(u64 flags) | |||
318 | return bits; | 341 | return bits; |
319 | } | 342 | } |
320 | 343 | ||
321 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | 344 | static struct btrfs_block_group_cache * |
322 | struct btrfs_block_group_cache | 345 | __btrfs_find_block_group(struct btrfs_root *root, |
323 | *hint, u64 search_start, | 346 | struct btrfs_block_group_cache *hint, |
324 | int data, int owner) | 347 | u64 search_start, int data, int owner) |
325 | { | 348 | { |
326 | struct btrfs_block_group_cache *cache; | 349 | struct btrfs_block_group_cache *cache; |
327 | struct extent_io_tree *block_group_cache; | 350 | struct extent_io_tree *block_group_cache; |
@@ -411,6 +434,18 @@ found: | |||
411 | return found_group; | 434 | return found_group; |
412 | } | 435 | } |
413 | 436 | ||
437 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | ||
438 | struct btrfs_block_group_cache | ||
439 | *hint, u64 search_start, | ||
440 | int data, int owner) | ||
441 | { | ||
442 | |||
443 | struct btrfs_block_group_cache *ret; | ||
444 | mutex_lock(&root->fs_info->alloc_mutex); | ||
445 | ret = __btrfs_find_block_group(root, hint, search_start, data, owner); | ||
446 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
447 | return ret; | ||
448 | } | ||
414 | static u64 hash_extent_ref(u64 root_objectid, u64 ref_generation, | 449 | static u64 hash_extent_ref(u64 root_objectid, u64 ref_generation, |
415 | u64 owner, u64 owner_offset) | 450 | u64 owner, u64 owner_offset) |
416 | { | 451 | { |
@@ -646,7 +681,7 @@ out: | |||
646 | return ret; | 681 | return ret; |
647 | } | 682 | } |
648 | 683 | ||
649 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 684 | static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
650 | struct btrfs_root *root, | 685 | struct btrfs_root *root, |
651 | u64 bytenr, u64 num_bytes, | 686 | u64 bytenr, u64 num_bytes, |
652 | u64 root_objectid, u64 ref_generation, | 687 | u64 root_objectid, u64 ref_generation, |
@@ -696,6 +731,22 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
696 | return 0; | 731 | return 0; |
697 | } | 732 | } |
698 | 733 | ||
734 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | ||
735 | struct btrfs_root *root, | ||
736 | u64 bytenr, u64 num_bytes, | ||
737 | u64 root_objectid, u64 ref_generation, | ||
738 | u64 owner, u64 owner_offset) | ||
739 | { | ||
740 | int ret; | ||
741 | |||
742 | mutex_lock(&root->fs_info->alloc_mutex); | ||
743 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, | ||
744 | root_objectid, ref_generation, | ||
745 | owner, owner_offset); | ||
746 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
747 | return ret; | ||
748 | } | ||
749 | |||
699 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 750 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
700 | struct btrfs_root *root) | 751 | struct btrfs_root *root) |
701 | { | 752 | { |
@@ -760,6 +811,10 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, | |||
760 | struct btrfs_extent_ref *ref_item; | 811 | struct btrfs_extent_ref *ref_item; |
761 | int level = -1; | 812 | int level = -1; |
762 | 813 | ||
814 | /* FIXME, needs locking */ | ||
815 | BUG(); | ||
816 | |||
817 | mutex_lock(&root->fs_info->alloc_mutex); | ||
763 | path = btrfs_alloc_path(); | 818 | path = btrfs_alloc_path(); |
764 | again: | 819 | again: |
765 | if (level == -1) | 820 | if (level == -1) |
@@ -854,33 +909,9 @@ again: | |||
854 | 909 | ||
855 | out: | 910 | out: |
856 | btrfs_free_path(path); | 911 | btrfs_free_path(path); |
912 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
857 | return total_count; | 913 | return total_count; |
858 | } | 914 | } |
859 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | ||
860 | struct btrfs_root *root, u64 owner_objectid) | ||
861 | { | ||
862 | u64 generation; | ||
863 | u64 key_objectid; | ||
864 | u64 level; | ||
865 | u32 nritems; | ||
866 | struct btrfs_disk_key disk_key; | ||
867 | |||
868 | level = btrfs_header_level(root->node); | ||
869 | generation = trans->transid; | ||
870 | nritems = btrfs_header_nritems(root->node); | ||
871 | if (nritems > 0) { | ||
872 | if (level == 0) | ||
873 | btrfs_item_key(root->node, &disk_key, 0); | ||
874 | else | ||
875 | btrfs_node_key(root->node, &disk_key, 0); | ||
876 | key_objectid = btrfs_disk_key_objectid(&disk_key); | ||
877 | } else { | ||
878 | key_objectid = 0; | ||
879 | } | ||
880 | return btrfs_inc_extent_ref(trans, root, root->node->start, | ||
881 | root->node->len, owner_objectid, | ||
882 | generation, level, key_objectid); | ||
883 | } | ||
884 | 915 | ||
885 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 916 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
886 | struct extent_buffer *buf) | 917 | struct extent_buffer *buf) |
@@ -897,6 +928,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
897 | if (!root->ref_cows) | 928 | if (!root->ref_cows) |
898 | return 0; | 929 | return 0; |
899 | 930 | ||
931 | mutex_lock(&root->fs_info->alloc_mutex); | ||
900 | level = btrfs_header_level(buf); | 932 | level = btrfs_header_level(buf); |
901 | nritems = btrfs_header_nritems(buf); | 933 | nritems = btrfs_header_nritems(buf); |
902 | for (i = 0; i < nritems; i++) { | 934 | for (i = 0; i < nritems; i++) { |
@@ -913,7 +945,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
913 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | 945 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
914 | if (disk_bytenr == 0) | 946 | if (disk_bytenr == 0) |
915 | continue; | 947 | continue; |
916 | ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, | 948 | ret = __btrfs_inc_extent_ref(trans, root, disk_bytenr, |
917 | btrfs_file_extent_disk_num_bytes(buf, fi), | 949 | btrfs_file_extent_disk_num_bytes(buf, fi), |
918 | root->root_key.objectid, trans->transid, | 950 | root->root_key.objectid, trans->transid, |
919 | key.objectid, key.offset); | 951 | key.objectid, key.offset); |
@@ -924,7 +956,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
924 | } else { | 956 | } else { |
925 | bytenr = btrfs_node_blockptr(buf, i); | 957 | bytenr = btrfs_node_blockptr(buf, i); |
926 | btrfs_node_key_to_cpu(buf, &key, i); | 958 | btrfs_node_key_to_cpu(buf, &key, i); |
927 | ret = btrfs_inc_extent_ref(trans, root, bytenr, | 959 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, |
928 | btrfs_level_size(root, level - 1), | 960 | btrfs_level_size(root, level - 1), |
929 | root->root_key.objectid, | 961 | root->root_key.objectid, |
930 | trans->transid, | 962 | trans->transid, |
@@ -935,6 +967,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
935 | } | 967 | } |
936 | } | 968 | } |
937 | } | 969 | } |
970 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
938 | return 0; | 971 | return 0; |
939 | fail: | 972 | fail: |
940 | WARN_ON(1); | 973 | WARN_ON(1); |
@@ -965,6 +998,7 @@ fail: | |||
965 | } | 998 | } |
966 | } | 999 | } |
967 | #endif | 1000 | #endif |
1001 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
968 | return ret; | 1002 | return ret; |
969 | } | 1003 | } |
970 | 1004 | ||
@@ -1019,6 +1053,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
1019 | if (!path) | 1053 | if (!path) |
1020 | return -ENOMEM; | 1054 | return -ENOMEM; |
1021 | 1055 | ||
1056 | mutex_lock(&root->fs_info->alloc_mutex); | ||
1022 | while(1) { | 1057 | while(1) { |
1023 | ret = find_first_extent_bit(block_group_cache, last, | 1058 | ret = find_first_extent_bit(block_group_cache, last, |
1024 | &start, &end, BLOCK_GROUP_DIRTY); | 1059 | &start, &end, BLOCK_GROUP_DIRTY); |
@@ -1045,6 +1080,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
1045 | BLOCK_GROUP_DIRTY, GFP_NOFS); | 1080 | BLOCK_GROUP_DIRTY, GFP_NOFS); |
1046 | } | 1081 | } |
1047 | btrfs_free_path(path); | 1082 | btrfs_free_path(path); |
1083 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1048 | return werr; | 1084 | return werr; |
1049 | } | 1085 | } |
1050 | 1086 | ||
@@ -1162,26 +1198,28 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
1162 | space_info->force_alloc = 0; | 1198 | space_info->force_alloc = 0; |
1163 | } | 1199 | } |
1164 | if (space_info->full) | 1200 | if (space_info->full) |
1165 | return 0; | 1201 | goto out; |
1166 | 1202 | ||
1167 | thresh = div_factor(space_info->total_bytes, 6); | 1203 | thresh = div_factor(space_info->total_bytes, 6); |
1168 | if (!force && | 1204 | if (!force && |
1169 | (space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) < | 1205 | (space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) < |
1170 | thresh) | 1206 | thresh) |
1171 | return 0; | 1207 | goto out; |
1172 | 1208 | ||
1209 | mutex_lock(&extent_root->fs_info->chunk_mutex); | ||
1173 | ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); | 1210 | ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); |
1174 | if (ret == -ENOSPC) { | 1211 | if (ret == -ENOSPC) { |
1175 | printk("space info full %Lu\n", flags); | 1212 | printk("space info full %Lu\n", flags); |
1176 | space_info->full = 1; | 1213 | space_info->full = 1; |
1177 | return 0; | 1214 | goto out; |
1178 | } | 1215 | } |
1179 | BUG_ON(ret); | 1216 | BUG_ON(ret); |
1180 | 1217 | ||
1181 | ret = btrfs_make_block_group(trans, extent_root, 0, flags, | 1218 | ret = btrfs_make_block_group(trans, extent_root, 0, flags, |
1182 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); | 1219 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); |
1183 | BUG_ON(ret); | 1220 | BUG_ON(ret); |
1184 | 1221 | mutex_unlock(&extent_root->fs_info->chunk_mutex); | |
1222 | out: | ||
1185 | return 0; | 1223 | return 0; |
1186 | } | 1224 | } |
1187 | 1225 | ||
@@ -1318,6 +1356,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
1318 | struct extent_io_tree *free_space_cache; | 1356 | struct extent_io_tree *free_space_cache; |
1319 | free_space_cache = &root->fs_info->free_space_cache; | 1357 | free_space_cache = &root->fs_info->free_space_cache; |
1320 | 1358 | ||
1359 | mutex_lock(&root->fs_info->alloc_mutex); | ||
1321 | while(1) { | 1360 | while(1) { |
1322 | ret = find_first_extent_bit(unpin, 0, &start, &end, | 1361 | ret = find_first_extent_bit(unpin, 0, &start, &end, |
1323 | EXTENT_DIRTY); | 1362 | EXTENT_DIRTY); |
@@ -1327,6 +1366,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
1327 | clear_extent_dirty(unpin, start, end, GFP_NOFS); | 1366 | clear_extent_dirty(unpin, start, end, GFP_NOFS); |
1328 | set_extent_dirty(free_space_cache, start, end, GFP_NOFS); | 1367 | set_extent_dirty(free_space_cache, start, end, GFP_NOFS); |
1329 | } | 1368 | } |
1369 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1330 | return 0; | 1370 | return 0; |
1331 | } | 1371 | } |
1332 | 1372 | ||
@@ -1363,18 +1403,24 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1363 | GFP_NOFS); | 1403 | GFP_NOFS); |
1364 | eb = read_tree_block(extent_root, ins.objectid, ins.offset, | 1404 | eb = read_tree_block(extent_root, ins.objectid, ins.offset, |
1365 | trans->transid); | 1405 | trans->transid); |
1406 | btrfs_tree_lock(eb); | ||
1366 | level = btrfs_header_level(eb); | 1407 | level = btrfs_header_level(eb); |
1367 | if (level == 0) { | 1408 | if (level == 0) { |
1368 | btrfs_item_key(eb, &first, 0); | 1409 | btrfs_item_key(eb, &first, 0); |
1369 | } else { | 1410 | } else { |
1370 | btrfs_node_key(eb, &first, 0); | 1411 | btrfs_node_key(eb, &first, 0); |
1371 | } | 1412 | } |
1413 | btrfs_tree_unlock(eb); | ||
1414 | free_extent_buffer(eb); | ||
1415 | /* | ||
1416 | * the first key is just a hint, so the race we've created | ||
1417 | * against reading it is fine | ||
1418 | */ | ||
1372 | err = btrfs_insert_extent_backref(trans, extent_root, path, | 1419 | err = btrfs_insert_extent_backref(trans, extent_root, path, |
1373 | start, extent_root->root_key.objectid, | 1420 | start, extent_root->root_key.objectid, |
1374 | 0, level, | 1421 | 0, level, |
1375 | btrfs_disk_key_objectid(&first)); | 1422 | btrfs_disk_key_objectid(&first)); |
1376 | BUG_ON(err); | 1423 | BUG_ON(err); |
1377 | free_extent_buffer(eb); | ||
1378 | } | 1424 | } |
1379 | btrfs_free_path(path); | 1425 | btrfs_free_path(path); |
1380 | return 0; | 1426 | return 0; |
@@ -1384,12 +1430,14 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, | |||
1384 | int pending) | 1430 | int pending) |
1385 | { | 1431 | { |
1386 | int err = 0; | 1432 | int err = 0; |
1387 | struct extent_buffer *buf; | ||
1388 | 1433 | ||
1389 | if (!pending) { | 1434 | if (!pending) { |
1435 | #if 0 | ||
1436 | struct extent_buffer *buf; | ||
1390 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); | 1437 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
1391 | if (buf) { | 1438 | if (buf) { |
1392 | if (btrfs_buffer_uptodate(buf, 0)) { | 1439 | if (!btrfs_try_tree_lock(buf) && |
1440 | btrfs_buffer_uptodate(buf, 0)) { | ||
1393 | u64 transid = | 1441 | u64 transid = |
1394 | root->fs_info->running_transaction->transid; | 1442 | root->fs_info->running_transaction->transid; |
1395 | u64 header_transid = | 1443 | u64 header_transid = |
@@ -1398,12 +1446,15 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, | |||
1398 | !btrfs_header_flag(buf, | 1446 | !btrfs_header_flag(buf, |
1399 | BTRFS_HEADER_FLAG_WRITTEN)) { | 1447 | BTRFS_HEADER_FLAG_WRITTEN)) { |
1400 | clean_tree_block(NULL, root, buf); | 1448 | clean_tree_block(NULL, root, buf); |
1449 | btrfs_tree_unlock(buf); | ||
1401 | free_extent_buffer(buf); | 1450 | free_extent_buffer(buf); |
1402 | return 1; | 1451 | return 1; |
1403 | } | 1452 | } |
1453 | btrfs_tree_unlock(buf); | ||
1404 | } | 1454 | } |
1405 | free_extent_buffer(buf); | 1455 | free_extent_buffer(buf); |
1406 | } | 1456 | } |
1457 | #endif | ||
1407 | update_pinned_extents(root, bytenr, num_bytes, 1); | 1458 | update_pinned_extents(root, bytenr, num_bytes, 1); |
1408 | } else { | 1459 | } else { |
1409 | set_extent_bits(&root->fs_info->pending_del, | 1460 | set_extent_bits(&root->fs_info->pending_del, |
@@ -1586,10 +1637,11 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
1586 | /* | 1637 | /* |
1587 | * remove an extent from the root, returns 0 on success | 1638 | * remove an extent from the root, returns 0 on success |
1588 | */ | 1639 | */ |
1589 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1640 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, |
1590 | *root, u64 bytenr, u64 num_bytes, | 1641 | struct btrfs_root *root, u64 bytenr, |
1591 | u64 root_objectid, u64 ref_generation, | 1642 | u64 num_bytes, u64 root_objectid, |
1592 | u64 owner_objectid, u64 owner_offset, int pin) | 1643 | u64 ref_generation, u64 owner_objectid, |
1644 | u64 owner_offset, int pin) | ||
1593 | { | 1645 | { |
1594 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 1646 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
1595 | int pending_ret; | 1647 | int pending_ret; |
@@ -1610,6 +1662,22 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1610 | return ret ? ret : pending_ret; | 1662 | return ret ? ret : pending_ret; |
1611 | } | 1663 | } |
1612 | 1664 | ||
1665 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | ||
1666 | struct btrfs_root *root, u64 bytenr, | ||
1667 | u64 num_bytes, u64 root_objectid, | ||
1668 | u64 ref_generation, u64 owner_objectid, | ||
1669 | u64 owner_offset, int pin) | ||
1670 | { | ||
1671 | int ret; | ||
1672 | |||
1673 | maybe_lock_mutex(root); | ||
1674 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, | ||
1675 | root_objectid, ref_generation, | ||
1676 | owner_objectid, owner_offset, pin); | ||
1677 | maybe_unlock_mutex(root); | ||
1678 | return ret; | ||
1679 | } | ||
1680 | |||
1613 | static u64 stripe_align(struct btrfs_root *root, u64 val) | 1681 | static u64 stripe_align(struct btrfs_root *root, u64 val) |
1614 | { | 1682 | { |
1615 | u64 mask = ((u64)root->stripesize - 1); | 1683 | u64 mask = ((u64)root->stripesize - 1); |
@@ -1679,12 +1747,12 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans, | |||
1679 | block_group = btrfs_lookup_first_block_group(info, hint_byte); | 1747 | block_group = btrfs_lookup_first_block_group(info, hint_byte); |
1680 | if (!block_group) | 1748 | if (!block_group) |
1681 | hint_byte = search_start; | 1749 | hint_byte = search_start; |
1682 | block_group = btrfs_find_block_group(root, block_group, | 1750 | block_group = __btrfs_find_block_group(root, block_group, |
1683 | hint_byte, data, 1); | 1751 | hint_byte, data, 1); |
1684 | if (last_ptr && *last_ptr == 0 && block_group) | 1752 | if (last_ptr && *last_ptr == 0 && block_group) |
1685 | hint_byte = block_group->key.objectid; | 1753 | hint_byte = block_group->key.objectid; |
1686 | } else { | 1754 | } else { |
1687 | block_group = btrfs_find_block_group(root, | 1755 | block_group = __btrfs_find_block_group(root, |
1688 | trans->block_group, | 1756 | trans->block_group, |
1689 | search_start, data, 1); | 1757 | search_start, data, 1); |
1690 | } | 1758 | } |
@@ -1806,7 +1874,7 @@ enospc: | |||
1806 | } | 1874 | } |
1807 | block_group = btrfs_lookup_first_block_group(info, search_start); | 1875 | block_group = btrfs_lookup_first_block_group(info, search_start); |
1808 | cond_resched(); | 1876 | cond_resched(); |
1809 | block_group = btrfs_find_block_group(root, block_group, | 1877 | block_group = __btrfs_find_block_group(root, block_group, |
1810 | search_start, data, 0); | 1878 | search_start, data, 0); |
1811 | goto check_failed; | 1879 | goto check_failed; |
1812 | 1880 | ||
@@ -1843,6 +1911,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1843 | struct btrfs_path *path; | 1911 | struct btrfs_path *path; |
1844 | struct btrfs_key keys[2]; | 1912 | struct btrfs_key keys[2]; |
1845 | 1913 | ||
1914 | maybe_lock_mutex(root); | ||
1915 | |||
1846 | if (data) { | 1916 | if (data) { |
1847 | alloc_profile = info->avail_data_alloc_bits & | 1917 | alloc_profile = info->avail_data_alloc_bits & |
1848 | info->data_alloc_profile; | 1918 | info->data_alloc_profile; |
@@ -1892,9 +1962,10 @@ again: | |||
1892 | if (ret) { | 1962 | if (ret) { |
1893 | printk("allocation failed flags %Lu\n", data); | 1963 | printk("allocation failed flags %Lu\n", data); |
1894 | } | 1964 | } |
1895 | BUG_ON(ret); | 1965 | if (ret) { |
1896 | if (ret) | 1966 | BUG(); |
1897 | return ret; | 1967 | goto out; |
1968 | } | ||
1898 | 1969 | ||
1899 | /* block accounting for super block */ | 1970 | /* block accounting for super block */ |
1900 | super_used = btrfs_super_bytes_used(&info->super_copy); | 1971 | super_used = btrfs_super_bytes_used(&info->super_copy); |
@@ -1953,11 +2024,11 @@ again: | |||
1953 | finish_current_insert(trans, extent_root); | 2024 | finish_current_insert(trans, extent_root); |
1954 | pending_ret = del_pending_extents(trans, extent_root); | 2025 | pending_ret = del_pending_extents(trans, extent_root); |
1955 | 2026 | ||
1956 | if (ret) { | 2027 | if (ret) |
1957 | return ret; | 2028 | goto out; |
1958 | } | ||
1959 | if (pending_ret) { | 2029 | if (pending_ret) { |
1960 | return pending_ret; | 2030 | ret = pending_ret; |
2031 | goto out; | ||
1961 | } | 2032 | } |
1962 | 2033 | ||
1963 | update_block: | 2034 | update_block: |
@@ -1967,9 +2038,10 @@ update_block: | |||
1967 | ins->objectid, ins->offset); | 2038 | ins->objectid, ins->offset); |
1968 | BUG(); | 2039 | BUG(); |
1969 | } | 2040 | } |
1970 | return 0; | 2041 | out: |
2042 | maybe_unlock_mutex(root); | ||
2043 | return ret; | ||
1971 | } | 2044 | } |
1972 | |||
1973 | /* | 2045 | /* |
1974 | * helper function to allocate a block for a given tree | 2046 | * helper function to allocate a block for a given tree |
1975 | * returns the tree buffer or NULL. | 2047 | * returns the tree buffer or NULL. |
@@ -1977,28 +2049,6 @@ update_block: | |||
1977 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 2049 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1978 | struct btrfs_root *root, | 2050 | struct btrfs_root *root, |
1979 | u32 blocksize, | 2051 | u32 blocksize, |
1980 | u64 root_objectid, u64 hint, | ||
1981 | u64 empty_size) | ||
1982 | { | ||
1983 | u64 ref_generation; | ||
1984 | |||
1985 | if (root->ref_cows) | ||
1986 | ref_generation = trans->transid; | ||
1987 | else | ||
1988 | ref_generation = 0; | ||
1989 | |||
1990 | |||
1991 | return __btrfs_alloc_free_block(trans, root, blocksize, root_objectid, | ||
1992 | ref_generation, 0, 0, hint, empty_size); | ||
1993 | } | ||
1994 | |||
1995 | /* | ||
1996 | * helper function to allocate a block for a given tree | ||
1997 | * returns the tree buffer or NULL. | ||
1998 | */ | ||
1999 | struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | ||
2000 | struct btrfs_root *root, | ||
2001 | u32 blocksize, | ||
2002 | u64 root_objectid, | 2052 | u64 root_objectid, |
2003 | u64 ref_generation, | 2053 | u64 ref_generation, |
2004 | u64 first_objectid, | 2054 | u64 first_objectid, |
@@ -2026,6 +2076,7 @@ struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2026 | return ERR_PTR(-ENOMEM); | 2076 | return ERR_PTR(-ENOMEM); |
2027 | } | 2077 | } |
2028 | btrfs_set_header_generation(buf, trans->transid); | 2078 | btrfs_set_header_generation(buf, trans->transid); |
2079 | btrfs_tree_lock(buf); | ||
2029 | clean_tree_block(trans, root, buf); | 2080 | clean_tree_block(trans, root, buf); |
2030 | btrfs_set_buffer_uptodate(buf); | 2081 | btrfs_set_buffer_uptodate(buf); |
2031 | 2082 | ||
@@ -2076,7 +2127,7 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2076 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | 2127 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
2077 | if (disk_bytenr == 0) | 2128 | if (disk_bytenr == 0) |
2078 | continue; | 2129 | continue; |
2079 | ret = btrfs_free_extent(trans, root, disk_bytenr, | 2130 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
2080 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 2131 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
2081 | leaf_owner, leaf_generation, | 2132 | leaf_owner, leaf_generation, |
2082 | key.objectid, key.offset, 0); | 2133 | key.objectid, key.offset, 0); |
@@ -2151,6 +2202,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2151 | int ret; | 2202 | int ret; |
2152 | u32 refs; | 2203 | u32 refs; |
2153 | 2204 | ||
2205 | mutex_lock(&root->fs_info->alloc_mutex); | ||
2206 | |||
2154 | WARN_ON(*level < 0); | 2207 | WARN_ON(*level < 0); |
2155 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 2208 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
2156 | ret = lookup_extent_ref(trans, root, | 2209 | ret = lookup_extent_ref(trans, root, |
@@ -2182,6 +2235,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2182 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); | 2235 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
2183 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); | 2236 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); |
2184 | blocksize = btrfs_level_size(root, *level - 1); | 2237 | blocksize = btrfs_level_size(root, *level - 1); |
2238 | |||
2185 | ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); | 2239 | ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); |
2186 | BUG_ON(ret); | 2240 | BUG_ON(ret); |
2187 | if (refs != 1) { | 2241 | if (refs != 1) { |
@@ -2189,7 +2243,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2189 | root_owner = btrfs_header_owner(parent); | 2243 | root_owner = btrfs_header_owner(parent); |
2190 | root_gen = btrfs_header_generation(parent); | 2244 | root_gen = btrfs_header_generation(parent); |
2191 | path->slots[*level]++; | 2245 | path->slots[*level]++; |
2192 | ret = btrfs_free_extent(trans, root, bytenr, | 2246 | ret = __btrfs_free_extent(trans, root, bytenr, |
2193 | blocksize, root_owner, | 2247 | blocksize, root_owner, |
2194 | root_gen, 0, 0, 1); | 2248 | root_gen, 0, 0, 1); |
2195 | BUG_ON(ret); | 2249 | BUG_ON(ret); |
@@ -2201,9 +2255,11 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2201 | reada_walk_down(root, cur, path->slots[*level]); | 2255 | reada_walk_down(root, cur, path->slots[*level]); |
2202 | 2256 | ||
2203 | mutex_unlock(&root->fs_info->fs_mutex); | 2257 | mutex_unlock(&root->fs_info->fs_mutex); |
2258 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2204 | next = read_tree_block(root, bytenr, blocksize, | 2259 | next = read_tree_block(root, bytenr, blocksize, |
2205 | ptr_gen); | 2260 | ptr_gen); |
2206 | mutex_lock(&root->fs_info->fs_mutex); | 2261 | mutex_lock(&root->fs_info->fs_mutex); |
2262 | mutex_lock(&root->fs_info->alloc_mutex); | ||
2207 | 2263 | ||
2208 | /* we've dropped the lock, double check */ | 2264 | /* we've dropped the lock, double check */ |
2209 | ret = lookup_extent_ref(trans, root, bytenr, | 2265 | ret = lookup_extent_ref(trans, root, bytenr, |
@@ -2216,7 +2272,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2216 | 2272 | ||
2217 | path->slots[*level]++; | 2273 | path->slots[*level]++; |
2218 | free_extent_buffer(next); | 2274 | free_extent_buffer(next); |
2219 | ret = btrfs_free_extent(trans, root, bytenr, | 2275 | ret = __btrfs_free_extent(trans, root, bytenr, |
2220 | blocksize, | 2276 | blocksize, |
2221 | root_owner, | 2277 | root_owner, |
2222 | root_gen, 0, 0, 1); | 2278 | root_gen, 0, 0, 1); |
@@ -2244,13 +2300,14 @@ out: | |||
2244 | } | 2300 | } |
2245 | 2301 | ||
2246 | root_gen = btrfs_header_generation(parent); | 2302 | root_gen = btrfs_header_generation(parent); |
2247 | ret = btrfs_free_extent(trans, root, path->nodes[*level]->start, | 2303 | ret = __btrfs_free_extent(trans, root, path->nodes[*level]->start, |
2248 | path->nodes[*level]->len, | 2304 | path->nodes[*level]->len, |
2249 | root_owner, root_gen, 0, 0, 1); | 2305 | root_owner, root_gen, 0, 0, 1); |
2250 | free_extent_buffer(path->nodes[*level]); | 2306 | free_extent_buffer(path->nodes[*level]); |
2251 | path->nodes[*level] = NULL; | 2307 | path->nodes[*level] = NULL; |
2252 | *level += 1; | 2308 | *level += 1; |
2253 | BUG_ON(ret); | 2309 | BUG_ON(ret); |
2310 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2254 | return 0; | 2311 | return 0; |
2255 | } | 2312 | } |
2256 | 2313 | ||
@@ -2350,6 +2407,12 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2350 | btrfs_node_key(node, &found_key, path->slots[level]); | 2407 | btrfs_node_key(node, &found_key, path->slots[level]); |
2351 | WARN_ON(memcmp(&found_key, &root_item->drop_progress, | 2408 | WARN_ON(memcmp(&found_key, &root_item->drop_progress, |
2352 | sizeof(found_key))); | 2409 | sizeof(found_key))); |
2410 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
2411 | if (path->nodes[i] && path->locks[i]) { | ||
2412 | path->locks[i] = 0; | ||
2413 | btrfs_tree_unlock(path->nodes[i]); | ||
2414 | } | ||
2415 | } | ||
2353 | } | 2416 | } |
2354 | while(1) { | 2417 | while(1) { |
2355 | wret = walk_down_tree(trans, root, path, &level); | 2418 | wret = walk_down_tree(trans, root, path, &level); |
@@ -2383,6 +2446,8 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
2383 | u64 end; | 2446 | u64 end; |
2384 | u64 ptr; | 2447 | u64 ptr; |
2385 | int ret; | 2448 | int ret; |
2449 | |||
2450 | mutex_lock(&info->alloc_mutex); | ||
2386 | while(1) { | 2451 | while(1) { |
2387 | ret = find_first_extent_bit(&info->block_group_cache, 0, | 2452 | ret = find_first_extent_bit(&info->block_group_cache, 0, |
2388 | &start, &end, (unsigned int)-1); | 2453 | &start, &end, (unsigned int)-1); |
@@ -2402,6 +2467,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
2402 | clear_extent_dirty(&info->free_space_cache, start, | 2467 | clear_extent_dirty(&info->free_space_cache, start, |
2403 | end, GFP_NOFS); | 2468 | end, GFP_NOFS); |
2404 | } | 2469 | } |
2470 | mutex_unlock(&info->alloc_mutex); | ||
2405 | return 0; | 2471 | return 0; |
2406 | } | 2472 | } |
2407 | 2473 | ||
@@ -2678,6 +2744,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root, | |||
2678 | 2744 | ||
2679 | eb = read_tree_block(found_root, extent_key->objectid, | 2745 | eb = read_tree_block(found_root, extent_key->objectid, |
2680 | extent_key->offset, 0); | 2746 | extent_key->offset, 0); |
2747 | btrfs_tree_lock(eb); | ||
2681 | level = btrfs_header_level(eb); | 2748 | level = btrfs_header_level(eb); |
2682 | 2749 | ||
2683 | if (level == 0) | 2750 | if (level == 0) |
@@ -2685,6 +2752,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root, | |||
2685 | else | 2752 | else |
2686 | btrfs_node_key_to_cpu(eb, &found_key, 0); | 2753 | btrfs_node_key_to_cpu(eb, &found_key, 0); |
2687 | 2754 | ||
2755 | btrfs_tree_unlock(eb); | ||
2688 | free_extent_buffer(eb); | 2756 | free_extent_buffer(eb); |
2689 | 2757 | ||
2690 | ret = find_root_for_ref(extent_root, path, &found_key, | 2758 | ret = find_root_for_ref(extent_root, path, &found_key, |
@@ -2888,6 +2956,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start) | |||
2888 | int ret; | 2956 | int ret; |
2889 | int progress; | 2957 | int progress; |
2890 | 2958 | ||
2959 | mutex_lock(&root->fs_info->alloc_mutex); | ||
2891 | shrink_block_group = btrfs_lookup_block_group(root->fs_info, | 2960 | shrink_block_group = btrfs_lookup_block_group(root->fs_info, |
2892 | shrink_start); | 2961 | shrink_start); |
2893 | BUG_ON(!shrink_block_group); | 2962 | BUG_ON(!shrink_block_group); |
@@ -3044,20 +3113,22 @@ next: | |||
3044 | (unsigned int)-1, GFP_NOFS); | 3113 | (unsigned int)-1, GFP_NOFS); |
3045 | out: | 3114 | out: |
3046 | btrfs_free_path(path); | 3115 | btrfs_free_path(path); |
3116 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
3047 | return ret; | 3117 | return ret; |
3048 | } | 3118 | } |
3049 | 3119 | ||
3050 | int find_first_block_group(struct btrfs_root *root, struct btrfs_path *path, | 3120 | int find_first_block_group(struct btrfs_root *root, struct btrfs_path *path, |
3051 | struct btrfs_key *key) | 3121 | struct btrfs_key *key) |
3052 | { | 3122 | { |
3053 | int ret; | 3123 | int ret = 0; |
3054 | struct btrfs_key found_key; | 3124 | struct btrfs_key found_key; |
3055 | struct extent_buffer *leaf; | 3125 | struct extent_buffer *leaf; |
3056 | int slot; | 3126 | int slot; |
3057 | 3127 | ||
3058 | ret = btrfs_search_slot(NULL, root, key, path, 0, 0); | 3128 | ret = btrfs_search_slot(NULL, root, key, path, 0, 0); |
3059 | if (ret < 0) | 3129 | if (ret < 0) |
3060 | return ret; | 3130 | goto out; |
3131 | |||
3061 | while(1) { | 3132 | while(1) { |
3062 | slot = path->slots[0]; | 3133 | slot = path->slots[0]; |
3063 | leaf = path->nodes[0]; | 3134 | leaf = path->nodes[0]; |
@@ -3066,18 +3137,20 @@ int find_first_block_group(struct btrfs_root *root, struct btrfs_path *path, | |||
3066 | if (ret == 0) | 3137 | if (ret == 0) |
3067 | continue; | 3138 | continue; |
3068 | if (ret < 0) | 3139 | if (ret < 0) |
3069 | goto error; | 3140 | goto out; |
3070 | break; | 3141 | break; |
3071 | } | 3142 | } |
3072 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 3143 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
3073 | 3144 | ||
3074 | if (found_key.objectid >= key->objectid && | 3145 | if (found_key.objectid >= key->objectid && |
3075 | found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) | 3146 | found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) { |
3076 | return 0; | 3147 | ret = 0; |
3148 | goto out; | ||
3149 | } | ||
3077 | path->slots[0]++; | 3150 | path->slots[0]++; |
3078 | } | 3151 | } |
3079 | ret = -ENOENT; | 3152 | ret = -ENOENT; |
3080 | error: | 3153 | out: |
3081 | return ret; | 3154 | return ret; |
3082 | } | 3155 | } |
3083 | 3156 | ||
@@ -3103,6 +3176,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
3103 | if (!path) | 3176 | if (!path) |
3104 | return -ENOMEM; | 3177 | return -ENOMEM; |
3105 | 3178 | ||
3179 | mutex_lock(&root->fs_info->alloc_mutex); | ||
3106 | while(1) { | 3180 | while(1) { |
3107 | ret = find_first_block_group(root, path, &key); | 3181 | ret = find_first_block_group(root, path, &key); |
3108 | if (ret > 0) { | 3182 | if (ret > 0) { |
@@ -3158,6 +3232,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
3158 | ret = 0; | 3232 | ret = 0; |
3159 | error: | 3233 | error: |
3160 | btrfs_free_path(path); | 3234 | btrfs_free_path(path); |
3235 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
3161 | return ret; | 3236 | return ret; |
3162 | } | 3237 | } |
3163 | 3238 | ||
@@ -3205,5 +3280,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
3205 | ret = del_pending_extents(trans, extent_root); | 3280 | ret = del_pending_extents(trans, extent_root); |
3206 | BUG_ON(ret); | 3281 | BUG_ON(ret); |
3207 | set_avail_alloc_bits(extent_root->fs_info, type); | 3282 | set_avail_alloc_bits(extent_root->fs_info, type); |
3283 | |||
3208 | return 0; | 3284 | return 0; |
3209 | } | 3285 | } |