From patchwork Wed Jan 24 18:44:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Foster X-Patchwork-Id: 10183007 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 55C1960567 for ; Wed, 24 Jan 2018 18:44:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53A1F28553 for ; Wed, 24 Jan 2018 18:44:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4877E288B3; Wed, 24 Jan 2018 18:44:30 +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.9 required=2.0 tests=BAYES_00,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 C22AF288A8 for ; Wed, 24 Jan 2018 18:44:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965101AbeAXSo2 (ORCPT ); Wed, 24 Jan 2018 13:44:28 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33716 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965099AbeAXSoU (ORCPT ); Wed, 24 Jan 2018 13:44:20 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 91A53780F2 for ; Wed, 24 Jan 2018 18:44:20 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-20.bos.redhat.com [10.18.41.20]) by smtp.corp.redhat.com (Postfix) with ESMTP id 61D7D60BE0 for ; Wed, 24 Jan 2018 18:44:20 +0000 (UTC) Received: by bfoster.bfoster (Postfix, from userid 1000) id 7612912116C; Wed, 24 Jan 2018 13:44:18 -0500 (EST) From: Brian Foster To: linux-xfs@vger.kernel.org Subject: [RFCv2 5/9] xfs: defer agfl frees from inode inactivation Date: Wed, 24 Jan 2018 13:44:14 -0500 Message-Id: <20180124184418.40403-6-bfoster@redhat.com> In-Reply-To: <20180124184418.40403-1-bfoster@redhat.com> References: <20180124184418.40403-1-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 24 Jan 2018 18:44:20 +0000 (UTC) Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP XFS inode chunks are already freed via deferred operations (which now also defer AGFL block frees), but inode btree blocks are freed directly in the associated context. This has been known to lead to log reservation overruns in particular workloads where an inobt block free may require several AGFL block frees (and thus several allocation btree modifications) before the inobt block itself is actually freed. To avoid this problem, we want to defer the frees of any AGFL blocks that must be dropped before the inobt block free can take place. This requires passing the dfops from xfs_inactive_ifree() down through the inobt ->[alloc|free]_block() callouts, which essentially only requires to attach the dfops to the transaction since it is already carried all the way through to the inobt update and allocation. Since dfops is attached to the transaction, we no longer have to pass it down explicitly through xfs_difree() and friends to defer the physical inode chunk free. Kill two stones with one bird and clean up the entire codepath to reference ->t_dfops. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_ialloc.c | 6 ++---- fs/xfs/libxfs/xfs_ialloc.h | 1 - fs/xfs/xfs_inode.c | 15 ++++++++++----- fs/xfs/xfs_inode.h | 3 +-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 3625d1da7462..52f36adceef5 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1897,7 +1897,6 @@ xfs_difree_inobt( struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agino_t agino, - struct xfs_defer_ops *dfops, struct xfs_icluster *xic, struct xfs_inobt_rec_incore *orec) { @@ -1984,7 +1983,7 @@ xfs_difree_inobt( goto error0; } - xfs_difree_inode_chunk(mp, agno, &rec, dfops); + xfs_difree_inode_chunk(mp, agno, &rec, tp->t_dfops); } else { xic->deleted = false; @@ -2129,7 +2128,6 @@ int xfs_difree( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ - struct xfs_defer_ops *dfops, /* extents to free */ struct xfs_icluster *xic) /* cluster info if deleted */ { /* REFERENCED */ @@ -2181,7 +2179,7 @@ xfs_difree( /* * Fix up the inode allocation btree. */ - error = xfs_difree_inobt(mp, tp, agbp, agino, dfops, xic, &rec); + error = xfs_difree_inobt(mp, tp, agbp, agino, xic, &rec); if (error) goto error0; diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index c5402bb4ce0c..884562efd708 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -94,7 +94,6 @@ int /* error */ xfs_difree( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ - struct xfs_defer_ops *dfops, /* extents to free */ struct xfs_icluster *ifree); /* cluster info if deleted */ /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c9e40d4fc939..4c4a2fa3ad11 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1801,8 +1801,14 @@ xfs_inactive_ifree( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); + /* + * Attach dfops to tp to defer any physical inode chunk frees and/or + * AGFL block frees that occur as a result of inobt block allocation + * operations. + */ xfs_defer_init(&dfops, &first_block); - error = xfs_ifree(tp, ip, &dfops); + tp->t_dfops = &dfops; + error = xfs_ifree(tp, ip); if (error) { /* * If we fail to free the inode, shut down. The cancel @@ -2421,9 +2427,8 @@ xfs_ifree_local_data( */ int xfs_ifree( - xfs_trans_t *tp, - xfs_inode_t *ip, - struct xfs_defer_ops *dfops) + struct xfs_trans *tp, + struct xfs_inode *ip) { int error; struct xfs_icluster xic = { 0 }; @@ -2442,7 +2447,7 @@ xfs_ifree( if (error) return error; - error = xfs_difree(tp, ip->i_ino, dfops, &xic); + error = xfs_difree(tp, ip->i_ino, &xic); if (error) return error; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 386b0bb3c92a..efd676374ac3 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -413,8 +413,7 @@ uint xfs_ilock_data_map_shared(struct xfs_inode *); uint xfs_ilock_attr_map_shared(struct xfs_inode *); uint xfs_ip2xflags(struct xfs_inode *); -int xfs_ifree(struct xfs_trans *, xfs_inode_t *, - struct xfs_defer_ops *); +int xfs_ifree(struct xfs_trans *, struct xfs_inode *); int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, int, xfs_fsize_t); void xfs_iext_realloc(xfs_inode_t *, int, int);