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.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 18ea90c8943b..0b044e509e9f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4063,23 +4063,30 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
4063 */ 4063 */
4064static unsigned drop_outstanding_extent(struct inode *inode) 4064static unsigned drop_outstanding_extent(struct inode *inode)
4065{ 4065{
4066 unsigned drop_inode_space = 0;
4066 unsigned dropped_extents = 0; 4067 unsigned dropped_extents = 0;
4067 4068
4068 BUG_ON(!BTRFS_I(inode)->outstanding_extents); 4069 BUG_ON(!BTRFS_I(inode)->outstanding_extents);
4069 BTRFS_I(inode)->outstanding_extents--; 4070 BTRFS_I(inode)->outstanding_extents--;
4070 4071
4072 if (BTRFS_I(inode)->outstanding_extents == 0 &&
4073 BTRFS_I(inode)->delalloc_meta_reserved) {
4074 drop_inode_space = 1;
4075 BTRFS_I(inode)->delalloc_meta_reserved = 0;
4076 }
4077
4071 /* 4078 /*
4072 * If we have more or the same amount of outsanding extents than we have 4079 * If we have more or the same amount of outsanding extents than we have
4073 * reserved then we need to leave the reserved extents count alone. 4080 * reserved then we need to leave the reserved extents count alone.
4074 */ 4081 */
4075 if (BTRFS_I(inode)->outstanding_extents >= 4082 if (BTRFS_I(inode)->outstanding_extents >=
4076 BTRFS_I(inode)->reserved_extents) 4083 BTRFS_I(inode)->reserved_extents)
4077 return 0; 4084 return drop_inode_space;
4078 4085
4079 dropped_extents = BTRFS_I(inode)->reserved_extents - 4086 dropped_extents = BTRFS_I(inode)->reserved_extents -
4080 BTRFS_I(inode)->outstanding_extents; 4087 BTRFS_I(inode)->outstanding_extents;
4081 BTRFS_I(inode)->reserved_extents -= dropped_extents; 4088 BTRFS_I(inode)->reserved_extents -= dropped_extents;
4082 return dropped_extents; 4089 return dropped_extents + drop_inode_space;
4083} 4090}
4084 4091
4085/** 4092/**
@@ -4165,9 +4172,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4165 nr_extents = BTRFS_I(inode)->outstanding_extents - 4172 nr_extents = BTRFS_I(inode)->outstanding_extents -
4166 BTRFS_I(inode)->reserved_extents; 4173 BTRFS_I(inode)->reserved_extents;
4167 BTRFS_I(inode)->reserved_extents += nr_extents; 4174 BTRFS_I(inode)->reserved_extents += nr_extents;
4175 }
4168 4176
4169 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); 4177 /*
4178 * Add an item to reserve for updating the inode when we complete the
4179 * delalloc io.
4180 */
4181 if (!BTRFS_I(inode)->delalloc_meta_reserved) {
4182 nr_extents++;
4183 BTRFS_I(inode)->delalloc_meta_reserved = 1;
4170 } 4184 }
4185
4186 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
4171 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); 4187 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
4172 spin_unlock(&BTRFS_I(inode)->lock); 4188 spin_unlock(&BTRFS_I(inode)->lock);
4173 4189