aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorZheng Yan <zheng.yan@oracle.com>2008-09-23 13:14:14 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:07 -0400
commit31840ae1a6b433ca0e6a8d341756ff478bbf959e (patch)
tree9343db596aec175e9640aa2800b80f01496d7047 /fs/btrfs/tree-log.c
parent1c2308f8e7d8491467e0095af2b01500f1b70819 (diff)
Btrfs: Full back reference support
This patch makes the back reference system to explicit record the location of parent node for all types of extents. The location of parent node is placed into the offset field of backref key. Every time a tree block is balanced, the back references for the affected lower level extents are updated. Signed-off-by: Chris Mason <chris.mason@oracle.com>
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 }