aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/btrfs_inode.h6
-rw-r--r--fs/btrfs/extent-tree.c117
-rw-r--r--fs/btrfs/inode.c3
3 files changed, 118 insertions, 8 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index c70fb10a307b..5a5d325a3935 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -123,6 +123,12 @@ struct btrfs_inode {
123 */ 123 */
124 u64 last_unlink_trans; 124 u64 last_unlink_trans;
125 125
126 /*
127 * Number of bytes outstanding that are going to need csums. This is
128 * used in ENOSPC accounting.
129 */
130 u64 csum_bytes;
131
126 /* flags field from the on disk inode */ 132 /* flags field from the on disk inode */
127 u32 flags; 133 u32 flags;
128 134
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fbe6278f466b..4add1ac2dda0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3984,11 +3984,19 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
3984 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); 3984 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
3985} 3985}
3986 3986
3987/**
3988 * drop_outstanding_extent - drop an outstanding extent
3989 * @inode: the inode we're dropping the extent for
3990 *
3991 * This is called when we are freeing up an outstanding extent, either called
3992 * after an error or after an extent is written. This will return the number of
3993 * reserved extents that need to be freed. This must be called with
3994 * BTRFS_I(inode)->lock held.
3995 */
3987static unsigned drop_outstanding_extent(struct inode *inode) 3996static unsigned drop_outstanding_extent(struct inode *inode)
3988{ 3997{
3989 unsigned dropped_extents = 0; 3998 unsigned dropped_extents = 0;
3990 3999
3991 spin_lock(&BTRFS_I(inode)->lock);
3992 BUG_ON(!BTRFS_I(inode)->outstanding_extents); 4000 BUG_ON(!BTRFS_I(inode)->outstanding_extents);
3993 BTRFS_I(inode)->outstanding_extents--; 4001 BTRFS_I(inode)->outstanding_extents--;
3994 4002
@@ -3998,19 +4006,70 @@ static unsigned drop_outstanding_extent(struct inode *inode)
3998 */ 4006 */
3999 if (BTRFS_I(inode)->outstanding_extents >= 4007 if (BTRFS_I(inode)->outstanding_extents >=
4000 BTRFS_I(inode)->reserved_extents) 4008 BTRFS_I(inode)->reserved_extents)
4001 goto out; 4009 return 0;
4002 4010
4003 dropped_extents = BTRFS_I(inode)->reserved_extents - 4011 dropped_extents = BTRFS_I(inode)->reserved_extents -
4004 BTRFS_I(inode)->outstanding_extents; 4012 BTRFS_I(inode)->outstanding_extents;
4005 BTRFS_I(inode)->reserved_extents -= dropped_extents; 4013 BTRFS_I(inode)->reserved_extents -= dropped_extents;
4006out:
4007 spin_unlock(&BTRFS_I(inode)->lock);
4008 return dropped_extents; 4014 return dropped_extents;
4009} 4015}
4010 4016
4011static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes) 4017/**
4018 * calc_csum_metadata_size - return the amount of metada space that must be
4019 * reserved/free'd for the given bytes.
4020 * @inode: the inode we're manipulating
4021 * @num_bytes: the number of bytes in question
4022 * @reserve: 1 if we are reserving space, 0 if we are freeing space
4023 *
4024 * This adjusts the number of csum_bytes in the inode and then returns the
4025 * correct amount of metadata that must either be reserved or freed. We
4026 * calculate how many checksums we can fit into one leaf and then divide the
4027 * number of bytes that will need to be checksumed by this value to figure out
4028 * how many checksums will be required. If we are adding bytes then the number
4029 * may go up and we will return the number of additional bytes that must be
4030 * reserved. If it is going down we will return the number of bytes that must
4031 * be freed.
4032 *
4033 * This must be called with BTRFS_I(inode)->lock held.
4034 */
4035static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes,
4036 int reserve)
4012{ 4037{
4013 return num_bytes >>= 3; 4038 struct btrfs_root *root = BTRFS_I(inode)->root;
4039 u64 csum_size;
4040 int num_csums_per_leaf;
4041 int num_csums;
4042 int old_csums;
4043
4044 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM &&
4045 BTRFS_I(inode)->csum_bytes == 0)
4046 return 0;
4047
4048 old_csums = (int)div64_u64(BTRFS_I(inode)->csum_bytes, root->sectorsize);
4049 if (reserve)
4050 BTRFS_I(inode)->csum_bytes += num_bytes;
4051 else
4052 BTRFS_I(inode)->csum_bytes -= num_bytes;
4053 csum_size = BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item);
4054 num_csums_per_leaf = (int)div64_u64(csum_size,
4055 sizeof(struct btrfs_csum_item) +
4056 sizeof(struct btrfs_disk_key));
4057 num_csums = (int)div64_u64(BTRFS_I(inode)->csum_bytes, root->sectorsize);
4058 num_csums = num_csums + num_csums_per_leaf - 1;
4059 num_csums = num_csums / num_csums_per_leaf;
4060
4061 old_csums = old_csums + num_csums_per_leaf - 1;
4062 old_csums = old_csums / num_csums_per_leaf;
4063
4064 /* No change, no need to reserve more */
4065 if (old_csums == num_csums)
4066 return 0;
4067
4068 if (reserve)
4069 return btrfs_calc_trans_metadata_size(root,
4070 num_csums - old_csums);
4071
4072 return btrfs_calc_trans_metadata_size(root, old_csums - num_csums);
4014} 4073}
4015 4074
4016int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) 4075int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
@@ -4037,9 +4096,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4037 4096
4038 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); 4097 to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
4039 } 4098 }
4099 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
4040 spin_unlock(&BTRFS_I(inode)->lock); 4100 spin_unlock(&BTRFS_I(inode)->lock);
4041 4101
4042 to_reserve += calc_csum_metadata_size(inode, num_bytes);
4043 ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); 4102 ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1);
4044 if (ret) { 4103 if (ret) {
4045 unsigned dropped; 4104 unsigned dropped;
@@ -4047,8 +4106,11 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4047 * We don't need the return value since our reservation failed, 4106 * We don't need the return value since our reservation failed,
4048 * we just need to clean up our counter. 4107 * we just need to clean up our counter.
4049 */ 4108 */
4109 spin_lock(&BTRFS_I(inode)->lock);
4050 dropped = drop_outstanding_extent(inode); 4110 dropped = drop_outstanding_extent(inode);
4051 WARN_ON(dropped > 1); 4111 WARN_ON(dropped > 1);
4112 BTRFS_I(inode)->csum_bytes -= num_bytes;
4113 spin_unlock(&BTRFS_I(inode)->lock);
4052 return ret; 4114 return ret;
4053 } 4115 }
4054 4116
@@ -4057,6 +4119,15 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4057 return 0; 4119 return 0;
4058} 4120}
4059 4121
4122/**
4123 * btrfs_delalloc_release_metadata - release a metadata reservation for an inode
4124 * @inode: the inode to release the reservation for
4125 * @num_bytes: the number of bytes we're releasing
4126 *
4127 * This will release the metadata reservation for an inode. This can be called
4128 * once we complete IO for a given set of bytes to release their metadata
4129 * reservations.
4130 */
4060void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) 4131void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
4061{ 4132{
4062 struct btrfs_root *root = BTRFS_I(inode)->root; 4133 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -4064,9 +4135,11 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
4064 unsigned dropped; 4135 unsigned dropped;
4065 4136
4066 num_bytes = ALIGN(num_bytes, root->sectorsize); 4137 num_bytes = ALIGN(num_bytes, root->sectorsize);
4138 spin_lock(&BTRFS_I(inode)->lock);
4067 dropped = drop_outstanding_extent(inode); 4139 dropped = drop_outstanding_extent(inode);
4068 4140
4069 to_free = calc_csum_metadata_size(inode, num_bytes); 4141 to_free = calc_csum_metadata_size(inode, num_bytes, 0);
4142 spin_unlock(&BTRFS_I(inode)->lock);
4070 if (dropped > 0) 4143 if (dropped > 0)
4071 to_free += btrfs_calc_trans_metadata_size(root, dropped); 4144 to_free += btrfs_calc_trans_metadata_size(root, dropped);
4072 4145
@@ -4074,6 +4147,21 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
4074 to_free); 4147 to_free);
4075} 4148}
4076 4149
4150/**
4151 * btrfs_delalloc_reserve_space - reserve data and metadata space for delalloc
4152 * @inode: inode we're writing to
4153 * @num_bytes: the number of bytes we want to allocate
4154 *
4155 * This will do the following things
4156 *
4157 * o reserve space in the data space info for num_bytes
4158 * o reserve space in the metadata space info based on number of outstanding
4159 * extents and how much csums will be needed
4160 * o add to the inodes ->delalloc_bytes
4161 * o add it to the fs_info's delalloc inodes list.
4162 *
4163 * This will return 0 for success and -ENOSPC if there is no space left.
4164 */
4077int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes) 4165int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes)
4078{ 4166{
4079 int ret; 4167 int ret;
@@ -4091,6 +4179,19 @@ int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes)
4091 return 0; 4179 return 0;
4092} 4180}
4093 4181
4182/**
4183 * btrfs_delalloc_release_space - release data and metadata space for delalloc
4184 * @inode: inode we're releasing space for
4185 * @num_bytes: the number of bytes we want to free up
4186 *
4187 * This must be matched with a call to btrfs_delalloc_reserve_space. This is
4188 * called in the case that we don't need the metadata AND data reservations
4189 * anymore. So if there is an error or we insert an inline extent.
4190 *
4191 * This function will release the metadata space that was not used and will
4192 * decrement ->delalloc_bytes and remove it from the fs_info delalloc_inodes
4193 * list if there are no delalloc bytes left.
4194 */
4094void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes) 4195void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes)
4095{ 4196{
4096 btrfs_delalloc_release_metadata(inode, num_bytes); 4197 btrfs_delalloc_release_metadata(inode, num_bytes);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 156c3a0da792..98b9fa2d77f7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6757,6 +6757,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
6757 ei->delalloc_bytes = 0; 6757 ei->delalloc_bytes = 0;
6758 ei->disk_i_size = 0; 6758 ei->disk_i_size = 0;
6759 ei->flags = 0; 6759 ei->flags = 0;
6760 ei->csum_bytes = 0;
6760 ei->index_cnt = (u64)-1; 6761 ei->index_cnt = (u64)-1;
6761 ei->last_unlink_trans = 0; 6762 ei->last_unlink_trans = 0;
6762 6763
@@ -6802,6 +6803,8 @@ void btrfs_destroy_inode(struct inode *inode)
6802 WARN_ON(inode->i_data.nrpages); 6803 WARN_ON(inode->i_data.nrpages);
6803 WARN_ON(BTRFS_I(inode)->outstanding_extents); 6804 WARN_ON(BTRFS_I(inode)->outstanding_extents);
6804 WARN_ON(BTRFS_I(inode)->reserved_extents); 6805 WARN_ON(BTRFS_I(inode)->reserved_extents);
6806 WARN_ON(BTRFS_I(inode)->delalloc_bytes);
6807 WARN_ON(BTRFS_I(inode)->csum_bytes);
6805 6808
6806 /* 6809 /*
6807 * This can happen where we create an inode, but somebody else also 6810 * This can happen where we create an inode, but somebody else also