From patchwork Tue Feb 24 21:35:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 5875621 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3F309BF440 for ; Tue, 24 Feb 2015 21:36:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6018320253 for ; Tue, 24 Feb 2015 21:36:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C9972024F for ; Tue, 24 Feb 2015 21:36:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752552AbbBXVgI (ORCPT ); Tue, 24 Feb 2015 16:36:08 -0500 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:21802 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751721AbbBXVgH (ORCPT ); Tue, 24 Feb 2015 16:36:07 -0500 Received: from pps.filterd (m0044012 [127.0.0.1]) by mx0a-00082601.pphosted.com (8.14.5/8.14.5) with SMTP id t1OLVulS000777 for ; Tue, 24 Feb 2015 13:36:05 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=from : to : subject : date : message-id : mime-version : content-type; s=facebook; bh=wflQC9BrD7Kd51uwFb8xeeQ3Jz300/WJKJ3D1xbZWyc=; b=b9kdCzgZBIQ+37QRyK4k/okx/VaoTeGbPccn/TvGZCMh2Xk5TC8W1V+MzPCRwqTsnQg9 bA/iWWOwNferIDYbYk/oBuu9kkpzMOS4M8Daz5WmWmfbLz111vfOyJpv98oUItdfw9yz HekoDd90N10icIpJmEqR8HSNhnS4nWKuHXo= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 1sry8ar8yt-5 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT) for ; Tue, 24 Feb 2015 13:36:05 -0800 Received: from localhost (192.168.57.29) by mail.thefacebook.com (192.168.16.15) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 24 Feb 2015 13:35:42 -0800 From: Josef Bacik To: Subject: [PATCH] Btrfs: check before stealing from the global rsv in evict Date: Tue, 24 Feb 2015 16:35:41 -0500 Message-ID: <1424813741-26172-1-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 1.8.3.1 MIME-Version: 1.0 X-Originating-IP: [192.168.57.29] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68, 1.0.33, 0.0.0000 definitions=2015-02-24_06:2015-02-24, 2015-02-24, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=4.93938223655732e-13 kscore.compositescore=0 circleOfTrustscore=0 compositescore=0.996183534634169 suspectscore=3 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 rbsscore=0.996183534634169 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=0 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.996183534634169 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1502240187 X-FB-Internal: deliver Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Even with all of the current fixes we still had one gluster box abort() with enospc when removing files. This is because evict() will steal from the global reserve unconditionally if it cannot make its reservation. This isn't ideal when we've built up a lot of backlock in delayed refs, so we can race with this migration and the checks to see if we need to commit the transaction. So instead note that we need to steal from the global reserve and then check if we have enough space in the global reserve to handle the outstanding work we have queued up. If not we commit the transaction and try again. If we fail to get space again and commit the transaction again we'll break out and let it cleanup after a remount. Thanks, Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e6d82bd..6938b83 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4892,6 +4892,7 @@ void btrfs_evict_inode(struct inode *inode) struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_block_rsv *rsv, *global_rsv; + int steal_from_global = 0; u64 min_size = btrfs_calc_trunc_metadata_size(root, 1); int ret; @@ -4959,9 +4960,20 @@ void btrfs_evict_inode(struct inode *inode) * hard as possible to get this to work. */ if (ret) - ret = btrfs_block_rsv_migrate(global_rsv, rsv, min_size); + steal_from_global++; + else + steal_from_global = 0; + ret = 0; - if (ret) { + /* + * steal_from_global == 0: we reserved stuff, hooray! + * steal_from_global == 1: we didn't reserve stuff, boo! + * steal_from_global == 2: we've committed, still not a lot of + * room but maybe we'll have room in the global reserve this + * time. + * steal_from_global == 3: abandon all hope! + */ + if (steal_from_global > 2) { btrfs_warn(root->fs_info, "Could not get space for a delete, will truncate on mount %d", ret); @@ -4977,6 +4989,36 @@ void btrfs_evict_inode(struct inode *inode) goto no_delete; } + /* + * We can't just steal from the global reserve, we need tomake + * sure there is room to do it, if not we need to commit and try + * again. + */ + if (steal_from_global) { + if (!btrfs_check_space_for_delayed_refs(trans, root)) + ret = btrfs_block_rsv_migrate(global_rsv, rsv, + min_size); + else + ret = -ENOSPC; + } + + /* + * Couldn't steal from the global reserve, we have too much + * pending stuff built up, commit the transaction and try it + * again. + */ + if (ret) { + ret = btrfs_commit_transaction(trans, root); + if (ret) { + btrfs_orphan_del(NULL, inode); + btrfs_free_block_rsv(root, rsv); + goto no_delete; + } + continue; + } else { + steal_from_global = 0; + } + trans->block_rsv = rsv; ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0);