aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.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/ioctl.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/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f84b5f6991cc..4c6e0c15754d 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -76,9 +76,8 @@ static noinline int create_subvol(struct btrfs_root *root, char *name,
76 if (ret) 76 if (ret)
77 goto fail; 77 goto fail;
78 78
79 leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 79 leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
80 objectid, trans->transid, 0, 0, 80 objectid, trans->transid, 0, 0, 0);
81 0, 0);
82 if (IS_ERR(leaf)) { 81 if (IS_ERR(leaf)) {
83 ret = PTR_ERR(leaf); 82 ret = PTR_ERR(leaf);
84 goto fail; 83 goto fail;
@@ -525,13 +524,10 @@ long btrfs_ioctl_clone(struct file *file, unsigned long src_fd)
525 struct file *src_file; 524 struct file *src_file;
526 struct inode *src; 525 struct inode *src;
527 struct btrfs_trans_handle *trans; 526 struct btrfs_trans_handle *trans;
528 struct btrfs_ordered_extent *ordered;
529 struct btrfs_path *path; 527 struct btrfs_path *path;
530 struct extent_buffer *leaf; 528 struct extent_buffer *leaf;
531 char *buf; 529 char *buf;
532 struct btrfs_key key; 530 struct btrfs_key key;
533 struct btrfs_key new_key;
534 u32 size;
535 u32 nritems; 531 u32 nritems;
536 int slot; 532 int slot;
537 int ret; 533 int ret;
@@ -576,6 +572,7 @@ long btrfs_ioctl_clone(struct file *file, unsigned long src_fd)
576 /* do any pending delalloc/csum calc on src, one way or 572 /* do any pending delalloc/csum calc on src, one way or
577 another, and lock file content */ 573 another, and lock file content */
578 while (1) { 574 while (1) {
575 struct btrfs_ordered_extent *ordered;
579 lock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS); 576 lock_extent(&BTRFS_I(src)->io_tree, 0, (u64)-1, GFP_NOFS);
580 ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1); 577 ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);
581 if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered) 578 if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered)
@@ -619,6 +616,32 @@ long btrfs_ioctl_clone(struct file *file, unsigned long src_fd)
619 key.objectid != src->i_ino) 616 key.objectid != src->i_ino)
620 break; 617 break;
621 618
619 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY ||
620 btrfs_key_type(&key) == BTRFS_CSUM_ITEM_KEY) {
621 u32 size;
622 struct btrfs_key new_key;
623
624 size = btrfs_item_size_nr(leaf, slot);
625 read_extent_buffer(leaf, buf,
626 btrfs_item_ptr_offset(leaf, slot),
627 size);
628 btrfs_release_path(root, path);
629
630 memcpy(&new_key, &key, sizeof(new_key));
631 new_key.objectid = inode->i_ino;
632 ret = btrfs_insert_empty_item(trans, root, path,
633 &new_key, size);
634 if (ret)
635 goto out;
636
637 leaf = path->nodes[0];
638 slot = path->slots[0];
639 write_extent_buffer(leaf, buf,
640 btrfs_item_ptr_offset(leaf, slot),
641 size);
642 btrfs_mark_buffer_dirty(leaf);
643 }
644
622 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { 645 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) {
623 struct btrfs_file_extent_item *extent; 646 struct btrfs_file_extent_item *extent;
624 int found_type; 647 int found_type;
@@ -634,31 +657,15 @@ long btrfs_ioctl_clone(struct file *file, unsigned long src_fd)
634 /* ds == 0 means there's a hole */ 657 /* ds == 0 means there's a hole */
635 if (ds != 0) { 658 if (ds != 0) {
636 ret = btrfs_inc_extent_ref(trans, root, 659 ret = btrfs_inc_extent_ref(trans, root,
637 ds, dl, 660 ds, dl, leaf->start,
638 root->root_key.objectid, 661 root->root_key.objectid,
639 trans->transid, 662 trans->transid,
640 inode->i_ino, key.offset); 663 inode->i_ino, key.offset);
641 if (ret) 664 BUG_ON(ret);
642 goto out;
643 } 665 }
644 } 666 }
645 } 667 }
646 668 btrfs_release_path(root, path);
647 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY ||
648 btrfs_key_type(&key) == BTRFS_CSUM_ITEM_KEY) {
649 size = btrfs_item_size_nr(leaf, slot);
650 read_extent_buffer(leaf, buf,
651 btrfs_item_ptr_offset(leaf, slot),
652 size);
653 btrfs_release_path(root, path);
654 memcpy(&new_key, &key, sizeof(new_key));
655 new_key.objectid = inode->i_ino;
656 ret = btrfs_insert_item(trans, root, &new_key,
657 buf, size);
658 BUG_ON(ret);
659 } else {
660 btrfs_release_path(root, path);
661 }
662 key.offset++; 669 key.offset++;
663 } 670 }
664 ret = 0; 671 ret = 0;