diff options
-rw-r--r-- | fs/btrfs/ctree.c | 7 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 41 |
3 files changed, 32 insertions, 22 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 64346721173f..61b5bcd57b7e 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1005,8 +1005,11 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
1005 | return ret; | 1005 | return ret; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | if (root->ref_cows) | 1008 | if (root->ref_cows) { |
1009 | btrfs_reloc_cow_block(trans, root, buf, cow); | 1009 | ret = btrfs_reloc_cow_block(trans, root, buf, cow); |
1010 | if (ret) | ||
1011 | return ret; | ||
1012 | } | ||
1010 | 1013 | ||
1011 | if (buf == root->node) { | 1014 | if (buf == root->node) { |
1012 | WARN_ON(parent && parent != buf); | 1015 | WARN_ON(parent && parent != buf); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3c1da6f98a4d..2491ba076b42 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3939,9 +3939,9 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, | |||
3939 | struct btrfs_root *root); | 3939 | struct btrfs_root *root); |
3940 | int btrfs_recover_relocation(struct btrfs_root *root); | 3940 | int btrfs_recover_relocation(struct btrfs_root *root); |
3941 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); | 3941 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); |
3942 | void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, | 3942 | int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, |
3943 | struct btrfs_root *root, struct extent_buffer *buf, | 3943 | struct btrfs_root *root, struct extent_buffer *buf, |
3944 | struct extent_buffer *cow); | 3944 | struct extent_buffer *cow); |
3945 | void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans, | 3945 | void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans, |
3946 | struct btrfs_pending_snapshot *pending, | 3946 | struct btrfs_pending_snapshot *pending, |
3947 | u64 *bytes_to_reserve); | 3947 | u64 *bytes_to_reserve); |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index aacc2121e87c..09b2b9a0a491 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1548,7 +1548,7 @@ static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr, | |||
1548 | btrfs_file_extent_other_encoding(leaf, fi)); | 1548 | btrfs_file_extent_other_encoding(leaf, fi)); |
1549 | 1549 | ||
1550 | if (num_bytes != btrfs_file_extent_disk_num_bytes(leaf, fi)) { | 1550 | if (num_bytes != btrfs_file_extent_disk_num_bytes(leaf, fi)) { |
1551 | ret = 1; | 1551 | ret = -EINVAL; |
1552 | goto out; | 1552 | goto out; |
1553 | } | 1553 | } |
1554 | 1554 | ||
@@ -1579,7 +1579,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1579 | u64 end; | 1579 | u64 end; |
1580 | u32 nritems; | 1580 | u32 nritems; |
1581 | u32 i; | 1581 | u32 i; |
1582 | int ret; | 1582 | int ret = 0; |
1583 | int first = 1; | 1583 | int first = 1; |
1584 | int dirty = 0; | 1584 | int dirty = 0; |
1585 | 1585 | ||
@@ -1642,11 +1642,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1642 | 1642 | ||
1643 | ret = get_new_location(rc->data_inode, &new_bytenr, | 1643 | ret = get_new_location(rc->data_inode, &new_bytenr, |
1644 | bytenr, num_bytes); | 1644 | bytenr, num_bytes); |
1645 | if (ret > 0) { | 1645 | if (ret) { |
1646 | WARN_ON(1); | 1646 | /* |
1647 | continue; | 1647 | * Don't have to abort since we've not changed anything |
1648 | * in the file extent yet. | ||
1649 | */ | ||
1650 | break; | ||
1648 | } | 1651 | } |
1649 | BUG_ON(ret < 0); | ||
1650 | 1652 | ||
1651 | btrfs_set_file_extent_disk_bytenr(leaf, fi, new_bytenr); | 1653 | btrfs_set_file_extent_disk_bytenr(leaf, fi, new_bytenr); |
1652 | dirty = 1; | 1654 | dirty = 1; |
@@ -1656,18 +1658,24 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1656 | num_bytes, parent, | 1658 | num_bytes, parent, |
1657 | btrfs_header_owner(leaf), | 1659 | btrfs_header_owner(leaf), |
1658 | key.objectid, key.offset, 1); | 1660 | key.objectid, key.offset, 1); |
1659 | BUG_ON(ret); | 1661 | if (ret) { |
1662 | btrfs_abort_transaction(trans, root, ret); | ||
1663 | break; | ||
1664 | } | ||
1660 | 1665 | ||
1661 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 1666 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
1662 | parent, btrfs_header_owner(leaf), | 1667 | parent, btrfs_header_owner(leaf), |
1663 | key.objectid, key.offset, 1); | 1668 | key.objectid, key.offset, 1); |
1664 | BUG_ON(ret); | 1669 | if (ret) { |
1670 | btrfs_abort_transaction(trans, root, ret); | ||
1671 | break; | ||
1672 | } | ||
1665 | } | 1673 | } |
1666 | if (dirty) | 1674 | if (dirty) |
1667 | btrfs_mark_buffer_dirty(leaf); | 1675 | btrfs_mark_buffer_dirty(leaf); |
1668 | if (inode) | 1676 | if (inode) |
1669 | btrfs_add_delayed_iput(inode); | 1677 | btrfs_add_delayed_iput(inode); |
1670 | return 0; | 1678 | return ret; |
1671 | } | 1679 | } |
1672 | 1680 | ||
1673 | static noinline_for_stack | 1681 | static noinline_for_stack |
@@ -4499,19 +4507,19 @@ out: | |||
4499 | return ret; | 4507 | return ret; |
4500 | } | 4508 | } |
4501 | 4509 | ||
4502 | void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, | 4510 | int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, |
4503 | struct btrfs_root *root, struct extent_buffer *buf, | 4511 | struct btrfs_root *root, struct extent_buffer *buf, |
4504 | struct extent_buffer *cow) | 4512 | struct extent_buffer *cow) |
4505 | { | 4513 | { |
4506 | struct reloc_control *rc; | 4514 | struct reloc_control *rc; |
4507 | struct backref_node *node; | 4515 | struct backref_node *node; |
4508 | int first_cow = 0; | 4516 | int first_cow = 0; |
4509 | int level; | 4517 | int level; |
4510 | int ret; | 4518 | int ret = 0; |
4511 | 4519 | ||
4512 | rc = root->fs_info->reloc_ctl; | 4520 | rc = root->fs_info->reloc_ctl; |
4513 | if (!rc) | 4521 | if (!rc) |
4514 | return; | 4522 | return 0; |
4515 | 4523 | ||
4516 | BUG_ON(rc->stage == UPDATE_DATA_PTRS && | 4524 | BUG_ON(rc->stage == UPDATE_DATA_PTRS && |
4517 | root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID); | 4525 | root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID); |
@@ -4547,10 +4555,9 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, | |||
4547 | rc->nodes_relocated += buf->len; | 4555 | rc->nodes_relocated += buf->len; |
4548 | } | 4556 | } |
4549 | 4557 | ||
4550 | if (level == 0 && first_cow && rc->stage == UPDATE_DATA_PTRS) { | 4558 | if (level == 0 && first_cow && rc->stage == UPDATE_DATA_PTRS) |
4551 | ret = replace_file_extents(trans, rc, root, cow); | 4559 | ret = replace_file_extents(trans, rc, root, cow); |
4552 | BUG_ON(ret); | 4560 | return ret; |
4553 | } | ||
4554 | } | 4561 | } |
4555 | 4562 | ||
4556 | /* | 4563 | /* |