diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.c | 228 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 62 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 4 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 1143 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 3 | ||||
-rw-r--r-- | fs/btrfs/file.c | 121 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 57 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 57 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 5 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 108 |
10 files changed, 1066 insertions, 722 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 6f467901246f..50aea8cb653a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -125,7 +125,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
125 | u32 nritems; | 125 | u32 nritems; |
126 | int ret = 0; | 126 | int ret = 0; |
127 | int level; | 127 | int level; |
128 | struct btrfs_key first_key; | ||
129 | struct btrfs_root *new_root; | 128 | struct btrfs_root *new_root; |
130 | 129 | ||
131 | new_root = kmalloc(sizeof(*new_root), GFP_NOFS); | 130 | new_root = kmalloc(sizeof(*new_root), GFP_NOFS); |
@@ -141,18 +140,10 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
141 | 140 | ||
142 | level = btrfs_header_level(buf); | 141 | level = btrfs_header_level(buf); |
143 | nritems = btrfs_header_nritems(buf); | 142 | nritems = btrfs_header_nritems(buf); |
144 | if (nritems) { | 143 | |
145 | if (level == 0) | 144 | cow = btrfs_alloc_free_block(trans, new_root, buf->len, 0, |
146 | btrfs_item_key_to_cpu(buf, &first_key, 0); | 145 | new_root_objectid, trans->transid, |
147 | else | 146 | level, buf->start, 0); |
148 | btrfs_node_key_to_cpu(buf, &first_key, 0); | ||
149 | } else { | ||
150 | first_key.objectid = 0; | ||
151 | } | ||
152 | cow = btrfs_alloc_free_block(trans, new_root, buf->len, | ||
153 | new_root_objectid, | ||
154 | trans->transid, first_key.objectid, | ||
155 | level, buf->start, 0); | ||
156 | if (IS_ERR(cow)) { | 147 | if (IS_ERR(cow)) { |
157 | kfree(new_root); | 148 | kfree(new_root); |
158 | return PTR_ERR(cow); | 149 | return PTR_ERR(cow); |
@@ -165,7 +156,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
165 | btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN); | 156 | btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN); |
166 | 157 | ||
167 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 158 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
168 | ret = btrfs_inc_ref(trans, new_root, buf, 0); | 159 | ret = btrfs_inc_ref(trans, new_root, buf, cow, NULL); |
169 | kfree(new_root); | 160 | kfree(new_root); |
170 | 161 | ||
171 | if (ret) | 162 | if (ret) |
@@ -184,39 +175,31 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
184 | u64 search_start, u64 empty_size, | 175 | u64 search_start, u64 empty_size, |
185 | u64 prealloc_dest) | 176 | u64 prealloc_dest) |
186 | { | 177 | { |
187 | u64 root_gen; | 178 | u64 parent_start; |
188 | struct extent_buffer *cow; | 179 | struct extent_buffer *cow; |
189 | u32 nritems; | 180 | u32 nritems; |
190 | int ret = 0; | 181 | int ret = 0; |
191 | int different_trans = 0; | 182 | int different_trans = 0; |
192 | int level; | 183 | int level; |
193 | int unlock_orig = 0; | 184 | int unlock_orig = 0; |
194 | struct btrfs_key first_key; | ||
195 | 185 | ||
196 | if (*cow_ret == buf) | 186 | if (*cow_ret == buf) |
197 | unlock_orig = 1; | 187 | unlock_orig = 1; |
198 | 188 | ||
199 | WARN_ON(!btrfs_tree_locked(buf)); | 189 | WARN_ON(!btrfs_tree_locked(buf)); |
200 | 190 | ||
201 | if (root->ref_cows) { | 191 | if (parent) |
202 | root_gen = trans->transid; | 192 | parent_start = parent->start; |
203 | } else { | 193 | else |
204 | root_gen = 0; | 194 | parent_start = 0; |
205 | } | 195 | |
206 | WARN_ON(root->ref_cows && trans->transid != | 196 | WARN_ON(root->ref_cows && trans->transid != |
207 | root->fs_info->running_transaction->transid); | 197 | root->fs_info->running_transaction->transid); |
208 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | 198 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); |
209 | 199 | ||
210 | level = btrfs_header_level(buf); | 200 | level = btrfs_header_level(buf); |
211 | nritems = btrfs_header_nritems(buf); | 201 | nritems = btrfs_header_nritems(buf); |
212 | if (nritems) { | 202 | |
213 | if (level == 0) | ||
214 | btrfs_item_key_to_cpu(buf, &first_key, 0); | ||
215 | else | ||
216 | btrfs_node_key_to_cpu(buf, &first_key, 0); | ||
217 | } else { | ||
218 | first_key.objectid = 0; | ||
219 | } | ||
220 | if (prealloc_dest) { | 203 | if (prealloc_dest) { |
221 | struct btrfs_key ins; | 204 | struct btrfs_key ins; |
222 | 205 | ||
@@ -224,19 +207,19 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
224 | ins.offset = buf->len; | 207 | ins.offset = buf->len; |
225 | ins.type = BTRFS_EXTENT_ITEM_KEY; | 208 | ins.type = BTRFS_EXTENT_ITEM_KEY; |
226 | 209 | ||
227 | ret = btrfs_alloc_reserved_extent(trans, root, | 210 | ret = btrfs_alloc_reserved_extent(trans, root, parent_start, |
228 | root->root_key.objectid, | 211 | root->root_key.objectid, |
229 | root_gen, level, | 212 | trans->transid, level, 0, |
230 | first_key.objectid, | ||
231 | &ins); | 213 | &ins); |
232 | BUG_ON(ret); | 214 | BUG_ON(ret); |
233 | cow = btrfs_init_new_buffer(trans, root, prealloc_dest, | 215 | cow = btrfs_init_new_buffer(trans, root, prealloc_dest, |
234 | buf->len); | 216 | buf->len); |
235 | } else { | 217 | } else { |
236 | cow = btrfs_alloc_free_block(trans, root, buf->len, | 218 | cow = btrfs_alloc_free_block(trans, root, buf->len, |
219 | parent_start, | ||
237 | root->root_key.objectid, | 220 | root->root_key.objectid, |
238 | root_gen, first_key.objectid, | 221 | trans->transid, level, |
239 | level, search_start, empty_size); | 222 | search_start, empty_size); |
240 | } | 223 | } |
241 | if (IS_ERR(cow)) | 224 | if (IS_ERR(cow)) |
242 | return PTR_ERR(cow); | 225 | return PTR_ERR(cow); |
@@ -249,17 +232,23 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
249 | 232 | ||
250 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 233 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
251 | if (btrfs_header_generation(buf) != trans->transid) { | 234 | if (btrfs_header_generation(buf) != trans->transid) { |
235 | u32 nr_extents; | ||
252 | different_trans = 1; | 236 | different_trans = 1; |
253 | ret = btrfs_inc_ref(trans, root, buf, 1); | 237 | ret = btrfs_inc_ref(trans, root, buf, cow, &nr_extents); |
254 | if (ret) | 238 | if (ret) |
255 | return ret; | 239 | return ret; |
240 | |||
241 | ret = btrfs_cache_ref(trans, root, buf, nr_extents); | ||
242 | WARN_ON(ret); | ||
256 | } else { | 243 | } else { |
244 | ret = btrfs_update_ref(trans, root, buf, cow, 0, nritems); | ||
245 | if (ret) | ||
246 | return ret; | ||
257 | clean_tree_block(trans, root, buf); | 247 | clean_tree_block(trans, root, buf); |
258 | } | 248 | } |
259 | 249 | ||
260 | if (buf == root->node) { | 250 | if (buf == root->node) { |
261 | WARN_ON(parent && parent != buf); | 251 | WARN_ON(parent && parent != buf); |
262 | root_gen = btrfs_header_generation(buf); | ||
263 | 252 | ||
264 | spin_lock(&root->node_lock); | 253 | spin_lock(&root->node_lock); |
265 | root->node = cow; | 254 | root->node = cow; |
@@ -268,13 +257,14 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
268 | 257 | ||
269 | if (buf != root->commit_root) { | 258 | if (buf != root->commit_root) { |
270 | btrfs_free_extent(trans, root, buf->start, | 259 | btrfs_free_extent(trans, root, buf->start, |
271 | buf->len, root->root_key.objectid, | 260 | buf->len, buf->start, |
272 | root_gen, 0, 0, 1); | 261 | root->root_key.objectid, |
262 | btrfs_header_generation(buf), | ||
263 | 0, 0, 1); | ||
273 | } | 264 | } |
274 | free_extent_buffer(buf); | 265 | free_extent_buffer(buf); |
275 | add_root_to_dirty_list(root); | 266 | add_root_to_dirty_list(root); |
276 | } else { | 267 | } else { |
277 | root_gen = btrfs_header_generation(parent); | ||
278 | btrfs_set_node_blockptr(parent, parent_slot, | 268 | btrfs_set_node_blockptr(parent, parent_slot, |
279 | cow->start); | 269 | cow->start); |
280 | WARN_ON(trans->transid == 0); | 270 | WARN_ON(trans->transid == 0); |
@@ -283,8 +273,8 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
283 | btrfs_mark_buffer_dirty(parent); | 273 | btrfs_mark_buffer_dirty(parent); |
284 | WARN_ON(btrfs_header_generation(parent) != trans->transid); | 274 | WARN_ON(btrfs_header_generation(parent) != trans->transid); |
285 | btrfs_free_extent(trans, root, buf->start, buf->len, | 275 | btrfs_free_extent(trans, root, buf->start, buf->len, |
286 | btrfs_header_owner(parent), root_gen, | 276 | parent_start, btrfs_header_owner(parent), |
287 | 0, 0, 1); | 277 | btrfs_header_generation(parent), 0, 0, 1); |
288 | } | 278 | } |
289 | if (unlock_orig) | 279 | if (unlock_orig) |
290 | btrfs_tree_unlock(buf); | 280 | btrfs_tree_unlock(buf); |
@@ -831,6 +821,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
831 | root->node = child; | 821 | root->node = child; |
832 | spin_unlock(&root->node_lock); | 822 | spin_unlock(&root->node_lock); |
833 | 823 | ||
824 | ret = btrfs_update_extent_ref(trans, root, child->start, | ||
825 | mid->start, child->start, | ||
826 | root->root_key.objectid, | ||
827 | trans->transid, level - 1, 0); | ||
828 | BUG_ON(ret); | ||
829 | |||
834 | add_root_to_dirty_list(root); | 830 | add_root_to_dirty_list(root); |
835 | btrfs_tree_unlock(child); | 831 | btrfs_tree_unlock(child); |
836 | path->locks[level] = 0; | 832 | path->locks[level] = 0; |
@@ -840,7 +836,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
840 | /* once for the path */ | 836 | /* once for the path */ |
841 | free_extent_buffer(mid); | 837 | free_extent_buffer(mid); |
842 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, | 838 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, |
843 | root->root_key.objectid, | 839 | mid->start, root->root_key.objectid, |
844 | btrfs_header_generation(mid), 0, 0, 1); | 840 | btrfs_header_generation(mid), 0, 0, 1); |
845 | /* once for the root ptr */ | 841 | /* once for the root ptr */ |
846 | free_extent_buffer(mid); | 842 | free_extent_buffer(mid); |
@@ -905,7 +901,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
905 | if (wret) | 901 | if (wret) |
906 | ret = wret; | 902 | ret = wret; |
907 | wret = btrfs_free_extent(trans, root, bytenr, | 903 | wret = btrfs_free_extent(trans, root, bytenr, |
908 | blocksize, | 904 | blocksize, parent->start, |
909 | btrfs_header_owner(parent), | 905 | btrfs_header_owner(parent), |
910 | generation, 0, 0, 1); | 906 | generation, 0, 0, 1); |
911 | if (wret) | 907 | if (wret) |
@@ -954,6 +950,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
954 | if (wret) | 950 | if (wret) |
955 | ret = wret; | 951 | ret = wret; |
956 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, | 952 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, |
953 | parent->start, | ||
957 | btrfs_header_owner(parent), | 954 | btrfs_header_owner(parent), |
958 | root_gen, 0, 0, 1); | 955 | root_gen, 0, 0, 1); |
959 | if (wret) | 956 | if (wret) |
@@ -1500,6 +1497,41 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, | |||
1500 | } | 1497 | } |
1501 | 1498 | ||
1502 | /* | 1499 | /* |
1500 | * update item key. | ||
1501 | * | ||
1502 | * This function isn't completely safe. It's the caller's responsibility | ||
1503 | * that the new key won't break the order | ||
1504 | */ | ||
1505 | int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, | ||
1506 | struct btrfs_root *root, struct btrfs_path *path, | ||
1507 | struct btrfs_key *new_key) | ||
1508 | { | ||
1509 | struct btrfs_disk_key disk_key; | ||
1510 | struct extent_buffer *eb; | ||
1511 | int slot; | ||
1512 | |||
1513 | eb = path->nodes[0]; | ||
1514 | slot = path->slots[0]; | ||
1515 | if (slot > 0) { | ||
1516 | btrfs_item_key(eb, &disk_key, slot - 1); | ||
1517 | if (comp_keys(&disk_key, new_key) >= 0) | ||
1518 | return -1; | ||
1519 | } | ||
1520 | if (slot < btrfs_header_nritems(eb) - 1) { | ||
1521 | btrfs_item_key(eb, &disk_key, slot + 1); | ||
1522 | if (comp_keys(&disk_key, new_key) <= 0) | ||
1523 | return -1; | ||
1524 | } | ||
1525 | |||
1526 | btrfs_cpu_key_to_disk(&disk_key, new_key); | ||
1527 | btrfs_set_item_key(eb, &disk_key, slot); | ||
1528 | btrfs_mark_buffer_dirty(eb); | ||
1529 | if (slot == 0) | ||
1530 | fixup_low_keys(trans, root, path, &disk_key, 1); | ||
1531 | return 0; | ||
1532 | } | ||
1533 | |||
1534 | /* | ||
1503 | * try to push data from one node into the next node left in the | 1535 | * try to push data from one node into the next node left in the |
1504 | * tree. | 1536 | * tree. |
1505 | * | 1537 | * |
@@ -1558,6 +1590,10 @@ static int push_node_left(struct btrfs_trans_handle *trans, | |||
1558 | btrfs_set_header_nritems(dst, dst_nritems + push_items); | 1590 | btrfs_set_header_nritems(dst, dst_nritems + push_items); |
1559 | btrfs_mark_buffer_dirty(src); | 1591 | btrfs_mark_buffer_dirty(src); |
1560 | btrfs_mark_buffer_dirty(dst); | 1592 | btrfs_mark_buffer_dirty(dst); |
1593 | |||
1594 | ret = btrfs_update_ref(trans, root, src, dst, dst_nritems, push_items); | ||
1595 | BUG_ON(ret); | ||
1596 | |||
1561 | return ret; | 1597 | return ret; |
1562 | } | 1598 | } |
1563 | 1599 | ||
@@ -1619,6 +1655,10 @@ static int balance_node_right(struct btrfs_trans_handle *trans, | |||
1619 | 1655 | ||
1620 | btrfs_mark_buffer_dirty(src); | 1656 | btrfs_mark_buffer_dirty(src); |
1621 | btrfs_mark_buffer_dirty(dst); | 1657 | btrfs_mark_buffer_dirty(dst); |
1658 | |||
1659 | ret = btrfs_update_ref(trans, root, src, dst, 0, push_items); | ||
1660 | BUG_ON(ret); | ||
1661 | |||
1622 | return ret; | 1662 | return ret; |
1623 | } | 1663 | } |
1624 | 1664 | ||
@@ -1633,30 +1673,24 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, | |||
1633 | struct btrfs_root *root, | 1673 | struct btrfs_root *root, |
1634 | struct btrfs_path *path, int level) | 1674 | struct btrfs_path *path, int level) |
1635 | { | 1675 | { |
1636 | u64 root_gen; | ||
1637 | u64 lower_gen; | 1676 | u64 lower_gen; |
1638 | struct extent_buffer *lower; | 1677 | struct extent_buffer *lower; |
1639 | struct extent_buffer *c; | 1678 | struct extent_buffer *c; |
1640 | struct extent_buffer *old; | 1679 | struct extent_buffer *old; |
1641 | struct btrfs_disk_key lower_key; | 1680 | struct btrfs_disk_key lower_key; |
1681 | int ret; | ||
1642 | 1682 | ||
1643 | BUG_ON(path->nodes[level]); | 1683 | BUG_ON(path->nodes[level]); |
1644 | BUG_ON(path->nodes[level-1] != root->node); | 1684 | BUG_ON(path->nodes[level-1] != root->node); |
1645 | 1685 | ||
1646 | if (root->ref_cows) | ||
1647 | root_gen = trans->transid; | ||
1648 | else | ||
1649 | root_gen = 0; | ||
1650 | |||
1651 | lower = path->nodes[level-1]; | 1686 | lower = path->nodes[level-1]; |
1652 | if (level == 1) | 1687 | if (level == 1) |
1653 | btrfs_item_key(lower, &lower_key, 0); | 1688 | btrfs_item_key(lower, &lower_key, 0); |
1654 | else | 1689 | else |
1655 | btrfs_node_key(lower, &lower_key, 0); | 1690 | btrfs_node_key(lower, &lower_key, 0); |
1656 | 1691 | ||
1657 | c = btrfs_alloc_free_block(trans, root, root->nodesize, | 1692 | c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, |
1658 | root->root_key.objectid, | 1693 | root->root_key.objectid, trans->transid, |
1659 | root_gen, le64_to_cpu(lower_key.objectid), | ||
1660 | level, root->node->start, 0); | 1694 | level, root->node->start, 0); |
1661 | if (IS_ERR(c)) | 1695 | if (IS_ERR(c)) |
1662 | return PTR_ERR(c); | 1696 | return PTR_ERR(c); |
@@ -1679,7 +1713,7 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, | |||
1679 | btrfs_set_node_key(c, &lower_key, 0); | 1713 | btrfs_set_node_key(c, &lower_key, 0); |
1680 | btrfs_set_node_blockptr(c, 0, lower->start); | 1714 | btrfs_set_node_blockptr(c, 0, lower->start); |
1681 | lower_gen = btrfs_header_generation(lower); | 1715 | lower_gen = btrfs_header_generation(lower); |
1682 | WARN_ON(lower_gen == 0); | 1716 | WARN_ON(lower_gen != trans->transid); |
1683 | 1717 | ||
1684 | btrfs_set_node_ptr_generation(c, 0, lower_gen); | 1718 | btrfs_set_node_ptr_generation(c, 0, lower_gen); |
1685 | 1719 | ||
@@ -1690,6 +1724,12 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, | |||
1690 | root->node = c; | 1724 | root->node = c; |
1691 | spin_unlock(&root->node_lock); | 1725 | spin_unlock(&root->node_lock); |
1692 | 1726 | ||
1727 | ret = btrfs_update_extent_ref(trans, root, lower->start, | ||
1728 | lower->start, c->start, | ||
1729 | root->root_key.objectid, | ||
1730 | trans->transid, level - 1, 0); | ||
1731 | BUG_ON(ret); | ||
1732 | |||
1693 | /* the super has an extra ref to root->node */ | 1733 | /* the super has an extra ref to root->node */ |
1694 | free_extent_buffer(old); | 1734 | free_extent_buffer(old); |
1695 | 1735 | ||
@@ -1698,20 +1738,6 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, | |||
1698 | path->nodes[level] = c; | 1738 | path->nodes[level] = c; |
1699 | path->locks[level] = 1; | 1739 | path->locks[level] = 1; |
1700 | path->slots[level] = 0; | 1740 | path->slots[level] = 0; |
1701 | |||
1702 | if (root->ref_cows && lower_gen != trans->transid) { | ||
1703 | struct btrfs_path *back_path = btrfs_alloc_path(); | ||
1704 | int ret; | ||
1705 | mutex_lock(&root->fs_info->alloc_mutex); | ||
1706 | ret = btrfs_insert_extent_backref(trans, | ||
1707 | root->fs_info->extent_root, | ||
1708 | path, lower->start, | ||
1709 | root->root_key.objectid, | ||
1710 | trans->transid, 0, 0); | ||
1711 | BUG_ON(ret); | ||
1712 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1713 | btrfs_free_path(back_path); | ||
1714 | } | ||
1715 | return 0; | 1741 | return 0; |
1716 | } | 1742 | } |
1717 | 1743 | ||
@@ -1766,7 +1792,6 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
1766 | struct btrfs_root *root, | 1792 | struct btrfs_root *root, |
1767 | struct btrfs_path *path, int level) | 1793 | struct btrfs_path *path, int level) |
1768 | { | 1794 | { |
1769 | u64 root_gen; | ||
1770 | struct extent_buffer *c; | 1795 | struct extent_buffer *c; |
1771 | struct extent_buffer *split; | 1796 | struct extent_buffer *split; |
1772 | struct btrfs_disk_key disk_key; | 1797 | struct btrfs_disk_key disk_key; |
@@ -1793,17 +1818,11 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
1793 | } | 1818 | } |
1794 | 1819 | ||
1795 | c_nritems = btrfs_header_nritems(c); | 1820 | c_nritems = btrfs_header_nritems(c); |
1796 | if (root->ref_cows) | ||
1797 | root_gen = trans->transid; | ||
1798 | else | ||
1799 | root_gen = 0; | ||
1800 | 1821 | ||
1801 | btrfs_node_key(c, &disk_key, 0); | ||
1802 | split = btrfs_alloc_free_block(trans, root, root->nodesize, | 1822 | split = btrfs_alloc_free_block(trans, root, root->nodesize, |
1803 | root->root_key.objectid, | 1823 | path->nodes[level + 1]->start, |
1804 | root_gen, | 1824 | root->root_key.objectid, |
1805 | btrfs_disk_key_objectid(&disk_key), | 1825 | trans->transid, level, c->start, 0); |
1806 | level, c->start, 0); | ||
1807 | if (IS_ERR(split)) | 1826 | if (IS_ERR(split)) |
1808 | return PTR_ERR(split); | 1827 | return PTR_ERR(split); |
1809 | 1828 | ||
@@ -1840,6 +1859,9 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
1840 | if (wret) | 1859 | if (wret) |
1841 | ret = wret; | 1860 | ret = wret; |
1842 | 1861 | ||
1862 | ret = btrfs_update_ref(trans, root, c, split, 0, c_nritems - mid); | ||
1863 | BUG_ON(ret); | ||
1864 | |||
1843 | if (path->slots[level] >= mid) { | 1865 | if (path->slots[level] >= mid) { |
1844 | path->slots[level] -= mid; | 1866 | path->slots[level] -= mid; |
1845 | btrfs_tree_unlock(c); | 1867 | btrfs_tree_unlock(c); |
@@ -1955,10 +1977,23 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1955 | else | 1977 | else |
1956 | nr = 1; | 1978 | nr = 1; |
1957 | 1979 | ||
1980 | if (path->slots[0] >= left_nritems) | ||
1981 | push_space += data_size + sizeof(*item); | ||
1982 | |||
1958 | i = left_nritems - 1; | 1983 | i = left_nritems - 1; |
1959 | while (i >= nr) { | 1984 | while (i >= nr) { |
1960 | item = btrfs_item_nr(left, i); | 1985 | item = btrfs_item_nr(left, i); |
1961 | 1986 | ||
1987 | if (!empty && push_items > 0) { | ||
1988 | if (path->slots[0] > i) | ||
1989 | break; | ||
1990 | if (path->slots[0] == i) { | ||
1991 | int space = btrfs_leaf_free_space(root, left); | ||
1992 | if (space + push_space * 2 > free_space) | ||
1993 | break; | ||
1994 | } | ||
1995 | } | ||
1996 | |||
1962 | if (path->slots[0] == i) | 1997 | if (path->slots[0] == i) |
1963 | push_space += data_size + sizeof(*item); | 1998 | push_space += data_size + sizeof(*item); |
1964 | 1999 | ||
@@ -1973,6 +2008,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1973 | this_item_size = btrfs_item_size(left, item); | 2008 | this_item_size = btrfs_item_size(left, item); |
1974 | if (this_item_size + sizeof(*item) + push_space > free_space) | 2009 | if (this_item_size + sizeof(*item) + push_space > free_space) |
1975 | break; | 2010 | break; |
2011 | |||
1976 | push_items++; | 2012 | push_items++; |
1977 | push_space += this_item_size + sizeof(*item); | 2013 | push_space += this_item_size + sizeof(*item); |
1978 | if (i == 0) | 2014 | if (i == 0) |
@@ -2046,6 +2082,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2046 | btrfs_mark_buffer_dirty(left); | 2082 | btrfs_mark_buffer_dirty(left); |
2047 | btrfs_mark_buffer_dirty(right); | 2083 | btrfs_mark_buffer_dirty(right); |
2048 | 2084 | ||
2085 | ret = btrfs_update_ref(trans, root, left, right, 0, push_items); | ||
2086 | BUG_ON(ret); | ||
2087 | |||
2049 | btrfs_item_key(right, &disk_key, 0); | 2088 | btrfs_item_key(right, &disk_key, 0); |
2050 | btrfs_set_node_key(upper, &disk_key, slot + 1); | 2089 | btrfs_set_node_key(upper, &disk_key, slot + 1); |
2051 | btrfs_mark_buffer_dirty(upper); | 2090 | btrfs_mark_buffer_dirty(upper); |
@@ -2147,6 +2186,16 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2147 | KM_USER1); | 2186 | KM_USER1); |
2148 | } | 2187 | } |
2149 | 2188 | ||
2189 | if (!empty && push_items > 0) { | ||
2190 | if (path->slots[0] < i) | ||
2191 | break; | ||
2192 | if (path->slots[0] == i) { | ||
2193 | int space = btrfs_leaf_free_space(root, right); | ||
2194 | if (space + push_space * 2 > free_space) | ||
2195 | break; | ||
2196 | } | ||
2197 | } | ||
2198 | |||
2150 | if (path->slots[0] == i) | 2199 | if (path->slots[0] == i) |
2151 | push_space += data_size + sizeof(*item); | 2200 | push_space += data_size + sizeof(*item); |
2152 | 2201 | ||
@@ -2255,6 +2304,10 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2255 | if (right_nritems) | 2304 | if (right_nritems) |
2256 | btrfs_mark_buffer_dirty(right); | 2305 | btrfs_mark_buffer_dirty(right); |
2257 | 2306 | ||
2307 | ret = btrfs_update_ref(trans, root, right, left, | ||
2308 | old_left_nritems, push_items); | ||
2309 | BUG_ON(ret); | ||
2310 | |||
2258 | btrfs_item_key(right, &disk_key, 0); | 2311 | btrfs_item_key(right, &disk_key, 0); |
2259 | wret = fixup_low_keys(trans, root, path, &disk_key, 1); | 2312 | wret = fixup_low_keys(trans, root, path, &disk_key, 1); |
2260 | if (wret) | 2313 | if (wret) |
@@ -2294,7 +2347,6 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, | |||
2294 | struct btrfs_path *path, int data_size, | 2347 | struct btrfs_path *path, int data_size, |
2295 | int extend) | 2348 | int extend) |
2296 | { | 2349 | { |
2297 | u64 root_gen; | ||
2298 | struct extent_buffer *l; | 2350 | struct extent_buffer *l; |
2299 | u32 nritems; | 2351 | u32 nritems; |
2300 | int mid; | 2352 | int mid; |
@@ -2313,11 +2365,6 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, | |||
2313 | if (extend) | 2365 | if (extend) |
2314 | space_needed = data_size; | 2366 | space_needed = data_size; |
2315 | 2367 | ||
2316 | if (root->ref_cows) | ||
2317 | root_gen = trans->transid; | ||
2318 | else | ||
2319 | root_gen = 0; | ||
2320 | |||
2321 | /* first try to make some room by pushing left and right */ | 2368 | /* first try to make some room by pushing left and right */ |
2322 | if (ins_key->type != BTRFS_DIR_ITEM_KEY) { | 2369 | if (ins_key->type != BTRFS_DIR_ITEM_KEY) { |
2323 | wret = push_leaf_right(trans, root, path, data_size, 0); | 2370 | wret = push_leaf_right(trans, root, path, data_size, 0); |
@@ -2348,13 +2395,10 @@ again: | |||
2348 | nritems = btrfs_header_nritems(l); | 2395 | nritems = btrfs_header_nritems(l); |
2349 | mid = (nritems + 1)/ 2; | 2396 | mid = (nritems + 1)/ 2; |
2350 | 2397 | ||
2351 | btrfs_item_key(l, &disk_key, 0); | ||
2352 | |||
2353 | right = btrfs_alloc_free_block(trans, root, root->leafsize, | 2398 | right = btrfs_alloc_free_block(trans, root, root->leafsize, |
2354 | root->root_key.objectid, | 2399 | path->nodes[1]->start, |
2355 | root_gen, | 2400 | root->root_key.objectid, |
2356 | le64_to_cpu(disk_key.objectid), | 2401 | trans->transid, 0, l->start, 0); |
2357 | 0, l->start, 0); | ||
2358 | if (IS_ERR(right)) { | 2402 | if (IS_ERR(right)) { |
2359 | BUG_ON(1); | 2403 | BUG_ON(1); |
2360 | return PTR_ERR(right); | 2404 | return PTR_ERR(right); |
@@ -2485,6 +2529,9 @@ again: | |||
2485 | btrfs_mark_buffer_dirty(l); | 2529 | btrfs_mark_buffer_dirty(l); |
2486 | BUG_ON(path->slots[0] != slot); | 2530 | BUG_ON(path->slots[0] != slot); |
2487 | 2531 | ||
2532 | ret = btrfs_update_ref(trans, root, l, right, 0, nritems); | ||
2533 | BUG_ON(ret); | ||
2534 | |||
2488 | if (mid <= slot) { | 2535 | if (mid <= slot) { |
2489 | btrfs_tree_unlock(path->nodes[0]); | 2536 | btrfs_tree_unlock(path->nodes[0]); |
2490 | free_extent_buffer(path->nodes[0]); | 2537 | free_extent_buffer(path->nodes[0]); |
@@ -2956,6 +3003,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2956 | ret = wret; | 3003 | ret = wret; |
2957 | wret = btrfs_free_extent(trans, root, | 3004 | wret = btrfs_free_extent(trans, root, |
2958 | leaf->start, leaf->len, | 3005 | leaf->start, leaf->len, |
3006 | path->nodes[1]->start, | ||
2959 | btrfs_header_owner(path->nodes[1]), | 3007 | btrfs_header_owner(path->nodes[1]), |
2960 | root_gen, 0, 0, 1); | 3008 | root_gen, 0, 0, 1); |
2961 | if (wret) | 3009 | if (wret) |
@@ -3007,7 +3055,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
3007 | 3055 | ||
3008 | free_extent_buffer(leaf); | 3056 | free_extent_buffer(leaf); |
3009 | wret = btrfs_free_extent(trans, root, bytenr, | 3057 | wret = btrfs_free_extent(trans, root, bytenr, |
3010 | blocksize, | 3058 | blocksize, path->nodes[1]->start, |
3011 | btrfs_header_owner(path->nodes[1]), | 3059 | btrfs_header_owner(path->nodes[1]), |
3012 | root_gen, 0, 0, 1); | 3060 | root_gen, 0, 0, 1); |
3013 | if (wret) | 3061 | if (wret) |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 730aae3bc181..138c157bbc45 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -40,7 +40,7 @@ extern struct kmem_cache *btrfs_bit_radix_cachep; | |||
40 | extern struct kmem_cache *btrfs_path_cachep; | 40 | extern struct kmem_cache *btrfs_path_cachep; |
41 | struct btrfs_ordered_sum; | 41 | struct btrfs_ordered_sum; |
42 | 42 | ||
43 | #define BTRFS_MAGIC "_B8RfS_M" | 43 | #define BTRFS_MAGIC "_B9RfS_M" |
44 | 44 | ||
45 | #define BTRFS_ACL_NOT_CACHED ((void *)-1) | 45 | #define BTRFS_ACL_NOT_CACHED ((void *)-1) |
46 | 46 | ||
@@ -81,6 +81,9 @@ struct btrfs_ordered_sum; | |||
81 | #define BTRFS_TREE_LOG_OBJECTID -6ULL | 81 | #define BTRFS_TREE_LOG_OBJECTID -6ULL |
82 | #define BTRFS_TREE_LOG_FIXUP_OBJECTID -7ULL | 82 | #define BTRFS_TREE_LOG_FIXUP_OBJECTID -7ULL |
83 | 83 | ||
84 | /* dummy objectid represents multiple objectids */ | ||
85 | #define BTRFS_MULTIPLE_OBJECTIDS -255ULL | ||
86 | |||
84 | /* | 87 | /* |
85 | * All files have objectids in this range. | 88 | * All files have objectids in this range. |
86 | */ | 89 | */ |
@@ -369,6 +372,7 @@ struct btrfs_extent_ref { | |||
369 | __le64 generation; | 372 | __le64 generation; |
370 | __le64 objectid; | 373 | __le64 objectid; |
371 | __le64 offset; | 374 | __le64 offset; |
375 | __le32 num_refs; | ||
372 | } __attribute__ ((__packed__)); | 376 | } __attribute__ ((__packed__)); |
373 | 377 | ||
374 | /* dev extents record free space on individual devices. The owner | 378 | /* dev extents record free space on individual devices. The owner |
@@ -1047,9 +1051,6 @@ btrfs_inode_otime(struct btrfs_inode_item *inode_item) | |||
1047 | BTRFS_SETGET_FUNCS(timespec_sec, struct btrfs_timespec, sec, 64); | 1051 | BTRFS_SETGET_FUNCS(timespec_sec, struct btrfs_timespec, sec, 64); |
1048 | BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_timespec, nsec, 32); | 1052 | BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_timespec, nsec, 32); |
1049 | 1053 | ||
1050 | /* struct btrfs_extent_item */ | ||
1051 | BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); | ||
1052 | |||
1053 | /* struct btrfs_dev_extent */ | 1054 | /* struct btrfs_dev_extent */ |
1054 | BTRFS_SETGET_FUNCS(dev_extent_chunk_tree, struct btrfs_dev_extent, | 1055 | BTRFS_SETGET_FUNCS(dev_extent_chunk_tree, struct btrfs_dev_extent, |
1055 | chunk_tree, 64); | 1056 | chunk_tree, 64); |
@@ -1070,14 +1071,20 @@ BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64); | |||
1070 | BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64); | 1071 | BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64); |
1071 | BTRFS_SETGET_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64); | 1072 | BTRFS_SETGET_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64); |
1072 | BTRFS_SETGET_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64); | 1073 | BTRFS_SETGET_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64); |
1074 | BTRFS_SETGET_FUNCS(ref_num_refs, struct btrfs_extent_ref, num_refs, 32); | ||
1073 | 1075 | ||
1074 | BTRFS_SETGET_STACK_FUNCS(stack_ref_root, struct btrfs_extent_ref, root, 64); | 1076 | BTRFS_SETGET_STACK_FUNCS(stack_ref_root, struct btrfs_extent_ref, root, 64); |
1075 | BTRFS_SETGET_STACK_FUNCS(stack_ref_generation, struct btrfs_extent_ref, | 1077 | BTRFS_SETGET_STACK_FUNCS(stack_ref_generation, struct btrfs_extent_ref, |
1076 | generation, 64); | 1078 | generation, 64); |
1077 | BTRFS_SETGET_STACK_FUNCS(stack_ref_objectid, struct btrfs_extent_ref, | 1079 | BTRFS_SETGET_STACK_FUNCS(stack_ref_objectid, struct btrfs_extent_ref, |
1078 | objectid, 64); | 1080 | objectid, 64); |
1079 | BTRFS_SETGET_STACK_FUNCS(stack_ref_offset, struct btrfs_extent_ref, offset, 64); | 1081 | BTRFS_SETGET_STACK_FUNCS(stack_ref_offset, struct btrfs_extent_ref, |
1082 | offset, 64); | ||
1083 | BTRFS_SETGET_STACK_FUNCS(stack_ref_num_refs, struct btrfs_extent_ref, | ||
1084 | num_refs, 32); | ||
1080 | 1085 | ||
1086 | /* struct btrfs_extent_item */ | ||
1087 | BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); | ||
1081 | BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item, | 1088 | BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item, |
1082 | refs, 32); | 1089 | refs, 32); |
1083 | 1090 | ||
@@ -1474,8 +1481,7 @@ static inline struct dentry *fdentry(struct file *file) { | |||
1474 | } | 1481 | } |
1475 | 1482 | ||
1476 | /* extent-tree.c */ | 1483 | /* extent-tree.c */ |
1477 | int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | 1484 | int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); |
1478 | u64 start, u64 len); | ||
1479 | int btrfs_update_pinned_extents(struct btrfs_root *root, | 1485 | int btrfs_update_pinned_extents(struct btrfs_root *root, |
1480 | u64 bytenr, u64 num, int pin); | 1486 | u64 bytenr, u64 num, int pin); |
1481 | int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | 1487 | int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, |
@@ -1495,10 +1501,9 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | |||
1495 | int data, int owner); | 1501 | int data, int owner); |
1496 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1502 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1497 | struct btrfs_root *root, | 1503 | struct btrfs_root *root, |
1498 | u32 blocksize, | 1504 | u32 blocksize, u64 parent, |
1499 | u64 root_objectid, | 1505 | u64 root_objectid, |
1500 | u64 ref_generation, | 1506 | u64 ref_generation, |
1501 | u64 first_objectid, | ||
1502 | int level, | 1507 | int level, |
1503 | u64 hint, | 1508 | u64 hint, |
1504 | u64 empty_size); | 1509 | u64 empty_size); |
@@ -1508,23 +1513,24 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
1508 | int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size); | 1513 | int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size); |
1509 | int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans, | 1514 | int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans, |
1510 | struct btrfs_root *root, | 1515 | struct btrfs_root *root, |
1511 | struct btrfs_path *path, u64 bytenr, | 1516 | struct btrfs_path *path, |
1517 | u64 bytenr, u64 parent, | ||
1512 | u64 root_objectid, u64 ref_generation, | 1518 | u64 root_objectid, u64 ref_generation, |
1513 | u64 owner, u64 owner_offset); | 1519 | u64 owner, u64 owner_offset); |
1514 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 1520 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
1515 | struct btrfs_root *root, | 1521 | struct btrfs_root *root, |
1516 | u64 num_bytes, u64 min_bytes, | 1522 | u64 num_bytes, u64 parent, u64 min_bytes, |
1517 | u64 root_objectid, u64 ref_generation, | 1523 | u64 root_objectid, u64 ref_generation, |
1518 | u64 owner, u64 owner_offset, | 1524 | u64 owner, u64 owner_offset, |
1519 | u64 empty_size, u64 hint_byte, | 1525 | u64 empty_size, u64 hint_byte, |
1520 | u64 search_end, struct btrfs_key *ins, u64 data); | 1526 | u64 search_end, struct btrfs_key *ins, u64 data); |
1521 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 1527 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
1522 | struct btrfs_root *root, | 1528 | struct btrfs_root *root, u64 parent, |
1523 | u64 root_objectid, u64 ref_generation, | 1529 | u64 root_objectid, u64 ref_generation, |
1524 | u64 owner, u64 owner_offset, | 1530 | u64 owner, u64 owner_offset, |
1525 | struct btrfs_key *ins); | 1531 | struct btrfs_key *ins); |
1526 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | 1532 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, |
1527 | struct btrfs_root *root, | 1533 | struct btrfs_root *root, u64 parent, |
1528 | u64 root_objectid, u64 ref_generation, | 1534 | u64 root_objectid, u64 ref_generation, |
1529 | u64 owner, u64 owner_offset, | 1535 | u64 owner, u64 owner_offset, |
1530 | struct btrfs_key *ins); | 1536 | struct btrfs_key *ins); |
@@ -1535,9 +1541,16 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
1535 | u64 search_end, struct btrfs_key *ins, | 1541 | u64 search_end, struct btrfs_key *ins, |
1536 | u64 data); | 1542 | u64 data); |
1537 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1543 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1538 | struct extent_buffer *buf, int cache_ref); | 1544 | struct extent_buffer *orig_buf, struct extent_buffer *buf, |
1539 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1545 | u32 *nr_extents); |
1540 | *root, u64 bytenr, u64 num_bytes, | 1546 | int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1547 | struct extent_buffer *buf, u32 nr_extents); | ||
1548 | int btrfs_update_ref(struct btrfs_trans_handle *trans, | ||
1549 | struct btrfs_root *root, struct extent_buffer *orig_buf, | ||
1550 | struct extent_buffer *buf, int start_slot, int nr); | ||
1551 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | ||
1552 | struct btrfs_root *root, | ||
1553 | u64 bytenr, u64 num_bytes, u64 parent, | ||
1541 | u64 root_objectid, u64 ref_generation, | 1554 | u64 root_objectid, u64 ref_generation, |
1542 | u64 owner_objectid, u64 owner_offset, int pin); | 1555 | u64 owner_objectid, u64 owner_offset, int pin); |
1543 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); | 1556 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); |
@@ -1545,10 +1558,15 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
1545 | struct btrfs_root *root, | 1558 | struct btrfs_root *root, |
1546 | struct extent_io_tree *unpin); | 1559 | struct extent_io_tree *unpin); |
1547 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1560 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
1548 | struct btrfs_root *root, | 1561 | struct btrfs_root *root, |
1549 | u64 bytenr, u64 num_bytes, | 1562 | u64 bytenr, u64 num_bytes, u64 parent, |
1550 | u64 root_objectid, u64 ref_generation, | 1563 | u64 root_objectid, u64 ref_generation, |
1551 | u64 owner, u64 owner_offset); | 1564 | u64 owner, u64 owner_offset); |
1565 | int btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | ||
1566 | struct btrfs_root *root, u64 bytenr, | ||
1567 | u64 orig_parent, u64 parent, | ||
1568 | u64 root_objectid, u64 ref_generation, | ||
1569 | u64 owner, u64 owner_offset); | ||
1552 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | 1570 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
1553 | struct btrfs_root *root); | 1571 | struct btrfs_root *root); |
1554 | int btrfs_free_block_groups(struct btrfs_fs_info *info); | 1572 | int btrfs_free_block_groups(struct btrfs_fs_info *info); |
@@ -1561,7 +1579,9 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
1561 | int btrfs_previous_item(struct btrfs_root *root, | 1579 | int btrfs_previous_item(struct btrfs_root *root, |
1562 | struct btrfs_path *path, u64 min_objectid, | 1580 | struct btrfs_path *path, u64 min_objectid, |
1563 | int type); | 1581 | int type); |
1564 | 1582 | int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, | |
1583 | struct btrfs_root *root, struct btrfs_path *path, | ||
1584 | struct btrfs_key *new_key); | ||
1565 | struct extent_buffer *btrfs_root_node(struct btrfs_root *root); | 1585 | struct extent_buffer *btrfs_root_node(struct btrfs_root *root); |
1566 | struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root); | 1586 | struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root); |
1567 | int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | 1587 | int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 25be96946a2f..d35ca6a3f513 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -882,8 +882,8 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
882 | root->ref_cows = 0; | 882 | root->ref_cows = 0; |
883 | 883 | ||
884 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, | 884 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, |
885 | BTRFS_TREE_LOG_OBJECTID, | 885 | 0, BTRFS_TREE_LOG_OBJECTID, |
886 | 0, 0, 0, 0, 0); | 886 | trans->transid, 0, 0, 0); |
887 | 887 | ||
888 | btrfs_set_header_nritems(root->node, 0); | 888 | btrfs_set_header_nritems(root->node, 0); |
889 | btrfs_set_header_level(root->node, 0); | 889 | btrfs_set_header_level(root->node, 0); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 558fbe407368..5258923d621f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -29,6 +29,21 @@ | |||
29 | #include "locking.h" | 29 | #include "locking.h" |
30 | #include "ref-cache.h" | 30 | #include "ref-cache.h" |
31 | 31 | ||
32 | #define PENDING_EXTENT_INSERT 0 | ||
33 | #define PENDING_EXTENT_DELETE 1 | ||
34 | #define PENDING_BACKREF_UPDATE 2 | ||
35 | |||
36 | struct pending_extent_op { | ||
37 | int type; | ||
38 | u64 bytenr; | ||
39 | u64 num_bytes; | ||
40 | u64 parent; | ||
41 | u64 orig_parent; | ||
42 | u64 generation; | ||
43 | u64 orig_generation; | ||
44 | int level; | ||
45 | }; | ||
46 | |||
32 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct | 47 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
33 | btrfs_root *extent_root); | 48 | btrfs_root *extent_root); |
34 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 49 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
@@ -487,48 +502,15 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | |||
487 | return ret; | 502 | return ret; |
488 | } | 503 | } |
489 | 504 | ||
490 | static u64 hash_extent_ref(u64 root_objectid, u64 ref_generation, | ||
491 | u64 owner, u64 owner_offset) | ||
492 | { | ||
493 | u32 high_crc = ~(u32)0; | ||
494 | u32 low_crc = ~(u32)0; | ||
495 | __le64 lenum; | ||
496 | lenum = cpu_to_le64(root_objectid); | ||
497 | high_crc = btrfs_crc32c(high_crc, &lenum, sizeof(lenum)); | ||
498 | lenum = cpu_to_le64(ref_generation); | ||
499 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
500 | if (owner >= BTRFS_FIRST_FREE_OBJECTID) { | ||
501 | lenum = cpu_to_le64(owner); | ||
502 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
503 | lenum = cpu_to_le64(owner_offset); | ||
504 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
505 | } | ||
506 | return ((u64)high_crc << 32) | (u64)low_crc; | ||
507 | } | ||
508 | |||
509 | static int match_extent_ref(struct extent_buffer *leaf, | ||
510 | struct btrfs_extent_ref *disk_ref, | ||
511 | struct btrfs_extent_ref *cpu_ref) | ||
512 | { | ||
513 | int ret; | ||
514 | int len; | ||
515 | |||
516 | if (cpu_ref->objectid) | ||
517 | len = sizeof(*cpu_ref); | ||
518 | else | ||
519 | len = 2 * sizeof(u64); | ||
520 | ret = memcmp_extent_buffer(leaf, cpu_ref, (unsigned long)disk_ref, | ||
521 | len); | ||
522 | return ret == 0; | ||
523 | } | ||
524 | |||
525 | /* simple helper to search for an existing extent at a given offset */ | 505 | /* simple helper to search for an existing extent at a given offset */ |
526 | int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | 506 | int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) |
527 | u64 start, u64 len) | ||
528 | { | 507 | { |
529 | int ret; | 508 | int ret; |
530 | struct btrfs_key key; | 509 | struct btrfs_key key; |
510 | struct btrfs_path *path; | ||
531 | 511 | ||
512 | path = btrfs_alloc_path(); | ||
513 | BUG_ON(!path); | ||
532 | maybe_lock_mutex(root); | 514 | maybe_lock_mutex(root); |
533 | key.objectid = start; | 515 | key.objectid = start; |
534 | key.offset = len; | 516 | key.offset = len; |
@@ -536,72 +518,7 @@ int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | |||
536 | ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, | 518 | ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, |
537 | 0, 0); | 519 | 0, 0); |
538 | maybe_unlock_mutex(root); | 520 | maybe_unlock_mutex(root); |
539 | return ret; | 521 | btrfs_free_path(path); |
540 | } | ||
541 | |||
542 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, | ||
543 | struct btrfs_root *root, | ||
544 | struct btrfs_path *path, u64 bytenr, | ||
545 | u64 root_objectid, | ||
546 | u64 ref_generation, u64 owner, | ||
547 | u64 owner_offset, int del) | ||
548 | { | ||
549 | u64 hash; | ||
550 | struct btrfs_key key; | ||
551 | struct btrfs_key found_key; | ||
552 | struct btrfs_extent_ref ref; | ||
553 | struct extent_buffer *leaf; | ||
554 | struct btrfs_extent_ref *disk_ref; | ||
555 | int ret; | ||
556 | int ret2; | ||
557 | |||
558 | btrfs_set_stack_ref_root(&ref, root_objectid); | ||
559 | btrfs_set_stack_ref_generation(&ref, ref_generation); | ||
560 | btrfs_set_stack_ref_objectid(&ref, owner); | ||
561 | btrfs_set_stack_ref_offset(&ref, owner_offset); | ||
562 | |||
563 | hash = hash_extent_ref(root_objectid, ref_generation, owner, | ||
564 | owner_offset); | ||
565 | key.offset = hash; | ||
566 | key.objectid = bytenr; | ||
567 | key.type = BTRFS_EXTENT_REF_KEY; | ||
568 | |||
569 | while (1) { | ||
570 | ret = btrfs_search_slot(trans, root, &key, path, | ||
571 | del ? -1 : 0, del); | ||
572 | if (ret < 0) | ||
573 | goto out; | ||
574 | leaf = path->nodes[0]; | ||
575 | if (ret != 0) { | ||
576 | u32 nritems = btrfs_header_nritems(leaf); | ||
577 | if (path->slots[0] >= nritems) { | ||
578 | ret2 = btrfs_next_leaf(root, path); | ||
579 | if (ret2) | ||
580 | goto out; | ||
581 | leaf = path->nodes[0]; | ||
582 | } | ||
583 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
584 | if (found_key.objectid != bytenr || | ||
585 | found_key.type != BTRFS_EXTENT_REF_KEY) | ||
586 | goto out; | ||
587 | key.offset = found_key.offset; | ||
588 | if (del) { | ||
589 | btrfs_release_path(root, path); | ||
590 | continue; | ||
591 | } | ||
592 | } | ||
593 | disk_ref = btrfs_item_ptr(path->nodes[0], | ||
594 | path->slots[0], | ||
595 | struct btrfs_extent_ref); | ||
596 | if (match_extent_ref(path->nodes[0], disk_ref, &ref)) { | ||
597 | ret = 0; | ||
598 | goto out; | ||
599 | } | ||
600 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
601 | key.offset = found_key.offset + 1; | ||
602 | btrfs_release_path(root, path); | ||
603 | } | ||
604 | out: | ||
605 | return ret; | 522 | return ret; |
606 | } | 523 | } |
607 | 524 | ||
@@ -622,7 +539,7 @@ out: | |||
622 | * File extents can be referenced by: | 539 | * File extents can be referenced by: |
623 | * | 540 | * |
624 | * - multiple snapshots, subvolumes, or different generations in one subvol | 541 | * - multiple snapshots, subvolumes, or different generations in one subvol |
625 | * - different files inside a single subvolume (in theory, not implemented yet) | 542 | * - different files inside a single subvolume |
626 | * - different offsets inside a file (bookend extents in file.c) | 543 | * - different offsets inside a file (bookend extents in file.c) |
627 | * | 544 | * |
628 | * The extent ref structure has fields for: | 545 | * The extent ref structure has fields for: |
@@ -631,119 +548,284 @@ out: | |||
631 | * - Generation number of the tree holding the reference | 548 | * - Generation number of the tree holding the reference |
632 | * - objectid of the file holding the reference | 549 | * - objectid of the file holding the reference |
633 | * - offset in the file corresponding to the key holding the reference | 550 | * - offset in the file corresponding to the key holding the reference |
551 | * - number of references holding by parent node (alway 1 for tree blocks) | ||
552 | * | ||
553 | * Btree leaf may hold multiple references to a file extent. In most cases, | ||
554 | * these references are from same file and the corresponding offsets inside | ||
555 | * the file are close together. So inode objectid and offset in file are | ||
556 | * just hints, they provide hints about where in the btree the references | ||
557 | * can be found and when we can stop searching. | ||
634 | * | 558 | * |
635 | * When a file extent is allocated the fields are filled in: | 559 | * When a file extent is allocated the fields are filled in: |
636 | * (root_key.objectid, trans->transid, inode objectid, offset in file) | 560 | * (root_key.objectid, trans->transid, inode objectid, offset in file, 1) |
637 | * | 561 | * |
638 | * When a leaf is cow'd new references are added for every file extent found | 562 | * When a leaf is cow'd new references are added for every file extent found |
639 | * in the leaf. It looks the same as the create case, but trans->transid | 563 | * in the leaf. It looks similar to the create case, but trans->transid will |
640 | * will be different when the block is cow'd. | 564 | * be different when the block is cow'd. |
641 | * | 565 | * |
642 | * (root_key.objectid, trans->transid, inode objectid, offset in file) | 566 | * (root_key.objectid, trans->transid, inode objectid, offset in file, |
567 | * number of references in the leaf) | ||
643 | * | 568 | * |
644 | * When a file extent is removed either during snapshot deletion or file | 569 | * Because inode objectid and offset in file are just hints, they are not |
645 | * truncation, the corresponding back reference is found | 570 | * used when backrefs are deleted. When a file extent is removed either |
646 | * by searching for: | 571 | * during snapshot deletion or file truncation, we find the corresponding |
572 | * back back reference and check the following fields. | ||
647 | * | 573 | * |
648 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf), | 574 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf)) |
649 | * inode objectid, offset in file) | ||
650 | * | 575 | * |
651 | * Btree extents can be referenced by: | 576 | * Btree extents can be referenced by: |
652 | * | 577 | * |
653 | * - Different subvolumes | 578 | * - Different subvolumes |
654 | * - Different generations of the same subvolume | 579 | * - Different generations of the same subvolume |
655 | * | 580 | * |
656 | * Storing sufficient information for a full reverse mapping of a btree | ||
657 | * block would require storing the lowest key of the block in the backref, | ||
658 | * and it would require updating that lowest key either before write out or | ||
659 | * every time it changed. Instead, the objectid of the lowest key is stored | ||
660 | * along with the level of the tree block. This provides a hint | ||
661 | * about where in the btree the block can be found. Searches through the | ||
662 | * btree only need to look for a pointer to that block, so they stop one | ||
663 | * level higher than the level recorded in the backref. | ||
664 | * | ||
665 | * Some btrees do not do reference counting on their extents. These | ||
666 | * include the extent tree and the tree of tree roots. Backrefs for these | ||
667 | * trees always have a generation of zero. | ||
668 | * | ||
669 | * When a tree block is created, back references are inserted: | 581 | * When a tree block is created, back references are inserted: |
670 | * | 582 | * |
671 | * (root->root_key.objectid, trans->transid or zero, level, lowest_key_objectid) | 583 | * (root->root_key.objectid, trans->transid, level, 0, 1) |
672 | * | 584 | * |
673 | * When a tree block is cow'd in a reference counted root, | 585 | * When a tree block is cow'd, new back references are added for all the |
674 | * new back references are added for all the blocks it points to. | 586 | * blocks it points to. If the tree block isn't in reference counted root, |
675 | * These are of the form (trans->transid will have increased since creation): | 587 | * the old back references are removed. These new back references are of |
588 | * the form (trans->transid will have increased since creation): | ||
676 | * | 589 | * |
677 | * (root->root_key.objectid, trans->transid, level, lowest_key_objectid) | 590 | * (root->root_key.objectid, trans->transid, level, 0, 1) |
678 | * | 591 | * |
679 | * Because the lowest_key_objectid and the level are just hints | 592 | * When a backref is in deleting, the following fields are checked: |
680 | * they are not used when backrefs are deleted. When a backref is deleted: | ||
681 | * | 593 | * |
682 | * if backref was for a tree root: | 594 | * if backref was for a tree root: |
683 | * root_objectid = root->root_key.objectid | 595 | * (btrfs_header_owner(itself), btrfs_header_generation(itself)) |
684 | * else | 596 | * else |
685 | * root_objectid = btrfs_header_owner(parent) | 597 | * (btrfs_header_owner(parent), btrfs_header_generation(parent)) |
686 | * | 598 | * |
687 | * (root_objectid, btrfs_header_generation(parent) or zero, 0, 0) | 599 | * Back Reference Key composing: |
688 | * | 600 | * |
689 | * Back Reference Key hashing: | 601 | * The key objectid corresponds to the first byte in the extent, the key |
690 | * | 602 | * type is set to BTRFS_EXTENT_REF_KEY, and the key offset is the first |
691 | * Back references have four fields, each 64 bits long. Unfortunately, | 603 | * byte of parent extent. If a extent is tree root, the key offset is set |
692 | * This is hashed into a single 64 bit number and placed into the key offset. | 604 | * to the key objectid. |
693 | * The key objectid corresponds to the first byte in the extent, and the | ||
694 | * key type is set to BTRFS_EXTENT_REF_KEY | ||
695 | */ | 605 | */ |
696 | int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans, | 606 | |
697 | struct btrfs_root *root, | 607 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, |
698 | struct btrfs_path *path, u64 bytenr, | 608 | struct btrfs_root *root, |
699 | u64 root_objectid, u64 ref_generation, | 609 | struct btrfs_path *path, u64 bytenr, |
700 | u64 owner, u64 owner_offset) | 610 | u64 parent, u64 ref_root, |
611 | u64 ref_generation, int del) | ||
701 | { | 612 | { |
702 | u64 hash; | ||
703 | struct btrfs_key key; | 613 | struct btrfs_key key; |
704 | struct btrfs_extent_ref ref; | 614 | struct btrfs_extent_ref *ref; |
705 | struct btrfs_extent_ref *disk_ref; | 615 | struct extent_buffer *leaf; |
706 | int ret; | 616 | int ret; |
707 | 617 | ||
708 | btrfs_set_stack_ref_root(&ref, root_objectid); | 618 | key.objectid = bytenr; |
709 | btrfs_set_stack_ref_generation(&ref, ref_generation); | 619 | key.type = BTRFS_EXTENT_REF_KEY; |
710 | btrfs_set_stack_ref_objectid(&ref, owner); | 620 | key.offset = parent; |
711 | btrfs_set_stack_ref_offset(&ref, owner_offset); | 621 | |
622 | ret = btrfs_search_slot(trans, root, &key, path, del ? -1 : 0, 1); | ||
623 | if (ret < 0) | ||
624 | goto out; | ||
625 | if (ret > 0) { | ||
626 | ret = -ENOENT; | ||
627 | goto out; | ||
628 | } | ||
629 | |||
630 | leaf = path->nodes[0]; | ||
631 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); | ||
632 | if (btrfs_ref_root(leaf, ref) != ref_root || | ||
633 | btrfs_ref_generation(leaf, ref) != ref_generation) { | ||
634 | ret = -EIO; | ||
635 | WARN_ON(1); | ||
636 | goto out; | ||
637 | } | ||
638 | ret = 0; | ||
639 | out: | ||
640 | return ret; | ||
641 | } | ||
642 | |||
643 | static int noinline insert_extent_backref(struct btrfs_trans_handle *trans, | ||
644 | struct btrfs_root *root, | ||
645 | struct btrfs_path *path, | ||
646 | u64 bytenr, u64 parent, | ||
647 | u64 ref_root, u64 ref_generation, | ||
648 | u64 owner_objectid, u64 owner_offset) | ||
649 | { | ||
650 | struct btrfs_key key; | ||
651 | struct extent_buffer *leaf; | ||
652 | struct btrfs_extent_ref *ref; | ||
653 | u32 num_refs; | ||
654 | int ret; | ||
712 | 655 | ||
713 | hash = hash_extent_ref(root_objectid, ref_generation, owner, | ||
714 | owner_offset); | ||
715 | key.offset = hash; | ||
716 | key.objectid = bytenr; | 656 | key.objectid = bytenr; |
717 | key.type = BTRFS_EXTENT_REF_KEY; | 657 | key.type = BTRFS_EXTENT_REF_KEY; |
658 | key.offset = parent; | ||
718 | 659 | ||
719 | ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(ref)); | 660 | ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*ref)); |
720 | while (ret == -EEXIST) { | 661 | if (ret == 0) { |
721 | disk_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 662 | leaf = path->nodes[0]; |
722 | struct btrfs_extent_ref); | 663 | ref = btrfs_item_ptr(leaf, path->slots[0], |
723 | if (match_extent_ref(path->nodes[0], disk_ref, &ref)) | 664 | struct btrfs_extent_ref); |
665 | btrfs_set_ref_root(leaf, ref, ref_root); | ||
666 | btrfs_set_ref_generation(leaf, ref, ref_generation); | ||
667 | btrfs_set_ref_objectid(leaf, ref, owner_objectid); | ||
668 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
669 | btrfs_set_ref_num_refs(leaf, ref, 1); | ||
670 | } else if (ret == -EEXIST) { | ||
671 | u64 existing_owner; | ||
672 | BUG_ON(owner_objectid < BTRFS_FIRST_FREE_OBJECTID); | ||
673 | leaf = path->nodes[0]; | ||
674 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
675 | struct btrfs_extent_ref); | ||
676 | if (btrfs_ref_root(leaf, ref) != ref_root || | ||
677 | btrfs_ref_generation(leaf, ref) != ref_generation) { | ||
678 | ret = -EIO; | ||
679 | WARN_ON(1); | ||
724 | goto out; | 680 | goto out; |
725 | key.offset++; | 681 | } |
726 | btrfs_release_path(root, path); | 682 | |
727 | ret = btrfs_insert_empty_item(trans, root, path, &key, | 683 | num_refs = btrfs_ref_num_refs(leaf, ref); |
728 | sizeof(ref)); | 684 | BUG_ON(num_refs == 0); |
729 | } | 685 | btrfs_set_ref_num_refs(leaf, ref, num_refs + 1); |
730 | if (ret) | 686 | |
687 | existing_owner = btrfs_ref_objectid(leaf, ref); | ||
688 | if (existing_owner == owner_objectid && | ||
689 | btrfs_ref_offset(leaf, ref) > owner_offset) { | ||
690 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
691 | } else if (existing_owner != owner_objectid && | ||
692 | existing_owner != BTRFS_MULTIPLE_OBJECTIDS) { | ||
693 | btrfs_set_ref_objectid(leaf, ref, | ||
694 | BTRFS_MULTIPLE_OBJECTIDS); | ||
695 | btrfs_set_ref_offset(leaf, ref, 0); | ||
696 | } | ||
697 | ret = 0; | ||
698 | } else { | ||
731 | goto out; | 699 | goto out; |
732 | disk_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 700 | } |
733 | struct btrfs_extent_ref); | ||
734 | write_extent_buffer(path->nodes[0], &ref, (unsigned long)disk_ref, | ||
735 | sizeof(ref)); | ||
736 | btrfs_mark_buffer_dirty(path->nodes[0]); | 701 | btrfs_mark_buffer_dirty(path->nodes[0]); |
737 | out: | 702 | out: |
738 | btrfs_release_path(root, path); | 703 | btrfs_release_path(root, path); |
739 | return ret; | 704 | return ret; |
740 | } | 705 | } |
741 | 706 | ||
707 | static int noinline remove_extent_backref(struct btrfs_trans_handle *trans, | ||
708 | struct btrfs_root *root, | ||
709 | struct btrfs_path *path) | ||
710 | { | ||
711 | struct extent_buffer *leaf; | ||
712 | struct btrfs_extent_ref *ref; | ||
713 | u32 num_refs; | ||
714 | int ret = 0; | ||
715 | |||
716 | leaf = path->nodes[0]; | ||
717 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); | ||
718 | num_refs = btrfs_ref_num_refs(leaf, ref); | ||
719 | BUG_ON(num_refs == 0); | ||
720 | num_refs -= 1; | ||
721 | if (num_refs == 0) { | ||
722 | ret = btrfs_del_item(trans, root, path); | ||
723 | } else { | ||
724 | btrfs_set_ref_num_refs(leaf, ref, num_refs); | ||
725 | btrfs_mark_buffer_dirty(leaf); | ||
726 | } | ||
727 | btrfs_release_path(root, path); | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | ||
732 | struct btrfs_root *root, u64 bytenr, | ||
733 | u64 orig_parent, u64 parent, | ||
734 | u64 orig_root, u64 ref_root, | ||
735 | u64 orig_generation, u64 ref_generation, | ||
736 | u64 owner_objectid, u64 owner_offset) | ||
737 | { | ||
738 | int ret; | ||
739 | struct btrfs_root *extent_root = root->fs_info->extent_root; | ||
740 | struct btrfs_path *path; | ||
741 | |||
742 | if (root == root->fs_info->extent_root) { | ||
743 | struct pending_extent_op *extent_op; | ||
744 | u64 num_bytes; | ||
745 | |||
746 | BUG_ON(owner_objectid >= BTRFS_MAX_LEVEL); | ||
747 | num_bytes = btrfs_level_size(root, (int)owner_objectid); | ||
748 | if (test_range_bit(&root->fs_info->extent_ins, bytenr, | ||
749 | bytenr + num_bytes - 1, EXTENT_LOCKED, 0)) { | ||
750 | u64 priv; | ||
751 | ret = get_state_private(&root->fs_info->extent_ins, | ||
752 | bytenr, &priv); | ||
753 | BUG_ON(ret); | ||
754 | extent_op = (struct pending_extent_op *) | ||
755 | (unsigned long)priv; | ||
756 | BUG_ON(extent_op->parent != orig_parent); | ||
757 | BUG_ON(extent_op->generation != orig_generation); | ||
758 | extent_op->parent = parent; | ||
759 | extent_op->generation = ref_generation; | ||
760 | } else { | ||
761 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
762 | BUG_ON(!extent_op); | ||
763 | |||
764 | extent_op->type = PENDING_BACKREF_UPDATE; | ||
765 | extent_op->bytenr = bytenr; | ||
766 | extent_op->num_bytes = num_bytes; | ||
767 | extent_op->parent = parent; | ||
768 | extent_op->orig_parent = orig_parent; | ||
769 | extent_op->generation = ref_generation; | ||
770 | extent_op->orig_generation = orig_generation; | ||
771 | extent_op->level = (int)owner_objectid; | ||
772 | |||
773 | set_extent_bits(&root->fs_info->extent_ins, | ||
774 | bytenr, bytenr + num_bytes - 1, | ||
775 | EXTENT_LOCKED, GFP_NOFS); | ||
776 | set_state_private(&root->fs_info->extent_ins, | ||
777 | bytenr, (unsigned long)extent_op); | ||
778 | } | ||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | path = btrfs_alloc_path(); | ||
783 | if (!path) | ||
784 | return -ENOMEM; | ||
785 | ret = lookup_extent_backref(trans, extent_root, path, | ||
786 | bytenr, orig_parent, orig_root, | ||
787 | orig_generation, 1); | ||
788 | if (ret) | ||
789 | goto out; | ||
790 | ret = remove_extent_backref(trans, extent_root, path); | ||
791 | if (ret) | ||
792 | goto out; | ||
793 | ret = insert_extent_backref(trans, extent_root, path, bytenr, | ||
794 | parent, ref_root, ref_generation, | ||
795 | owner_objectid, owner_offset); | ||
796 | BUG_ON(ret); | ||
797 | finish_current_insert(trans, extent_root); | ||
798 | del_pending_extents(trans, extent_root); | ||
799 | out: | ||
800 | btrfs_free_path(path); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | int btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | ||
805 | struct btrfs_root *root, u64 bytenr, | ||
806 | u64 orig_parent, u64 parent, | ||
807 | u64 ref_root, u64 ref_generation, | ||
808 | u64 owner_objectid, u64 owner_offset) | ||
809 | { | ||
810 | int ret; | ||
811 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | ||
812 | owner_objectid < BTRFS_FIRST_FREE_OBJECTID) | ||
813 | return 0; | ||
814 | maybe_lock_mutex(root); | ||
815 | ret = __btrfs_update_extent_ref(trans, root, bytenr, orig_parent, | ||
816 | parent, ref_root, ref_root, | ||
817 | ref_generation, ref_generation, | ||
818 | owner_objectid, owner_offset); | ||
819 | maybe_unlock_mutex(root); | ||
820 | return ret; | ||
821 | } | ||
822 | |||
742 | static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 823 | static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
743 | struct btrfs_root *root, | 824 | struct btrfs_root *root, u64 bytenr, |
744 | u64 bytenr, u64 num_bytes, | 825 | u64 orig_parent, u64 parent, |
745 | u64 root_objectid, u64 ref_generation, | 826 | u64 orig_root, u64 ref_root, |
746 | u64 owner, u64 owner_offset) | 827 | u64 orig_generation, u64 ref_generation, |
828 | u64 owner_objectid, u64 owner_offset) | ||
747 | { | 829 | { |
748 | struct btrfs_path *path; | 830 | struct btrfs_path *path; |
749 | int ret; | 831 | int ret; |
@@ -752,24 +834,28 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
752 | struct btrfs_extent_item *item; | 834 | struct btrfs_extent_item *item; |
753 | u32 refs; | 835 | u32 refs; |
754 | 836 | ||
755 | WARN_ON(num_bytes < root->sectorsize); | ||
756 | path = btrfs_alloc_path(); | 837 | path = btrfs_alloc_path(); |
757 | if (!path) | 838 | if (!path) |
758 | return -ENOMEM; | 839 | return -ENOMEM; |
759 | 840 | ||
760 | path->reada = 1; | 841 | path->reada = 1; |
761 | key.objectid = bytenr; | 842 | key.objectid = bytenr; |
762 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 843 | key.type = BTRFS_EXTENT_ITEM_KEY; |
763 | key.offset = num_bytes; | 844 | key.offset = (u64)-1; |
845 | |||
764 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 846 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
765 | 0, 1); | 847 | 0, 1); |
766 | if (ret < 0) | 848 | if (ret < 0) |
767 | return ret; | 849 | return ret; |
768 | if (ret != 0) { | 850 | BUG_ON(ret == 0 || path->slots[0] == 0); |
769 | BUG(); | 851 | |
770 | } | 852 | path->slots[0]--; |
771 | BUG_ON(ret != 0); | ||
772 | l = path->nodes[0]; | 853 | l = path->nodes[0]; |
854 | |||
855 | btrfs_item_key_to_cpu(l, &key, path->slots[0]); | ||
856 | BUG_ON(key.objectid != bytenr); | ||
857 | BUG_ON(key.type != BTRFS_EXTENT_ITEM_KEY); | ||
858 | |||
773 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); | 859 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); |
774 | refs = btrfs_extent_refs(l, item); | 860 | refs = btrfs_extent_refs(l, item); |
775 | btrfs_set_extent_refs(l, item, refs + 1); | 861 | btrfs_set_extent_refs(l, item, refs + 1); |
@@ -778,9 +864,10 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
778 | btrfs_release_path(root->fs_info->extent_root, path); | 864 | btrfs_release_path(root->fs_info->extent_root, path); |
779 | 865 | ||
780 | path->reada = 1; | 866 | path->reada = 1; |
781 | ret = btrfs_insert_extent_backref(trans, root->fs_info->extent_root, | 867 | ret = insert_extent_backref(trans, root->fs_info->extent_root, |
782 | path, bytenr, root_objectid, | 868 | path, bytenr, parent, |
783 | ref_generation, owner, owner_offset); | 869 | ref_root, ref_generation, |
870 | owner_objectid, owner_offset); | ||
784 | BUG_ON(ret); | 871 | BUG_ON(ret); |
785 | finish_current_insert(trans, root->fs_info->extent_root); | 872 | finish_current_insert(trans, root->fs_info->extent_root); |
786 | del_pending_extents(trans, root->fs_info->extent_root); | 873 | del_pending_extents(trans, root->fs_info->extent_root); |
@@ -790,18 +877,20 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
790 | } | 877 | } |
791 | 878 | ||
792 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 879 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
793 | struct btrfs_root *root, | 880 | struct btrfs_root *root, |
794 | u64 bytenr, u64 num_bytes, | 881 | u64 bytenr, u64 num_bytes, u64 parent, |
795 | u64 root_objectid, u64 ref_generation, | 882 | u64 ref_root, u64 ref_generation, |
796 | u64 owner, u64 owner_offset) | 883 | u64 owner_objectid, u64 owner_offset) |
797 | { | 884 | { |
798 | int ret; | 885 | int ret; |
799 | 886 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | |
800 | mutex_lock(&root->fs_info->alloc_mutex); | 887 | owner_objectid < BTRFS_FIRST_FREE_OBJECTID) |
801 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, | 888 | return 0; |
802 | root_objectid, ref_generation, | 889 | maybe_lock_mutex(root); |
803 | owner, owner_offset); | 890 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, 0, parent, |
804 | mutex_unlock(&root->fs_info->alloc_mutex); | 891 | 0, ref_root, 0, ref_generation, |
892 | owner_objectid, owner_offset); | ||
893 | maybe_unlock_mutex(root); | ||
805 | return ret; | 894 | return ret; |
806 | } | 895 | } |
807 | 896 | ||
@@ -813,9 +902,9 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | |||
813 | return 0; | 902 | return 0; |
814 | } | 903 | } |
815 | 904 | ||
816 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 905 | int btrfs_lookup_extent_ref(struct btrfs_trans_handle *trans, |
817 | struct btrfs_root *root, u64 bytenr, | 906 | struct btrfs_root *root, u64 bytenr, |
818 | u64 num_bytes, u32 *refs) | 907 | u64 num_bytes, u32 *refs) |
819 | { | 908 | { |
820 | struct btrfs_path *path; | 909 | struct btrfs_path *path; |
821 | int ret; | 910 | int ret; |
@@ -846,7 +935,6 @@ out: | |||
846 | return 0; | 935 | return 0; |
847 | } | 936 | } |
848 | 937 | ||
849 | |||
850 | static int get_reference_status(struct btrfs_root *root, u64 bytenr, | 938 | static int get_reference_status(struct btrfs_root *root, u64 bytenr, |
851 | u64 parent_gen, u64 ref_objectid, | 939 | u64 parent_gen, u64 ref_objectid, |
852 | u64 *min_generation, u32 *ref_count) | 940 | u64 *min_generation, u32 *ref_count) |
@@ -863,7 +951,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
863 | int ret; | 951 | int ret; |
864 | 952 | ||
865 | key.objectid = bytenr; | 953 | key.objectid = bytenr; |
866 | key.offset = 0; | 954 | key.offset = (u64)-1; |
867 | key.type = BTRFS_EXTENT_ITEM_KEY; | 955 | key.type = BTRFS_EXTENT_ITEM_KEY; |
868 | 956 | ||
869 | path = btrfs_alloc_path(); | 957 | path = btrfs_alloc_path(); |
@@ -872,7 +960,10 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
872 | if (ret < 0) | 960 | if (ret < 0) |
873 | goto out; | 961 | goto out; |
874 | BUG_ON(ret == 0); | 962 | BUG_ON(ret == 0); |
963 | if (ret < 0 || path->slots[0] == 0) | ||
964 | goto out; | ||
875 | 965 | ||
966 | path->slots[0]--; | ||
876 | leaf = path->nodes[0]; | 967 | leaf = path->nodes[0]; |
877 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 968 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
878 | 969 | ||
@@ -909,7 +1000,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
909 | struct btrfs_extent_ref); | 1000 | struct btrfs_extent_ref); |
910 | ref_generation = btrfs_ref_generation(leaf, ref_item); | 1001 | ref_generation = btrfs_ref_generation(leaf, ref_item); |
911 | /* | 1002 | /* |
912 | * For (parent_gen > 0 && parent_gen > ref_gen): | 1003 | * For (parent_gen > 0 && parent_gen > ref_generation): |
913 | * | 1004 | * |
914 | * we reach here through the oldest root, therefore | 1005 | * we reach here through the oldest root, therefore |
915 | * all other reference from same snapshot should have | 1006 | * all other reference from same snapshot should have |
@@ -919,8 +1010,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
919 | (parent_gen > 0 && parent_gen > ref_generation) || | 1010 | (parent_gen > 0 && parent_gen > ref_generation) || |
920 | (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID && | 1011 | (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID && |
921 | ref_objectid != btrfs_ref_objectid(leaf, ref_item))) { | 1012 | ref_objectid != btrfs_ref_objectid(leaf, ref_item))) { |
922 | if (ref_count) | 1013 | *ref_count = 2; |
923 | *ref_count = 2; | ||
924 | break; | 1014 | break; |
925 | } | 1015 | } |
926 | 1016 | ||
@@ -1020,80 +1110,29 @@ out: | |||
1020 | return ret; | 1110 | return ret; |
1021 | } | 1111 | } |
1022 | 1112 | ||
1023 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1113 | int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1024 | struct extent_buffer *buf, int cache_ref) | 1114 | struct extent_buffer *buf, u32 nr_extents) |
1025 | { | 1115 | { |
1026 | u64 bytenr; | ||
1027 | u32 nritems; | 1116 | u32 nritems; |
1028 | struct btrfs_key key; | 1117 | struct btrfs_key key; |
1029 | struct btrfs_file_extent_item *fi; | 1118 | struct btrfs_file_extent_item *fi; |
1030 | int i; | 1119 | int i; |
1031 | int level; | 1120 | int level; |
1032 | int ret; | 1121 | int ret = 0; |
1033 | int faili; | ||
1034 | int nr_file_extents = 0; | ||
1035 | 1122 | ||
1036 | if (!root->ref_cows) | 1123 | if (!root->ref_cows) |
1037 | return 0; | 1124 | return 0; |
1038 | 1125 | ||
1039 | level = btrfs_header_level(buf); | 1126 | level = btrfs_header_level(buf); |
1040 | nritems = btrfs_header_nritems(buf); | 1127 | nritems = btrfs_header_nritems(buf); |
1041 | for (i = 0; i < nritems; i++) { | ||
1042 | cond_resched(); | ||
1043 | if (level == 0) { | ||
1044 | u64 disk_bytenr; | ||
1045 | btrfs_item_key_to_cpu(buf, &key, i); | ||
1046 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
1047 | continue; | ||
1048 | fi = btrfs_item_ptr(buf, i, | ||
1049 | struct btrfs_file_extent_item); | ||
1050 | if (btrfs_file_extent_type(buf, fi) == | ||
1051 | BTRFS_FILE_EXTENT_INLINE) | ||
1052 | continue; | ||
1053 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | ||
1054 | if (disk_bytenr == 0) | ||
1055 | continue; | ||
1056 | |||
1057 | if (buf != root->commit_root) | ||
1058 | nr_file_extents++; | ||
1059 | |||
1060 | mutex_lock(&root->fs_info->alloc_mutex); | ||
1061 | ret = __btrfs_inc_extent_ref(trans, root, disk_bytenr, | ||
1062 | btrfs_file_extent_disk_num_bytes(buf, fi), | ||
1063 | root->root_key.objectid, trans->transid, | ||
1064 | key.objectid, key.offset); | ||
1065 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1066 | if (ret) { | ||
1067 | faili = i; | ||
1068 | WARN_ON(1); | ||
1069 | goto fail; | ||
1070 | } | ||
1071 | } else { | ||
1072 | bytenr = btrfs_node_blockptr(buf, i); | ||
1073 | btrfs_node_key_to_cpu(buf, &key, i); | ||
1074 | 1128 | ||
1075 | mutex_lock(&root->fs_info->alloc_mutex); | 1129 | if (level == 0) { |
1076 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, | ||
1077 | btrfs_level_size(root, level - 1), | ||
1078 | root->root_key.objectid, | ||
1079 | trans->transid, | ||
1080 | level - 1, key.objectid); | ||
1081 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1082 | if (ret) { | ||
1083 | faili = i; | ||
1084 | WARN_ON(1); | ||
1085 | goto fail; | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | /* cache orignal leaf block's references */ | ||
1090 | if (level == 0 && cache_ref && buf != root->commit_root) { | ||
1091 | struct btrfs_leaf_ref *ref; | 1130 | struct btrfs_leaf_ref *ref; |
1092 | struct btrfs_extent_info *info; | 1131 | struct btrfs_extent_info *info; |
1093 | 1132 | ||
1094 | ref = btrfs_alloc_leaf_ref(root, nr_file_extents); | 1133 | ref = btrfs_alloc_leaf_ref(root, nr_extents); |
1095 | if (!ref) { | 1134 | if (!ref) { |
1096 | WARN_ON(1); | 1135 | ret = -ENOMEM; |
1097 | goto out; | 1136 | goto out; |
1098 | } | 1137 | } |
1099 | 1138 | ||
@@ -1101,10 +1140,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1101 | ref->bytenr = buf->start; | 1140 | ref->bytenr = buf->start; |
1102 | ref->owner = btrfs_header_owner(buf); | 1141 | ref->owner = btrfs_header_owner(buf); |
1103 | ref->generation = btrfs_header_generation(buf); | 1142 | ref->generation = btrfs_header_generation(buf); |
1104 | ref->nritems = nr_file_extents; | 1143 | ref->nritems = nr_extents; |
1105 | info = ref->extents; | 1144 | info = ref->extents; |
1106 | 1145 | ||
1107 | for (i = 0; nr_file_extents > 0 && i < nritems; i++) { | 1146 | for (i = 0; nr_extents > 0 && i < nritems; i++) { |
1108 | u64 disk_bytenr; | 1147 | u64 disk_bytenr; |
1109 | btrfs_item_key_to_cpu(buf, &key, i); | 1148 | btrfs_item_key_to_cpu(buf, &key, i); |
1110 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1149 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
@@ -1132,13 +1171,52 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1132 | btrfs_free_leaf_ref(root, ref); | 1171 | btrfs_free_leaf_ref(root, ref); |
1133 | } | 1172 | } |
1134 | out: | 1173 | out: |
1135 | return 0; | 1174 | return ret; |
1136 | fail: | 1175 | } |
1137 | WARN_ON(1); | 1176 | |
1138 | #if 0 | 1177 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1139 | for (i =0; i < faili; i++) { | 1178 | struct extent_buffer *orig_buf, struct extent_buffer *buf, |
1179 | u32 *nr_extents) | ||
1180 | { | ||
1181 | u64 bytenr; | ||
1182 | u64 ref_root; | ||
1183 | u64 orig_root; | ||
1184 | u64 ref_generation; | ||
1185 | u64 orig_generation; | ||
1186 | u32 nritems; | ||
1187 | u32 nr_file_extents = 0; | ||
1188 | struct btrfs_key key; | ||
1189 | struct btrfs_file_extent_item *fi; | ||
1190 | int i; | ||
1191 | int level; | ||
1192 | int ret = 0; | ||
1193 | int faili = 0; | ||
1194 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, | ||
1195 | u64, u64, u64, u64, u64, u64, u64, u64, u64); | ||
1196 | |||
1197 | ref_root = btrfs_header_owner(buf); | ||
1198 | ref_generation = btrfs_header_generation(buf); | ||
1199 | orig_root = btrfs_header_owner(orig_buf); | ||
1200 | orig_generation = btrfs_header_generation(orig_buf); | ||
1201 | |||
1202 | nritems = btrfs_header_nritems(buf); | ||
1203 | level = btrfs_header_level(buf); | ||
1204 | |||
1205 | if (root->ref_cows) { | ||
1206 | process_func = __btrfs_inc_extent_ref; | ||
1207 | } else { | ||
1208 | if (level == 0 && | ||
1209 | root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) | ||
1210 | goto out; | ||
1211 | if (level != 0 && | ||
1212 | root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) | ||
1213 | goto out; | ||
1214 | process_func = __btrfs_update_extent_ref; | ||
1215 | } | ||
1216 | |||
1217 | for (i = 0; i < nritems; i++) { | ||
1218 | cond_resched(); | ||
1140 | if (level == 0) { | 1219 | if (level == 0) { |
1141 | u64 disk_bytenr; | ||
1142 | btrfs_item_key_to_cpu(buf, &key, i); | 1220 | btrfs_item_key_to_cpu(buf, &key, i); |
1143 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1221 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
1144 | continue; | 1222 | continue; |
@@ -1147,24 +1225,131 @@ fail: | |||
1147 | if (btrfs_file_extent_type(buf, fi) == | 1225 | if (btrfs_file_extent_type(buf, fi) == |
1148 | BTRFS_FILE_EXTENT_INLINE) | 1226 | BTRFS_FILE_EXTENT_INLINE) |
1149 | continue; | 1227 | continue; |
1150 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | 1228 | bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
1151 | if (disk_bytenr == 0) | 1229 | if (bytenr == 0) |
1152 | continue; | 1230 | continue; |
1153 | err = btrfs_free_extent(trans, root, disk_bytenr, | 1231 | |
1154 | btrfs_file_extent_disk_num_bytes(buf, | 1232 | nr_file_extents++; |
1155 | fi), 0); | 1233 | |
1156 | BUG_ON(err); | 1234 | maybe_lock_mutex(root); |
1235 | ret = process_func(trans, root, bytenr, | ||
1236 | orig_buf->start, buf->start, | ||
1237 | orig_root, ref_root, | ||
1238 | orig_generation, ref_generation, | ||
1239 | key.objectid, key.offset); | ||
1240 | maybe_unlock_mutex(root); | ||
1241 | |||
1242 | if (ret) { | ||
1243 | faili = i; | ||
1244 | WARN_ON(1); | ||
1245 | goto fail; | ||
1246 | } | ||
1157 | } else { | 1247 | } else { |
1158 | bytenr = btrfs_node_blockptr(buf, i); | 1248 | bytenr = btrfs_node_blockptr(buf, i); |
1159 | err = btrfs_free_extent(trans, root, bytenr, | 1249 | maybe_lock_mutex(root); |
1160 | btrfs_level_size(root, level - 1), 0); | 1250 | ret = process_func(trans, root, bytenr, |
1161 | BUG_ON(err); | 1251 | orig_buf->start, buf->start, |
1252 | orig_root, ref_root, | ||
1253 | orig_generation, ref_generation, | ||
1254 | level - 1, 0); | ||
1255 | maybe_unlock_mutex(root); | ||
1256 | if (ret) { | ||
1257 | faili = i; | ||
1258 | WARN_ON(1); | ||
1259 | goto fail; | ||
1260 | } | ||
1162 | } | 1261 | } |
1163 | } | 1262 | } |
1164 | #endif | 1263 | out: |
1264 | if (nr_extents) { | ||
1265 | if (level == 0) | ||
1266 | *nr_extents = nr_file_extents; | ||
1267 | else | ||
1268 | *nr_extents = nritems; | ||
1269 | } | ||
1270 | return 0; | ||
1271 | fail: | ||
1272 | WARN_ON(1); | ||
1165 | return ret; | 1273 | return ret; |
1166 | } | 1274 | } |
1167 | 1275 | ||
1276 | int btrfs_update_ref(struct btrfs_trans_handle *trans, | ||
1277 | struct btrfs_root *root, struct extent_buffer *orig_buf, | ||
1278 | struct extent_buffer *buf, int start_slot, int nr) | ||
1279 | |||
1280 | { | ||
1281 | u64 bytenr; | ||
1282 | u64 ref_root; | ||
1283 | u64 orig_root; | ||
1284 | u64 ref_generation; | ||
1285 | u64 orig_generation; | ||
1286 | struct btrfs_key key; | ||
1287 | struct btrfs_file_extent_item *fi; | ||
1288 | int i; | ||
1289 | int ret; | ||
1290 | int slot; | ||
1291 | int level; | ||
1292 | |||
1293 | BUG_ON(start_slot < 0); | ||
1294 | BUG_ON(start_slot + nr > btrfs_header_nritems(buf)); | ||
1295 | |||
1296 | ref_root = btrfs_header_owner(buf); | ||
1297 | ref_generation = btrfs_header_generation(buf); | ||
1298 | orig_root = btrfs_header_owner(orig_buf); | ||
1299 | orig_generation = btrfs_header_generation(orig_buf); | ||
1300 | level = btrfs_header_level(buf); | ||
1301 | |||
1302 | if (!root->ref_cows) { | ||
1303 | if (level == 0 && | ||
1304 | root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) | ||
1305 | return 0; | ||
1306 | if (level != 0 && | ||
1307 | root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) | ||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | for (i = 0, slot = start_slot; i < nr; i++, slot++) { | ||
1312 | cond_resched(); | ||
1313 | if (level == 0) { | ||
1314 | btrfs_item_key_to_cpu(buf, &key, slot); | ||
1315 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
1316 | continue; | ||
1317 | fi = btrfs_item_ptr(buf, slot, | ||
1318 | struct btrfs_file_extent_item); | ||
1319 | if (btrfs_file_extent_type(buf, fi) == | ||
1320 | BTRFS_FILE_EXTENT_INLINE) | ||
1321 | continue; | ||
1322 | bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | ||
1323 | if (bytenr == 0) | ||
1324 | continue; | ||
1325 | maybe_lock_mutex(root); | ||
1326 | ret = __btrfs_update_extent_ref(trans, root, bytenr, | ||
1327 | orig_buf->start, buf->start, | ||
1328 | orig_root, ref_root, | ||
1329 | orig_generation, ref_generation, | ||
1330 | key.objectid, key.offset); | ||
1331 | maybe_unlock_mutex(root); | ||
1332 | if (ret) | ||
1333 | goto fail; | ||
1334 | } else { | ||
1335 | bytenr = btrfs_node_blockptr(buf, slot); | ||
1336 | maybe_lock_mutex(root); | ||
1337 | ret = __btrfs_update_extent_ref(trans, root, bytenr, | ||
1338 | orig_buf->start, buf->start, | ||
1339 | orig_root, ref_root, | ||
1340 | orig_generation, ref_generation, | ||
1341 | level - 1, 0); | ||
1342 | maybe_unlock_mutex(root); | ||
1343 | if (ret) | ||
1344 | goto fail; | ||
1345 | } | ||
1346 | } | ||
1347 | return 0; | ||
1348 | fail: | ||
1349 | WARN_ON(1); | ||
1350 | return -1; | ||
1351 | } | ||
1352 | |||
1168 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 1353 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
1169 | struct btrfs_root *root, | 1354 | struct btrfs_root *root, |
1170 | struct btrfs_path *path, | 1355 | struct btrfs_path *path, |
@@ -1539,19 +1724,18 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1539 | { | 1724 | { |
1540 | u64 start; | 1725 | u64 start; |
1541 | u64 end; | 1726 | u64 end; |
1727 | u64 priv; | ||
1542 | struct btrfs_fs_info *info = extent_root->fs_info; | 1728 | struct btrfs_fs_info *info = extent_root->fs_info; |
1543 | struct extent_buffer *eb; | ||
1544 | struct btrfs_path *path; | 1729 | struct btrfs_path *path; |
1545 | struct btrfs_key ins; | 1730 | struct btrfs_extent_ref *ref; |
1546 | struct btrfs_disk_key first; | 1731 | struct pending_extent_op *extent_op; |
1732 | struct btrfs_key key; | ||
1547 | struct btrfs_extent_item extent_item; | 1733 | struct btrfs_extent_item extent_item; |
1548 | int ret; | 1734 | int ret; |
1549 | int level; | ||
1550 | int err = 0; | 1735 | int err = 0; |
1551 | 1736 | ||
1552 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); | 1737 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); |
1553 | btrfs_set_stack_extent_refs(&extent_item, 1); | 1738 | btrfs_set_stack_extent_refs(&extent_item, 1); |
1554 | btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); | ||
1555 | path = btrfs_alloc_path(); | 1739 | path = btrfs_alloc_path(); |
1556 | 1740 | ||
1557 | while(1) { | 1741 | while(1) { |
@@ -1560,37 +1744,54 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1560 | if (ret) | 1744 | if (ret) |
1561 | break; | 1745 | break; |
1562 | 1746 | ||
1563 | ins.objectid = start; | 1747 | ret = get_state_private(&info->extent_ins, start, &priv); |
1564 | ins.offset = end + 1 - start; | 1748 | BUG_ON(ret); |
1565 | err = btrfs_insert_item(trans, extent_root, &ins, | 1749 | extent_op = (struct pending_extent_op *)(unsigned long)priv; |
1750 | |||
1751 | if (extent_op->type == PENDING_EXTENT_INSERT) { | ||
1752 | key.objectid = start; | ||
1753 | key.offset = end + 1 - start; | ||
1754 | key.type = BTRFS_EXTENT_ITEM_KEY; | ||
1755 | err = btrfs_insert_item(trans, extent_root, &key, | ||
1566 | &extent_item, sizeof(extent_item)); | 1756 | &extent_item, sizeof(extent_item)); |
1567 | clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED, | 1757 | BUG_ON(err); |
1568 | GFP_NOFS); | ||
1569 | 1758 | ||
1570 | eb = btrfs_find_create_tree_block(extent_root, ins.objectid, | 1759 | clear_extent_bits(&info->extent_ins, start, end, |
1571 | ins.offset); | 1760 | EXTENT_LOCKED, GFP_NOFS); |
1572 | 1761 | ||
1573 | if (!btrfs_buffer_uptodate(eb, trans->transid)) | 1762 | err = insert_extent_backref(trans, extent_root, path, |
1574 | btrfs_read_buffer(eb, trans->transid); | 1763 | start, extent_op->parent, |
1764 | extent_root->root_key.objectid, | ||
1765 | extent_op->generation, | ||
1766 | extent_op->level, 0); | ||
1767 | BUG_ON(err); | ||
1768 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | ||
1769 | err = lookup_extent_backref(trans, extent_root, path, | ||
1770 | start, extent_op->orig_parent, | ||
1771 | extent_root->root_key.objectid, | ||
1772 | extent_op->orig_generation, 0); | ||
1773 | BUG_ON(err); | ||
1575 | 1774 | ||
1576 | btrfs_tree_lock(eb); | 1775 | clear_extent_bits(&info->extent_ins, start, end, |
1577 | level = btrfs_header_level(eb); | 1776 | EXTENT_LOCKED, GFP_NOFS); |
1578 | if (level == 0) { | 1777 | |
1579 | btrfs_item_key(eb, &first, 0); | 1778 | key.objectid = start; |
1779 | key.offset = extent_op->parent; | ||
1780 | key.type = BTRFS_EXTENT_REF_KEY; | ||
1781 | err = btrfs_set_item_key_safe(trans, extent_root, path, | ||
1782 | &key); | ||
1783 | BUG_ON(err); | ||
1784 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
1785 | struct btrfs_extent_ref); | ||
1786 | btrfs_set_ref_generation(path->nodes[0], ref, | ||
1787 | extent_op->generation); | ||
1788 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
1789 | btrfs_release_path(extent_root, path); | ||
1580 | } else { | 1790 | } else { |
1581 | btrfs_node_key(eb, &first, 0); | 1791 | BUG_ON(1); |
1582 | } | 1792 | } |
1583 | btrfs_tree_unlock(eb); | 1793 | kfree(extent_op); |
1584 | free_extent_buffer(eb); | 1794 | |
1585 | /* | ||
1586 | * the first key is just a hint, so the race we've created | ||
1587 | * against reading it is fine | ||
1588 | */ | ||
1589 | err = btrfs_insert_extent_backref(trans, extent_root, path, | ||
1590 | start, extent_root->root_key.objectid, | ||
1591 | 0, level, | ||
1592 | btrfs_disk_key_objectid(&first)); | ||
1593 | BUG_ON(err); | ||
1594 | if (need_resched()) { | 1795 | if (need_resched()) { |
1595 | mutex_unlock(&extent_root->fs_info->alloc_mutex); | 1796 | mutex_unlock(&extent_root->fs_info->alloc_mutex); |
1596 | cond_resched(); | 1797 | cond_resched(); |
@@ -1601,52 +1802,44 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1601 | return 0; | 1802 | return 0; |
1602 | } | 1803 | } |
1603 | 1804 | ||
1604 | static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, | 1805 | static int pin_down_bytes(struct btrfs_trans_handle *trans, |
1605 | int is_data, int pending) | 1806 | struct btrfs_root *root, |
1807 | u64 bytenr, u64 num_bytes, int is_data) | ||
1606 | { | 1808 | { |
1607 | int err = 0; | 1809 | int err = 0; |
1810 | struct extent_buffer *buf; | ||
1608 | 1811 | ||
1609 | WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex)); | 1812 | WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex)); |
1610 | if (!pending) { | 1813 | if (is_data) |
1611 | struct extent_buffer *buf; | 1814 | goto pinit; |
1612 | 1815 | ||
1613 | if (is_data) | 1816 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
1614 | goto pinit; | 1817 | if (!buf) |
1615 | 1818 | goto pinit; | |
1616 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); | 1819 | |
1617 | if (buf) { | 1820 | /* we can reuse a block if it hasn't been written |
1618 | /* we can reuse a block if it hasn't been written | 1821 | * and it is from this transaction. We can't |
1619 | * and it is from this transaction. We can't | 1822 | * reuse anything from the tree log root because |
1620 | * reuse anything from the tree log root because | 1823 | * it has tiny sub-transactions. |
1621 | * it has tiny sub-transactions. | 1824 | */ |
1622 | */ | 1825 | if (btrfs_buffer_uptodate(buf, 0) && |
1623 | if (btrfs_buffer_uptodate(buf, 0) && | 1826 | btrfs_try_tree_lock(buf)) { |
1624 | btrfs_try_tree_lock(buf)) { | 1827 | u64 header_owner = btrfs_header_owner(buf); |
1625 | u64 transid = | 1828 | u64 header_transid = btrfs_header_generation(buf); |
1626 | root->fs_info->running_transaction->transid; | 1829 | if (header_owner != BTRFS_TREE_LOG_OBJECTID && |
1627 | u64 header_transid = | 1830 | header_transid == trans->transid && |
1628 | btrfs_header_generation(buf); | 1831 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { |
1629 | if (btrfs_header_owner(buf) != | 1832 | clean_tree_block(NULL, root, buf); |
1630 | BTRFS_TREE_LOG_OBJECTID && | 1833 | btrfs_tree_unlock(buf); |
1631 | header_transid == transid && | ||
1632 | !btrfs_header_flag(buf, | ||
1633 | BTRFS_HEADER_FLAG_WRITTEN)) { | ||
1634 | clean_tree_block(NULL, root, buf); | ||
1635 | btrfs_tree_unlock(buf); | ||
1636 | free_extent_buffer(buf); | ||
1637 | return 1; | ||
1638 | } | ||
1639 | btrfs_tree_unlock(buf); | ||
1640 | } | ||
1641 | free_extent_buffer(buf); | 1834 | free_extent_buffer(buf); |
1835 | return 1; | ||
1642 | } | 1836 | } |
1643 | pinit: | 1837 | btrfs_tree_unlock(buf); |
1644 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | ||
1645 | } else { | ||
1646 | set_extent_bits(&root->fs_info->pending_del, | ||
1647 | bytenr, bytenr + num_bytes - 1, | ||
1648 | EXTENT_LOCKED, GFP_NOFS); | ||
1649 | } | 1838 | } |
1839 | free_extent_buffer(buf); | ||
1840 | pinit: | ||
1841 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | ||
1842 | |||
1650 | BUG_ON(err < 0); | 1843 | BUG_ON(err < 0); |
1651 | return 0; | 1844 | return 0; |
1652 | } | 1845 | } |
@@ -1654,11 +1847,12 @@ pinit: | |||
1654 | /* | 1847 | /* |
1655 | * remove an extent from the root, returns 0 on success | 1848 | * remove an extent from the root, returns 0 on success |
1656 | */ | 1849 | */ |
1657 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1850 | static int __free_extent(struct btrfs_trans_handle *trans, |
1658 | *root, u64 bytenr, u64 num_bytes, | 1851 | struct btrfs_root *root, |
1852 | u64 bytenr, u64 num_bytes, u64 parent, | ||
1659 | u64 root_objectid, u64 ref_generation, | 1853 | u64 root_objectid, u64 ref_generation, |
1660 | u64 owner_objectid, u64 owner_offset, int pin, | 1854 | u64 owner_objectid, u64 owner_offset, |
1661 | int mark_free) | 1855 | int pin, int mark_free) |
1662 | { | 1856 | { |
1663 | struct btrfs_path *path; | 1857 | struct btrfs_path *path; |
1664 | struct btrfs_key key; | 1858 | struct btrfs_key key; |
@@ -1681,10 +1875,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1681 | return -ENOMEM; | 1875 | return -ENOMEM; |
1682 | 1876 | ||
1683 | path->reada = 1; | 1877 | path->reada = 1; |
1684 | ret = lookup_extent_backref(trans, extent_root, path, | 1878 | ret = lookup_extent_backref(trans, extent_root, path, bytenr, parent, |
1685 | bytenr, root_objectid, | 1879 | root_objectid, ref_generation, 1); |
1686 | ref_generation, | ||
1687 | owner_objectid, owner_offset, 1); | ||
1688 | if (ret == 0) { | 1880 | if (ret == 0) { |
1689 | struct btrfs_key found_key; | 1881 | struct btrfs_key found_key; |
1690 | extent_slot = path->slots[0]; | 1882 | extent_slot = path->slots[0]; |
@@ -1702,8 +1894,15 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1702 | if (path->slots[0] - extent_slot > 5) | 1894 | if (path->slots[0] - extent_slot > 5) |
1703 | break; | 1895 | break; |
1704 | } | 1896 | } |
1705 | if (!found_extent) | 1897 | if (!found_extent) { |
1706 | ret = btrfs_del_item(trans, extent_root, path); | 1898 | ret = remove_extent_backref(trans, extent_root, path); |
1899 | BUG_ON(ret); | ||
1900 | btrfs_release_path(extent_root, path); | ||
1901 | ret = btrfs_search_slot(trans, extent_root, | ||
1902 | &key, path, -1, 1); | ||
1903 | BUG_ON(ret); | ||
1904 | extent_slot = path->slots[0]; | ||
1905 | } | ||
1707 | } else { | 1906 | } else { |
1708 | btrfs_print_leaf(extent_root, path->nodes[0]); | 1907 | btrfs_print_leaf(extent_root, path->nodes[0]); |
1709 | WARN_ON(1); | 1908 | WARN_ON(1); |
@@ -1712,14 +1911,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1712 | root_objectid, ref_generation, owner_objectid, | 1911 | root_objectid, ref_generation, owner_objectid, |
1713 | owner_offset); | 1912 | owner_offset); |
1714 | } | 1913 | } |
1715 | if (!found_extent) { | ||
1716 | btrfs_release_path(extent_root, path); | ||
1717 | ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); | ||
1718 | if (ret < 0) | ||
1719 | return ret; | ||
1720 | BUG_ON(ret); | ||
1721 | extent_slot = path->slots[0]; | ||
1722 | } | ||
1723 | 1914 | ||
1724 | leaf = path->nodes[0]; | 1915 | leaf = path->nodes[0]; |
1725 | ei = btrfs_item_ptr(leaf, extent_slot, | 1916 | ei = btrfs_item_ptr(leaf, extent_slot, |
@@ -1732,6 +1923,10 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1732 | btrfs_mark_buffer_dirty(leaf); | 1923 | btrfs_mark_buffer_dirty(leaf); |
1733 | 1924 | ||
1734 | if (refs == 0 && found_extent && path->slots[0] == extent_slot + 1) { | 1925 | if (refs == 0 && found_extent && path->slots[0] == extent_slot + 1) { |
1926 | struct btrfs_extent_ref *ref; | ||
1927 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
1928 | struct btrfs_extent_ref); | ||
1929 | BUG_ON(btrfs_ref_num_refs(leaf, ref) != 1); | ||
1735 | /* if the back ref and the extent are next to each other | 1930 | /* if the back ref and the extent are next to each other |
1736 | * they get deleted below in one shot | 1931 | * they get deleted below in one shot |
1737 | */ | 1932 | */ |
@@ -1739,15 +1934,13 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1739 | num_to_del = 2; | 1934 | num_to_del = 2; |
1740 | } else if (found_extent) { | 1935 | } else if (found_extent) { |
1741 | /* otherwise delete the extent back ref */ | 1936 | /* otherwise delete the extent back ref */ |
1742 | ret = btrfs_del_item(trans, extent_root, path); | 1937 | ret = remove_extent_backref(trans, extent_root, path); |
1743 | BUG_ON(ret); | 1938 | BUG_ON(ret); |
1744 | /* if refs are 0, we need to setup the path for deletion */ | 1939 | /* if refs are 0, we need to setup the path for deletion */ |
1745 | if (refs == 0) { | 1940 | if (refs == 0) { |
1746 | btrfs_release_path(extent_root, path); | 1941 | btrfs_release_path(extent_root, path); |
1747 | ret = btrfs_search_slot(trans, extent_root, &key, path, | 1942 | ret = btrfs_search_slot(trans, extent_root, &key, path, |
1748 | -1, 1); | 1943 | -1, 1); |
1749 | if (ret < 0) | ||
1750 | return ret; | ||
1751 | BUG_ON(ret); | 1944 | BUG_ON(ret); |
1752 | } | 1945 | } |
1753 | } | 1946 | } |
@@ -1761,8 +1954,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1761 | #endif | 1954 | #endif |
1762 | 1955 | ||
1763 | if (pin) { | 1956 | if (pin) { |
1764 | ret = pin_down_bytes(root, bytenr, num_bytes, | 1957 | ret = pin_down_bytes(trans, root, bytenr, num_bytes, |
1765 | owner_objectid >= BTRFS_FIRST_FREE_OBJECTID, 0); | 1958 | owner_objectid >= BTRFS_FIRST_FREE_OBJECTID); |
1766 | if (ret > 0) | 1959 | if (ret > 0) |
1767 | mark_free = 1; | 1960 | mark_free = 1; |
1768 | BUG_ON(ret < 0); | 1961 | BUG_ON(ret < 0); |
@@ -1781,9 +1974,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1781 | root_used - num_bytes); | 1974 | root_used - num_bytes); |
1782 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], | 1975 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], |
1783 | num_to_del); | 1976 | num_to_del); |
1784 | if (ret) { | 1977 | BUG_ON(ret); |
1785 | return ret; | ||
1786 | } | ||
1787 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, | 1978 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, |
1788 | mark_free); | 1979 | mark_free); |
1789 | BUG_ON(ret); | 1980 | BUG_ON(ret); |
@@ -1822,33 +2013,61 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
1822 | { | 2013 | { |
1823 | int ret; | 2014 | int ret; |
1824 | int err = 0; | 2015 | int err = 0; |
2016 | int mark_free = 0; | ||
1825 | u64 start; | 2017 | u64 start; |
1826 | u64 end; | 2018 | u64 end; |
2019 | u64 priv; | ||
1827 | struct extent_io_tree *pending_del; | 2020 | struct extent_io_tree *pending_del; |
1828 | struct extent_io_tree *pinned_extents; | 2021 | struct extent_io_tree *extent_ins; |
2022 | struct pending_extent_op *extent_op; | ||
1829 | 2023 | ||
1830 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); | 2024 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); |
2025 | extent_ins = &extent_root->fs_info->extent_ins; | ||
1831 | pending_del = &extent_root->fs_info->pending_del; | 2026 | pending_del = &extent_root->fs_info->pending_del; |
1832 | pinned_extents = &extent_root->fs_info->pinned_extents; | ||
1833 | 2027 | ||
1834 | while(1) { | 2028 | while(1) { |
1835 | ret = find_first_extent_bit(pending_del, 0, &start, &end, | 2029 | ret = find_first_extent_bit(pending_del, 0, &start, &end, |
1836 | EXTENT_LOCKED); | 2030 | EXTENT_LOCKED); |
1837 | if (ret) | 2031 | if (ret) |
1838 | break; | 2032 | break; |
2033 | |||
2034 | ret = get_state_private(pending_del, start, &priv); | ||
2035 | BUG_ON(ret); | ||
2036 | extent_op = (struct pending_extent_op *)(unsigned long)priv; | ||
2037 | |||
1839 | clear_extent_bits(pending_del, start, end, EXTENT_LOCKED, | 2038 | clear_extent_bits(pending_del, start, end, EXTENT_LOCKED, |
1840 | GFP_NOFS); | 2039 | GFP_NOFS); |
1841 | if (!test_range_bit(&extent_root->fs_info->extent_ins, | 2040 | |
1842 | start, end, EXTENT_LOCKED, 0)) { | 2041 | ret = pin_down_bytes(trans, extent_root, start, |
1843 | btrfs_update_pinned_extents(extent_root, start, | 2042 | end + 1 - start, 0); |
1844 | end + 1 - start, 1); | 2043 | mark_free = ret > 0; |
2044 | if (!test_range_bit(extent_ins, start, end, | ||
2045 | EXTENT_LOCKED, 0)) { | ||
2046 | free_extent: | ||
1845 | ret = __free_extent(trans, extent_root, | 2047 | ret = __free_extent(trans, extent_root, |
1846 | start, end + 1 - start, | 2048 | start, end + 1 - start, |
1847 | extent_root->root_key.objectid, | 2049 | extent_op->orig_parent, |
1848 | 0, 0, 0, 0, 0); | 2050 | extent_root->root_key.objectid, |
2051 | extent_op->orig_generation, | ||
2052 | extent_op->level, 0, 0, mark_free); | ||
2053 | kfree(extent_op); | ||
1849 | } else { | 2054 | } else { |
1850 | clear_extent_bits(&extent_root->fs_info->extent_ins, | 2055 | kfree(extent_op); |
1851 | start, end, EXTENT_LOCKED, GFP_NOFS); | 2056 | ret = get_state_private(extent_ins, start, &priv); |
2057 | BUG_ON(ret); | ||
2058 | extent_op = (struct pending_extent_op *) | ||
2059 | (unsigned long)priv; | ||
2060 | |||
2061 | clear_extent_bits(extent_ins, start, end, | ||
2062 | EXTENT_LOCKED, GFP_NOFS); | ||
2063 | |||
2064 | if (extent_op->type == PENDING_BACKREF_UPDATE) | ||
2065 | goto free_extent; | ||
2066 | |||
2067 | ret = update_block_group(trans, extent_root, start, | ||
2068 | end + 1 - start, 0, mark_free); | ||
2069 | BUG_ON(ret); | ||
2070 | kfree(extent_op); | ||
1852 | } | 2071 | } |
1853 | if (ret) | 2072 | if (ret) |
1854 | err = ret; | 2073 | err = ret; |
@@ -1866,21 +2085,36 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
1866 | * remove an extent from the root, returns 0 on success | 2085 | * remove an extent from the root, returns 0 on success |
1867 | */ | 2086 | */ |
1868 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | 2087 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, |
1869 | struct btrfs_root *root, u64 bytenr, | 2088 | struct btrfs_root *root, |
1870 | u64 num_bytes, u64 root_objectid, | 2089 | u64 bytenr, u64 num_bytes, u64 parent, |
1871 | u64 ref_generation, u64 owner_objectid, | 2090 | u64 root_objectid, u64 ref_generation, |
1872 | u64 owner_offset, int pin) | 2091 | u64 owner_objectid, u64 owner_offset, int pin) |
1873 | { | 2092 | { |
1874 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 2093 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
1875 | int pending_ret; | 2094 | int pending_ret; |
1876 | int ret; | 2095 | int ret; |
1877 | 2096 | ||
1878 | WARN_ON(num_bytes < root->sectorsize); | 2097 | WARN_ON(num_bytes < root->sectorsize); |
1879 | if (!root->ref_cows) | ||
1880 | ref_generation = 0; | ||
1881 | |||
1882 | if (root == extent_root) { | 2098 | if (root == extent_root) { |
1883 | pin_down_bytes(root, bytenr, num_bytes, 0, 1); | 2099 | struct pending_extent_op *extent_op; |
2100 | |||
2101 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
2102 | BUG_ON(!extent_op); | ||
2103 | |||
2104 | extent_op->type = PENDING_EXTENT_DELETE; | ||
2105 | extent_op->bytenr = bytenr; | ||
2106 | extent_op->num_bytes = num_bytes; | ||
2107 | extent_op->parent = parent; | ||
2108 | extent_op->orig_parent = parent; | ||
2109 | extent_op->generation = ref_generation; | ||
2110 | extent_op->orig_generation = ref_generation; | ||
2111 | extent_op->level = (int)owner_objectid; | ||
2112 | |||
2113 | set_extent_bits(&root->fs_info->pending_del, | ||
2114 | bytenr, bytenr + num_bytes - 1, | ||
2115 | EXTENT_LOCKED, GFP_NOFS); | ||
2116 | set_state_private(&root->fs_info->pending_del, | ||
2117 | bytenr, (unsigned long)extent_op); | ||
1884 | return 0; | 2118 | return 0; |
1885 | } | 2119 | } |
1886 | /* if metadata always pin */ | 2120 | /* if metadata always pin */ |
@@ -1901,9 +2135,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
1901 | if (ref_generation != trans->transid) | 2135 | if (ref_generation != trans->transid) |
1902 | pin = 1; | 2136 | pin = 1; |
1903 | 2137 | ||
1904 | ret = __free_extent(trans, root, bytenr, num_bytes, root_objectid, | 2138 | ret = __free_extent(trans, root, bytenr, num_bytes, parent, |
1905 | ref_generation, owner_objectid, owner_offset, | 2139 | root_objectid, ref_generation, owner_objectid, |
1906 | pin, pin == 0); | 2140 | owner_offset, pin, pin == 0); |
1907 | 2141 | ||
1908 | finish_current_insert(trans, root->fs_info->extent_root); | 2142 | finish_current_insert(trans, root->fs_info->extent_root); |
1909 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 2143 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); |
@@ -1911,15 +2145,15 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
1911 | } | 2145 | } |
1912 | 2146 | ||
1913 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 2147 | int btrfs_free_extent(struct btrfs_trans_handle *trans, |
1914 | struct btrfs_root *root, u64 bytenr, | 2148 | struct btrfs_root *root, |
1915 | u64 num_bytes, u64 root_objectid, | 2149 | u64 bytenr, u64 num_bytes, u64 parent, |
1916 | u64 ref_generation, u64 owner_objectid, | 2150 | u64 root_objectid, u64 ref_generation, |
1917 | u64 owner_offset, int pin) | 2151 | u64 owner_objectid, u64 owner_offset, int pin) |
1918 | { | 2152 | { |
1919 | int ret; | 2153 | int ret; |
1920 | 2154 | ||
1921 | maybe_lock_mutex(root); | 2155 | maybe_lock_mutex(root); |
1922 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, | 2156 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, parent, |
1923 | root_objectid, ref_generation, | 2157 | root_objectid, ref_generation, |
1924 | owner_objectid, owner_offset, pin); | 2158 | owner_objectid, owner_offset, pin); |
1925 | maybe_unlock_mutex(root); | 2159 | maybe_unlock_mutex(root); |
@@ -2271,7 +2505,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
2271 | } | 2505 | } |
2272 | 2506 | ||
2273 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2507 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2274 | struct btrfs_root *root, | 2508 | struct btrfs_root *root, u64 parent, |
2275 | u64 root_objectid, u64 ref_generation, | 2509 | u64 root_objectid, u64 ref_generation, |
2276 | u64 owner, u64 owner_offset, | 2510 | u64 owner, u64 owner_offset, |
2277 | struct btrfs_key *ins) | 2511 | struct btrfs_key *ins) |
@@ -2289,6 +2523,9 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2289 | struct btrfs_path *path; | 2523 | struct btrfs_path *path; |
2290 | struct btrfs_key keys[2]; | 2524 | struct btrfs_key keys[2]; |
2291 | 2525 | ||
2526 | if (parent == 0) | ||
2527 | parent = ins->objectid; | ||
2528 | |||
2292 | /* block accounting for super block */ | 2529 | /* block accounting for super block */ |
2293 | spin_lock_irq(&info->delalloc_lock); | 2530 | spin_lock_irq(&info->delalloc_lock); |
2294 | super_used = btrfs_super_bytes_used(&info->super_copy); | 2531 | super_used = btrfs_super_bytes_used(&info->super_copy); |
@@ -2300,17 +2537,32 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2300 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); | 2537 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); |
2301 | 2538 | ||
2302 | if (root == extent_root) { | 2539 | if (root == extent_root) { |
2540 | struct pending_extent_op *extent_op; | ||
2541 | |||
2542 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
2543 | BUG_ON(!extent_op); | ||
2544 | |||
2545 | extent_op->type = PENDING_EXTENT_INSERT; | ||
2546 | extent_op->bytenr = ins->objectid; | ||
2547 | extent_op->num_bytes = ins->offset; | ||
2548 | extent_op->parent = parent; | ||
2549 | extent_op->orig_parent = 0; | ||
2550 | extent_op->generation = ref_generation; | ||
2551 | extent_op->orig_generation = 0; | ||
2552 | extent_op->level = (int)owner; | ||
2553 | |||
2303 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, | 2554 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, |
2304 | ins->objectid + ins->offset - 1, | 2555 | ins->objectid + ins->offset - 1, |
2305 | EXTENT_LOCKED, GFP_NOFS); | 2556 | EXTENT_LOCKED, GFP_NOFS); |
2557 | set_state_private(&root->fs_info->extent_ins, | ||
2558 | ins->objectid, (unsigned long)extent_op); | ||
2306 | goto update_block; | 2559 | goto update_block; |
2307 | } | 2560 | } |
2308 | 2561 | ||
2309 | memcpy(&keys[0], ins, sizeof(*ins)); | 2562 | memcpy(&keys[0], ins, sizeof(*ins)); |
2310 | keys[1].offset = hash_extent_ref(root_objectid, ref_generation, | ||
2311 | owner, owner_offset); | ||
2312 | keys[1].objectid = ins->objectid; | 2563 | keys[1].objectid = ins->objectid; |
2313 | keys[1].type = BTRFS_EXTENT_REF_KEY; | 2564 | keys[1].type = BTRFS_EXTENT_REF_KEY; |
2565 | keys[1].offset = parent; | ||
2314 | sizes[0] = sizeof(*extent_item); | 2566 | sizes[0] = sizeof(*extent_item); |
2315 | sizes[1] = sizeof(*ref); | 2567 | sizes[1] = sizeof(*ref); |
2316 | 2568 | ||
@@ -2331,6 +2583,7 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2331 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); | 2583 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); |
2332 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); | 2584 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); |
2333 | btrfs_set_ref_offset(path->nodes[0], ref, owner_offset); | 2585 | btrfs_set_ref_offset(path->nodes[0], ref, owner_offset); |
2586 | btrfs_set_ref_num_refs(path->nodes[0], ref, 1); | ||
2334 | 2587 | ||
2335 | btrfs_mark_buffer_dirty(path->nodes[0]); | 2588 | btrfs_mark_buffer_dirty(path->nodes[0]); |
2336 | 2589 | ||
@@ -2359,7 +2612,7 @@ out: | |||
2359 | } | 2612 | } |
2360 | 2613 | ||
2361 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2614 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2362 | struct btrfs_root *root, | 2615 | struct btrfs_root *root, u64 parent, |
2363 | u64 root_objectid, u64 ref_generation, | 2616 | u64 root_objectid, u64 ref_generation, |
2364 | u64 owner, u64 owner_offset, | 2617 | u64 owner, u64 owner_offset, |
2365 | struct btrfs_key *ins) | 2618 | struct btrfs_key *ins) |
@@ -2369,9 +2622,9 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2369 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) | 2622 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) |
2370 | return 0; | 2623 | return 0; |
2371 | maybe_lock_mutex(root); | 2624 | maybe_lock_mutex(root); |
2372 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2625 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, |
2373 | ref_generation, owner, | 2626 | root_objectid, ref_generation, |
2374 | owner_offset, ins); | 2627 | owner, owner_offset, ins); |
2375 | maybe_unlock_mutex(root); | 2628 | maybe_unlock_mutex(root); |
2376 | return ret; | 2629 | return ret; |
2377 | } | 2630 | } |
@@ -2382,7 +2635,7 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2382 | * space cache bits as well | 2635 | * space cache bits as well |
2383 | */ | 2636 | */ |
2384 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | 2637 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, |
2385 | struct btrfs_root *root, | 2638 | struct btrfs_root *root, u64 parent, |
2386 | u64 root_objectid, u64 ref_generation, | 2639 | u64 root_objectid, u64 ref_generation, |
2387 | u64 owner, u64 owner_offset, | 2640 | u64 owner, u64 owner_offset, |
2388 | struct btrfs_key *ins) | 2641 | struct btrfs_key *ins) |
@@ -2396,10 +2649,9 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | |||
2396 | 2649 | ||
2397 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); | 2650 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); |
2398 | BUG_ON(ret); | 2651 | BUG_ON(ret); |
2399 | 2652 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, | |
2400 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2653 | root_objectid, ref_generation, |
2401 | ref_generation, owner, | 2654 | owner, owner_offset, ins); |
2402 | owner_offset, ins); | ||
2403 | maybe_unlock_mutex(root); | 2655 | maybe_unlock_mutex(root); |
2404 | return ret; | 2656 | return ret; |
2405 | } | 2657 | } |
@@ -2413,9 +2665,9 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | |||
2413 | */ | 2665 | */ |
2414 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 2666 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
2415 | struct btrfs_root *root, | 2667 | struct btrfs_root *root, |
2416 | u64 num_bytes, u64 min_alloc_size, | 2668 | u64 num_bytes, u64 parent, u64 min_alloc_size, |
2417 | u64 root_objectid, u64 ref_generation, | 2669 | u64 root_objectid, u64 ref_generation, |
2418 | u64 owner, u64 owner_offset, | 2670 | u64 owner_objectid, u64 owner_offset, |
2419 | u64 empty_size, u64 hint_byte, | 2671 | u64 empty_size, u64 hint_byte, |
2420 | u64 search_end, struct btrfs_key *ins, u64 data) | 2672 | u64 search_end, struct btrfs_key *ins, u64 data) |
2421 | { | 2673 | { |
@@ -2428,9 +2680,9 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
2428 | search_end, ins, data); | 2680 | search_end, ins, data); |
2429 | BUG_ON(ret); | 2681 | BUG_ON(ret); |
2430 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { | 2682 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { |
2431 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2683 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, |
2432 | ref_generation, owner, | 2684 | root_objectid, ref_generation, |
2433 | owner_offset, ins); | 2685 | owner_objectid, owner_offset, ins); |
2434 | BUG_ON(ret); | 2686 | BUG_ON(ret); |
2435 | 2687 | ||
2436 | } | 2688 | } |
@@ -2468,10 +2720,9 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
2468 | */ | 2720 | */ |
2469 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 2721 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
2470 | struct btrfs_root *root, | 2722 | struct btrfs_root *root, |
2471 | u32 blocksize, | 2723 | u32 blocksize, u64 parent, |
2472 | u64 root_objectid, | 2724 | u64 root_objectid, |
2473 | u64 ref_generation, | 2725 | u64 ref_generation, |
2474 | u64 first_objectid, | ||
2475 | int level, | 2726 | int level, |
2476 | u64 hint, | 2727 | u64 hint, |
2477 | u64 empty_size) | 2728 | u64 empty_size) |
@@ -2480,10 +2731,9 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2480 | int ret; | 2731 | int ret; |
2481 | struct extent_buffer *buf; | 2732 | struct extent_buffer *buf; |
2482 | 2733 | ||
2483 | ret = btrfs_alloc_extent(trans, root, blocksize, blocksize, | 2734 | ret = btrfs_alloc_extent(trans, root, blocksize, parent, blocksize, |
2484 | root_objectid, ref_generation, | 2735 | root_objectid, ref_generation, level, 0, |
2485 | level, first_objectid, empty_size, hint, | 2736 | empty_size, hint, (u64)-1, &ins, 0); |
2486 | (u64)-1, &ins, 0); | ||
2487 | if (ret) { | 2737 | if (ret) { |
2488 | BUG_ON(ret > 0); | 2738 | BUG_ON(ret > 0); |
2489 | return ERR_PTR(ret); | 2739 | return ERR_PTR(ret); |
@@ -2531,15 +2781,14 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2531 | mutex_lock(&root->fs_info->alloc_mutex); | 2781 | mutex_lock(&root->fs_info->alloc_mutex); |
2532 | ret = __btrfs_free_extent(trans, root, disk_bytenr, | 2782 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
2533 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 2783 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
2534 | leaf_owner, leaf_generation, | 2784 | leaf->start, leaf_owner, leaf_generation, |
2535 | key.objectid, key.offset, 0); | 2785 | key.objectid, key.offset, 0); |
2536 | mutex_unlock(&root->fs_info->alloc_mutex); | 2786 | mutex_unlock(&root->fs_info->alloc_mutex); |
2787 | BUG_ON(ret); | ||
2537 | 2788 | ||
2538 | atomic_inc(&root->fs_info->throttle_gen); | 2789 | atomic_inc(&root->fs_info->throttle_gen); |
2539 | wake_up(&root->fs_info->transaction_throttle); | 2790 | wake_up(&root->fs_info->transaction_throttle); |
2540 | cond_resched(); | 2791 | cond_resched(); |
2541 | |||
2542 | BUG_ON(ret); | ||
2543 | } | 2792 | } |
2544 | return 0; | 2793 | return 0; |
2545 | } | 2794 | } |
@@ -2554,10 +2803,10 @@ static int noinline cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2554 | 2803 | ||
2555 | for (i = 0; i < ref->nritems; i++) { | 2804 | for (i = 0; i < ref->nritems; i++) { |
2556 | mutex_lock(&root->fs_info->alloc_mutex); | 2805 | mutex_lock(&root->fs_info->alloc_mutex); |
2557 | ret = __btrfs_free_extent(trans, root, | 2806 | ret = __btrfs_free_extent(trans, root, info->bytenr, |
2558 | info->bytenr, info->num_bytes, | 2807 | info->num_bytes, ref->bytenr, |
2559 | ref->owner, ref->generation, | 2808 | ref->owner, ref->generation, |
2560 | info->objectid, info->offset, 0); | 2809 | info->objectid, info->offset, 0); |
2561 | mutex_unlock(&root->fs_info->alloc_mutex); | 2810 | mutex_unlock(&root->fs_info->alloc_mutex); |
2562 | 2811 | ||
2563 | atomic_inc(&root->fs_info->throttle_gen); | 2812 | atomic_inc(&root->fs_info->throttle_gen); |
@@ -2576,7 +2825,7 @@ int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len, | |||
2576 | { | 2825 | { |
2577 | int ret; | 2826 | int ret; |
2578 | 2827 | ||
2579 | ret = lookup_extent_ref(NULL, root, start, len, refs); | 2828 | ret = btrfs_lookup_extent_ref(NULL, root, start, len, refs); |
2580 | BUG_ON(ret); | 2829 | BUG_ON(ret); |
2581 | 2830 | ||
2582 | #if 0 // some debugging code in case we see problems here | 2831 | #if 0 // some debugging code in case we see problems here |
@@ -2672,8 +2921,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2672 | 2921 | ||
2673 | mutex_lock(&root->fs_info->alloc_mutex); | 2922 | mutex_lock(&root->fs_info->alloc_mutex); |
2674 | ret = __btrfs_free_extent(trans, root, bytenr, | 2923 | ret = __btrfs_free_extent(trans, root, bytenr, |
2675 | blocksize, root_owner, | 2924 | blocksize, parent->start, |
2676 | root_gen, 0, 0, 1); | 2925 | root_owner, root_gen, 0, 0, 1); |
2677 | BUG_ON(ret); | 2926 | BUG_ON(ret); |
2678 | mutex_unlock(&root->fs_info->alloc_mutex); | 2927 | mutex_unlock(&root->fs_info->alloc_mutex); |
2679 | 2928 | ||
@@ -2690,8 +2939,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2690 | * So, we don't need to check it again | 2939 | * So, we don't need to check it again |
2691 | */ | 2940 | */ |
2692 | if (*level == 1) { | 2941 | if (*level == 1) { |
2693 | struct btrfs_key key; | ||
2694 | btrfs_node_key_to_cpu(cur, &key, path->slots[*level]); | ||
2695 | ref = btrfs_lookup_leaf_ref(root, bytenr); | 2942 | ref = btrfs_lookup_leaf_ref(root, bytenr); |
2696 | if (ref) { | 2943 | if (ref) { |
2697 | ret = cache_drop_leaf_ref(trans, root, ref); | 2944 | ret = cache_drop_leaf_ref(trans, root, ref); |
@@ -2750,12 +2997,13 @@ out: | |||
2750 | 2997 | ||
2751 | mutex_lock(&root->fs_info->alloc_mutex); | 2998 | mutex_lock(&root->fs_info->alloc_mutex); |
2752 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, | 2999 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, |
2753 | root_owner, root_gen, 0, 0, 1); | 3000 | parent->start, root_owner, root_gen, |
3001 | 0, 0, 1); | ||
3002 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2754 | free_extent_buffer(path->nodes[*level]); | 3003 | free_extent_buffer(path->nodes[*level]); |
2755 | path->nodes[*level] = NULL; | 3004 | path->nodes[*level] = NULL; |
2756 | *level += 1; | 3005 | *level += 1; |
2757 | BUG_ON(ret); | 3006 | BUG_ON(ret); |
2758 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2759 | 3007 | ||
2760 | cond_resched(); | 3008 | cond_resched(); |
2761 | return 0; | 3009 | return 0; |
@@ -2792,19 +3040,18 @@ static int noinline walk_up_tree(struct btrfs_trans_handle *trans, | |||
2792 | root_item->drop_level = i; | 3040 | root_item->drop_level = i; |
2793 | return 0; | 3041 | return 0; |
2794 | } else { | 3042 | } else { |
2795 | if (path->nodes[*level] == root->node) { | 3043 | struct extent_buffer *parent; |
2796 | root_owner = root->root_key.objectid; | 3044 | if (path->nodes[*level] == root->node) |
2797 | root_gen = | 3045 | parent = path->nodes[*level]; |
2798 | btrfs_header_generation(path->nodes[*level]); | 3046 | else |
2799 | } else { | 3047 | parent = path->nodes[*level + 1]; |
2800 | struct extent_buffer *node; | 3048 | |
2801 | node = path->nodes[*level + 1]; | 3049 | root_owner = btrfs_header_owner(parent); |
2802 | root_owner = btrfs_header_owner(node); | 3050 | root_gen = btrfs_header_generation(parent); |
2803 | root_gen = btrfs_header_generation(node); | ||
2804 | } | ||
2805 | ret = btrfs_free_extent(trans, root, | 3051 | ret = btrfs_free_extent(trans, root, |
2806 | path->nodes[*level]->start, | 3052 | path->nodes[*level]->start, |
2807 | path->nodes[*level]->len, | 3053 | path->nodes[*level]->len, |
3054 | parent->start, | ||
2808 | root_owner, root_gen, 0, 0, 1); | 3055 | root_owner, root_gen, 0, 0, 1); |
2809 | BUG_ON(ret); | 3056 | BUG_ON(ret); |
2810 | free_extent_buffer(path->nodes[*level]); | 3057 | free_extent_buffer(path->nodes[*level]); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 8624f3e88036..58ad25838a41 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2201,9 +2201,10 @@ retry: | |||
2201 | } | 2201 | } |
2202 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 2202 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
2203 | mapping->writeback_index = index; | 2203 | mapping->writeback_index = index; |
2204 | 2204 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) | |
2205 | if (wbc->range_cont) | 2205 | if (wbc->range_cont) |
2206 | wbc->range_start = index << PAGE_CACHE_SHIFT; | 2206 | wbc->range_start = index << PAGE_CACHE_SHIFT; |
2207 | #endif | ||
2207 | return ret; | 2208 | return ret; |
2208 | } | 2209 | } |
2209 | EXPORT_SYMBOL(extent_write_cache_pages); | 2210 | EXPORT_SYMBOL(extent_write_cache_pages); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 58b329ddb426..48a702d41c8c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -524,6 +524,9 @@ int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
524 | { | 524 | { |
525 | u64 extent_end = 0; | 525 | u64 extent_end = 0; |
526 | u64 search_start = start; | 526 | u64 search_start = start; |
527 | u64 leaf_start; | ||
528 | u64 root_gen; | ||
529 | u64 root_owner; | ||
527 | struct extent_buffer *leaf; | 530 | struct extent_buffer *leaf; |
528 | struct btrfs_file_extent_item *extent; | 531 | struct btrfs_file_extent_item *extent; |
529 | struct btrfs_path *path; | 532 | struct btrfs_path *path; |
@@ -562,6 +565,9 @@ next_slot: | |||
562 | bookend = 0; | 565 | bookend = 0; |
563 | found_extent = 0; | 566 | found_extent = 0; |
564 | found_inline = 0; | 567 | found_inline = 0; |
568 | leaf_start = 0; | ||
569 | root_gen = 0; | ||
570 | root_owner = 0; | ||
565 | extent = NULL; | 571 | extent = NULL; |
566 | leaf = path->nodes[0]; | 572 | leaf = path->nodes[0]; |
567 | slot = path->slots[0]; | 573 | slot = path->slots[0]; |
@@ -628,27 +634,18 @@ next_slot: | |||
628 | search_start = extent_end; | 634 | search_start = extent_end; |
629 | if (end <= extent_end && start >= key.offset && found_inline) { | 635 | if (end <= extent_end && start >= key.offset && found_inline) { |
630 | *hint_byte = EXTENT_MAP_INLINE; | 636 | *hint_byte = EXTENT_MAP_INLINE; |
631 | continue; | 637 | goto out; |
638 | } | ||
639 | |||
640 | if (found_extent) { | ||
641 | read_extent_buffer(leaf, &old, (unsigned long)extent, | ||
642 | sizeof(old)); | ||
643 | root_gen = btrfs_header_generation(leaf); | ||
644 | root_owner = btrfs_header_owner(leaf); | ||
645 | leaf_start = leaf->start; | ||
632 | } | 646 | } |
647 | |||
633 | if (end < extent_end && end >= key.offset) { | 648 | if (end < extent_end && end >= key.offset) { |
634 | if (found_extent) { | ||
635 | u64 disk_bytenr = | ||
636 | btrfs_file_extent_disk_bytenr(leaf, extent); | ||
637 | u64 disk_num_bytes = | ||
638 | btrfs_file_extent_disk_num_bytes(leaf, | ||
639 | extent); | ||
640 | read_extent_buffer(leaf, &old, | ||
641 | (unsigned long)extent, | ||
642 | sizeof(old)); | ||
643 | if (disk_bytenr != 0) { | ||
644 | ret = btrfs_inc_extent_ref(trans, root, | ||
645 | disk_bytenr, disk_num_bytes, | ||
646 | root->root_key.objectid, | ||
647 | trans->transid, | ||
648 | key.objectid, end); | ||
649 | BUG_ON(ret); | ||
650 | } | ||
651 | } | ||
652 | bookend = 1; | 649 | bookend = 1; |
653 | if (found_inline && start <= key.offset) | 650 | if (found_inline && start <= key.offset) |
654 | keep = 1; | 651 | keep = 1; |
@@ -687,49 +684,12 @@ next_slot: | |||
687 | } | 684 | } |
688 | /* delete the entire extent */ | 685 | /* delete the entire extent */ |
689 | if (!keep) { | 686 | if (!keep) { |
690 | u64 disk_bytenr = 0; | ||
691 | u64 disk_num_bytes = 0; | ||
692 | u64 extent_num_bytes = 0; | ||
693 | u64 root_gen; | ||
694 | u64 root_owner; | ||
695 | |||
696 | root_gen = btrfs_header_generation(leaf); | ||
697 | root_owner = btrfs_header_owner(leaf); | ||
698 | if (found_extent) { | ||
699 | disk_bytenr = | ||
700 | btrfs_file_extent_disk_bytenr(leaf, | ||
701 | extent); | ||
702 | disk_num_bytes = | ||
703 | btrfs_file_extent_disk_num_bytes(leaf, | ||
704 | extent); | ||
705 | extent_num_bytes = | ||
706 | btrfs_file_extent_num_bytes(leaf, extent); | ||
707 | *hint_byte = | ||
708 | btrfs_file_extent_disk_bytenr(leaf, | ||
709 | extent); | ||
710 | } | ||
711 | ret = btrfs_del_item(trans, root, path); | 687 | ret = btrfs_del_item(trans, root, path); |
712 | /* TODO update progress marker and return */ | 688 | /* TODO update progress marker and return */ |
713 | BUG_ON(ret); | 689 | BUG_ON(ret); |
714 | btrfs_release_path(root, path); | ||
715 | extent = NULL; | 690 | extent = NULL; |
716 | if (found_extent && disk_bytenr != 0) { | 691 | btrfs_release_path(root, path); |
717 | dec_i_blocks(inode, extent_num_bytes); | 692 | /* the extent will be freed later */ |
718 | ret = btrfs_free_extent(trans, root, | ||
719 | disk_bytenr, | ||
720 | disk_num_bytes, | ||
721 | root_owner, | ||
722 | root_gen, inode->i_ino, | ||
723 | key.offset, 0); | ||
724 | } | ||
725 | |||
726 | BUG_ON(ret); | ||
727 | if (!bookend && search_start >= end) { | ||
728 | ret = 0; | ||
729 | goto out; | ||
730 | } | ||
731 | if (!bookend) | ||
732 | continue; | ||
733 | } | 693 | } |
734 | if (bookend && found_inline && start <= key.offset) { | 694 | if (bookend && found_inline && start <= key.offset) { |
735 | u32 new_size; | 695 | u32 new_size; |
@@ -737,10 +697,13 @@ next_slot: | |||
737 | extent_end - end); | 697 | extent_end - end); |
738 | dec_i_blocks(inode, (extent_end - key.offset) - | 698 | dec_i_blocks(inode, (extent_end - key.offset) - |
739 | (extent_end - end)); | 699 | (extent_end - end)); |
740 | btrfs_truncate_item(trans, root, path, new_size, 0); | 700 | ret = btrfs_truncate_item(trans, root, path, |
701 | new_size, 0); | ||
702 | BUG_ON(ret); | ||
741 | } | 703 | } |
742 | /* create bookend, splitting the extent in two */ | 704 | /* create bookend, splitting the extent in two */ |
743 | if (bookend && found_extent) { | 705 | if (bookend && found_extent) { |
706 | u64 disk_bytenr; | ||
744 | struct btrfs_key ins; | 707 | struct btrfs_key ins; |
745 | ins.objectid = inode->i_ino; | 708 | ins.objectid = inode->i_ino; |
746 | ins.offset = end; | 709 | ins.offset = end; |
@@ -748,13 +711,9 @@ next_slot: | |||
748 | btrfs_release_path(root, path); | 711 | btrfs_release_path(root, path); |
749 | ret = btrfs_insert_empty_item(trans, root, path, &ins, | 712 | ret = btrfs_insert_empty_item(trans, root, path, &ins, |
750 | sizeof(*extent)); | 713 | sizeof(*extent)); |
714 | BUG_ON(ret); | ||
751 | 715 | ||
752 | leaf = path->nodes[0]; | 716 | leaf = path->nodes[0]; |
753 | if (ret) { | ||
754 | btrfs_print_leaf(root, leaf); | ||
755 | printk("got %d on inserting %Lu %u %Lu start %Lu end %Lu found %Lu %Lu keep was %d\n", ret , ins.objectid, ins.type, ins.offset, start, end, key.offset, extent_end, keep); | ||
756 | } | ||
757 | BUG_ON(ret); | ||
758 | extent = btrfs_item_ptr(leaf, path->slots[0], | 717 | extent = btrfs_item_ptr(leaf, path->slots[0], |
759 | struct btrfs_file_extent_item); | 718 | struct btrfs_file_extent_item); |
760 | write_extent_buffer(leaf, &old, | 719 | write_extent_buffer(leaf, &old, |
@@ -770,11 +729,43 @@ next_slot: | |||
770 | BTRFS_FILE_EXTENT_REG); | 729 | BTRFS_FILE_EXTENT_REG); |
771 | 730 | ||
772 | btrfs_mark_buffer_dirty(path->nodes[0]); | 731 | btrfs_mark_buffer_dirty(path->nodes[0]); |
773 | if (le64_to_cpu(old.disk_bytenr) != 0) { | 732 | |
733 | disk_bytenr = le64_to_cpu(old.disk_bytenr); | ||
734 | if (disk_bytenr != 0) { | ||
735 | ret = btrfs_inc_extent_ref(trans, root, | ||
736 | disk_bytenr, | ||
737 | le64_to_cpu(old.disk_num_bytes), | ||
738 | leaf->start, | ||
739 | root->root_key.objectid, | ||
740 | trans->transid, | ||
741 | ins.objectid, ins.offset); | ||
742 | BUG_ON(ret); | ||
743 | } | ||
744 | btrfs_release_path(root, path); | ||
745 | if (disk_bytenr != 0) { | ||
774 | inode->i_blocks += | 746 | inode->i_blocks += |
775 | btrfs_file_extent_num_bytes(leaf, | 747 | btrfs_file_extent_num_bytes(leaf, |
776 | extent) >> 9; | 748 | extent) >> 9; |
777 | } | 749 | } |
750 | } | ||
751 | |||
752 | if (found_extent && !keep) { | ||
753 | u64 disk_bytenr = le64_to_cpu(old.disk_bytenr); | ||
754 | |||
755 | if (disk_bytenr != 0) { | ||
756 | dec_i_blocks(inode, le64_to_cpu(old.num_bytes)); | ||
757 | ret = btrfs_free_extent(trans, root, | ||
758 | disk_bytenr, | ||
759 | le64_to_cpu(old.disk_num_bytes), | ||
760 | leaf_start, root_owner, | ||
761 | root_gen, key.objectid, | ||
762 | key.offset, 0); | ||
763 | BUG_ON(ret); | ||
764 | *hint_byte = disk_bytenr; | ||
765 | } | ||
766 | } | ||
767 | |||
768 | if (search_start >= end) { | ||
778 | ret = 0; | 769 | ret = 0; |
779 | goto out; | 770 | goto out; |
780 | } | 771 | } |
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); |
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; |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index f1374d597a17..3577badfa5bc 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -102,11 +102,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
102 | case BTRFS_EXTENT_REF_KEY: | 102 | case BTRFS_EXTENT_REF_KEY: |
103 | ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref); | 103 | ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref); |
104 | printk("\t\textent back ref root %llu gen %llu " | 104 | printk("\t\textent back ref root %llu gen %llu " |
105 | "owner %llu offset %llu\n", | 105 | "owner %llu offset %llu num_refs %lu\n", |
106 | (unsigned long long)btrfs_ref_root(l, ref), | 106 | (unsigned long long)btrfs_ref_root(l, ref), |
107 | (unsigned long long)btrfs_ref_generation(l, ref), | 107 | (unsigned long long)btrfs_ref_generation(l, ref), |
108 | (unsigned long long)btrfs_ref_objectid(l, ref), | 108 | (unsigned long long)btrfs_ref_objectid(l, ref), |
109 | (unsigned long long)btrfs_ref_offset(l, ref)); | 109 | (unsigned long long)btrfs_ref_offset(l, ref), |
110 | (unsigned long)btrfs_ref_num_refs(l, ref)); | ||
110 | break; | 111 | break; |
111 | 112 | ||
112 | case BTRFS_EXTENT_DATA_KEY: | 113 | case BTRFS_EXTENT_DATA_KEY: |
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 | } | ||
436 | no_copy: | 479 | no_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 | } |