diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-11 09:25:06 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 7bb86316c3961d1bc401ef184fd996f999556c7f (patch) | |
tree | e67de3b594cf680f295010095a71ed7e825cb757 /fs/btrfs/inode.c | |
parent | 74493f7a59bfd4d1c7029c74ab2cd0e400612c6b (diff) |
Btrfs: Add back pointers from extents to the btree or file referencing them
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d0af0807d9f8..bb70db0c9df4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -93,7 +93,9 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end) | |||
93 | if (alloc_hint == EXTENT_MAP_INLINE) | 93 | if (alloc_hint == EXTENT_MAP_INLINE) |
94 | goto out; | 94 | goto out; |
95 | 95 | ||
96 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, num_bytes, 0, | 96 | ret = btrfs_alloc_extent(trans, root, num_bytes, |
97 | root->root_key.objectid, trans->transid, | ||
98 | inode->i_ino, start, 0, | ||
97 | alloc_hint, (u64)-1, &ins, 1); | 99 | alloc_hint, (u64)-1, &ins, 1); |
98 | if (ret) { | 100 | if (ret) { |
99 | WARN_ON(1); | 101 | WARN_ON(1); |
@@ -560,6 +562,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
560 | u64 extent_start = 0; | 562 | u64 extent_start = 0; |
561 | u64 extent_num_bytes = 0; | 563 | u64 extent_num_bytes = 0; |
562 | u64 item_end = 0; | 564 | u64 item_end = 0; |
565 | u64 root_gen = 0; | ||
563 | int found_extent; | 566 | int found_extent; |
564 | int del_item; | 567 | int del_item; |
565 | int extent_type = -1; | 568 | int extent_type = -1; |
@@ -670,6 +673,15 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
670 | found_extent = 1; | 673 | found_extent = 1; |
671 | inode->i_blocks -= num_dec; | 674 | inode->i_blocks -= num_dec; |
672 | } | 675 | } |
676 | if (leaf == root->node) { | ||
677 | root_gen = | ||
678 | btrfs_header_generation(leaf); | ||
679 | } else { | ||
680 | struct extent_buffer *parent; | ||
681 | parent = path->nodes[1]; | ||
682 | root_gen = | ||
683 | btrfs_header_generation(parent); | ||
684 | } | ||
673 | } | 685 | } |
674 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE && | 686 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE && |
675 | !del_item) { | 687 | !del_item) { |
@@ -690,7 +702,10 @@ delete: | |||
690 | btrfs_release_path(root, path); | 702 | btrfs_release_path(root, path); |
691 | if (found_extent) { | 703 | if (found_extent) { |
692 | ret = btrfs_free_extent(trans, root, extent_start, | 704 | ret = btrfs_free_extent(trans, root, extent_start, |
693 | extent_num_bytes, 0); | 705 | extent_num_bytes, |
706 | root->root_key.objectid, | ||
707 | root_gen, inode->i_ino, | ||
708 | found_key.offset, 0); | ||
694 | BUG_ON(ret); | 709 | BUG_ON(ret); |
695 | } | 710 | } |
696 | } | 711 | } |
@@ -1900,7 +1915,14 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1900 | trans = btrfs_start_transaction(root, 1); | 1915 | trans = btrfs_start_transaction(root, 1); |
1901 | BUG_ON(!trans); | 1916 | BUG_ON(!trans); |
1902 | 1917 | ||
1903 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, 0); | 1918 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
1919 | 0, &objectid); | ||
1920 | if (ret) | ||
1921 | goto fail; | ||
1922 | |||
1923 | leaf = __btrfs_alloc_free_block(trans, root, root->leafsize, | ||
1924 | objectid, trans->transid, 0, 0, | ||
1925 | 0, 0); | ||
1904 | if (IS_ERR(leaf)) | 1926 | if (IS_ERR(leaf)) |
1905 | return PTR_ERR(leaf); | 1927 | return PTR_ERR(leaf); |
1906 | 1928 | ||
@@ -1908,7 +1930,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1908 | btrfs_set_header_level(leaf, 0); | 1930 | btrfs_set_header_level(leaf, 0); |
1909 | btrfs_set_header_bytenr(leaf, leaf->start); | 1931 | btrfs_set_header_bytenr(leaf, leaf->start); |
1910 | btrfs_set_header_generation(leaf, trans->transid); | 1932 | btrfs_set_header_generation(leaf, trans->transid); |
1911 | btrfs_set_header_owner(leaf, root->root_key.objectid); | 1933 | btrfs_set_header_owner(leaf, objectid); |
1934 | |||
1912 | write_extent_buffer(leaf, root->fs_info->fsid, | 1935 | write_extent_buffer(leaf, root->fs_info->fsid, |
1913 | (unsigned long)btrfs_header_fsid(leaf), | 1936 | (unsigned long)btrfs_header_fsid(leaf), |
1914 | BTRFS_FSID_SIZE); | 1937 | BTRFS_FSID_SIZE); |
@@ -1933,11 +1956,6 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1933 | free_extent_buffer(leaf); | 1956 | free_extent_buffer(leaf); |
1934 | leaf = NULL; | 1957 | leaf = NULL; |
1935 | 1958 | ||
1936 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | ||
1937 | 0, &objectid); | ||
1938 | if (ret) | ||
1939 | goto fail; | ||
1940 | |||
1941 | btrfs_set_root_dirid(&root_item, new_dirid); | 1959 | btrfs_set_root_dirid(&root_item, new_dirid); |
1942 | 1960 | ||
1943 | key.objectid = objectid; | 1961 | key.objectid = objectid; |
@@ -2056,7 +2074,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2056 | if (ret) | 2074 | if (ret) |
2057 | goto fail; | 2075 | goto fail; |
2058 | 2076 | ||
2059 | ret = btrfs_inc_root_ref(trans, root); | 2077 | ret = btrfs_inc_root_ref(trans, root, objectid); |
2060 | if (ret) | 2078 | if (ret) |
2061 | goto fail; | 2079 | goto fail; |
2062 | fail: | 2080 | fail: |