From patchwork Fri Nov 10 15:13:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 10053319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0606760365 for ; Fri, 10 Nov 2017 15:13:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E2DB12B32B for ; Fri, 10 Nov 2017 15:13:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D659A2B32D; Fri, 10 Nov 2017 15:13:46 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 61E4D2B32B for ; Fri, 10 Nov 2017 15:13:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752592AbdKJPNo (ORCPT ); Fri, 10 Nov 2017 10:13:44 -0500 Received: from mail-qt0-f193.google.com ([209.85.216.193]:48455 "EHLO mail-qt0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751455AbdKJPNm (ORCPT ); Fri, 10 Nov 2017 10:13:42 -0500 Received: by mail-qt0-f193.google.com with SMTP id f8so12172386qta.5 for ; Fri, 10 Nov 2017 07:13:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=aeDELx8ptJzeD/MTkkkEuqyZ6APtqmL5uMJGxkSwAH0=; b=LpgUfG1mfqt6jZYY6CuSnqGZDNS2XEDC3Gnt40hZOFxteo+1FGwzDxMA9AgNICFpn/ uEZHw9yPDUvLJb6oVBWWhEqI96+BDHuioRnodcwJh2PKGi0Fime9/KIkWscG9KUL29+N 43r/99beCEC/N1VNBEbsUd5FygdGt8MH6hn1rQl5OwMM85C4fo0iz881BUBoxk+wQgsC bpWHJ0IaLMVoA100KCpjB6cuFz9MOFy3jbCJZSgO+VPbovuhmfrCbtTcUiaTDwQJ9Jvt IsoPceKsor7M/I//T5CpEg/KrKte6dLez6Ko19lBaoFHLzEafQeuni33HdKl+yHiMo11 dWjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=aeDELx8ptJzeD/MTkkkEuqyZ6APtqmL5uMJGxkSwAH0=; b=dtUHvI36uExI8oeI+TIVcrUJTBRovv8NFPyebYSseOTb0t2n7ViL41eR4fg+7ilcCa bnvB3UlFjmuwQ4uRSKNRfCPj1+R2XaO2JTOCLKcScEHaVFxTZz0CCcGyA14qpesN4pUi b9l1QWwlxbX1Itsy3EmJ6E82HQ2fGh5/EnNZxFzXbeRjWrVEK9d9lSBl3n7GIh2mNRs+ yBBLBaavGRjKpng5ZIxf2TboR8RrYyaOD89Nq3rt8z4IaQ8vw9MJ84cEfCkfkV5pDbYW sYacmiAZ1pvoSpvyWqIvpXQ/Y5he+KxS8D7HmGgJ2YyOy8cz1n0lp+kiGCqLEY2FIyVQ OneA== X-Gm-Message-State: AJaThX41XVKURkmf6ARSytvuaYFci/Yoyt/Gp/66dr1EhCy0co8Gn1WD MR8y3iT47rDJN+Lz49sNZgRd4W6h X-Google-Smtp-Source: AGs4zMYFPlEp9+aS2UFrsUh5hCs+70neNdsDGU5URcnFrGrZWhlxbxvnOK6fZFt5ONM3W2ssDuX2HA== X-Received: by 10.200.23.23 with SMTP id w23mr1072834qtj.32.1510326822027; Fri, 10 Nov 2017 07:13:42 -0800 (PST) Received: from localhost (cpe-2606-A000-4381-1201-225-22FF-FEB3-E51A.dyn6.twc.com. [2606:a000:4381:1201:225:22ff:feb3:e51a]) by smtp.gmail.com with ESMTPSA id j19sm6524908qtk.87.2017.11.10.07.13.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Nov 2017 07:13:41 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Cc: Josef Bacik Subject: [PATCH][v2] btrfs: don't bug_on with enomem in __clear_state_bit Date: Fri, 10 Nov 2017 10:13:40 -0500 Message-Id: <1510326820-17865-1-git-send-email-josef@toxicpanda.com> X-Mailer: git-send-email 2.7.5 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 From: Josef Bacik Since we're allocating under atomic we could every easily enomem, so if that's the case and we can block then loop around and try to allocate the prealloc not under a lock. We also saw this happen during try_to_release_page in production, in which case it's completely valid to return ENOMEM so we can tell try_to_release_page that we can't release this page. Signed-off-by: Josef Bacik --- v1->v2: - this time with my local changes committed! fs/btrfs/extent_io.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index dd941885b9c3..fb0c1636c1c4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -590,8 +590,9 @@ static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state *prealloc = NULL; struct rb_node *node; u64 last_end; - int err; + int err = 0; int clear = 0; + bool need_prealloc = false; btrfs_debug_check_extent_io_range(tree, start, end); @@ -614,6 +615,9 @@ static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, * If we end up needing a new extent state we allocate it later. */ prealloc = alloc_extent_state(mask); + if (!prealloc && need_prealloc) + return -ENOMEM; + need_prealloc = false; } spin_lock(&tree->lock); @@ -673,7 +677,15 @@ static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, if (state->start < start) { prealloc = alloc_extent_state_atomic(prealloc); - BUG_ON(!prealloc); + if (!prealloc) { + if (gfpflags_allow_blocking(mask)) { + need_prealloc = true; + spin_unlock(&tree->lock); + goto again; + } + err = -ENOMEM; + goto out; + } err = split_state(tree, state, prealloc, start); if (err) extent_io_tree_panic(tree, err); @@ -696,7 +708,15 @@ static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, */ if (state->start <= end && state->end > end) { prealloc = alloc_extent_state_atomic(prealloc); - BUG_ON(!prealloc); + if (!prealloc) { + if (gfpflags_allow_blocking(mask)) { + need_prealloc = true; + spin_unlock(&tree->lock); + goto again; + } + err = -ENOMEM; + goto out; + } err = split_state(tree, state, prealloc, end + 1); if (err) extent_io_tree_panic(tree, err); @@ -731,7 +751,7 @@ static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, if (prealloc) free_extent_state(prealloc); - return 0; + return err; }