diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 108 |
1 files changed, 58 insertions, 50 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 56de3fb2d8d5..88bbfd959f18 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -89,9 +89,9 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | |||
89 | int ret; | 89 | int ret; |
90 | u64 objectid = root->root_key.objectid; | 90 | u64 objectid = root->root_key.objectid; |
91 | 91 | ||
92 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 92 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
93 | BTRFS_TREE_LOG_OBJECTID, | 93 | BTRFS_TREE_LOG_OBJECTID, |
94 | 0, 0, 0, 0, 0); | 94 | trans->transid, 0, 0, 0); |
95 | if (IS_ERR(leaf)) { | 95 | if (IS_ERR(leaf)) { |
96 | ret = PTR_ERR(leaf); | 96 | ret = PTR_ERR(leaf); |
97 | return ret; | 97 | return ret; |
@@ -433,6 +433,49 @@ insert: | |||
433 | trans->transid); | 433 | trans->transid); |
434 | } | 434 | } |
435 | } | 435 | } |
436 | |||
437 | if (overwrite_root && | ||
438 | key->type == BTRFS_EXTENT_DATA_KEY) { | ||
439 | int extent_type; | ||
440 | struct btrfs_file_extent_item *fi; | ||
441 | |||
442 | fi = (struct btrfs_file_extent_item *)dst_ptr; | ||
443 | extent_type = btrfs_file_extent_type(path->nodes[0], fi); | ||
444 | if (extent_type == BTRFS_FILE_EXTENT_REG) { | ||
445 | struct btrfs_key ins; | ||
446 | ins.objectid = btrfs_file_extent_disk_bytenr( | ||
447 | path->nodes[0], fi); | ||
448 | ins.offset = btrfs_file_extent_disk_num_bytes( | ||
449 | path->nodes[0], fi); | ||
450 | ins.type = BTRFS_EXTENT_ITEM_KEY; | ||
451 | |||
452 | /* | ||
453 | * is this extent already allocated in the extent | ||
454 | * allocation tree? If so, just add a reference | ||
455 | */ | ||
456 | ret = btrfs_lookup_extent(root, ins.objectid, | ||
457 | ins.offset); | ||
458 | if (ret == 0) { | ||
459 | ret = btrfs_inc_extent_ref(trans, root, | ||
460 | ins.objectid, ins.offset, | ||
461 | path->nodes[0]->start, | ||
462 | root->root_key.objectid, | ||
463 | trans->transid, | ||
464 | key->objectid, key->offset); | ||
465 | } else { | ||
466 | /* | ||
467 | * insert the extent pointer in the extent | ||
468 | * allocation tree | ||
469 | */ | ||
470 | ret = btrfs_alloc_logged_extent(trans, root, | ||
471 | path->nodes[0]->start, | ||
472 | root->root_key.objectid, | ||
473 | trans->transid, key->objectid, | ||
474 | key->offset, &ins); | ||
475 | BUG_ON(ret); | ||
476 | } | ||
477 | } | ||
478 | } | ||
436 | no_copy: | 479 | no_copy: |
437 | btrfs_mark_buffer_dirty(path->nodes[0]); | 480 | btrfs_mark_buffer_dirty(path->nodes[0]); |
438 | btrfs_release_path(root, path); | 481 | btrfs_release_path(root, path); |
@@ -551,45 +594,10 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
551 | start, extent_end, start, &alloc_hint); | 594 | start, extent_end, start, &alloc_hint); |
552 | BUG_ON(ret); | 595 | BUG_ON(ret); |
553 | 596 | ||
597 | /* insert the extent */ | ||
598 | ret = overwrite_item(trans, root, path, eb, slot, key); | ||
554 | BUG_ON(ret); | 599 | BUG_ON(ret); |
555 | if (found_type == BTRFS_FILE_EXTENT_REG) { | ||
556 | struct btrfs_key ins; | ||
557 | |||
558 | ins.objectid = btrfs_file_extent_disk_bytenr(eb, item); | ||
559 | ins.offset = btrfs_file_extent_disk_num_bytes(eb, item); | ||
560 | ins.type = BTRFS_EXTENT_ITEM_KEY; | ||
561 | |||
562 | /* insert the extent pointer in the file */ | ||
563 | ret = overwrite_item(trans, root, path, eb, slot, key); | ||
564 | BUG_ON(ret); | ||
565 | 600 | ||
566 | /* | ||
567 | * is this extent already allocated in the extent | ||
568 | * allocation tree? If so, just add a reference | ||
569 | */ | ||
570 | ret = btrfs_lookup_extent(root, path, ins.objectid, ins.offset); | ||
571 | btrfs_release_path(root, path); | ||
572 | if (ret == 0) { | ||
573 | ret = btrfs_inc_extent_ref(trans, root, | ||
574 | ins.objectid, ins.offset, | ||
575 | root->root_key.objectid, | ||
576 | trans->transid, key->objectid, start); | ||
577 | } else { | ||
578 | /* | ||
579 | * insert the extent pointer in the extent | ||
580 | * allocation tree | ||
581 | */ | ||
582 | ret = btrfs_alloc_logged_extent(trans, root, | ||
583 | root->root_key.objectid, | ||
584 | trans->transid, key->objectid, | ||
585 | start, &ins); | ||
586 | BUG_ON(ret); | ||
587 | } | ||
588 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | ||
589 | /* inline extents are easy, we just overwrite them */ | ||
590 | ret = overwrite_item(trans, root, path, eb, slot, key); | ||
591 | BUG_ON(ret); | ||
592 | } | ||
593 | /* btrfs_drop_extents changes i_blocks, update it here */ | 601 | /* btrfs_drop_extents changes i_blocks, update it here */ |
594 | inode->i_blocks += (extent_end - start) >> 9; | 602 | inode->i_blocks += (extent_end - start) >> 9; |
595 | btrfs_update_inode(trans, root, inode); | 603 | btrfs_update_inode(trans, root, inode); |
@@ -1806,16 +1814,14 @@ static int noinline walk_up_log_tree(struct btrfs_trans_handle *trans, | |||
1806 | WARN_ON(*level == 0); | 1814 | WARN_ON(*level == 0); |
1807 | return 0; | 1815 | return 0; |
1808 | } else { | 1816 | } else { |
1809 | if (path->nodes[*level] == root->node) { | 1817 | struct extent_buffer *parent; |
1810 | root_owner = root->root_key.objectid; | 1818 | if (path->nodes[*level] == root->node) |
1811 | root_gen = | 1819 | parent = path->nodes[*level]; |
1812 | btrfs_header_generation(path->nodes[*level]); | 1820 | else |
1813 | } else { | 1821 | parent = path->nodes[*level + 1]; |
1814 | struct extent_buffer *node; | 1822 | |
1815 | node = path->nodes[*level + 1]; | 1823 | root_owner = btrfs_header_owner(parent); |
1816 | root_owner = btrfs_header_owner(node); | 1824 | root_gen = btrfs_header_generation(parent); |
1817 | root_gen = btrfs_header_generation(node); | ||
1818 | } | ||
1819 | wc->process_func(root, path->nodes[*level], wc, | 1825 | wc->process_func(root, path->nodes[*level], wc, |
1820 | btrfs_header_generation(path->nodes[*level])); | 1826 | btrfs_header_generation(path->nodes[*level])); |
1821 | if (wc->free) { | 1827 | if (wc->free) { |
@@ -2525,8 +2531,10 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
2525 | if (ds != 0) { | 2531 | if (ds != 0) { |
2526 | ret = btrfs_inc_extent_ref(trans, log, | 2532 | ret = btrfs_inc_extent_ref(trans, log, |
2527 | ds, dl, | 2533 | ds, dl, |
2534 | dst_path->nodes[0]->start, | ||
2528 | BTRFS_TREE_LOG_OBJECTID, | 2535 | BTRFS_TREE_LOG_OBJECTID, |
2529 | 0, ins_keys[i].objectid, | 2536 | trans->transid, |
2537 | ins_keys[i].objectid, | ||
2530 | ins_keys[i].offset); | 2538 | ins_keys[i].offset); |
2531 | BUG_ON(ret); | 2539 | BUG_ON(ret); |
2532 | } | 2540 | } |