diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1af1ea88e8a8..f2fb974ed8f0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -764,6 +764,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
764 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 764 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
765 | int ret = 0; | 765 | int ret = 0; |
766 | 766 | ||
767 | BUG_ON(root == root->fs_info->tree_root); | ||
767 | trans = btrfs_join_transaction(root, 1); | 768 | trans = btrfs_join_transaction(root, 1); |
768 | BUG_ON(!trans); | 769 | BUG_ON(!trans); |
769 | btrfs_set_trans_block_group(trans, inode); | 770 | btrfs_set_trans_block_group(trans, inode); |
@@ -1035,10 +1036,16 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
1035 | int type; | 1036 | int type; |
1036 | int nocow; | 1037 | int nocow; |
1037 | int check_prev = 1; | 1038 | int check_prev = 1; |
1039 | bool nolock = false; | ||
1038 | 1040 | ||
1039 | path = btrfs_alloc_path(); | 1041 | path = btrfs_alloc_path(); |
1040 | BUG_ON(!path); | 1042 | BUG_ON(!path); |
1041 | trans = btrfs_join_transaction(root, 1); | 1043 | if (root == root->fs_info->tree_root) { |
1044 | nolock = true; | ||
1045 | trans = btrfs_join_transaction_nolock(root, 1); | ||
1046 | } else { | ||
1047 | trans = btrfs_join_transaction(root, 1); | ||
1048 | } | ||
1042 | BUG_ON(!trans); | 1049 | BUG_ON(!trans); |
1043 | 1050 | ||
1044 | cow_start = (u64)-1; | 1051 | cow_start = (u64)-1; |
@@ -1211,8 +1218,13 @@ out_check: | |||
1211 | BUG_ON(ret); | 1218 | BUG_ON(ret); |
1212 | } | 1219 | } |
1213 | 1220 | ||
1214 | ret = btrfs_end_transaction(trans, root); | 1221 | if (nolock) { |
1215 | BUG_ON(ret); | 1222 | ret = btrfs_end_transaction_nolock(trans, root); |
1223 | BUG_ON(ret); | ||
1224 | } else { | ||
1225 | ret = btrfs_end_transaction(trans, root); | ||
1226 | BUG_ON(ret); | ||
1227 | } | ||
1216 | btrfs_free_path(path); | 1228 | btrfs_free_path(path); |
1217 | return 0; | 1229 | return 0; |
1218 | } | 1230 | } |
@@ -1289,6 +1301,8 @@ static int btrfs_set_bit_hook(struct inode *inode, | |||
1289 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1301 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
1290 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1302 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1291 | u64 len = state->end + 1 - state->start; | 1303 | u64 len = state->end + 1 - state->start; |
1304 | int do_list = (root->root_key.objectid != | ||
1305 | BTRFS_ROOT_TREE_OBJECTID); | ||
1292 | 1306 | ||
1293 | if (*bits & EXTENT_FIRST_DELALLOC) | 1307 | if (*bits & EXTENT_FIRST_DELALLOC) |
1294 | *bits &= ~EXTENT_FIRST_DELALLOC; | 1308 | *bits &= ~EXTENT_FIRST_DELALLOC; |
@@ -1298,7 +1312,7 @@ static int btrfs_set_bit_hook(struct inode *inode, | |||
1298 | spin_lock(&root->fs_info->delalloc_lock); | 1312 | spin_lock(&root->fs_info->delalloc_lock); |
1299 | BTRFS_I(inode)->delalloc_bytes += len; | 1313 | BTRFS_I(inode)->delalloc_bytes += len; |
1300 | root->fs_info->delalloc_bytes += len; | 1314 | root->fs_info->delalloc_bytes += len; |
1301 | if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1315 | if (do_list && list_empty(&BTRFS_I(inode)->delalloc_inodes)) { |
1302 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | 1316 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, |
1303 | &root->fs_info->delalloc_inodes); | 1317 | &root->fs_info->delalloc_inodes); |
1304 | } | 1318 | } |
@@ -1321,6 +1335,8 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1321 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1335 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
1322 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1336 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1323 | u64 len = state->end + 1 - state->start; | 1337 | u64 len = state->end + 1 - state->start; |
1338 | int do_list = (root->root_key.objectid != | ||
1339 | BTRFS_ROOT_TREE_OBJECTID); | ||
1324 | 1340 | ||
1325 | if (*bits & EXTENT_FIRST_DELALLOC) | 1341 | if (*bits & EXTENT_FIRST_DELALLOC) |
1326 | *bits &= ~EXTENT_FIRST_DELALLOC; | 1342 | *bits &= ~EXTENT_FIRST_DELALLOC; |
@@ -1330,14 +1346,15 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1330 | if (*bits & EXTENT_DO_ACCOUNTING) | 1346 | if (*bits & EXTENT_DO_ACCOUNTING) |
1331 | btrfs_delalloc_release_metadata(inode, len); | 1347 | btrfs_delalloc_release_metadata(inode, len); |
1332 | 1348 | ||
1333 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) | 1349 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID |
1350 | && do_list) | ||
1334 | btrfs_free_reserved_data_space(inode, len); | 1351 | btrfs_free_reserved_data_space(inode, len); |
1335 | 1352 | ||
1336 | spin_lock(&root->fs_info->delalloc_lock); | 1353 | spin_lock(&root->fs_info->delalloc_lock); |
1337 | root->fs_info->delalloc_bytes -= len; | 1354 | root->fs_info->delalloc_bytes -= len; |
1338 | BTRFS_I(inode)->delalloc_bytes -= len; | 1355 | BTRFS_I(inode)->delalloc_bytes -= len; |
1339 | 1356 | ||
1340 | if (BTRFS_I(inode)->delalloc_bytes == 0 && | 1357 | if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 && |
1341 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1358 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { |
1342 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); | 1359 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); |
1343 | } | 1360 | } |
@@ -1426,7 +1443,10 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
1426 | 1443 | ||
1427 | skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; | 1444 | skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; |
1428 | 1445 | ||
1429 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | 1446 | if (root == root->fs_info->tree_root) |
1447 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); | ||
1448 | else | ||
1449 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | ||
1430 | BUG_ON(ret); | 1450 | BUG_ON(ret); |
1431 | 1451 | ||
1432 | if (!(rw & REQ_WRITE)) { | 1452 | if (!(rw & REQ_WRITE)) { |
@@ -1662,6 +1682,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1662 | struct extent_state *cached_state = NULL; | 1682 | struct extent_state *cached_state = NULL; |
1663 | int compressed = 0; | 1683 | int compressed = 0; |
1664 | int ret; | 1684 | int ret; |
1685 | bool nolock = false; | ||
1665 | 1686 | ||
1666 | ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, | 1687 | ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, |
1667 | end - start + 1); | 1688 | end - start + 1); |
@@ -1669,11 +1690,17 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1669 | return 0; | 1690 | return 0; |
1670 | BUG_ON(!ordered_extent); | 1691 | BUG_ON(!ordered_extent); |
1671 | 1692 | ||
1693 | nolock = (root == root->fs_info->tree_root); | ||
1694 | |||
1672 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { | 1695 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { |
1673 | BUG_ON(!list_empty(&ordered_extent->list)); | 1696 | BUG_ON(!list_empty(&ordered_extent->list)); |
1674 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1697 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1675 | if (!ret) { | 1698 | if (!ret) { |
1676 | trans = btrfs_join_transaction(root, 1); | 1699 | if (nolock) |
1700 | trans = btrfs_join_transaction_nolock(root, 1); | ||
1701 | else | ||
1702 | trans = btrfs_join_transaction(root, 1); | ||
1703 | BUG_ON(!trans); | ||
1677 | btrfs_set_trans_block_group(trans, inode); | 1704 | btrfs_set_trans_block_group(trans, inode); |
1678 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1705 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
1679 | ret = btrfs_update_inode(trans, root, inode); | 1706 | ret = btrfs_update_inode(trans, root, inode); |
@@ -1686,7 +1713,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1686 | ordered_extent->file_offset + ordered_extent->len - 1, | 1713 | ordered_extent->file_offset + ordered_extent->len - 1, |
1687 | 0, &cached_state, GFP_NOFS); | 1714 | 0, &cached_state, GFP_NOFS); |
1688 | 1715 | ||
1689 | trans = btrfs_join_transaction(root, 1); | 1716 | if (nolock) |
1717 | trans = btrfs_join_transaction_nolock(root, 1); | ||
1718 | else | ||
1719 | trans = btrfs_join_transaction(root, 1); | ||
1690 | btrfs_set_trans_block_group(trans, inode); | 1720 | btrfs_set_trans_block_group(trans, inode); |
1691 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1721 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
1692 | 1722 | ||
@@ -1725,9 +1755,15 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1725 | ret = btrfs_update_inode(trans, root, inode); | 1755 | ret = btrfs_update_inode(trans, root, inode); |
1726 | BUG_ON(ret); | 1756 | BUG_ON(ret); |
1727 | out: | 1757 | out: |
1728 | btrfs_delalloc_release_metadata(inode, ordered_extent->len); | 1758 | if (nolock) { |
1729 | if (trans) | 1759 | if (trans) |
1730 | btrfs_end_transaction(trans, root); | 1760 | btrfs_end_transaction_nolock(trans, root); |
1761 | } else { | ||
1762 | btrfs_delalloc_release_metadata(inode, ordered_extent->len); | ||
1763 | if (trans) | ||
1764 | btrfs_end_transaction(trans, root); | ||
1765 | } | ||
1766 | |||
1731 | /* once for us */ | 1767 | /* once for us */ |
1732 | btrfs_put_ordered_extent(ordered_extent); | 1768 | btrfs_put_ordered_extent(ordered_extent); |
1733 | /* once for the tree */ | 1769 | /* once for the tree */ |