From: Josef Bacik <josef@toxicpanda.com>
To: kernel-team@fb.com, linux-btrfs@vger.kernel.org
Subject: [PATCH 15/36] btrfs: don't enospc all tickets on flush failure
Date: Tue, 11 Sep 2018 13:57:46 -0400 [thread overview]
Message-ID: <20180911175807.26181-16-josef@toxicpanda.com> (raw)
In-Reply-To: <20180911175807.26181-1-josef@toxicpanda.com>
With the introduction of the per-inode block_rsv it became possible to
have really really large reservation requests made because of data
fragmentation. Since the ticket stuff assumed that we'd always have
relatively small reservation requests it just killed all tickets if we
were unable to satisfy the current request. However this is generally
not the case anymore. So fix this logic to instead see if we had a
ticket that we were able to give some reservation to, and if we were
continue the flushing loop again. Likewise we make the tickets use the
space_info_add_old_bytes() method of returning what reservation they did
receive in hopes that it could satisfy reservations down the line.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/extent-tree.c | 45 +++++++++++++++++++++++++--------------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 44d59bee6e5e..76941fc5af79 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4779,6 +4779,7 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim,
}
struct reserve_ticket {
+ u64 orig_bytes;
u64 bytes;
int error;
struct list_head list;
@@ -5000,7 +5001,7 @@ static inline int need_do_async_reclaim(struct btrfs_fs_info *fs_info,
!test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state));
}
-static void wake_all_tickets(struct list_head *head)
+static bool wake_all_tickets(struct list_head *head)
{
struct reserve_ticket *ticket;
@@ -5009,7 +5010,10 @@ static void wake_all_tickets(struct list_head *head)
list_del_init(&ticket->list);
ticket->error = -ENOSPC;
wake_up(&ticket->wait);
+ if (ticket->bytes != ticket->orig_bytes)
+ return true;
}
+ return false;
}
/*
@@ -5077,8 +5081,12 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
if (flush_state > COMMIT_TRANS) {
commit_cycles++;
if (commit_cycles > 2) {
- wake_all_tickets(&space_info->tickets);
- space_info->flush = 0;
+ if (wake_all_tickets(&space_info->tickets)) {
+ flush_state = FLUSH_DELAYED_ITEMS_NR;
+ commit_cycles--;
+ } else {
+ space_info->flush = 0;
+ }
} else {
flush_state = FLUSH_DELAYED_ITEMS_NR;
}
@@ -5130,10 +5138,11 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info,
static int wait_reserve_ticket(struct btrfs_fs_info *fs_info,
struct btrfs_space_info *space_info,
- struct reserve_ticket *ticket, u64 orig_bytes)
+ struct reserve_ticket *ticket)
{
DEFINE_WAIT(wait);
+ u64 reclaim_bytes = 0;
int ret = 0;
spin_lock(&space_info->lock);
@@ -5154,14 +5163,12 @@ static int wait_reserve_ticket(struct btrfs_fs_info *fs_info,
ret = ticket->error;
if (!list_empty(&ticket->list))
list_del_init(&ticket->list);
- if (ticket->bytes && ticket->bytes < orig_bytes) {
- u64 num_bytes = orig_bytes - ticket->bytes;
- space_info->bytes_may_use -= num_bytes;
- trace_btrfs_space_reservation(fs_info, "space_info",
- space_info->flags, num_bytes, 0);
- }
+ if (ticket->bytes && ticket->bytes < ticket->orig_bytes)
+ reclaim_bytes = ticket->orig_bytes - ticket->bytes;
spin_unlock(&space_info->lock);
+ if (reclaim_bytes)
+ space_info_add_old_bytes(fs_info, space_info, reclaim_bytes);
return ret;
}
@@ -5187,6 +5194,7 @@ static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info,
{
struct reserve_ticket ticket;
u64 used;
+ u64 reclaim_bytes = 0;
int ret = 0;
ASSERT(orig_bytes);
@@ -5222,6 +5230,7 @@ static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info,
* the list and we will do our own flushing further down.
*/
if (ret && flush != BTRFS_RESERVE_NO_FLUSH) {
+ ticket.orig_bytes = orig_bytes;
ticket.bytes = orig_bytes;
ticket.error = 0;
init_waitqueue_head(&ticket.wait);
@@ -5262,25 +5271,21 @@ static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info,
return ret;
if (flush == BTRFS_RESERVE_FLUSH_ALL)
- return wait_reserve_ticket(fs_info, space_info, &ticket,
- orig_bytes);
+ return wait_reserve_ticket(fs_info, space_info, &ticket);
ret = 0;
priority_reclaim_metadata_space(fs_info, space_info, &ticket);
spin_lock(&space_info->lock);
if (ticket.bytes) {
- if (ticket.bytes < orig_bytes) {
- u64 num_bytes = orig_bytes - ticket.bytes;
- space_info->bytes_may_use -= num_bytes;
- trace_btrfs_space_reservation(fs_info, "space_info",
- space_info->flags,
- num_bytes, 0);
-
- }
+ if (ticket.bytes < orig_bytes)
+ reclaim_bytes = orig_bytes - ticket.bytes;
list_del_init(&ticket.list);
ret = -ENOSPC;
}
spin_unlock(&space_info->lock);
+
+ if (reclaim_bytes)
+ space_info_add_old_bytes(fs_info, space_info, reclaim_bytes);
ASSERT(list_empty(&ticket.list));
return ret;
}
--
2.14.3
next prev parent reply other threads:[~2018-09-11 22:59 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-11 17:57 [PATCH 00/35][v2] My current patch queue Josef Bacik
2018-09-11 17:57 ` [PATCH 01/36] btrfs: add btrfs_delete_ref_head helper Josef Bacik
2018-09-11 22:52 ` Omar Sandoval
2018-09-11 17:57 ` [PATCH 02/36] btrfs: add cleanup_ref_head_accounting helper Josef Bacik
2018-09-11 17:57 ` [PATCH 03/36] btrfs: cleanup extent_op handling Josef Bacik
2018-09-11 23:24 ` Omar Sandoval
2018-09-11 17:57 ` [PATCH 04/36] btrfs: only track ref_heads in delayed_ref_updates Josef Bacik
2018-09-11 17:57 ` [PATCH 05/36] btrfs: only count ref heads run in __btrfs_run_delayed_refs Josef Bacik
2018-09-11 23:07 ` Omar Sandoval
2018-09-12 17:46 ` David Sterba
2018-09-11 17:57 ` [PATCH 06/36] btrfs: introduce delayed_refs_rsv Josef Bacik
2018-09-11 17:57 ` [PATCH 07/36] btrfs: check if free bgs for commit Josef Bacik
2018-09-11 23:09 ` Omar Sandoval
2018-09-11 17:57 ` [PATCH 08/36] btrfs: dump block_rsv whe dumping space info Josef Bacik
2018-09-11 23:11 ` Omar Sandoval
2018-09-12 17:24 ` David Sterba
2018-09-11 17:57 ` [PATCH 09/36] btrfs: release metadata before running delayed refs Josef Bacik
2018-09-11 17:57 ` [PATCH 10/36] btrfs: protect space cache inode alloc with nofs Josef Bacik
2018-09-11 17:57 ` [PATCH 11/36] btrfs: fix truncate throttling Josef Bacik
2018-09-11 17:57 ` [PATCH 12/36] btrfs: don't use global rsv for chunk allocation Josef Bacik
2018-09-11 17:57 ` [PATCH 13/36] btrfs: add ALLOC_CHUNK_FORCE to the flushing code Josef Bacik
2018-09-11 17:57 ` [PATCH 14/36] btrfs: reset max_extent_size properly Josef Bacik
2018-09-18 23:54 ` Omar Sandoval
2018-09-11 17:57 ` Josef Bacik [this message]
2018-09-11 17:57 ` [PATCH 16/36] btrfs: run delayed iputs before committing Josef Bacik
2018-09-18 23:59 ` Omar Sandoval
2018-09-11 17:57 ` [PATCH 17/36] btrfs: loop in inode_rsv_refill Josef Bacik
2018-09-19 0:17 ` Omar Sandoval
2018-09-11 17:57 ` [PATCH 18/36] btrfs: move the dio_sem higher up the callchain Josef Bacik
2018-09-11 17:57 ` [PATCH 19/36] btrfs: set max_extent_size properly Josef Bacik
2018-09-11 17:57 ` [PATCH 20/36] btrfs: don't use ctl->free_space for max_extent_size Josef Bacik
2018-09-11 17:57 ` [PATCH 21/36] btrfs: reset max_extent_size on clear in a bitmap Josef Bacik
2018-09-11 17:57 ` [PATCH 22/36] btrfs: only run delayed refs if we're committing Josef Bacik
2018-09-11 17:57 ` [PATCH 23/36] btrfs: make sure we create all new bgs Josef Bacik
2018-09-11 17:57 ` [PATCH 24/36] btrfs: assert on non-empty delayed iputs Josef Bacik
2018-09-11 17:57 ` [PATCH 25/36] btrfs: pass delayed_refs_root to btrfs_delayed_ref_lock Josef Bacik
2018-09-11 17:57 ` [PATCH 26/36] btrfs: make btrfs_destroy_delayed_refs use btrfs_delayed_ref_lock Josef Bacik
2018-09-11 17:57 ` [PATCH 27/36] btrfs: make btrfs_destroy_delayed_refs use btrfs_delete_ref_head Josef Bacik
2018-09-11 17:57 ` [PATCH 28/36] btrfs: handle delayed ref head accounting cleanup in abort Josef Bacik
2018-09-11 17:58 ` [PATCH 29/36] btrfs: call btrfs_create_pending_block_groups unconditionally Josef Bacik
2018-09-11 17:58 ` [PATCH 30/36] btrfs: just delete pending bgs if we are aborted Josef Bacik
2018-09-11 17:58 ` [PATCH 31/36] btrfs: cleanup pending bgs on transaction abort Josef Bacik
2018-09-11 17:58 ` [PATCH 32/36] btrfs: clear delayed_refs_rsv for dirty bg cleanup Josef Bacik
2018-09-19 0:21 ` Omar Sandoval
2018-09-11 17:58 ` [PATCH 33/36] btrfs: only free reserved extent if we didn't insert it Josef Bacik
2018-09-19 0:20 ` Omar Sandoval
2018-09-11 17:58 ` [PATCH 34/36] btrfs: fix insert_reserved error handling Josef Bacik
2018-09-11 17:58 ` [PATCH 35/36] btrfs: wait on ordered extents on abort cleanup Josef Bacik
2018-09-11 17:58 ` [PATCH 36/36] MAINTAINERS: update my email address for btrfs Josef Bacik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180911175807.26181-16-josef@toxicpanda.com \
--to=josef@toxicpanda.com \
--cc=kernel-team@fb.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).