From patchwork Tue Sep 11 17:57:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 10596081 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 831AE14E5 for ; Tue, 11 Sep 2018 17:58:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6EEAB29B9D for ; Tue, 11 Sep 2018 17:58:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 636A129BA0; Tue, 11 Sep 2018 17:58:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E2AC429B9D for ; Tue, 11 Sep 2018 17:58:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728293AbeIKW7E (ORCPT ); Tue, 11 Sep 2018 18:59:04 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:43056 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728184AbeIKW7E (ORCPT ); Tue, 11 Sep 2018 18:59:04 -0400 Received: by mail-qt0-f196.google.com with SMTP id g53-v6so29156859qtg.10 for ; Tue, 11 Sep 2018 10:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=WZ7k1aE5b4HwVTATPYJZgOEw9YJuv/UTHtVnp/hK/QI=; b=MIUA8TP24GuZkZWZ/vef5qrBvYeq4oK6cniq8ZxrPR2Cm8Zkh8fmbS7PNnPJCp6KSr oE+Th0t+BU4C98x2KR5Uv1IsKyCGgdg8VBOWdjQD8Vw5cjQf1N8hAavBm3PpU7Y1IBi6 Zs9YM2VNHd6kDlTC2z7h7WUCLlWrjFWnkYxzO6YxfopiN85d/6mmJbSt7hMfS6yFgFSb 44sCcajYB+N3PYyikX7e9fSY9rTlWBvf24Bkijd3xGFRaaDOHS0Op/x22STfL3Jgbq7i bvZsV4sVzE8vM4+1SwGYFbVW8VfVi0LJPI0HsnbJQ9p333yCN6SyQijTgUO5zc89xuQK DClg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=WZ7k1aE5b4HwVTATPYJZgOEw9YJuv/UTHtVnp/hK/QI=; b=FeDz4fFz1Yr/QVAuaBwT5KVhotOTYvE2KF5xnDh5FYnj3IZkiAwmF9QtFSEdQRVWbZ c12Jf9K72Nq+cYVTHTrxBmudxmyh4d3sRMRosmi7g9MzE5u9vvZDn3Dzshz4A6zK+FuO rc66ScEbDxAIJoeXD8fXN94IPSNabOaDV8e0AFabK/plii1L9aKUakLR77MhVK3hYPDm oe6SYxKTxYumfjT6yk4nWgi0k0LkO2ZzKRHBcawRRyJWGlaCXrov6GwOANDtLMbUKZBH 3h/ZzBiqiOoihUEi1EsgiXPCiLlBnWsfnLROivEHB7+kjtLqYFBVUPfyNoGDHtWrfqy+ 7nNg== X-Gm-Message-State: APzg51CP7v1fxhCd3naoQ0Vitoa2X8xy7yMjImHqW+8eP3RHsyEpU0jm yc7955o3mexxjttnxJcQr1q+khX4pfA6Iw== X-Google-Smtp-Source: ANB0VdaSUU7G60Tkv5uVAXWq2OeYXOvGNwfVnuuvurcY0oZs8qNlEd2ugTFTMNaeJ8wimzzGu1ec2g== X-Received: by 2002:a0c:9aef:: with SMTP id k47-v6mr19940215qvf.134.1536688718401; Tue, 11 Sep 2018 10:58:38 -0700 (PDT) Received: from localhost ([107.15.81.208]) by smtp.gmail.com with ESMTPSA id f6-v6sm11745279qke.77.2018.09.11.10.58.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 11 Sep 2018 10:58:37 -0700 (PDT) From: Josef Bacik 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 Message-Id: <20180911175807.26181-16-josef@toxicpanda.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180911175807.26181-1-josef@toxicpanda.com> References: <20180911175807.26181-1-josef@toxicpanda.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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; }