aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.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/inode.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/inode.c')
-rw-r--r--fs/btrfs/inode.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 65b4f864b0df..2e7d82ec5d18 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -528,6 +528,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
528 struct btrfs_trans_handle *trans; 528 struct btrfs_trans_handle *trans;
529 struct btrfs_ordered_extent *ordered_extent; 529 struct btrfs_ordered_extent *ordered_extent;
530 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 530 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
531 struct btrfs_file_extent_item *extent_item;
532 struct btrfs_path *path = NULL;
533 struct extent_buffer *leaf;
531 u64 alloc_hint = 0; 534 u64 alloc_hint = 0;
532 struct list_head list; 535 struct list_head list;
533 struct btrfs_key ins; 536 struct btrfs_key ins;
@@ -544,20 +547,15 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
544 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) 547 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags))
545 goto nocow; 548 goto nocow;
546 549
550 path = btrfs_alloc_path();
551 BUG_ON(!path);
552
547 lock_extent(io_tree, ordered_extent->file_offset, 553 lock_extent(io_tree, ordered_extent->file_offset,
548 ordered_extent->file_offset + ordered_extent->len - 1, 554 ordered_extent->file_offset + ordered_extent->len - 1,
549 GFP_NOFS); 555 GFP_NOFS);
550 556
551 INIT_LIST_HEAD(&list); 557 INIT_LIST_HEAD(&list);
552 558
553 ins.objectid = ordered_extent->start;
554 ins.offset = ordered_extent->len;
555 ins.type = BTRFS_EXTENT_ITEM_KEY;
556
557 ret = btrfs_alloc_reserved_extent(trans, root, root->root_key.objectid,
558 trans->transid, inode->i_ino,
559 ordered_extent->file_offset, &ins);
560 BUG_ON(ret);
561 mutex_lock(&BTRFS_I(inode)->extent_mutex); 559 mutex_lock(&BTRFS_I(inode)->extent_mutex);
562 560
563 ret = btrfs_drop_extents(trans, root, inode, 561 ret = btrfs_drop_extents(trans, root, inode,
@@ -566,18 +564,42 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
566 ordered_extent->len, 564 ordered_extent->len,
567 ordered_extent->file_offset, &alloc_hint); 565 ordered_extent->file_offset, &alloc_hint);
568 BUG_ON(ret); 566 BUG_ON(ret);
569 ret = btrfs_insert_file_extent(trans, root, inode->i_ino, 567
570 ordered_extent->file_offset, 568 ins.objectid = inode->i_ino;
571 ordered_extent->start, 569 ins.offset = ordered_extent->file_offset;
572 ordered_extent->len, 570 ins.type = BTRFS_EXTENT_DATA_KEY;
573 ordered_extent->len, 0); 571 ret = btrfs_insert_empty_item(trans, root, path, &ins,
572 sizeof(*extent_item));
574 BUG_ON(ret); 573 BUG_ON(ret);
574 leaf = path->nodes[0];
575 extent_item = btrfs_item_ptr(leaf, path->slots[0],
576 struct btrfs_file_extent_item);
577 btrfs_set_file_extent_generation(leaf, extent_item, trans->transid);
578 btrfs_set_file_extent_type(leaf, extent_item, BTRFS_FILE_EXTENT_REG);
579 btrfs_set_file_extent_disk_bytenr(leaf, extent_item,
580 ordered_extent->start);
581 btrfs_set_file_extent_disk_num_bytes(leaf, extent_item,
582 ordered_extent->len);
583 btrfs_set_file_extent_offset(leaf, extent_item, 0);
584 btrfs_set_file_extent_num_bytes(leaf, extent_item,
585 ordered_extent->len);
586 btrfs_mark_buffer_dirty(leaf);
575 587
576 btrfs_drop_extent_cache(inode, ordered_extent->file_offset, 588 btrfs_drop_extent_cache(inode, ordered_extent->file_offset,
577 ordered_extent->file_offset + 589 ordered_extent->file_offset +
578 ordered_extent->len - 1); 590 ordered_extent->len - 1);
579 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 591 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
580 592
593 ins.objectid = ordered_extent->start;
594 ins.offset = ordered_extent->len;
595 ins.type = BTRFS_EXTENT_ITEM_KEY;
596 ret = btrfs_alloc_reserved_extent(trans, root, leaf->start,
597 root->root_key.objectid,
598 trans->transid, inode->i_ino,
599 ordered_extent->file_offset, &ins);
600 BUG_ON(ret);
601 btrfs_release_path(root, path);
602
581 inode->i_blocks += ordered_extent->len >> 9; 603 inode->i_blocks += ordered_extent->len >> 9;
582 unlock_extent(io_tree, ordered_extent->file_offset, 604 unlock_extent(io_tree, ordered_extent->file_offset,
583 ordered_extent->file_offset + ordered_extent->len - 1, 605 ordered_extent->file_offset + ordered_extent->len - 1,
@@ -596,6 +618,8 @@ nocow:
596 btrfs_put_ordered_extent(ordered_extent); 618 btrfs_put_ordered_extent(ordered_extent);
597 619
598 btrfs_end_transaction(trans, root); 620 btrfs_end_transaction(trans, root);
621 if (path)
622 btrfs_free_path(path);
599 return 0; 623 return 0;
600} 624}
601 625
@@ -1433,10 +1457,7 @@ search_again:
1433 if (root->ref_cows) 1457 if (root->ref_cows)
1434 dec_i_blocks(inode, num_dec); 1458 dec_i_blocks(inode, num_dec);
1435 } 1459 }
1436 if (root->ref_cows) { 1460 root_gen = btrfs_header_generation(leaf);
1437 root_gen =
1438 btrfs_header_generation(leaf);
1439 }
1440 root_owner = btrfs_header_owner(leaf); 1461 root_owner = btrfs_header_owner(leaf);
1441 } 1462 }
1442 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 1463 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
@@ -1477,7 +1498,7 @@ delete:
1477 if (found_extent) { 1498 if (found_extent) {
1478 ret = btrfs_free_extent(trans, root, extent_start, 1499 ret = btrfs_free_extent(trans, root, extent_start,
1479 extent_num_bytes, 1500 extent_num_bytes,
1480 root_owner, 1501 leaf->start, root_owner,
1481 root_gen, inode->i_ino, 1502 root_gen, inode->i_ino,
1482 found_key.offset, 0); 1503 found_key.offset, 0);
1483 BUG_ON(ret); 1504 BUG_ON(ret);