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.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 9879bd474632..b232150b5b6b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3797,16 +3797,16 @@ void btrfs_free_block_rsv(struct btrfs_root *root,
3797 kfree(rsv); 3797 kfree(rsv);
3798} 3798}
3799 3799
3800int btrfs_block_rsv_add(struct btrfs_root *root, 3800static inline int __block_rsv_add(struct btrfs_root *root,
3801 struct btrfs_block_rsv *block_rsv, 3801 struct btrfs_block_rsv *block_rsv,
3802 u64 num_bytes) 3802 u64 num_bytes, int flush)
3803{ 3803{
3804 int ret; 3804 int ret;
3805 3805
3806 if (num_bytes == 0) 3806 if (num_bytes == 0)
3807 return 0; 3807 return 0;
3808 3808
3809 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1); 3809 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
3810 if (!ret) { 3810 if (!ret) {
3811 block_rsv_add_bytes(block_rsv, num_bytes, 1); 3811 block_rsv_add_bytes(block_rsv, num_bytes, 1);
3812 return 0; 3812 return 0;
@@ -3815,22 +3815,18 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
3815 return ret; 3815 return ret;
3816} 3816}
3817 3817
3818int btrfs_block_rsv_add(struct btrfs_root *root,
3819 struct btrfs_block_rsv *block_rsv,
3820 u64 num_bytes)
3821{
3822 return __block_rsv_add(root, block_rsv, num_bytes, 1);
3823}
3824
3818int btrfs_block_rsv_add_noflush(struct btrfs_root *root, 3825int btrfs_block_rsv_add_noflush(struct btrfs_root *root,
3819 struct btrfs_block_rsv *block_rsv, 3826 struct btrfs_block_rsv *block_rsv,
3820 u64 num_bytes) 3827 u64 num_bytes)
3821{ 3828{
3822 int ret; 3829 return __block_rsv_add(root, block_rsv, num_bytes, 0);
3823
3824 if (num_bytes == 0)
3825 return 0;
3826
3827 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 0);
3828 if (!ret) {
3829 block_rsv_add_bytes(block_rsv, num_bytes, 1);
3830 return 0;
3831 }
3832
3833 return ret;
3834} 3830}
3835 3831
3836int btrfs_block_rsv_check(struct btrfs_root *root, 3832int btrfs_block_rsv_check(struct btrfs_root *root,
@@ -4064,23 +4060,30 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
4064 */ 4060 */
4065static unsigned drop_outstanding_extent(struct inode *inode) 4061static unsigned drop_outstanding_extent(struct inode *inode)
4066{ 4062{
4063 unsigned drop_inode_space = 0;
4067 unsigned dropped_extents = 0; 4064 unsigned dropped_extents = 0;
4068 4065
4069 BUG_ON(!BTRFS_I(inode)->outstanding_extents); 4066 BUG_ON(!BTRFS_I(inode)->outstanding_extents);
4070 BTRFS_I(inode)->outstanding_extents--; 4067 BTRFS_I(inode)->outstanding_extents--;
4071 4068
4069 if (BTRFS_I(inode)->outstanding_extents == 0 &&
4070 BTRFS_I(inode)->delalloc_meta_reserved) {
4071 drop_inode_space = 1;
4072 BTRFS_I(inode)->delalloc_meta_reserved = 0;
4073 }
4074
4072 /* 4075 /*
4073 * If we have more or the same amount of outsanding extents than we have 4076 * If we have more or the same amount of outsanding extents than we have
4074 * reserved then we need to leave the reserved extents count alone. 4077 * reserved then we need to leave the reserved extents count alone.
4075 */ 4078 */
4076 if (BTRFS_I(inode)->outstanding_extents >= 4079 if (BTRFS_I(inode)->outstanding_extents >=
4077 BTRFS_I(inode)->reserved_extents) 4080 BTRFS_I(inode)->reserved_extents)
4078 return 0; 4081 return drop_inode_space;
4079 4082
4080 dropped_extents = BTRFS_I(inode)->reserved_extents - 4083 dropped_extents = BTRFS_I(inode)->reserved_extents -
4081 BTRFS_I(inode)->outstanding_extents; 4084 BTRFS_I(inode)->outstanding_extents;
4082 BTRFS_I(inode)->reserved_extents -= dropped_extents; 4085 BTRFS_I(inode)->reserved_extents -= dropped_extents;
4083 return dropped_extents; 4086 return dropped_extents + drop_inode_space;
4084} 4087}
4085 4088
4086/** 4089/**
@@ -4166,9 +4169,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4166 nr_extents = BTRFS_I(inode)->outstanding_extents - 4169 nr_extents = BTRFS_I(inode)->outstanding_extents -
4167 BTRFS_I(inode)->reserved_extents; 4170 BTRFS_I(inode)->reserved_extents;
4168 BTRFS_I(inode)->reserved_extents += nr_extents; 4171 BTRFS_I(inode)->reserved_extents += nr_extents;
4172 }
4169 4173
4170 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); 4174 /*
4175 * Add an item to reserve for updating the inode when we complete the
4176 * delalloc io.
4177 */
4178 if (!BTRFS_I(inode)->delalloc_meta_reserved) {
4179 nr_extents++;
4180 BTRFS_I(inode)->delalloc_meta_reserved = 1;
4171 } 4181 }
4182
4183 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
4172 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); 4184 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
4173 spin_unlock(&BTRFS_I(inode)->lock); 4185 spin_unlock(&BTRFS_I(inode)->lock);
4174 4186