diff options
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 68 |
1 files changed, 25 insertions, 43 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index d3aaabbfada0..dd3c040139a2 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -553,7 +553,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
553 | dst_rsv = &root->fs_info->delayed_block_rsv; | 553 | dst_rsv = &root->fs_info->delayed_block_rsv; |
554 | 554 | ||
555 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 555 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
556 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 556 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); |
557 | if (!ret) { | 557 | if (!ret) { |
558 | trace_btrfs_space_reservation(root->fs_info, "delayed_item", | 558 | trace_btrfs_space_reservation(root->fs_info, "delayed_item", |
559 | item->key.objectid, | 559 | item->key.objectid, |
@@ -598,6 +598,29 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
598 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 598 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
599 | 599 | ||
600 | /* | 600 | /* |
601 | * If our block_rsv is the delalloc block reserve then check and see if | ||
602 | * we have our extra reservation for updating the inode. If not fall | ||
603 | * through and try to reserve space quickly. | ||
604 | * | ||
605 | * We used to try and steal from the delalloc block rsv or the global | ||
606 | * reserve, but we'd steal a full reservation, which isn't kind. We are | ||
607 | * here through delalloc which means we've likely just cowed down close | ||
608 | * to the leaf that contains the inode, so we would steal less just | ||
609 | * doing the fallback inode update, so if we do end up having to steal | ||
610 | * from the global block rsv we hopefully only steal one or two blocks | ||
611 | * worth which is less likely to hurt us. | ||
612 | */ | ||
613 | if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { | ||
614 | spin_lock(&BTRFS_I(inode)->lock); | ||
615 | if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, | ||
616 | &BTRFS_I(inode)->runtime_flags)) | ||
617 | release = true; | ||
618 | else | ||
619 | src_rsv = NULL; | ||
620 | spin_unlock(&BTRFS_I(inode)->lock); | ||
621 | } | ||
622 | |||
623 | /* | ||
601 | * btrfs_dirty_inode will update the inode under btrfs_join_transaction | 624 | * btrfs_dirty_inode will update the inode under btrfs_join_transaction |
602 | * which doesn't reserve space for speed. This is a problem since we | 625 | * which doesn't reserve space for speed. This is a problem since we |
603 | * still need to reserve space for this update, so try to reserve the | 626 | * still need to reserve space for this update, so try to reserve the |
@@ -626,51 +649,10 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
626 | num_bytes, 1); | 649 | num_bytes, 1); |
627 | } | 650 | } |
628 | return ret; | 651 | return ret; |
629 | } else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { | ||
630 | spin_lock(&BTRFS_I(inode)->lock); | ||
631 | if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, | ||
632 | &BTRFS_I(inode)->runtime_flags)) { | ||
633 | spin_unlock(&BTRFS_I(inode)->lock); | ||
634 | release = true; | ||
635 | goto migrate; | ||
636 | } | ||
637 | spin_unlock(&BTRFS_I(inode)->lock); | ||
638 | |||
639 | /* Ok we didn't have space pre-reserved. This shouldn't happen | ||
640 | * too often but it can happen if we do delalloc to an existing | ||
641 | * inode which gets dirtied because of the time update, and then | ||
642 | * isn't touched again until after the transaction commits and | ||
643 | * then we try to write out the data. First try to be nice and | ||
644 | * reserve something strictly for us. If not be a pain and try | ||
645 | * to steal from the delalloc block rsv. | ||
646 | */ | ||
647 | ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, | ||
648 | BTRFS_RESERVE_NO_FLUSH); | ||
649 | if (!ret) | ||
650 | goto out; | ||
651 | |||
652 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | ||
653 | if (!ret) | ||
654 | goto out; | ||
655 | |||
656 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) { | ||
657 | btrfs_debug(root->fs_info, | ||
658 | "block rsv migrate returned %d", ret); | ||
659 | WARN_ON(1); | ||
660 | } | ||
661 | /* | ||
662 | * Ok this is a problem, let's just steal from the global rsv | ||
663 | * since this really shouldn't happen that often. | ||
664 | */ | ||
665 | ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, | ||
666 | dst_rsv, num_bytes); | ||
667 | goto out; | ||
668 | } | 652 | } |
669 | 653 | ||
670 | migrate: | 654 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); |
671 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | ||
672 | 655 | ||
673 | out: | ||
674 | /* | 656 | /* |
675 | * Migrate only takes a reservation, it doesn't touch the size of the | 657 | * Migrate only takes a reservation, it doesn't touch the size of the |
676 | * block_rsv. This is to simplify people who don't normally have things | 658 | * block_rsv. This is to simplify people who don't normally have things |