diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 23:03:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 23:03:41 -0500 |
commit | 6a6662ced4153f6dbcfc40d7225c3cc45416039c (patch) | |
tree | 77ad5d577333f02cd854e44827a407dd0388d4eb /fs/btrfs/delayed-inode.c | |
parent | 32aaeffbd4a7457bf2f7448b33b5946ff2a960eb (diff) | |
parent | 7c7e82a77fe3d89ae50824aa7c897454675eb4c4 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (114 commits)
Btrfs: check for a null fs root when writing to the backup root log
Btrfs: fix race during transaction joins
Btrfs: fix a potential btrfs_bio leak on scrub fixups
Btrfs: rename btrfs_bio multi -> bbio for consistency
Btrfs: stop leaking btrfs_bios on readahead
Btrfs: stop the readahead threads on failed mount
Btrfs: fix extent_buffer leak in the metadata IO error handling
Btrfs: fix the new inspection ioctls for 32 bit compat
Btrfs: fix delayed insertion reservation
Btrfs: ClearPageError during writepage and clean_tree_block
Btrfs: be smarter about committing the transaction in reserve_metadata_bytes
Btrfs: make a delayed_block_rsv for the delayed item insertion
Btrfs: add a log of past tree roots
btrfs: separate superblock items out of fs_info
Btrfs: use the global reserve when truncating the free space cache inode
Btrfs: release metadata from global reserve if we have to fallback for unlink
Btrfs: make sure to flush queued bios if write_cache_pages waits
Btrfs: fix extent pinning bugs in the tree log
Btrfs: make sure btrfs_remove_free_space doesn't leak EAGAIN
Btrfs: don't wait as long for more batches during SSD log commit
...
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index ae4d9cd10961..3a1b939c9ae2 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -591,7 +591,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
591 | return 0; | 591 | return 0; |
592 | 592 | ||
593 | src_rsv = trans->block_rsv; | 593 | src_rsv = trans->block_rsv; |
594 | dst_rsv = &root->fs_info->global_block_rsv; | 594 | dst_rsv = &root->fs_info->delayed_block_rsv; |
595 | 595 | ||
596 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 596 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
597 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 597 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
@@ -609,7 +609,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, | |||
609 | if (!item->bytes_reserved) | 609 | if (!item->bytes_reserved) |
610 | return; | 610 | return; |
611 | 611 | ||
612 | rsv = &root->fs_info->global_block_rsv; | 612 | rsv = &root->fs_info->delayed_block_rsv; |
613 | btrfs_block_rsv_release(root, rsv, | 613 | btrfs_block_rsv_release(root, rsv, |
614 | item->bytes_reserved); | 614 | item->bytes_reserved); |
615 | } | 615 | } |
@@ -624,13 +624,36 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
624 | u64 num_bytes; | 624 | u64 num_bytes; |
625 | int ret; | 625 | int ret; |
626 | 626 | ||
627 | if (!trans->bytes_reserved) | ||
628 | return 0; | ||
629 | |||
630 | src_rsv = trans->block_rsv; | 627 | src_rsv = trans->block_rsv; |
631 | dst_rsv = &root->fs_info->global_block_rsv; | 628 | dst_rsv = &root->fs_info->delayed_block_rsv; |
632 | 629 | ||
633 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 630 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
631 | |||
632 | /* | ||
633 | * btrfs_dirty_inode will update the inode under btrfs_join_transaction | ||
634 | * which doesn't reserve space for speed. This is a problem since we | ||
635 | * still need to reserve space for this update, so try to reserve the | ||
636 | * space. | ||
637 | * | ||
638 | * Now if src_rsv == delalloc_block_rsv we'll let it just steal since | ||
639 | * we're accounted for. | ||
640 | */ | ||
641 | if (!trans->bytes_reserved && | ||
642 | src_rsv != &root->fs_info->delalloc_block_rsv) { | ||
643 | ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes); | ||
644 | /* | ||
645 | * Since we're under a transaction reserve_metadata_bytes could | ||
646 | * try to commit the transaction which will make it return | ||
647 | * EAGAIN to make us stop the transaction we have, so return | ||
648 | * ENOSPC instead so that btrfs_dirty_inode knows what to do. | ||
649 | */ | ||
650 | if (ret == -EAGAIN) | ||
651 | ret = -ENOSPC; | ||
652 | if (!ret) | ||
653 | node->bytes_reserved = num_bytes; | ||
654 | return ret; | ||
655 | } | ||
656 | |||
634 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 657 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
635 | if (!ret) | 658 | if (!ret) |
636 | node->bytes_reserved = num_bytes; | 659 | node->bytes_reserved = num_bytes; |
@@ -646,7 +669,7 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_root *root, | |||
646 | if (!node->bytes_reserved) | 669 | if (!node->bytes_reserved) |
647 | return; | 670 | return; |
648 | 671 | ||
649 | rsv = &root->fs_info->global_block_rsv; | 672 | rsv = &root->fs_info->delayed_block_rsv; |
650 | btrfs_block_rsv_release(root, rsv, | 673 | btrfs_block_rsv_release(root, rsv, |
651 | node->bytes_reserved); | 674 | node->bytes_reserved); |
652 | node->bytes_reserved = 0; | 675 | node->bytes_reserved = 0; |
@@ -1026,7 +1049,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1026 | path->leave_spinning = 1; | 1049 | path->leave_spinning = 1; |
1027 | 1050 | ||
1028 | block_rsv = trans->block_rsv; | 1051 | block_rsv = trans->block_rsv; |
1029 | trans->block_rsv = &root->fs_info->global_block_rsv; | 1052 | trans->block_rsv = &root->fs_info->delayed_block_rsv; |
1030 | 1053 | ||
1031 | delayed_root = btrfs_get_delayed_root(root); | 1054 | delayed_root = btrfs_get_delayed_root(root); |
1032 | 1055 | ||
@@ -1069,7 +1092,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1069 | path->leave_spinning = 1; | 1092 | path->leave_spinning = 1; |
1070 | 1093 | ||
1071 | block_rsv = trans->block_rsv; | 1094 | block_rsv = trans->block_rsv; |
1072 | trans->block_rsv = &node->root->fs_info->global_block_rsv; | 1095 | trans->block_rsv = &node->root->fs_info->delayed_block_rsv; |
1073 | 1096 | ||
1074 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1097 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); |
1075 | if (!ret) | 1098 | if (!ret) |
@@ -1149,7 +1172,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1149 | goto free_path; | 1172 | goto free_path; |
1150 | 1173 | ||
1151 | block_rsv = trans->block_rsv; | 1174 | block_rsv = trans->block_rsv; |
1152 | trans->block_rsv = &root->fs_info->global_block_rsv; | 1175 | trans->block_rsv = &root->fs_info->delayed_block_rsv; |
1153 | 1176 | ||
1154 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1177 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); |
1155 | if (!ret) | 1178 | if (!ret) |
@@ -1686,11 +1709,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | |||
1686 | } | 1709 | } |
1687 | 1710 | ||
1688 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); | 1711 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); |
1689 | /* | 1712 | if (ret) |
1690 | * we must reserve enough space when we start a new transaction, | 1713 | goto release_node; |
1691 | * so reserving metadata failure is impossible | ||
1692 | */ | ||
1693 | BUG_ON(ret); | ||
1694 | 1714 | ||
1695 | fill_stack_inode_item(trans, &delayed_node->inode_item, inode); | 1715 | fill_stack_inode_item(trans, &delayed_node->inode_item, inode); |
1696 | delayed_node->inode_dirty = 1; | 1716 | delayed_node->inode_dirty = 1; |