extent-tree.c (1a5bc167f6707542b79a55452075525620ed43f5) | extent-tree.c (db94535db75e67fab12ccbb7f5ee548e33fed891) |
---|---|
1/* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, --- 115 unchanged lines hidden (view full) --- 124 block_group->cached = 1; 125err: 126 btrfs_free_path(path); 127 return 0; 128} 129 130struct btrfs_block_group_cache *btrfs_lookup_block_group(struct 131 btrfs_fs_info *info, | 1/* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, --- 115 unchanged lines hidden (view full) --- 124 block_group->cached = 1; 125err: 126 btrfs_free_path(path); 127 return 0; 128} 129 130struct btrfs_block_group_cache *btrfs_lookup_block_group(struct 131 btrfs_fs_info *info, |
132 u64 blocknr) | 132 u64 bytenr) |
133{ 134 struct extent_map_tree *block_group_cache; 135 struct btrfs_block_group_cache *block_group = NULL; 136 u64 ptr; 137 u64 start; 138 u64 end; 139 int ret; 140 141 block_group_cache = &info->block_group_cache; 142 ret = find_first_extent_bit(block_group_cache, | 133{ 134 struct extent_map_tree *block_group_cache; 135 struct btrfs_block_group_cache *block_group = NULL; 136 u64 ptr; 137 u64 start; 138 u64 end; 139 int ret; 140 141 block_group_cache = &info->block_group_cache; 142 ret = find_first_extent_bit(block_group_cache, |
143 blocknr, &start, &end, | 143 bytenr, &start, &end, |
144 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); 145 if (ret) { 146 return NULL; 147 } 148 ret = get_state_private(block_group_cache, start, &ptr); 149 if (ret) 150 return NULL; 151 152 block_group = (struct btrfs_block_group_cache *)ptr; 153 154 | 144 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); 145 if (ret) { 146 return NULL; 147 } 148 ret = get_state_private(block_group_cache, start, &ptr); 149 if (ret) 150 return NULL; 151 152 block_group = (struct btrfs_block_group_cache *)ptr; 153 154 |
155 if (block_group->key.objectid <= blocknr && blocknr <= | 155 if (block_group->key.objectid <= bytenr && bytenr <= |
156 block_group->key.objectid + block_group->key.offset) 157 return block_group; 158 159 return NULL; 160} 161 162static u64 find_search_start(struct btrfs_root *root, 163 struct btrfs_block_group_cache **cache_ret, --- 146 unchanged lines hidden (view full) --- 310 goto again; 311 } 312found: 313 return found_group; 314} 315 316int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, 317 struct btrfs_root *root, | 156 block_group->key.objectid + block_group->key.offset) 157 return block_group; 158 159 return NULL; 160} 161 162static u64 find_search_start(struct btrfs_root *root, 163 struct btrfs_block_group_cache **cache_ret, --- 146 unchanged lines hidden (view full) --- 310 goto again; 311 } 312found: 313 return found_group; 314} 315 316int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, 317 struct btrfs_root *root, |
318 u64 blocknr, u64 num_blocks) | 318 u64 bytenr, u64 num_bytes) |
319{ 320 struct btrfs_path *path; 321 int ret; 322 struct btrfs_key key; 323 struct extent_buffer *l; 324 struct btrfs_extent_item *item; 325 u32 refs; 326 | 319{ 320 struct btrfs_path *path; 321 int ret; 322 struct btrfs_key key; 323 struct extent_buffer *l; 324 struct btrfs_extent_item *item; 325 u32 refs; 326 |
327 WARN_ON(num_bytes < root->sectorsize); |
|
327 path = btrfs_alloc_path(); 328 if (!path) 329 return -ENOMEM; 330 | 328 path = btrfs_alloc_path(); 329 if (!path) 330 return -ENOMEM; 331 |
331 key.objectid = blocknr; | 332 key.objectid = bytenr; |
332 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 333 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
333 key.offset = num_blocks; | 334 key.offset = num_bytes; |
334 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 335 0, 1); 336 if (ret < 0) 337 return ret; 338 if (ret != 0) { 339 BUG(); 340 } 341 BUG_ON(ret != 0); --- 14 unchanged lines hidden (view full) --- 356 struct btrfs_root *root) 357{ 358 finish_current_insert(trans, root->fs_info->extent_root); 359 del_pending_extents(trans, root->fs_info->extent_root); 360 return 0; 361} 362 363static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 335 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 336 0, 1); 337 if (ret < 0) 338 return ret; 339 if (ret != 0) { 340 BUG(); 341 } 342 BUG_ON(ret != 0); --- 14 unchanged lines hidden (view full) --- 357 struct btrfs_root *root) 358{ 359 finish_current_insert(trans, root->fs_info->extent_root); 360 del_pending_extents(trans, root->fs_info->extent_root); 361 return 0; 362} 363 364static int lookup_extent_ref(struct btrfs_trans_handle *trans, |
364 struct btrfs_root *root, u64 blocknr, 365 u64 num_blocks, u32 *refs) | 365 struct btrfs_root *root, u64 bytenr, 366 u64 num_bytes, u32 *refs) |
366{ 367 struct btrfs_path *path; 368 int ret; 369 struct btrfs_key key; 370 struct extent_buffer *l; 371 struct btrfs_extent_item *item; 372 | 367{ 368 struct btrfs_path *path; 369 int ret; 370 struct btrfs_key key; 371 struct extent_buffer *l; 372 struct btrfs_extent_item *item; 373 |
374 WARN_ON(num_bytes < root->sectorsize); |
|
373 path = btrfs_alloc_path(); | 375 path = btrfs_alloc_path(); |
374 key.objectid = blocknr; 375 key.offset = num_blocks; | 376 key.objectid = bytenr; 377 key.offset = num_bytes; |
376 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 377 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 378 0, 0); 379 if (ret < 0) 380 goto out; 381 if (ret != 0) { 382 btrfs_print_leaf(root, path->nodes[0]); | 378 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 379 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 380 0, 0); 381 if (ret < 0) 382 goto out; 383 if (ret != 0) { 384 btrfs_print_leaf(root, path->nodes[0]); |
383 printk("failed to find block number %Lu\n", blocknr); | 385 printk("failed to find block number %Lu\n", bytenr); |
384 BUG(); 385 } 386 l = path->nodes[0]; 387 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); 388 *refs = btrfs_extent_refs(l, item); 389out: 390 btrfs_free_path(path); 391 return 0; 392} 393 394int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 395 struct btrfs_root *root) 396{ | 386 BUG(); 387 } 388 l = path->nodes[0]; 389 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); 390 *refs = btrfs_extent_refs(l, item); 391out: 392 btrfs_free_path(path); 393 return 0; 394} 395 396int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 397 struct btrfs_root *root) 398{ |
397 return btrfs_inc_extent_ref(trans, root, 398 extent_buffer_blocknr(root->node), 1); | 399 return btrfs_inc_extent_ref(trans, root, root->node->start, 400 root->node->len); |
399} 400 401int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 402 struct extent_buffer *buf) 403{ | 401} 402 403int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 404 struct extent_buffer *buf) 405{ |
404 u64 blocknr; | 406 u64 bytenr; |
405 u32 nritems; 406 struct btrfs_key key; 407 struct btrfs_file_extent_item *fi; 408 int i; | 407 u32 nritems; 408 struct btrfs_key key; 409 struct btrfs_file_extent_item *fi; 410 int i; |
409 int leaf; | 411 int level; |
410 int ret; 411 int faili; 412 int err; 413 414 if (!root->ref_cows) 415 return 0; 416 | 412 int ret; 413 int faili; 414 int err; 415 416 if (!root->ref_cows) 417 return 0; 418 |
417 leaf = btrfs_is_leaf(buf); | 419 level = btrfs_header_level(buf); |
418 nritems = btrfs_header_nritems(buf); 419 for (i = 0; i < nritems; i++) { | 420 nritems = btrfs_header_nritems(buf); 421 for (i = 0; i < nritems; i++) { |
420 if (leaf) { 421 u64 disk_blocknr; | 422 if (level == 0) { 423 u64 disk_bytenr; |
422 btrfs_item_key_to_cpu(buf, &key, i); 423 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 424 continue; 425 fi = btrfs_item_ptr(buf, i, 426 struct btrfs_file_extent_item); 427 if (btrfs_file_extent_type(buf, fi) == 428 BTRFS_FILE_EXTENT_INLINE) 429 continue; | 424 btrfs_item_key_to_cpu(buf, &key, i); 425 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 426 continue; 427 fi = btrfs_item_ptr(buf, i, 428 struct btrfs_file_extent_item); 429 if (btrfs_file_extent_type(buf, fi) == 430 BTRFS_FILE_EXTENT_INLINE) 431 continue; |
430 disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); 431 if (disk_blocknr == 0) | 432 disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); 433 if (disk_bytenr == 0) |
432 continue; | 434 continue; |
433 ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, 434 btrfs_file_extent_disk_num_blocks(buf, fi)); | 435 ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, 436 btrfs_file_extent_disk_num_bytes(buf, fi)); |
435 if (ret) { 436 faili = i; 437 goto fail; 438 } 439 } else { | 437 if (ret) { 438 faili = i; 439 goto fail; 440 } 441 } else { |
440 blocknr = btrfs_node_blockptr(buf, i); 441 ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); | 442 bytenr = btrfs_node_blockptr(buf, i); 443 ret = btrfs_inc_extent_ref(trans, root, bytenr, 444 btrfs_level_size(root, level - 1)); |
442 if (ret) { 443 faili = i; 444 goto fail; 445 } 446 } 447 } 448 return 0; 449fail: 450 WARN_ON(1); 451 for (i =0; i < faili; i++) { | 445 if (ret) { 446 faili = i; 447 goto fail; 448 } 449 } 450 } 451 return 0; 452fail: 453 WARN_ON(1); 454 for (i =0; i < faili; i++) { |
452 if (leaf) { 453 u64 disk_blocknr; | 455 if (level == 0) { 456 u64 disk_bytenr; |
454 btrfs_item_key_to_cpu(buf, &key, i); 455 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 456 continue; 457 fi = btrfs_item_ptr(buf, i, 458 struct btrfs_file_extent_item); 459 if (btrfs_file_extent_type(buf, fi) == 460 BTRFS_FILE_EXTENT_INLINE) 461 continue; | 457 btrfs_item_key_to_cpu(buf, &key, i); 458 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 459 continue; 460 fi = btrfs_item_ptr(buf, i, 461 struct btrfs_file_extent_item); 462 if (btrfs_file_extent_type(buf, fi) == 463 BTRFS_FILE_EXTENT_INLINE) 464 continue; |
462 disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); 463 if (disk_blocknr == 0) | 465 disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); 466 if (disk_bytenr == 0) |
464 continue; | 467 continue; |
465 err = btrfs_free_extent(trans, root, disk_blocknr, 466 btrfs_file_extent_disk_num_blocks(buf, | 468 err = btrfs_free_extent(trans, root, disk_bytenr, 469 btrfs_file_extent_disk_num_bytes(buf, |
467 fi), 0); 468 BUG_ON(err); 469 } else { | 470 fi), 0); 471 BUG_ON(err); 472 } else { |
470 blocknr = btrfs_node_blockptr(buf, i); 471 err = btrfs_free_extent(trans, root, blocknr, 1, 0); | 473 bytenr = btrfs_node_blockptr(buf, i); 474 err = btrfs_free_extent(trans, root, bytenr, 475 btrfs_level_size(root, level - 1), 0); |
472 BUG_ON(err); 473 } 474 } 475 return ret; 476} 477 478static int write_one_cache_group(struct btrfs_trans_handle *trans, 479 struct btrfs_root *root, --- 73 unchanged lines hidden (view full) --- 553 BLOCK_GROUP_DIRTY, GFP_NOFS); 554 } 555 btrfs_free_path(path); 556 return werr; 557} 558 559static int update_block_group(struct btrfs_trans_handle *trans, 560 struct btrfs_root *root, | 476 BUG_ON(err); 477 } 478 } 479 return ret; 480} 481 482static int write_one_cache_group(struct btrfs_trans_handle *trans, 483 struct btrfs_root *root, --- 73 unchanged lines hidden (view full) --- 557 BLOCK_GROUP_DIRTY, GFP_NOFS); 558 } 559 btrfs_free_path(path); 560 return werr; 561} 562 563static int update_block_group(struct btrfs_trans_handle *trans, 564 struct btrfs_root *root, |
561 u64 blocknr, u64 num, int alloc, int mark_free, 562 int data) | 565 u64 bytenr, u64 num_bytes, int alloc, 566 int mark_free, int data) |
563{ 564 struct btrfs_block_group_cache *cache; 565 struct btrfs_fs_info *info = root->fs_info; | 567{ 568 struct btrfs_block_group_cache *cache; 569 struct btrfs_fs_info *info = root->fs_info; |
566 u64 total = num; | 570 u64 total = num_bytes; |
567 u64 old_val; | 571 u64 old_val; |
568 u64 block_in_group; | 572 u64 byte_in_group; |
569 u64 start; 570 u64 end; 571 572 while(total) { | 573 u64 start; 574 u64 end; 575 576 while(total) { |
573 cache = btrfs_lookup_block_group(info, blocknr); | 577 cache = btrfs_lookup_block_group(info, bytenr); |
574 if (!cache) { 575 return -1; 576 } | 578 if (!cache) { 579 return -1; 580 } |
577 block_in_group = blocknr - cache->key.objectid; 578 WARN_ON(block_in_group > cache->key.offset); | 581 byte_in_group = bytenr - cache->key.objectid; 582 WARN_ON(byte_in_group > cache->key.offset); |
579 start = cache->key.objectid; 580 end = start + cache->key.offset - 1; 581 set_extent_bits(&info->block_group_cache, start, end, 582 BLOCK_GROUP_DIRTY, GFP_NOFS); 583 584 old_val = btrfs_block_group_used(&cache->item); | 583 start = cache->key.objectid; 584 end = start + cache->key.offset - 1; 585 set_extent_bits(&info->block_group_cache, start, end, 586 BLOCK_GROUP_DIRTY, GFP_NOFS); 587 588 old_val = btrfs_block_group_used(&cache->item); |
585 num = min(total, cache->key.offset - block_in_group); | 589 num_bytes = min(total, cache->key.offset - byte_in_group); |
586 if (alloc) { 587 if (cache->data != data && 588 old_val < (cache->key.offset >> 1)) { 589 int bit_to_clear; 590 int bit_to_set; 591 592 cache->data = data; 593 if (data) { --- 9 unchanged lines hidden (view full) --- 603 } 604 clear_extent_bits(&info->block_group_cache, 605 start, end, bit_to_clear, 606 GFP_NOFS); 607 set_extent_bits(&info->block_group_cache, 608 start, end, bit_to_set, 609 GFP_NOFS); 610 } | 590 if (alloc) { 591 if (cache->data != data && 592 old_val < (cache->key.offset >> 1)) { 593 int bit_to_clear; 594 int bit_to_set; 595 596 cache->data = data; 597 if (data) { --- 9 unchanged lines hidden (view full) --- 607 } 608 clear_extent_bits(&info->block_group_cache, 609 start, end, bit_to_clear, 610 GFP_NOFS); 611 set_extent_bits(&info->block_group_cache, 612 start, end, bit_to_set, 613 GFP_NOFS); 614 } |
611 old_val += num; | 615 old_val += num_bytes; |
612 } else { | 616 } else { |
613 old_val -= num; | 617 old_val -= num_bytes; |
614 if (mark_free) { 615 set_extent_dirty(&info->free_space_cache, | 618 if (mark_free) { 619 set_extent_dirty(&info->free_space_cache, |
616 blocknr, blocknr + num - 1, | 620 bytenr, bytenr + num_bytes - 1, |
617 GFP_NOFS); 618 } 619 } 620 btrfs_set_block_group_used(&cache->item, old_val); | 621 GFP_NOFS); 622 } 623 } 624 btrfs_set_block_group_used(&cache->item, old_val); |
621 total -= num; 622 blocknr += num; | 625 total -= num_bytes; 626 bytenr += num_bytes; |
623 } 624 return 0; 625} 626 627int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy) 628{ 629 u64 last = 0; 630 u64 start; --- 65 unchanged lines hidden (view full) --- 696 err = btrfs_insert_item(trans, extent_root, &ins, 697 &extent_item, sizeof(extent_item)); 698 clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED, 699 GFP_NOFS); 700 } 701 return 0; 702} 703 | 627 } 628 return 0; 629} 630 631int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy) 632{ 633 u64 last = 0; 634 u64 start; --- 65 unchanged lines hidden (view full) --- 700 err = btrfs_insert_item(trans, extent_root, &ins, 701 &extent_item, sizeof(extent_item)); 702 clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED, 703 GFP_NOFS); 704 } 705 return 0; 706} 707 |
704static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | 708static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, 709 int pending) |
705{ 706 int err = 0; 707 struct extent_buffer *buf; 708 709 if (!pending) { | 710{ 711 int err = 0; 712 struct extent_buffer *buf; 713 714 if (!pending) { |
710 buf = btrfs_find_tree_block(root, blocknr); | 715 buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
711 if (buf) { 712 if (btrfs_buffer_uptodate(buf)) { 713 u64 transid = 714 root->fs_info->running_transaction->transid; 715 if (btrfs_header_generation(buf) == transid) { 716 free_extent_buffer(buf); 717 return 0; 718 } 719 } 720 free_extent_buffer(buf); 721 } 722 set_extent_dirty(&root->fs_info->pinned_extents, | 716 if (buf) { 717 if (btrfs_buffer_uptodate(buf)) { 718 u64 transid = 719 root->fs_info->running_transaction->transid; 720 if (btrfs_header_generation(buf) == transid) { 721 free_extent_buffer(buf); 722 return 0; 723 } 724 } 725 free_extent_buffer(buf); 726 } 727 set_extent_dirty(&root->fs_info->pinned_extents, |
723 blocknr, blocknr, GFP_NOFS); | 728 bytenr, bytenr + num_bytes - 1, GFP_NOFS); |
724 } else { 725 set_extent_bits(&root->fs_info->pending_del, | 729 } else { 730 set_extent_bits(&root->fs_info->pending_del, |
726 blocknr, blocknr, EXTENT_LOCKED, GFP_NOFS); | 731 bytenr, bytenr + num_bytes - 1, 732 EXTENT_LOCKED, GFP_NOFS); |
727 } 728 BUG_ON(err < 0); 729 return 0; 730} 731 732/* 733 * remove an extent from the root, returns 0 on success 734 */ 735static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 733 } 734 BUG_ON(err < 0); 735 return 0; 736} 737 738/* 739 * remove an extent from the root, returns 0 on success 740 */ 741static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
736 *root, u64 blocknr, u64 num_blocks, int pin, | 742 *root, u64 bytenr, u64 num_bytes, int pin, |
737 int mark_free) 738{ 739 struct btrfs_path *path; 740 struct btrfs_key key; 741 struct btrfs_fs_info *info = root->fs_info; 742 struct btrfs_root *extent_root = info->extent_root; 743 struct extent_buffer *leaf; 744 int ret; 745 struct btrfs_extent_item *ei; 746 u32 refs; 747 | 743 int mark_free) 744{ 745 struct btrfs_path *path; 746 struct btrfs_key key; 747 struct btrfs_fs_info *info = root->fs_info; 748 struct btrfs_root *extent_root = info->extent_root; 749 struct extent_buffer *leaf; 750 int ret; 751 struct btrfs_extent_item *ei; 752 u32 refs; 753 |
748 key.objectid = blocknr; | 754 key.objectid = bytenr; |
749 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 755 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
750 key.offset = num_blocks; | 756 key.offset = num_bytes; |
751 752 path = btrfs_alloc_path(); 753 if (!path) 754 return -ENOMEM; 755 756 ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); 757 if (ret < 0) 758 return ret; --- 4 unchanged lines hidden (view full) --- 763 struct btrfs_extent_item); 764 refs = btrfs_extent_refs(leaf, ei); 765 BUG_ON(refs == 0); 766 refs -= 1; 767 btrfs_set_extent_refs(leaf, ei, refs); 768 btrfs_mark_buffer_dirty(leaf); 769 770 if (refs == 0) { | 757 758 path = btrfs_alloc_path(); 759 if (!path) 760 return -ENOMEM; 761 762 ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); 763 if (ret < 0) 764 return ret; --- 4 unchanged lines hidden (view full) --- 769 struct btrfs_extent_item); 770 refs = btrfs_extent_refs(leaf, ei); 771 BUG_ON(refs == 0); 772 refs -= 1; 773 btrfs_set_extent_refs(leaf, ei, refs); 774 btrfs_mark_buffer_dirty(leaf); 775 776 if (refs == 0) { |
771 u64 super_blocks_used, root_blocks_used; | 777 u64 super_used; 778 u64 root_used; |
772 773 if (pin) { | 779 780 if (pin) { |
774 ret = pin_down_block(root, blocknr, 0); | 781 ret = pin_down_bytes(root, bytenr, num_bytes, 0); |
775 BUG_ON(ret); 776 } 777 778 /* block accounting for super block */ | 782 BUG_ON(ret); 783 } 784 785 /* block accounting for super block */ |
779 super_blocks_used = btrfs_super_blocks_used(&info->super_copy); 780 btrfs_set_super_blocks_used(&info->super_copy, 781 super_blocks_used - num_blocks); | 786 super_used = btrfs_super_bytes_used(&info->super_copy); 787 btrfs_set_super_bytes_used(&info->super_copy, 788 super_used - num_bytes); |
782 783 /* block accounting for root item */ | 789 790 /* block accounting for root item */ |
784 root_blocks_used = btrfs_root_used(&root->root_item); | 791 root_used = btrfs_root_used(&root->root_item); |
785 btrfs_set_root_used(&root->root_item, | 792 btrfs_set_root_used(&root->root_item, |
786 root_blocks_used - num_blocks); | 793 root_used - num_bytes); |
787 788 ret = btrfs_del_item(trans, extent_root, path); 789 if (ret) { 790 return ret; 791 } | 794 795 ret = btrfs_del_item(trans, extent_root, path); 796 if (ret) { 797 return ret; 798 } |
792 ret = update_block_group(trans, root, blocknr, num_blocks, 0, | 799 ret = update_block_group(trans, root, bytenr, num_bytes, 0, |
793 mark_free, 0); 794 BUG_ON(ret); 795 } 796 btrfs_free_path(path); 797 finish_current_insert(trans, extent_root); 798 return ret; 799} 800 --- 30 unchanged lines hidden (view full) --- 831 } 832 return err; 833} 834 835/* 836 * remove an extent from the root, returns 0 on success 837 */ 838int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 800 mark_free, 0); 801 BUG_ON(ret); 802 } 803 btrfs_free_path(path); 804 finish_current_insert(trans, extent_root); 805 return ret; 806} 807 --- 30 unchanged lines hidden (view full) --- 838 } 839 return err; 840} 841 842/* 843 * remove an extent from the root, returns 0 on success 844 */ 845int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
839 *root, u64 blocknr, u64 num_blocks, int pin) | 846 *root, u64 bytenr, u64 num_bytes, int pin) |
840{ 841 struct btrfs_root *extent_root = root->fs_info->extent_root; 842 int pending_ret; 843 int ret; 844 | 847{ 848 struct btrfs_root *extent_root = root->fs_info->extent_root; 849 int pending_ret; 850 int ret; 851 |
852 WARN_ON(num_bytes < root->sectorsize); |
|
845 if (root == extent_root) { | 853 if (root == extent_root) { |
846 pin_down_block(root, blocknr, 1); | 854 pin_down_bytes(root, bytenr, num_bytes, 1); |
847 return 0; 848 } | 855 return 0; 856 } |
849 ret = __free_extent(trans, root, blocknr, num_blocks, pin, pin == 0); | 857 ret = __free_extent(trans, root, bytenr, num_bytes, pin, pin == 0); |
850 pending_ret = del_pending_extents(trans, root->fs_info->extent_root); 851 return ret ? ret : pending_ret; 852} 853 854/* 855 * walks the btree of allocated extents and find a hole of a given size. 856 * The key ins is changed to record the hole: 857 * ins->objectid == block start 858 * ins->flags = BTRFS_EXTENT_ITEM_KEY 859 * ins->offset == number of blocks 860 * Any available blocks before search_start are skipped. 861 */ 862static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 858 pending_ret = del_pending_extents(trans, root->fs_info->extent_root); 859 return ret ? ret : pending_ret; 860} 861 862/* 863 * walks the btree of allocated extents and find a hole of a given size. 864 * The key ins is changed to record the hole: 865 * ins->objectid == block start 866 * ins->flags = BTRFS_EXTENT_ITEM_KEY 867 * ins->offset == number of blocks 868 * Any available blocks before search_start are skipped. 869 */ 870static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
863 *orig_root, u64 num_blocks, u64 empty_size, 864 u64 search_start, u64 search_end, u64 hint_block, | 871 *orig_root, u64 num_bytes, u64 empty_size, 872 u64 search_start, u64 search_end, u64 hint_byte, |
865 struct btrfs_key *ins, u64 exclude_start, 866 u64 exclude_nr, int data) 867{ 868 struct btrfs_path *path; 869 struct btrfs_key key; 870 int ret; 871 u64 hole_size = 0; 872 int slot = 0; | 873 struct btrfs_key *ins, u64 exclude_start, 874 u64 exclude_nr, int data) 875{ 876 struct btrfs_path *path; 877 struct btrfs_key key; 878 int ret; 879 u64 hole_size = 0; 880 int slot = 0; |
873 u64 last_block = 0; | 881 u64 last_byte = 0; |
874 u64 orig_search_start = search_start; 875 int start_found; 876 struct extent_buffer *l; 877 struct btrfs_root * root = orig_root->fs_info->extent_root; 878 struct btrfs_fs_info *info = root->fs_info; | 882 u64 orig_search_start = search_start; 883 int start_found; 884 struct extent_buffer *l; 885 struct btrfs_root * root = orig_root->fs_info->extent_root; 886 struct btrfs_fs_info *info = root->fs_info; |
879 int total_needed = num_blocks; | 887 u64 total_needed = num_bytes; |
880 int level; 881 struct btrfs_block_group_cache *block_group; 882 int full_scan = 0; 883 int wrapped = 0; | 888 int level; 889 struct btrfs_block_group_cache *block_group; 890 int full_scan = 0; 891 int wrapped = 0; |
884 u64 cached_search_start = 0; | |
885 | 892 |
886 WARN_ON(num_blocks < 1); | 893 WARN_ON(num_bytes < root->sectorsize); |
887 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 888 889 level = btrfs_header_level(root->node); 890 891 if (search_end == (u64)-1) | 894 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 895 896 level = btrfs_header_level(root->node); 897 898 if (search_end == (u64)-1) |
892 search_end = btrfs_super_total_blocks(&info->super_copy); 893 if (hint_block) { 894 block_group = btrfs_lookup_block_group(info, hint_block); | 899 search_end = btrfs_super_total_bytes(&info->super_copy); 900 if (hint_byte) { 901 block_group = btrfs_lookup_block_group(info, hint_byte); |
895 block_group = btrfs_find_block_group(root, block_group, | 902 block_group = btrfs_find_block_group(root, block_group, |
896 hint_block, data, 1); | 903 hint_byte, data, 1); |
897 } else { 898 block_group = btrfs_find_block_group(root, 899 trans->block_group, 0, 900 data, 1); 901 } 902 903 total_needed += empty_size; 904 path = btrfs_alloc_path(); 905 906check_failed: 907 search_start = find_search_start(root, &block_group, 908 search_start, total_needed, data); | 904 } else { 905 block_group = btrfs_find_block_group(root, 906 trans->block_group, 0, 907 data, 1); 908 } 909 910 total_needed += empty_size; 911 path = btrfs_alloc_path(); 912 913check_failed: 914 search_start = find_search_start(root, &block_group, 915 search_start, total_needed, data); |
909 cached_search_start = search_start; | |
910 911 btrfs_init_path(path); 912 ins->objectid = search_start; 913 ins->offset = 0; 914 start_found = 0; 915 path->reada = 2; 916 917 ret = btrfs_search_slot(trans, root, ins, path, 0, 0); --- 35 unchanged lines hidden (view full) --- 953 if (ret < 0) 954 goto error; 955 if (!start_found) { 956 ins->objectid = search_start; 957 ins->offset = search_end - search_start; 958 start_found = 1; 959 goto check_pending; 960 } | 916 917 btrfs_init_path(path); 918 ins->objectid = search_start; 919 ins->offset = 0; 920 start_found = 0; 921 path->reada = 2; 922 923 ret = btrfs_search_slot(trans, root, ins, path, 0, 0); --- 35 unchanged lines hidden (view full) --- 959 if (ret < 0) 960 goto error; 961 if (!start_found) { 962 ins->objectid = search_start; 963 ins->offset = search_end - search_start; 964 start_found = 1; 965 goto check_pending; 966 } |
961 ins->objectid = last_block > search_start ? 962 last_block : search_start; | 967 ins->objectid = last_byte > search_start ? 968 last_byte : search_start; |
963 ins->offset = search_end - ins->objectid; 964 goto check_pending; 965 } 966 btrfs_item_key_to_cpu(l, &key, slot); 967 | 969 ins->offset = search_end - ins->objectid; 970 goto check_pending; 971 } 972 btrfs_item_key_to_cpu(l, &key, slot); 973 |
968 if (key.objectid >= search_start && key.objectid > last_block && | 974 if (key.objectid >= search_start && key.objectid > last_byte && |
969 start_found) { | 975 start_found) { |
970 if (last_block < search_start) 971 last_block = search_start; 972 hole_size = key.objectid - last_block; 973 if (hole_size >= num_blocks) { 974 ins->objectid = last_block; | 976 if (last_byte < search_start) 977 last_byte = search_start; 978 hole_size = key.objectid - last_byte; 979 if (hole_size >= num_bytes) { 980 ins->objectid = last_byte; |
975 ins->offset = hole_size; 976 goto check_pending; 977 } 978 } 979 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { 980 if (!start_found) { | 981 ins->offset = hole_size; 982 goto check_pending; 983 } 984 } 985 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { 986 if (!start_found) { |
981 last_block = key.objectid; | 987 last_byte = key.objectid; |
982 start_found = 1; 983 } 984 goto next; 985 } 986 987 988 start_found = 1; | 988 start_found = 1; 989 } 990 goto next; 991 } 992 993 994 start_found = 1; |
989 last_block = key.objectid + key.offset; | 995 last_byte = key.objectid + key.offset; |
990 | 996 |
991 if (!full_scan && last_block >= block_group->key.objectid + | 997 if (!full_scan && last_byte >= block_group->key.objectid + |
992 block_group->key.offset) { 993 btrfs_release_path(root, path); 994 search_start = block_group->key.objectid + 995 block_group->key.offset * 2; 996 goto new_group; 997 } 998next: 999 path->slots[0]++; 1000 cond_resched(); 1001 } 1002check_pending: 1003 /* we have to make sure we didn't find an extent that has already 1004 * been allocated by the map tree or the original allocation 1005 */ 1006 btrfs_release_path(root, path); 1007 BUG_ON(ins->objectid < search_start); 1008 | 998 block_group->key.offset) { 999 btrfs_release_path(root, path); 1000 search_start = block_group->key.objectid + 1001 block_group->key.offset * 2; 1002 goto new_group; 1003 } 1004next: 1005 path->slots[0]++; 1006 cond_resched(); 1007 } 1008check_pending: 1009 /* we have to make sure we didn't find an extent that has already 1010 * been allocated by the map tree or the original allocation 1011 */ 1012 btrfs_release_path(root, path); 1013 BUG_ON(ins->objectid < search_start); 1014 |
1009 if (ins->objectid + num_blocks >= search_end) | 1015 if (ins->objectid + num_bytes >= search_end) |
1010 goto enospc; 1011 1012 if (test_range_bit(&info->extent_ins, ins->objectid, | 1016 goto enospc; 1017 1018 if (test_range_bit(&info->extent_ins, ins->objectid, |
1013 ins->objectid + num_blocks -1, EXTENT_LOCKED, 0)) { 1014 search_start = ins->objectid + num_blocks; | 1019 ins->objectid + num_bytes -1, EXTENT_LOCKED, 0)) { 1020 search_start = ins->objectid + num_bytes; |
1015 goto new_group; 1016 } 1017 if (test_range_bit(&info->pinned_extents, ins->objectid, | 1021 goto new_group; 1022 } 1023 if (test_range_bit(&info->pinned_extents, ins->objectid, |
1018 ins->objectid + num_blocks -1, EXTENT_DIRTY, 0)) { 1019 search_start = ins->objectid + num_blocks; | 1024 ins->objectid + num_bytes -1, EXTENT_DIRTY, 0)) { 1025 search_start = ins->objectid + num_bytes; |
1020 goto new_group; 1021 } | 1026 goto new_group; 1027 } |
1022 if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start && | 1028 if (exclude_nr > 0 && (ins->objectid + num_bytes > exclude_start && |
1023 ins->objectid < exclude_start + exclude_nr)) { 1024 search_start = exclude_start + exclude_nr; 1025 goto new_group; 1026 } 1027 if (!data) { 1028 block_group = btrfs_lookup_block_group(info, ins->objectid); 1029 if (block_group) 1030 trans->block_group = block_group; 1031 } | 1029 ins->objectid < exclude_start + exclude_nr)) { 1030 search_start = exclude_start + exclude_nr; 1031 goto new_group; 1032 } 1033 if (!data) { 1034 block_group = btrfs_lookup_block_group(info, ins->objectid); 1035 if (block_group) 1036 trans->block_group = block_group; 1037 } |
1032 ins->offset = num_blocks; | 1038 ins->offset = num_bytes; |
1033 btrfs_free_path(path); 1034 return 0; 1035 1036new_group: | 1039 btrfs_free_path(path); 1040 return 0; 1041 1042new_group: |
1037 if (search_start + num_blocks >= search_end) { | 1043 if (search_start + num_bytes >= search_end) { |
1038enospc: 1039 search_start = orig_search_start; 1040 if (full_scan) { 1041 ret = -ENOSPC; 1042 goto error; 1043 } 1044 if (wrapped) { 1045 if (!full_scan) --- 18 unchanged lines hidden (view full) --- 1064 * finds a free extent and does all the dirty work required for allocation 1065 * returns the key for the extent through ins, and a tree buffer for 1066 * the first block of the extent through buf. 1067 * 1068 * returns 0 if everything worked, non-zero otherwise. 1069 */ 1070int btrfs_alloc_extent(struct btrfs_trans_handle *trans, 1071 struct btrfs_root *root, u64 owner, | 1044enospc: 1045 search_start = orig_search_start; 1046 if (full_scan) { 1047 ret = -ENOSPC; 1048 goto error; 1049 } 1050 if (wrapped) { 1051 if (!full_scan) --- 18 unchanged lines hidden (view full) --- 1070 * finds a free extent and does all the dirty work required for allocation 1071 * returns the key for the extent through ins, and a tree buffer for 1072 * the first block of the extent through buf. 1073 * 1074 * returns 0 if everything worked, non-zero otherwise. 1075 */ 1076int btrfs_alloc_extent(struct btrfs_trans_handle *trans, 1077 struct btrfs_root *root, u64 owner, |
1072 u64 num_blocks, u64 empty_size, u64 hint_block, | 1078 u64 num_bytes, u64 empty_size, u64 hint_byte, |
1073 u64 search_end, struct btrfs_key *ins, int data) 1074{ 1075 int ret; 1076 int pending_ret; | 1079 u64 search_end, struct btrfs_key *ins, int data) 1080{ 1081 int ret; 1082 int pending_ret; |
1077 u64 super_blocks_used, root_blocks_used; | 1083 u64 super_used, root_used; |
1078 u64 search_start = 0; 1079 struct btrfs_fs_info *info = root->fs_info; 1080 struct btrfs_root *extent_root = info->extent_root; 1081 struct btrfs_extent_item extent_item; 1082 1083 btrfs_set_stack_extent_refs(&extent_item, 1); 1084 btrfs_set_stack_extent_owner(&extent_item, owner); 1085 | 1084 u64 search_start = 0; 1085 struct btrfs_fs_info *info = root->fs_info; 1086 struct btrfs_root *extent_root = info->extent_root; 1087 struct btrfs_extent_item extent_item; 1088 1089 btrfs_set_stack_extent_refs(&extent_item, 1); 1090 btrfs_set_stack_extent_owner(&extent_item, owner); 1091 |
1086 WARN_ON(num_blocks < 1); 1087 ret = find_free_extent(trans, root, num_blocks, empty_size, 1088 search_start, search_end, hint_block, ins, | 1092 WARN_ON(num_bytes < root->sectorsize); 1093 ret = find_free_extent(trans, root, num_bytes, empty_size, 1094 search_start, search_end, hint_byte, ins, |
1089 trans->alloc_exclude_start, 1090 trans->alloc_exclude_nr, data); 1091 BUG_ON(ret); 1092 if (ret) 1093 return ret; 1094 1095 /* block accounting for super block */ | 1095 trans->alloc_exclude_start, 1096 trans->alloc_exclude_nr, data); 1097 BUG_ON(ret); 1098 if (ret) 1099 return ret; 1100 1101 /* block accounting for super block */ |
1096 super_blocks_used = btrfs_super_blocks_used(&info->super_copy); 1097 btrfs_set_super_blocks_used(&info->super_copy, super_blocks_used + 1098 num_blocks); | 1102 super_used = btrfs_super_bytes_used(&info->super_copy); 1103 btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); |
1099 1100 /* block accounting for root item */ | 1104 1105 /* block accounting for root item */ |
1101 root_blocks_used = btrfs_root_used(&root->root_item); 1102 btrfs_set_root_used(&root->root_item, root_blocks_used + 1103 num_blocks); | 1106 root_used = btrfs_root_used(&root->root_item); 1107 btrfs_set_root_used(&root->root_item, root_used + num_bytes); |
1104 1105 clear_extent_dirty(&root->fs_info->free_space_cache, 1106 ins->objectid, ins->objectid + ins->offset - 1, 1107 GFP_NOFS); 1108 1109 if (root == extent_root) { | 1108 1109 clear_extent_dirty(&root->fs_info->free_space_cache, 1110 ins->objectid, ins->objectid + ins->offset - 1, 1111 GFP_NOFS); 1112 1113 if (root == extent_root) { |
1110 BUG_ON(num_blocks != 1); | |
1111 set_extent_bits(&root->fs_info->extent_ins, ins->objectid, 1112 ins->objectid + ins->offset - 1, 1113 EXTENT_LOCKED, GFP_NOFS); 1114 goto update_block; 1115 } 1116 1117 WARN_ON(trans->alloc_exclude_nr); 1118 trans->alloc_exclude_start = ins->objectid; --- 22 unchanged lines hidden (view full) --- 1141 return 0; 1142} 1143 1144/* 1145 * helper function to allocate a block for a given tree 1146 * returns the tree buffer or NULL. 1147 */ 1148struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1114 set_extent_bits(&root->fs_info->extent_ins, ins->objectid, 1115 ins->objectid + ins->offset - 1, 1116 EXTENT_LOCKED, GFP_NOFS); 1117 goto update_block; 1118 } 1119 1120 WARN_ON(trans->alloc_exclude_nr); 1121 trans->alloc_exclude_start = ins->objectid; --- 22 unchanged lines hidden (view full) --- 1144 return 0; 1145} 1146 1147/* 1148 * helper function to allocate a block for a given tree 1149 * returns the tree buffer or NULL. 1150 */ 1151struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1149 struct btrfs_root *root, u64 hint, | 1152 struct btrfs_root *root, 1153 u32 blocksize, u64 hint, |
1150 u64 empty_size) 1151{ 1152 struct btrfs_key ins; 1153 int ret; 1154 struct extent_buffer *buf; 1155 1156 ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, | 1154 u64 empty_size) 1155{ 1156 struct btrfs_key ins; 1157 int ret; 1158 struct extent_buffer *buf; 1159 1160 ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
1157 1, empty_size, hint, (u64)-1, &ins, 0); | 1161 blocksize, empty_size, hint, 1162 (u64)-1, &ins, 0); |
1158 if (ret) { 1159 BUG_ON(ret > 0); 1160 return ERR_PTR(ret); 1161 } | 1163 if (ret) { 1164 BUG_ON(ret > 0); 1165 return ERR_PTR(ret); 1166 } |
1162 buf = btrfs_find_create_tree_block(root, ins.objectid); | 1167 buf = btrfs_find_create_tree_block(root, ins.objectid, blocksize); |
1163 if (!buf) { | 1168 if (!buf) { |
1164 btrfs_free_extent(trans, root, ins.objectid, 1, 0); | 1169 btrfs_free_extent(trans, root, ins.objectid, blocksize, 0); |
1165 return ERR_PTR(-ENOMEM); 1166 } 1167 btrfs_set_buffer_uptodate(buf); 1168 buf->alloc_addr = (unsigned long)__builtin_return_address(0); 1169 set_extent_dirty(&trans->transaction->dirty_pages, buf->start, 1170 buf->start + buf->len - 1, GFP_NOFS); 1171 /* 1172 set_buffer_checked(buf); --- 13 unchanged lines hidden (view full) --- 1186 struct btrfs_file_extent_item *fi; 1187 int i; 1188 int nritems; 1189 int ret; 1190 1191 BUG_ON(!btrfs_is_leaf(leaf)); 1192 nritems = btrfs_header_nritems(leaf); 1193 for (i = 0; i < nritems; i++) { | 1170 return ERR_PTR(-ENOMEM); 1171 } 1172 btrfs_set_buffer_uptodate(buf); 1173 buf->alloc_addr = (unsigned long)__builtin_return_address(0); 1174 set_extent_dirty(&trans->transaction->dirty_pages, buf->start, 1175 buf->start + buf->len - 1, GFP_NOFS); 1176 /* 1177 set_buffer_checked(buf); --- 13 unchanged lines hidden (view full) --- 1191 struct btrfs_file_extent_item *fi; 1192 int i; 1193 int nritems; 1194 int ret; 1195 1196 BUG_ON(!btrfs_is_leaf(leaf)); 1197 nritems = btrfs_header_nritems(leaf); 1198 for (i = 0; i < nritems; i++) { |
1194 u64 disk_blocknr; | 1199 u64 disk_bytenr; |
1195 1196 btrfs_item_key_to_cpu(leaf, &key, i); 1197 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 1198 continue; 1199 fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); 1200 if (btrfs_file_extent_type(leaf, fi) == 1201 BTRFS_FILE_EXTENT_INLINE) 1202 continue; 1203 /* 1204 * FIXME make sure to insert a trans record that 1205 * repeats the snapshot del on crash 1206 */ | 1200 1201 btrfs_item_key_to_cpu(leaf, &key, i); 1202 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) 1203 continue; 1204 fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); 1205 if (btrfs_file_extent_type(leaf, fi) == 1206 BTRFS_FILE_EXTENT_INLINE) 1207 continue; 1208 /* 1209 * FIXME make sure to insert a trans record that 1210 * repeats the snapshot del on crash 1211 */ |
1207 disk_blocknr = btrfs_file_extent_disk_blocknr(leaf, fi); 1208 if (disk_blocknr == 0) | 1212 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); 1213 if (disk_bytenr == 0) |
1209 continue; | 1214 continue; |
1210 ret = btrfs_free_extent(trans, root, disk_blocknr, 1211 btrfs_file_extent_disk_num_blocks(leaf, fi), 0); | 1215 ret = btrfs_free_extent(trans, root, disk_bytenr, 1216 btrfs_file_extent_disk_num_bytes(leaf, fi), 0); |
1212 BUG_ON(ret); 1213 } 1214 return 0; 1215} 1216 1217static void reada_walk_down(struct btrfs_root *root, 1218 struct extent_buffer *node) 1219{ 1220 int i; 1221 u32 nritems; | 1217 BUG_ON(ret); 1218 } 1219 return 0; 1220} 1221 1222static void reada_walk_down(struct btrfs_root *root, 1223 struct extent_buffer *node) 1224{ 1225 int i; 1226 u32 nritems; |
1222 u64 blocknr; | 1227 u64 bytenr; |
1223 int ret; 1224 u32 refs; | 1228 int ret; 1229 u32 refs; |
1230 int level; 1231 u32 blocksize; |
|
1225 1226 nritems = btrfs_header_nritems(node); | 1232 1233 nritems = btrfs_header_nritems(node); |
1234 level = btrfs_header_level(node); |
|
1227 for (i = 0; i < nritems; i++) { | 1235 for (i = 0; i < nritems; i++) { |
1228 blocknr = btrfs_node_blockptr(node, i); 1229 ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); | 1236 bytenr = btrfs_node_blockptr(node, i); 1237 blocksize = btrfs_level_size(root, level - 1); 1238 ret = lookup_extent_ref(NULL, root, bytenr, blocksize, &refs); |
1230 BUG_ON(ret); 1231 if (refs != 1) 1232 continue; 1233 mutex_unlock(&root->fs_info->fs_mutex); | 1239 BUG_ON(ret); 1240 if (refs != 1) 1241 continue; 1242 mutex_unlock(&root->fs_info->fs_mutex); |
1234 ret = readahead_tree_block(root, blocknr); | 1243 ret = readahead_tree_block(root, bytenr, blocksize); |
1235 cond_resched(); 1236 mutex_lock(&root->fs_info->fs_mutex); 1237 if (ret) 1238 break; 1239 } 1240} 1241 1242/* 1243 * helper function for drop_snapshot, this walks down the tree dropping ref 1244 * counts as it goes. 1245 */ 1246static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root 1247 *root, struct btrfs_path *path, int *level) 1248{ 1249 struct extent_buffer *next; 1250 struct extent_buffer *cur; | 1244 cond_resched(); 1245 mutex_lock(&root->fs_info->fs_mutex); 1246 if (ret) 1247 break; 1248 } 1249} 1250 1251/* 1252 * helper function for drop_snapshot, this walks down the tree dropping ref 1253 * counts as it goes. 1254 */ 1255static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root 1256 *root, struct btrfs_path *path, int *level) 1257{ 1258 struct extent_buffer *next; 1259 struct extent_buffer *cur; |
1251 u64 blocknr; | 1260 u64 bytenr; 1261 u32 blocksize; |
1252 int ret; 1253 u32 refs; 1254 1255 WARN_ON(*level < 0); 1256 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1257 ret = lookup_extent_ref(trans, root, | 1262 int ret; 1263 u32 refs; 1264 1265 WARN_ON(*level < 0); 1266 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1267 ret = lookup_extent_ref(trans, root, |
1258 extent_buffer_blocknr(path->nodes[*level]), 1259 1, &refs); | 1268 path->nodes[*level]->start, 1269 path->nodes[*level]->len, &refs); |
1260 BUG_ON(ret); 1261 if (refs > 1) 1262 goto out; 1263 1264 /* 1265 * walk down to the last node level and free all the leaves 1266 */ 1267 while(*level >= 0) { --- 10 unchanged lines hidden (view full) --- 1278 if (path->slots[*level] >= 1279 btrfs_header_nritems(cur)) 1280 break; 1281 if (*level == 0) { 1282 ret = drop_leaf_ref(trans, root, cur); 1283 BUG_ON(ret); 1284 break; 1285 } | 1270 BUG_ON(ret); 1271 if (refs > 1) 1272 goto out; 1273 1274 /* 1275 * walk down to the last node level and free all the leaves 1276 */ 1277 while(*level >= 0) { --- 10 unchanged lines hidden (view full) --- 1288 if (path->slots[*level] >= 1289 btrfs_header_nritems(cur)) 1290 break; 1291 if (*level == 0) { 1292 ret = drop_leaf_ref(trans, root, cur); 1293 BUG_ON(ret); 1294 break; 1295 } |
1286 blocknr = btrfs_node_blockptr(cur, path->slots[*level]); 1287 ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1296 bytenr = btrfs_node_blockptr(cur, path->slots[*level]); 1297 blocksize = btrfs_level_size(root, *level - 1); 1298 ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); |
1288 BUG_ON(ret); 1289 if (refs != 1) { 1290 path->slots[*level]++; | 1299 BUG_ON(ret); 1300 if (refs != 1) { 1301 path->slots[*level]++; |
1291 ret = btrfs_free_extent(trans, root, blocknr, 1, 1); | 1302 ret = btrfs_free_extent(trans, root, bytenr, 1303 blocksize, 1); |
1292 BUG_ON(ret); 1293 continue; 1294 } | 1304 BUG_ON(ret); 1305 continue; 1306 } |
1295 next = btrfs_find_tree_block(root, blocknr); | 1307 next = btrfs_find_tree_block(root, bytenr, blocksize); |
1296 if (!next || !btrfs_buffer_uptodate(next)) { 1297 free_extent_buffer(next); 1298 mutex_unlock(&root->fs_info->fs_mutex); | 1308 if (!next || !btrfs_buffer_uptodate(next)) { 1309 free_extent_buffer(next); 1310 mutex_unlock(&root->fs_info->fs_mutex); |
1299 next = read_tree_block(root, blocknr); | 1311 next = read_tree_block(root, bytenr, blocksize); |
1300 mutex_lock(&root->fs_info->fs_mutex); 1301 1302 /* we dropped the lock, check one more time */ | 1312 mutex_lock(&root->fs_info->fs_mutex); 1313 1314 /* we dropped the lock, check one more time */ |
1303 ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1315 ret = lookup_extent_ref(trans, root, bytenr, 1316 blocksize, &refs); |
1304 BUG_ON(ret); 1305 if (refs != 1) { 1306 path->slots[*level]++; 1307 free_extent_buffer(next); 1308 ret = btrfs_free_extent(trans, root, | 1317 BUG_ON(ret); 1318 if (refs != 1) { 1319 path->slots[*level]++; 1320 free_extent_buffer(next); 1321 ret = btrfs_free_extent(trans, root, |
1309 blocknr, 1, 1); | 1322 bytenr, blocksize, 1); |
1310 BUG_ON(ret); 1311 continue; 1312 } 1313 } 1314 WARN_ON(*level <= 0); 1315 if (path->nodes[*level-1]) 1316 free_extent_buffer(path->nodes[*level-1]); 1317 path->nodes[*level-1] = next; 1318 *level = btrfs_header_level(next); 1319 path->slots[*level] = 0; 1320 } 1321out: 1322 WARN_ON(*level < 0); 1323 WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1323 BUG_ON(ret); 1324 continue; 1325 } 1326 } 1327 WARN_ON(*level <= 0); 1328 if (path->nodes[*level-1]) 1329 free_extent_buffer(path->nodes[*level-1]); 1330 path->nodes[*level-1] = next; 1331 *level = btrfs_header_level(next); 1332 path->slots[*level] = 0; 1333 } 1334out: 1335 WARN_ON(*level < 0); 1336 WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1324 ret = btrfs_free_extent(trans, root, 1325 extent_buffer_blocknr(path->nodes[*level]), 1, 1); | 1337 ret = btrfs_free_extent(trans, root, path->nodes[*level]->start, 1338 path->nodes[*level]->len, 1); |
1326 free_extent_buffer(path->nodes[*level]); 1327 path->nodes[*level] = NULL; 1328 *level += 1; 1329 BUG_ON(ret); 1330 return 0; 1331} 1332 1333/* --- 20 unchanged lines hidden (view full) --- 1354 WARN_ON(*level == 0); 1355 btrfs_node_key(node, &disk_key, path->slots[i]); 1356 memcpy(&root_item->drop_progress, 1357 &disk_key, sizeof(disk_key)); 1358 root_item->drop_level = i; 1359 return 0; 1360 } else { 1361 ret = btrfs_free_extent(trans, root, | 1339 free_extent_buffer(path->nodes[*level]); 1340 path->nodes[*level] = NULL; 1341 *level += 1; 1342 BUG_ON(ret); 1343 return 0; 1344} 1345 1346/* --- 20 unchanged lines hidden (view full) --- 1367 WARN_ON(*level == 0); 1368 btrfs_node_key(node, &disk_key, path->slots[i]); 1369 memcpy(&root_item->drop_progress, 1370 &disk_key, sizeof(disk_key)); 1371 root_item->drop_level = i; 1372 return 0; 1373 } else { 1374 ret = btrfs_free_extent(trans, root, |
1362 extent_buffer_blocknr(path->nodes[*level]), 1363 1, 1); | 1375 path->nodes[*level]->start, 1376 path->nodes[*level]->len, 1); |
1364 BUG_ON(ret); 1365 free_extent_buffer(path->nodes[*level]); 1366 path->nodes[*level] = NULL; 1367 *level = i + 1; 1368 } 1369 } 1370 return 1; 1371} --- 99 unchanged lines hidden (view full) --- 1471 int err = 0; 1472 int bit; 1473 struct btrfs_block_group_cache *cache; 1474 struct btrfs_fs_info *info = root->fs_info; 1475 struct extent_map_tree *block_group_cache; 1476 struct btrfs_key key; 1477 struct btrfs_key found_key; 1478 struct extent_buffer *leaf; | 1377 BUG_ON(ret); 1378 free_extent_buffer(path->nodes[*level]); 1379 path->nodes[*level] = NULL; 1380 *level = i + 1; 1381 } 1382 } 1383 return 1; 1384} --- 99 unchanged lines hidden (view full) --- 1484 int err = 0; 1485 int bit; 1486 struct btrfs_block_group_cache *cache; 1487 struct btrfs_fs_info *info = root->fs_info; 1488 struct extent_map_tree *block_group_cache; 1489 struct btrfs_key key; 1490 struct btrfs_key found_key; 1491 struct extent_buffer *leaf; |
1479 u64 group_size_blocks; | |
1480 1481 block_group_cache = &info->block_group_cache; 1482 | 1492 1493 block_group_cache = &info->block_group_cache; 1494 |
1483 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >> 1484 info->sb->s_blocksize_bits; 1485 | |
1486 root = info->extent_root; 1487 key.objectid = 0; | 1495 root = info->extent_root; 1496 key.objectid = 0; |
1488 key.offset = group_size_blocks; | 1497 key.offset = BTRFS_BLOCK_GROUP_SIZE; |
1489 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); 1490 1491 path = btrfs_alloc_path(); 1492 if (!path) 1493 return -ENOMEM; 1494 1495 while(1) { 1496 ret = btrfs_search_slot(NULL, info->extent_root, --- 30 unchanged lines hidden (view full) --- 1527 /* use EXTENT_LOCKED to prevent merging */ 1528 set_extent_bits(block_group_cache, found_key.objectid, 1529 found_key.objectid + found_key.offset - 1, 1530 bit | EXTENT_LOCKED, GFP_NOFS); 1531 set_state_private(block_group_cache, found_key.objectid, 1532 (u64)cache); 1533 1534 if (key.objectid >= | 1498 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); 1499 1500 path = btrfs_alloc_path(); 1501 if (!path) 1502 return -ENOMEM; 1503 1504 while(1) { 1505 ret = btrfs_search_slot(NULL, info->extent_root, --- 30 unchanged lines hidden (view full) --- 1536 /* use EXTENT_LOCKED to prevent merging */ 1537 set_extent_bits(block_group_cache, found_key.objectid, 1538 found_key.objectid + found_key.offset - 1, 1539 bit | EXTENT_LOCKED, GFP_NOFS); 1540 set_state_private(block_group_cache, found_key.objectid, 1541 (u64)cache); 1542 1543 if (key.objectid >= |
1535 btrfs_super_total_blocks(&info->super_copy)) | 1544 btrfs_super_total_bytes(&info->super_copy)) |
1536 break; 1537 } 1538 1539 btrfs_free_path(path); 1540 return 0; 1541} | 1545 break; 1546 } 1547 1548 btrfs_free_path(path); 1549 return 0; 1550} |