aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c108
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 }
436no_copy: 479no_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 }