aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 646b9148ca21..3181759da1cf 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1590,13 +1590,17 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
1590} 1590}
1591 1591
1592static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, 1592static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1593 int pending) 1593 int is_data, int pending)
1594{ 1594{
1595 int err = 0; 1595 int err = 0;
1596 1596
1597 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex)); 1597 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
1598 if (!pending) { 1598 if (!pending) {
1599 struct extent_buffer *buf; 1599 struct extent_buffer *buf;
1600
1601 if (is_data)
1602 goto pinit;
1603
1600 buf = btrfs_find_tree_block(root, bytenr, num_bytes); 1604 buf = btrfs_find_tree_block(root, bytenr, num_bytes);
1601 if (buf) { 1605 if (buf) {
1602 /* we can reuse a block if it hasn't been written 1606 /* we can reuse a block if it hasn't been written
@@ -1624,6 +1628,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1624 } 1628 }
1625 free_extent_buffer(buf); 1629 free_extent_buffer(buf);
1626 } 1630 }
1631pinit:
1627 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); 1632 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
1628 } else { 1633 } else {
1629 set_extent_bits(&root->fs_info->pending_del, 1634 set_extent_bits(&root->fs_info->pending_del,
@@ -1744,7 +1749,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
1744#endif 1749#endif
1745 1750
1746 if (pin) { 1751 if (pin) {
1747 ret = pin_down_bytes(root, bytenr, num_bytes, 0); 1752 ret = pin_down_bytes(root, bytenr, num_bytes,
1753 owner_objectid >= BTRFS_FIRST_FREE_OBJECTID, 0);
1748 if (ret > 0) 1754 if (ret > 0)
1749 mark_free = 1; 1755 mark_free = 1;
1750 BUG_ON(ret < 0); 1756 BUG_ON(ret < 0);
@@ -1862,9 +1868,17 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
1862 ref_generation = 0; 1868 ref_generation = 0;
1863 1869
1864 if (root == extent_root) { 1870 if (root == extent_root) {
1865 pin_down_bytes(root, bytenr, num_bytes, 1); 1871 pin_down_bytes(root, bytenr, num_bytes, 0, 1);
1866 return 0; 1872 return 0;
1867 } 1873 }
1874 /* if metadata always pin */
1875 if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID)
1876 pin = 1;
1877
1878 /* if data pin when any transaction has committed this */
1879 if (ref_generation != trans->transid)
1880 pin = 1;
1881
1868 ret = __free_extent(trans, root, bytenr, num_bytes, root_objectid, 1882 ret = __free_extent(trans, root, bytenr, num_bytes, root_objectid,
1869 ref_generation, owner_objectid, owner_offset, 1883 ref_generation, owner_objectid, owner_offset,
1870 pin, pin == 0); 1884 pin, pin == 0);