On Fri, Feb 21, 2020 at 04:41:10PM -0500, Josef Bacik wrote: > I noticed while running my snapshot torture test that we were getting a > lot of metadata chunks allocated with very little actually used. > Digging into this we would commit the transaction, still not have enough > space, and then force a chunk allocation. > > I noticed that we were barely flushing any delalloc at all, despite the > fact that we had around 13gib of outstanding delalloc reservations. It > turns out this is because of our btrfs_calc_reclaim_metadata_size() > calculation. It _only_ takes into account the outstanding ticket sizes, > which isn't the whole story. In this particular workload we're slowly > filling up the disk, which means our overcommit space will suddenly > become a lot less, and our outstanding reservations will be well more > than what we can handle. However we are only flushing based on our > ticket size, which is much less than we need to actually reclaim. > > So fix btrfs_calc_reclaim_metadata_size() to take into account the > overage in the case that we've gotten less available space suddenly. > This makes it so we attempt to reclaim a lot more delalloc space, which > allows us to make our reservations and we no longer are allocating a > bunch of needless metadata chunks. > > Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx> Added to misc-next, thanks. > --- > fs/btrfs/space-info.c | 44 ++++++++++++++++++++++++++++++++++--------- > 1 file changed, 35 insertions(+), 9 deletions(-) > > diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c > index f216ab72f5fc..26e1c492b9b5 100644 > --- a/fs/btrfs/space-info.c > +++ b/fs/btrfs/space-info.c > @@ -306,25 +306,20 @@ static inline u64 calc_global_rsv_need_space(struct btrfs_block_rsv *global) > return (global->size << 1); > } > > -int btrfs_can_overcommit(struct btrfs_fs_info *fs_info, > - struct btrfs_space_info *space_info, u64 bytes, > - enum btrfs_reserve_flush_enum flush) > +static inline u64 > +calc_available_free_space(struct btrfs_fs_info *fs_info, > + struct btrfs_space_info *space_info, > + enum btrfs_reserve_flush_enum flush) It does not seem to be a candidate for 'static inline', it's not in a header and the function body is beyond what looks suitable for inlining.
