diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
| -rw-r--r-- | fs/btrfs/ctree.c | 276 |
1 files changed, 244 insertions, 32 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9e46c0776816..551177c0011a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -54,6 +54,31 @@ struct btrfs_path *btrfs_alloc_path(void) | |||
| 54 | return path; | 54 | return path; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /* | ||
| 58 | * set all locked nodes in the path to blocking locks. This should | ||
| 59 | * be done before scheduling | ||
| 60 | */ | ||
| 61 | noinline void btrfs_set_path_blocking(struct btrfs_path *p) | ||
| 62 | { | ||
| 63 | int i; | ||
| 64 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
| 65 | if (p->nodes[i] && p->locks[i]) | ||
| 66 | btrfs_set_lock_blocking(p->nodes[i]); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /* | ||
| 71 | * reset all the locked nodes in the patch to spinning locks. | ||
| 72 | */ | ||
| 73 | noinline void btrfs_clear_path_blocking(struct btrfs_path *p) | ||
| 74 | { | ||
| 75 | int i; | ||
| 76 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
| 77 | if (p->nodes[i] && p->locks[i]) | ||
| 78 | btrfs_clear_lock_blocking(p->nodes[i]); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 57 | /* this also releases the path */ | 82 | /* this also releases the path */ |
| 58 | void btrfs_free_path(struct btrfs_path *p) | 83 | void btrfs_free_path(struct btrfs_path *p) |
| 59 | { | 84 | { |
| @@ -272,6 +297,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 272 | if (IS_ERR(cow)) | 297 | if (IS_ERR(cow)) |
| 273 | return PTR_ERR(cow); | 298 | return PTR_ERR(cow); |
| 274 | 299 | ||
| 300 | /* cow is set to blocking by btrfs_init_new_buffer */ | ||
| 301 | |||
| 275 | copy_extent_buffer(cow, buf, 0, 0, cow->len); | 302 | copy_extent_buffer(cow, buf, 0, 0, cow->len); |
| 276 | btrfs_set_header_bytenr(cow, cow->start); | 303 | btrfs_set_header_bytenr(cow, cow->start); |
| 277 | btrfs_set_header_generation(cow, trans->transid); | 304 | btrfs_set_header_generation(cow, trans->transid); |
| @@ -388,17 +415,20 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 388 | WARN_ON(1); | 415 | WARN_ON(1); |
| 389 | } | 416 | } |
| 390 | 417 | ||
| 391 | spin_lock(&root->fs_info->hash_lock); | ||
| 392 | if (btrfs_header_generation(buf) == trans->transid && | 418 | if (btrfs_header_generation(buf) == trans->transid && |
| 393 | btrfs_header_owner(buf) == root->root_key.objectid && | 419 | btrfs_header_owner(buf) == root->root_key.objectid && |
| 394 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { | 420 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { |
| 395 | *cow_ret = buf; | 421 | *cow_ret = buf; |
| 396 | spin_unlock(&root->fs_info->hash_lock); | ||
| 397 | WARN_ON(prealloc_dest); | 422 | WARN_ON(prealloc_dest); |
| 398 | return 0; | 423 | return 0; |
| 399 | } | 424 | } |
| 400 | spin_unlock(&root->fs_info->hash_lock); | 425 | |
| 401 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); | 426 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); |
| 427 | |||
| 428 | if (parent) | ||
| 429 | btrfs_set_lock_blocking(parent); | ||
| 430 | btrfs_set_lock_blocking(buf); | ||
| 431 | |||
| 402 | ret = __btrfs_cow_block(trans, root, buf, parent, | 432 | ret = __btrfs_cow_block(trans, root, buf, parent, |
| 403 | parent_slot, cow_ret, search_start, 0, | 433 | parent_slot, cow_ret, search_start, 0, |
| 404 | prealloc_dest); | 434 | prealloc_dest); |
| @@ -504,6 +534,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
| 504 | if (parent_nritems == 1) | 534 | if (parent_nritems == 1) |
| 505 | return 0; | 535 | return 0; |
| 506 | 536 | ||
| 537 | btrfs_set_lock_blocking(parent); | ||
| 538 | |||
| 507 | for (i = start_slot; i < end_slot; i++) { | 539 | for (i = start_slot; i < end_slot; i++) { |
| 508 | int close = 1; | 540 | int close = 1; |
| 509 | 541 | ||
| @@ -564,6 +596,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
| 564 | search_start = last_block; | 596 | search_start = last_block; |
| 565 | 597 | ||
| 566 | btrfs_tree_lock(cur); | 598 | btrfs_tree_lock(cur); |
| 599 | btrfs_set_lock_blocking(cur); | ||
| 567 | err = __btrfs_cow_block(trans, root, cur, parent, i, | 600 | err = __btrfs_cow_block(trans, root, cur, parent, i, |
| 568 | &cur, search_start, | 601 | &cur, search_start, |
| 569 | min(16 * blocksize, | 602 | min(16 * blocksize, |
| @@ -862,6 +895,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 862 | return 0; | 895 | return 0; |
| 863 | 896 | ||
| 864 | mid = path->nodes[level]; | 897 | mid = path->nodes[level]; |
| 898 | |||
| 865 | WARN_ON(!path->locks[level]); | 899 | WARN_ON(!path->locks[level]); |
| 866 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | 900 | WARN_ON(btrfs_header_generation(mid) != trans->transid); |
| 867 | 901 | ||
| @@ -884,6 +918,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 884 | /* promote the child to a root */ | 918 | /* promote the child to a root */ |
| 885 | child = read_node_slot(root, mid, 0); | 919 | child = read_node_slot(root, mid, 0); |
| 886 | btrfs_tree_lock(child); | 920 | btrfs_tree_lock(child); |
| 921 | btrfs_set_lock_blocking(child); | ||
| 887 | BUG_ON(!child); | 922 | BUG_ON(!child); |
| 888 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); | 923 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); |
| 889 | BUG_ON(ret); | 924 | BUG_ON(ret); |
| @@ -900,6 +935,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 900 | 935 | ||
| 901 | add_root_to_dirty_list(root); | 936 | add_root_to_dirty_list(root); |
| 902 | btrfs_tree_unlock(child); | 937 | btrfs_tree_unlock(child); |
| 938 | |||
| 903 | path->locks[level] = 0; | 939 | path->locks[level] = 0; |
| 904 | path->nodes[level] = NULL; | 940 | path->nodes[level] = NULL; |
| 905 | clean_tree_block(trans, root, mid); | 941 | clean_tree_block(trans, root, mid); |
| @@ -924,6 +960,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 924 | left = read_node_slot(root, parent, pslot - 1); | 960 | left = read_node_slot(root, parent, pslot - 1); |
| 925 | if (left) { | 961 | if (left) { |
| 926 | btrfs_tree_lock(left); | 962 | btrfs_tree_lock(left); |
| 963 | btrfs_set_lock_blocking(left); | ||
| 927 | wret = btrfs_cow_block(trans, root, left, | 964 | wret = btrfs_cow_block(trans, root, left, |
| 928 | parent, pslot - 1, &left, 0); | 965 | parent, pslot - 1, &left, 0); |
| 929 | if (wret) { | 966 | if (wret) { |
| @@ -934,6 +971,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 934 | right = read_node_slot(root, parent, pslot + 1); | 971 | right = read_node_slot(root, parent, pslot + 1); |
| 935 | if (right) { | 972 | if (right) { |
| 936 | btrfs_tree_lock(right); | 973 | btrfs_tree_lock(right); |
| 974 | btrfs_set_lock_blocking(right); | ||
| 937 | wret = btrfs_cow_block(trans, root, right, | 975 | wret = btrfs_cow_block(trans, root, right, |
| 938 | parent, pslot + 1, &right, 0); | 976 | parent, pslot + 1, &right, 0); |
| 939 | if (wret) { | 977 | if (wret) { |
| @@ -1109,6 +1147,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
| 1109 | u32 left_nr; | 1147 | u32 left_nr; |
| 1110 | 1148 | ||
| 1111 | btrfs_tree_lock(left); | 1149 | btrfs_tree_lock(left); |
| 1150 | btrfs_set_lock_blocking(left); | ||
| 1151 | |||
| 1112 | left_nr = btrfs_header_nritems(left); | 1152 | left_nr = btrfs_header_nritems(left); |
| 1113 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1153 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
| 1114 | wret = 1; | 1154 | wret = 1; |
| @@ -1155,7 +1195,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
| 1155 | */ | 1195 | */ |
| 1156 | if (right) { | 1196 | if (right) { |
| 1157 | u32 right_nr; | 1197 | u32 right_nr; |
| 1198 | |||
| 1158 | btrfs_tree_lock(right); | 1199 | btrfs_tree_lock(right); |
| 1200 | btrfs_set_lock_blocking(right); | ||
| 1201 | |||
| 1159 | right_nr = btrfs_header_nritems(right); | 1202 | right_nr = btrfs_header_nritems(right); |
| 1160 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1203 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
| 1161 | wret = 1; | 1204 | wret = 1; |
| @@ -1210,8 +1253,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1210 | struct btrfs_disk_key disk_key; | 1253 | struct btrfs_disk_key disk_key; |
| 1211 | u32 nritems; | 1254 | u32 nritems; |
| 1212 | u64 search; | 1255 | u64 search; |
| 1213 | u64 lowest_read; | 1256 | u64 target; |
| 1214 | u64 highest_read; | ||
| 1215 | u64 nread = 0; | 1257 | u64 nread = 0; |
| 1216 | int direction = path->reada; | 1258 | int direction = path->reada; |
| 1217 | struct extent_buffer *eb; | 1259 | struct extent_buffer *eb; |
| @@ -1235,8 +1277,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1235 | return; | 1277 | return; |
| 1236 | } | 1278 | } |
| 1237 | 1279 | ||
| 1238 | highest_read = search; | 1280 | target = search; |
| 1239 | lowest_read = search; | ||
| 1240 | 1281 | ||
| 1241 | nritems = btrfs_header_nritems(node); | 1282 | nritems = btrfs_header_nritems(node); |
| 1242 | nr = slot; | 1283 | nr = slot; |
| @@ -1256,27 +1297,80 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1256 | break; | 1297 | break; |
| 1257 | } | 1298 | } |
| 1258 | search = btrfs_node_blockptr(node, nr); | 1299 | search = btrfs_node_blockptr(node, nr); |
| 1259 | if ((search >= lowest_read && search <= highest_read) || | 1300 | if ((search <= target && target - search <= 65536) || |
| 1260 | (search < lowest_read && lowest_read - search <= 16384) || | 1301 | (search > target && search - target <= 65536)) { |
| 1261 | (search > highest_read && search - highest_read <= 16384)) { | ||
| 1262 | readahead_tree_block(root, search, blocksize, | 1302 | readahead_tree_block(root, search, blocksize, |
| 1263 | btrfs_node_ptr_generation(node, nr)); | 1303 | btrfs_node_ptr_generation(node, nr)); |
| 1264 | nread += blocksize; | 1304 | nread += blocksize; |
| 1265 | } | 1305 | } |
| 1266 | nscan++; | 1306 | nscan++; |
| 1267 | if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32)) | 1307 | if ((nread > 65536 || nscan > 32)) |
| 1268 | break; | 1308 | break; |
| 1309 | } | ||
| 1310 | } | ||
| 1269 | 1311 | ||
| 1270 | if (nread > (256 * 1024) || nscan > 128) | 1312 | /* |
| 1271 | break; | 1313 | * returns -EAGAIN if it had to drop the path, or zero if everything was in |
| 1314 | * cache | ||
| 1315 | */ | ||
| 1316 | static noinline int reada_for_balance(struct btrfs_root *root, | ||
| 1317 | struct btrfs_path *path, int level) | ||
| 1318 | { | ||
| 1319 | int slot; | ||
| 1320 | int nritems; | ||
| 1321 | struct extent_buffer *parent; | ||
| 1322 | struct extent_buffer *eb; | ||
| 1323 | u64 gen; | ||
| 1324 | u64 block1 = 0; | ||
| 1325 | u64 block2 = 0; | ||
| 1326 | int ret = 0; | ||
| 1327 | int blocksize; | ||
| 1272 | 1328 | ||
| 1273 | if (search < lowest_read) | 1329 | parent = path->nodes[level - 1]; |
| 1274 | lowest_read = search; | 1330 | if (!parent) |
| 1275 | if (search > highest_read) | 1331 | return 0; |
| 1276 | highest_read = search; | 1332 | |
| 1333 | nritems = btrfs_header_nritems(parent); | ||
| 1334 | slot = path->slots[level]; | ||
| 1335 | blocksize = btrfs_level_size(root, level); | ||
| 1336 | |||
| 1337 | if (slot > 0) { | ||
| 1338 | block1 = btrfs_node_blockptr(parent, slot - 1); | ||
| 1339 | gen = btrfs_node_ptr_generation(parent, slot - 1); | ||
| 1340 | eb = btrfs_find_tree_block(root, block1, blocksize); | ||
| 1341 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
| 1342 | block1 = 0; | ||
| 1343 | free_extent_buffer(eb); | ||
| 1344 | } | ||
| 1345 | if (slot < nritems) { | ||
| 1346 | block2 = btrfs_node_blockptr(parent, slot + 1); | ||
| 1347 | gen = btrfs_node_ptr_generation(parent, slot + 1); | ||
| 1348 | eb = btrfs_find_tree_block(root, block2, blocksize); | ||
| 1349 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
| 1350 | block2 = 0; | ||
| 1351 | free_extent_buffer(eb); | ||
| 1352 | } | ||
| 1353 | if (block1 || block2) { | ||
| 1354 | ret = -EAGAIN; | ||
| 1355 | btrfs_release_path(root, path); | ||
| 1356 | if (block1) | ||
| 1357 | readahead_tree_block(root, block1, blocksize, 0); | ||
| 1358 | if (block2) | ||
| 1359 | readahead_tree_block(root, block2, blocksize, 0); | ||
| 1360 | |||
| 1361 | if (block1) { | ||
| 1362 | eb = read_tree_block(root, block1, blocksize, 0); | ||
| 1363 | free_extent_buffer(eb); | ||
| 1364 | } | ||
| 1365 | if (block1) { | ||
| 1366 | eb = read_tree_block(root, block2, blocksize, 0); | ||
| 1367 | free_extent_buffer(eb); | ||
| 1368 | } | ||
| 1277 | } | 1369 | } |
| 1370 | return ret; | ||
| 1278 | } | 1371 | } |
| 1279 | 1372 | ||
| 1373 | |||
| 1280 | /* | 1374 | /* |
| 1281 | * when we walk down the tree, it is usually safe to unlock the higher layers | 1375 | * when we walk down the tree, it is usually safe to unlock the higher layers |
| 1282 | * in the tree. The exceptions are when our path goes through slot 0, because | 1376 | * in the tree. The exceptions are when our path goes through slot 0, because |
| @@ -1328,6 +1422,32 @@ static noinline void unlock_up(struct btrfs_path *path, int level, | |||
| 1328 | } | 1422 | } |
| 1329 | 1423 | ||
| 1330 | /* | 1424 | /* |
| 1425 | * This releases any locks held in the path starting at level and | ||
| 1426 | * going all the way up to the root. | ||
| 1427 | * | ||
| 1428 | * btrfs_search_slot will keep the lock held on higher nodes in a few | ||
| 1429 | * corner cases, such as COW of the block at slot zero in the node. This | ||
| 1430 | * ignores those rules, and it should only be called when there are no | ||
| 1431 | * more updates to be done higher up in the tree. | ||
| 1432 | */ | ||
| 1433 | noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) | ||
| 1434 | { | ||
| 1435 | int i; | ||
| 1436 | |||
| 1437 | if (path->keep_locks || path->lowest_level) | ||
| 1438 | return; | ||
| 1439 | |||
| 1440 | for (i = level; i < BTRFS_MAX_LEVEL; i++) { | ||
| 1441 | if (!path->nodes[i]) | ||
| 1442 | continue; | ||
| 1443 | if (!path->locks[i]) | ||
| 1444 | continue; | ||
| 1445 | btrfs_tree_unlock(path->nodes[i]); | ||
| 1446 | path->locks[i] = 0; | ||
| 1447 | } | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | /* | ||
| 1331 | * look for key in the tree. path is filled in with nodes along the way | 1451 | * look for key in the tree. path is filled in with nodes along the way |
| 1332 | * if key is found, we return zero and you can find the item in the leaf | 1452 | * if key is found, we return zero and you can find the item in the leaf |
| 1333 | * level of the path (level 0) | 1453 | * level of the path (level 0) |
| @@ -1387,31 +1507,30 @@ again: | |||
| 1387 | int wret; | 1507 | int wret; |
| 1388 | 1508 | ||
| 1389 | /* is a cow on this block not required */ | 1509 | /* is a cow on this block not required */ |
| 1390 | spin_lock(&root->fs_info->hash_lock); | ||
| 1391 | if (btrfs_header_generation(b) == trans->transid && | 1510 | if (btrfs_header_generation(b) == trans->transid && |
| 1392 | btrfs_header_owner(b) == root->root_key.objectid && | 1511 | btrfs_header_owner(b) == root->root_key.objectid && |
| 1393 | !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { | 1512 | !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { |
| 1394 | spin_unlock(&root->fs_info->hash_lock); | ||
| 1395 | goto cow_done; | 1513 | goto cow_done; |
| 1396 | } | 1514 | } |
| 1397 | spin_unlock(&root->fs_info->hash_lock); | ||
| 1398 | 1515 | ||
| 1399 | /* ok, we have to cow, is our old prealloc the right | 1516 | /* ok, we have to cow, is our old prealloc the right |
| 1400 | * size? | 1517 | * size? |
| 1401 | */ | 1518 | */ |
| 1402 | if (prealloc_block.objectid && | 1519 | if (prealloc_block.objectid && |
| 1403 | prealloc_block.offset != b->len) { | 1520 | prealloc_block.offset != b->len) { |
| 1521 | btrfs_release_path(root, p); | ||
| 1404 | btrfs_free_reserved_extent(root, | 1522 | btrfs_free_reserved_extent(root, |
| 1405 | prealloc_block.objectid, | 1523 | prealloc_block.objectid, |
| 1406 | prealloc_block.offset); | 1524 | prealloc_block.offset); |
| 1407 | prealloc_block.objectid = 0; | 1525 | prealloc_block.objectid = 0; |
| 1526 | goto again; | ||
| 1408 | } | 1527 | } |
| 1409 | 1528 | ||
| 1410 | /* | 1529 | /* |
| 1411 | * for higher level blocks, try not to allocate blocks | 1530 | * for higher level blocks, try not to allocate blocks |
| 1412 | * with the block and the parent locks held. | 1531 | * with the block and the parent locks held. |
| 1413 | */ | 1532 | */ |
| 1414 | if (level > 1 && !prealloc_block.objectid && | 1533 | if (level > 0 && !prealloc_block.objectid && |
| 1415 | btrfs_path_lock_waiting(p, level)) { | 1534 | btrfs_path_lock_waiting(p, level)) { |
| 1416 | u32 size = b->len; | 1535 | u32 size = b->len; |
| 1417 | u64 hint = b->start; | 1536 | u64 hint = b->start; |
| @@ -1425,6 +1544,8 @@ again: | |||
| 1425 | goto again; | 1544 | goto again; |
| 1426 | } | 1545 | } |
| 1427 | 1546 | ||
| 1547 | btrfs_set_path_blocking(p); | ||
| 1548 | |||
| 1428 | wret = btrfs_cow_block(trans, root, b, | 1549 | wret = btrfs_cow_block(trans, root, b, |
| 1429 | p->nodes[level + 1], | 1550 | p->nodes[level + 1], |
| 1430 | p->slots[level + 1], | 1551 | p->slots[level + 1], |
| @@ -1446,6 +1567,22 @@ cow_done: | |||
| 1446 | if (!p->skip_locking) | 1567 | if (!p->skip_locking) |
| 1447 | p->locks[level] = 1; | 1568 | p->locks[level] = 1; |
| 1448 | 1569 | ||
| 1570 | btrfs_clear_path_blocking(p); | ||
| 1571 | |||
| 1572 | /* | ||
| 1573 | * we have a lock on b and as long as we aren't changing | ||
| 1574 | * the tree, there is no way to for the items in b to change. | ||
| 1575 | * It is safe to drop the lock on our parent before we | ||
| 1576 | * go through the expensive btree search on b. | ||
| 1577 | * | ||
| 1578 | * If cow is true, then we might be changing slot zero, | ||
| 1579 | * which may require changing the parent. So, we can't | ||
| 1580 | * drop the lock until after we know which slot we're | ||
| 1581 | * operating on. | ||
| 1582 | */ | ||
| 1583 | if (!cow) | ||
| 1584 | btrfs_unlock_up_safe(p, level + 1); | ||
| 1585 | |||
| 1449 | ret = check_block(root, p, level); | 1586 | ret = check_block(root, p, level); |
| 1450 | if (ret) { | 1587 | if (ret) { |
| 1451 | ret = -1; | 1588 | ret = -1; |
| @@ -1453,6 +1590,7 @@ cow_done: | |||
| 1453 | } | 1590 | } |
| 1454 | 1591 | ||
| 1455 | ret = bin_search(b, key, level, &slot); | 1592 | ret = bin_search(b, key, level, &slot); |
| 1593 | |||
| 1456 | if (level != 0) { | 1594 | if (level != 0) { |
| 1457 | if (ret && slot > 0) | 1595 | if (ret && slot > 0) |
| 1458 | slot -= 1; | 1596 | slot -= 1; |
| @@ -1460,7 +1598,16 @@ cow_done: | |||
| 1460 | if ((p->search_for_split || ins_len > 0) && | 1598 | if ((p->search_for_split || ins_len > 0) && |
| 1461 | btrfs_header_nritems(b) >= | 1599 | btrfs_header_nritems(b) >= |
| 1462 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { | 1600 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { |
| 1463 | int sret = split_node(trans, root, p, level); | 1601 | int sret; |
| 1602 | |||
| 1603 | sret = reada_for_balance(root, p, level); | ||
| 1604 | if (sret) | ||
| 1605 | goto again; | ||
| 1606 | |||
| 1607 | btrfs_set_path_blocking(p); | ||
| 1608 | sret = split_node(trans, root, p, level); | ||
| 1609 | btrfs_clear_path_blocking(p); | ||
| 1610 | |||
| 1464 | BUG_ON(sret > 0); | 1611 | BUG_ON(sret > 0); |
| 1465 | if (sret) { | 1612 | if (sret) { |
| 1466 | ret = sret; | 1613 | ret = sret; |
| @@ -1468,9 +1615,19 @@ cow_done: | |||
| 1468 | } | 1615 | } |
| 1469 | b = p->nodes[level]; | 1616 | b = p->nodes[level]; |
| 1470 | slot = p->slots[level]; | 1617 | slot = p->slots[level]; |
| 1471 | } else if (ins_len < 0) { | 1618 | } else if (ins_len < 0 && |
| 1472 | int sret = balance_level(trans, root, p, | 1619 | btrfs_header_nritems(b) < |
| 1473 | level); | 1620 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) { |
| 1621 | int sret; | ||
| 1622 | |||
| 1623 | sret = reada_for_balance(root, p, level); | ||
| 1624 | if (sret) | ||
| 1625 | goto again; | ||
| 1626 | |||
| 1627 | btrfs_set_path_blocking(p); | ||
| 1628 | sret = balance_level(trans, root, p, level); | ||
| 1629 | btrfs_clear_path_blocking(p); | ||
| 1630 | |||
| 1474 | if (sret) { | 1631 | if (sret) { |
| 1475 | ret = sret; | 1632 | ret = sret; |
| 1476 | goto done; | 1633 | goto done; |
| @@ -1504,7 +1661,7 @@ cow_done: | |||
| 1504 | * of the btree by dropping locks before | 1661 | * of the btree by dropping locks before |
| 1505 | * we read. | 1662 | * we read. |
| 1506 | */ | 1663 | */ |
| 1507 | if (level > 1) { | 1664 | if (level > 0) { |
| 1508 | btrfs_release_path(NULL, p); | 1665 | btrfs_release_path(NULL, p); |
| 1509 | if (tmp) | 1666 | if (tmp) |
| 1510 | free_extent_buffer(tmp); | 1667 | free_extent_buffer(tmp); |
| @@ -1519,6 +1676,7 @@ cow_done: | |||
| 1519 | free_extent_buffer(tmp); | 1676 | free_extent_buffer(tmp); |
| 1520 | goto again; | 1677 | goto again; |
| 1521 | } else { | 1678 | } else { |
| 1679 | btrfs_set_path_blocking(p); | ||
| 1522 | if (tmp) | 1680 | if (tmp) |
| 1523 | free_extent_buffer(tmp); | 1681 | free_extent_buffer(tmp); |
| 1524 | if (should_reada) | 1682 | if (should_reada) |
| @@ -1528,14 +1686,29 @@ cow_done: | |||
| 1528 | b = read_node_slot(root, b, slot); | 1686 | b = read_node_slot(root, b, slot); |
| 1529 | } | 1687 | } |
| 1530 | } | 1688 | } |
| 1531 | if (!p->skip_locking) | 1689 | if (!p->skip_locking) { |
| 1532 | btrfs_tree_lock(b); | 1690 | int lret; |
| 1691 | |||
| 1692 | btrfs_clear_path_blocking(p); | ||
| 1693 | lret = btrfs_try_spin_lock(b); | ||
| 1694 | |||
| 1695 | if (!lret) { | ||
| 1696 | btrfs_set_path_blocking(p); | ||
| 1697 | btrfs_tree_lock(b); | ||
| 1698 | btrfs_clear_path_blocking(p); | ||
| 1699 | } | ||
| 1700 | } | ||
| 1533 | } else { | 1701 | } else { |
| 1534 | p->slots[level] = slot; | 1702 | p->slots[level] = slot; |
| 1535 | if (ins_len > 0 && | 1703 | if (ins_len > 0 && |
| 1536 | btrfs_leaf_free_space(root, b) < ins_len) { | 1704 | btrfs_leaf_free_space(root, b) < ins_len) { |
| 1537 | int sret = split_leaf(trans, root, key, | 1705 | int sret; |
| 1706 | |||
| 1707 | btrfs_set_path_blocking(p); | ||
| 1708 | sret = split_leaf(trans, root, key, | ||
| 1538 | p, ins_len, ret == 0); | 1709 | p, ins_len, ret == 0); |
| 1710 | btrfs_clear_path_blocking(p); | ||
| 1711 | |||
| 1539 | BUG_ON(sret > 0); | 1712 | BUG_ON(sret > 0); |
| 1540 | if (sret) { | 1713 | if (sret) { |
| 1541 | ret = sret; | 1714 | ret = sret; |
| @@ -1549,12 +1722,16 @@ cow_done: | |||
| 1549 | } | 1722 | } |
| 1550 | ret = 1; | 1723 | ret = 1; |
| 1551 | done: | 1724 | done: |
| 1725 | /* | ||
| 1726 | * we don't really know what they plan on doing with the path | ||
| 1727 | * from here on, so for now just mark it as blocking | ||
| 1728 | */ | ||
| 1729 | btrfs_set_path_blocking(p); | ||
| 1552 | if (prealloc_block.objectid) { | 1730 | if (prealloc_block.objectid) { |
| 1553 | btrfs_free_reserved_extent(root, | 1731 | btrfs_free_reserved_extent(root, |
| 1554 | prealloc_block.objectid, | 1732 | prealloc_block.objectid, |
| 1555 | prealloc_block.offset); | 1733 | prealloc_block.offset); |
| 1556 | } | 1734 | } |
| 1557 | |||
| 1558 | return ret; | 1735 | return ret; |
| 1559 | } | 1736 | } |
| 1560 | 1737 | ||
| @@ -1578,6 +1755,8 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1578 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); | 1755 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); |
| 1579 | BUG_ON(ret); | 1756 | BUG_ON(ret); |
| 1580 | 1757 | ||
| 1758 | btrfs_set_lock_blocking(eb); | ||
| 1759 | |||
| 1581 | parent = eb; | 1760 | parent = eb; |
| 1582 | while (1) { | 1761 | while (1) { |
| 1583 | level = btrfs_header_level(parent); | 1762 | level = btrfs_header_level(parent); |
| @@ -1602,6 +1781,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1602 | eb = read_tree_block(root, bytenr, blocksize, | 1781 | eb = read_tree_block(root, bytenr, blocksize, |
| 1603 | generation); | 1782 | generation); |
| 1604 | btrfs_tree_lock(eb); | 1783 | btrfs_tree_lock(eb); |
| 1784 | btrfs_set_lock_blocking(eb); | ||
| 1605 | } | 1785 | } |
| 1606 | 1786 | ||
| 1607 | /* | 1787 | /* |
| @@ -1626,6 +1806,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1626 | eb = read_tree_block(root, bytenr, blocksize, | 1806 | eb = read_tree_block(root, bytenr, blocksize, |
| 1627 | generation); | 1807 | generation); |
| 1628 | btrfs_tree_lock(eb); | 1808 | btrfs_tree_lock(eb); |
| 1809 | btrfs_set_lock_blocking(eb); | ||
| 1629 | } | 1810 | } |
| 1630 | 1811 | ||
| 1631 | ret = btrfs_cow_block(trans, root, eb, parent, slot, | 1812 | ret = btrfs_cow_block(trans, root, eb, parent, slot, |
| @@ -2172,6 +2353,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2172 | 2353 | ||
| 2173 | right = read_node_slot(root, upper, slot + 1); | 2354 | right = read_node_slot(root, upper, slot + 1); |
| 2174 | btrfs_tree_lock(right); | 2355 | btrfs_tree_lock(right); |
| 2356 | btrfs_set_lock_blocking(right); | ||
| 2357 | |||
| 2175 | free_space = btrfs_leaf_free_space(root, right); | 2358 | free_space = btrfs_leaf_free_space(root, right); |
| 2176 | if (free_space < data_size) | 2359 | if (free_space < data_size) |
| 2177 | goto out_unlock; | 2360 | goto out_unlock; |
| @@ -2367,6 +2550,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2367 | 2550 | ||
| 2368 | left = read_node_slot(root, path->nodes[1], slot - 1); | 2551 | left = read_node_slot(root, path->nodes[1], slot - 1); |
| 2369 | btrfs_tree_lock(left); | 2552 | btrfs_tree_lock(left); |
| 2553 | btrfs_set_lock_blocking(left); | ||
| 2554 | |||
| 2370 | free_space = btrfs_leaf_free_space(root, left); | 2555 | free_space = btrfs_leaf_free_space(root, left); |
| 2371 | if (free_space < data_size) { | 2556 | if (free_space < data_size) { |
| 2372 | ret = 1; | 2557 | ret = 1; |
| @@ -2825,6 +3010,12 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, | |||
| 2825 | path->keep_locks = 0; | 3010 | path->keep_locks = 0; |
| 2826 | BUG_ON(ret); | 3011 | BUG_ON(ret); |
| 2827 | 3012 | ||
| 3013 | /* | ||
| 3014 | * make sure any changes to the path from split_leaf leave it | ||
| 3015 | * in a blocking state | ||
| 3016 | */ | ||
| 3017 | btrfs_set_path_blocking(path); | ||
| 3018 | |||
| 2828 | leaf = path->nodes[0]; | 3019 | leaf = path->nodes[0]; |
| 2829 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); | 3020 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); |
| 2830 | 3021 | ||
| @@ -3354,6 +3545,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, | |||
| 3354 | BUG(); | 3545 | BUG(); |
| 3355 | } | 3546 | } |
| 3356 | out: | 3547 | out: |
| 3548 | btrfs_unlock_up_safe(path, 1); | ||
| 3357 | return ret; | 3549 | return ret; |
| 3358 | } | 3550 | } |
| 3359 | 3551 | ||
| @@ -3441,15 +3633,22 @@ noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, | |||
| 3441 | { | 3633 | { |
| 3442 | int ret; | 3634 | int ret; |
| 3443 | u64 root_gen = btrfs_header_generation(path->nodes[1]); | 3635 | u64 root_gen = btrfs_header_generation(path->nodes[1]); |
| 3636 | u64 parent_start = path->nodes[1]->start; | ||
| 3637 | u64 parent_owner = btrfs_header_owner(path->nodes[1]); | ||
| 3444 | 3638 | ||
| 3445 | ret = del_ptr(trans, root, path, 1, path->slots[1]); | 3639 | ret = del_ptr(trans, root, path, 1, path->slots[1]); |
| 3446 | if (ret) | 3640 | if (ret) |
| 3447 | return ret; | 3641 | return ret; |
| 3448 | 3642 | ||
| 3643 | /* | ||
| 3644 | * btrfs_free_extent is expensive, we want to make sure we | ||
| 3645 | * aren't holding any locks when we call it | ||
| 3646 | */ | ||
| 3647 | btrfs_unlock_up_safe(path, 0); | ||
| 3648 | |||
| 3449 | ret = btrfs_free_extent(trans, root, bytenr, | 3649 | ret = btrfs_free_extent(trans, root, bytenr, |
| 3450 | btrfs_level_size(root, 0), | 3650 | btrfs_level_size(root, 0), |
| 3451 | path->nodes[1]->start, | 3651 | parent_start, parent_owner, |
| 3452 | btrfs_header_owner(path->nodes[1]), | ||
| 3453 | root_gen, 0, 1); | 3652 | root_gen, 0, 1); |
| 3454 | return ret; | 3653 | return ret; |
| 3455 | } | 3654 | } |
| @@ -3721,12 +3920,14 @@ find_next_key: | |||
| 3721 | */ | 3920 | */ |
| 3722 | if (slot >= nritems) { | 3921 | if (slot >= nritems) { |
| 3723 | path->slots[level] = slot; | 3922 | path->slots[level] = slot; |
| 3923 | btrfs_set_path_blocking(path); | ||
| 3724 | sret = btrfs_find_next_key(root, path, min_key, level, | 3924 | sret = btrfs_find_next_key(root, path, min_key, level, |
| 3725 | cache_only, min_trans); | 3925 | cache_only, min_trans); |
| 3726 | if (sret == 0) { | 3926 | if (sret == 0) { |
| 3727 | btrfs_release_path(root, path); | 3927 | btrfs_release_path(root, path); |
| 3728 | goto again; | 3928 | goto again; |
| 3729 | } else { | 3929 | } else { |
| 3930 | btrfs_clear_path_blocking(path); | ||
| 3730 | goto out; | 3931 | goto out; |
| 3731 | } | 3932 | } |
| 3732 | } | 3933 | } |
| @@ -3738,16 +3939,20 @@ find_next_key: | |||
| 3738 | unlock_up(path, level, 1); | 3939 | unlock_up(path, level, 1); |
| 3739 | goto out; | 3940 | goto out; |
| 3740 | } | 3941 | } |
| 3942 | btrfs_set_path_blocking(path); | ||
| 3741 | cur = read_node_slot(root, cur, slot); | 3943 | cur = read_node_slot(root, cur, slot); |
| 3742 | 3944 | ||
| 3743 | btrfs_tree_lock(cur); | 3945 | btrfs_tree_lock(cur); |
| 3946 | |||
| 3744 | path->locks[level - 1] = 1; | 3947 | path->locks[level - 1] = 1; |
| 3745 | path->nodes[level - 1] = cur; | 3948 | path->nodes[level - 1] = cur; |
| 3746 | unlock_up(path, level, 1); | 3949 | unlock_up(path, level, 1); |
| 3950 | btrfs_clear_path_blocking(path); | ||
| 3747 | } | 3951 | } |
| 3748 | out: | 3952 | out: |
| 3749 | if (ret == 0) | 3953 | if (ret == 0) |
| 3750 | memcpy(min_key, &found_key, sizeof(found_key)); | 3954 | memcpy(min_key, &found_key, sizeof(found_key)); |
| 3955 | btrfs_set_path_blocking(path); | ||
| 3751 | return ret; | 3956 | return ret; |
| 3752 | } | 3957 | } |
| 3753 | 3958 | ||
| @@ -3843,6 +4048,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3843 | if (ret < 0) | 4048 | if (ret < 0) |
| 3844 | return ret; | 4049 | return ret; |
| 3845 | 4050 | ||
| 4051 | btrfs_set_path_blocking(path); | ||
| 3846 | nritems = btrfs_header_nritems(path->nodes[0]); | 4052 | nritems = btrfs_header_nritems(path->nodes[0]); |
| 3847 | /* | 4053 | /* |
| 3848 | * by releasing the path above we dropped all our locks. A balance | 4054 | * by releasing the path above we dropped all our locks. A balance |
| @@ -3873,6 +4079,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3873 | free_extent_buffer(next); | 4079 | free_extent_buffer(next); |
| 3874 | } | 4080 | } |
| 3875 | 4081 | ||
| 4082 | /* the path was set to blocking above */ | ||
| 3876 | if (level == 1 && (path->locks[1] || path->skip_locking) && | 4083 | if (level == 1 && (path->locks[1] || path->skip_locking) && |
| 3877 | path->reada) | 4084 | path->reada) |
| 3878 | reada_for_search(root, path, level, slot, 0); | 4085 | reada_for_search(root, path, level, slot, 0); |
| @@ -3881,6 +4088,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3881 | if (!path->skip_locking) { | 4088 | if (!path->skip_locking) { |
| 3882 | WARN_ON(!btrfs_tree_locked(c)); | 4089 | WARN_ON(!btrfs_tree_locked(c)); |
| 3883 | btrfs_tree_lock(next); | 4090 | btrfs_tree_lock(next); |
| 4091 | btrfs_set_lock_blocking(next); | ||
| 3884 | } | 4092 | } |
| 3885 | break; | 4093 | break; |
| 3886 | } | 4094 | } |
| @@ -3897,12 +4105,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3897 | path->locks[level] = 1; | 4105 | path->locks[level] = 1; |
| 3898 | if (!level) | 4106 | if (!level) |
| 3899 | break; | 4107 | break; |
| 4108 | |||
| 4109 | btrfs_set_path_blocking(path); | ||
| 3900 | if (level == 1 && path->locks[1] && path->reada) | 4110 | if (level == 1 && path->locks[1] && path->reada) |
| 3901 | reada_for_search(root, path, level, slot, 0); | 4111 | reada_for_search(root, path, level, slot, 0); |
| 3902 | next = read_node_slot(root, next, 0); | 4112 | next = read_node_slot(root, next, 0); |
| 3903 | if (!path->skip_locking) { | 4113 | if (!path->skip_locking) { |
| 3904 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); | 4114 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); |
| 3905 | btrfs_tree_lock(next); | 4115 | btrfs_tree_lock(next); |
| 4116 | btrfs_set_lock_blocking(next); | ||
| 3906 | } | 4117 | } |
| 3907 | } | 4118 | } |
| 3908 | done: | 4119 | done: |
| @@ -3927,6 +4138,7 @@ int btrfs_previous_item(struct btrfs_root *root, | |||
| 3927 | 4138 | ||
| 3928 | while (1) { | 4139 | while (1) { |
| 3929 | if (path->slots[0] == 0) { | 4140 | if (path->slots[0] == 0) { |
| 4141 | btrfs_set_path_blocking(path); | ||
| 3930 | ret = btrfs_prev_leaf(root, path); | 4142 | ret = btrfs_prev_leaf(root, path); |
| 3931 | if (ret != 0) | 4143 | if (ret != 0) |
| 3932 | return ret; | 4144 | return ret; |
