From patchwork Wed Jan 18 22:44:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107119 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15BBFC38159 for ; Wed, 18 Jan 2023 22:45:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229871AbjARWpT (ORCPT ); Wed, 18 Jan 2023 17:45:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229603AbjARWpP (ORCPT ); Wed, 18 Jan 2023 17:45:15 -0500 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BD0860499 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id jl3so556128plb.8 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=15e2UAXWr7DjHXYNVfG1pIY5WBwP+AvEXcPNz5p9Ow0=; b=avqMkrS3V2WWjLtFt0FN1ORGTdaQ4/9349AypXLxB8hNgImQkqPZqtcpTyszBHec9m h/ItLginCiMQxMh3rX6/7rlTOsrspMLJyM1j37V+g/dkU5JmKv5wm4I5+uKTQ9hRuSGb gIFVqzRj0bSFH4VHNbvhY08dpoMnV+BhT24336bIZoyFQYt8BtaqHSpFfx8lZr252ixe EYHotMimDmaUelK20yYxxa6slMA4vLy0iG0XiCgeQ0bVjapv2jsmLhltavikE2s8ZVZV PBP+yQnofCZ9ntDDpprM7LdNeMQmInRan0jFYVNW6EvQQdiY3eT4dxyxsMKJX52pHivb 7bbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=15e2UAXWr7DjHXYNVfG1pIY5WBwP+AvEXcPNz5p9Ow0=; b=275eh01fCLXfpbToFPhv+4+JJ63sKTATIH7GUBxQbpJDYIB4ePbgVc2JWpdygEsZZP 6XcxTzWt4pklpdAHirUCSfE+e9RS08RH2BG4yk/WAd9BUxuIOjLYDAFrgeu8UH2Co79E 44dQjmMMB9Cdtgd5z91Liwn5q5t3fqGwY3XqNA5I4pyo+A4IcpwSt7dzh56q+bHT9PT3 vAFGHyRw0yEt+q1nofDAA2Qm5w2wEz+pQYinNPt1YbxdNm0zpVV11e28Fk7eGipQ6vwR dO3d5UKz1edFal8pcjvsR4vfvETfjDRs4TsIludPql2q+itqh3vDk3k6vHjJX7YKZOrL gevg== X-Gm-Message-State: AFqh2koilqJ0ldvk/7hi/apUcnkgDML4IIW4zW/610UgajY66fYM8mJ+ E64dscBK+kUnV9n4HSgbJqUf9o1somUaePX2 X-Google-Smtp-Source: AMrXdXuYOSvZZRtRCe99QltoJlzKEfF2Wd0ZCKtQm5APw/Bfft3TEGvFWsV8UkFstDkKFq/v15Uozg== X-Received: by 2002:a17:902:d697:b0:194:abe9:bc83 with SMTP id v23-20020a170902d69700b00194abe9bc83mr8463038ply.61.1674081914025; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id q18-20020a170902bd9200b00186b7443082sm23652909pls.195.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWd-Qm for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCb-2h for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 01/42] xfs: fix low space alloc deadlock Date: Thu, 19 Jan 2023 09:44:24 +1100 Message-Id: <20230118224505.1964941-2-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner I've recently encountered an ABBA deadlock with g/476. The upcoming changes seem to make this much easier to hit, but the underlying problem is a pre-existing one. Essentially, if we select an AG for allocation, then lock the AGF and then fail to allocate for some reason (e.g. minimum length requirements cannot be satisfied), then we drop out of the allocation with the AGF still locked. The caller then modifies the allocation constraints - usually loosening them up - and tries again. This can result in trying to access AGFs that are lower than the AGF we already have locked from the failed attempt. e.g. the failed attempt skipped several AGs before failing, so we have locks an AG higher than the start AG. Retrying the allocation from the start AG then causes us to violate AGF lock ordering and this can lead to deadlocks. The deadlock exists even if allocation succeeds - we can do a followup allocations in the same transaction for BMBT blocks that aren't guaranteed to be in the same AG as the original, and can move into higher AGs. Hence we really need to move the tp->t_firstblock tracking down into xfs_alloc_vextent() where it can be set when we exit with a locked AG. xfs_alloc_vextent() can also check there if the requested allocation falls within the allow range of AGs set by tp->t_firstblock. If we can't allocate within the range set, we have to fail the allocation. If we are allowed to to non-blocking AGF locking, we can ignore the AG locking order limitations as we can use try-locks for the first iteration over requested AG range. This invalidates a set of post allocation asserts that check that the allocation is always above tp->t_firstblock if it is set. Because we can use try-locks to avoid the deadlock in some circumstances, having a pre-existing locked AGF doesn't always prevent allocation from lower order AGFs. Hence those ASSERTs need to be removed. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_alloc.c | 69 ++++++++++++++++++++++++++++++++------- fs/xfs/libxfs/xfs_bmap.c | 14 -------- fs/xfs/xfs_trace.h | 1 + 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 989cf341779b..c2f38f595d7f 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3164,10 +3164,13 @@ xfs_alloc_vextent( xfs_alloctype_t type; /* input allocation type */ int bump_rotor = 0; xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ + xfs_agnumber_t minimum_agno = 0; mp = args->mp; type = args->otype = args->type; args->agbno = NULLAGBLOCK; + if (args->tp->t_firstblock != NULLFSBLOCK) + minimum_agno = XFS_FSB_TO_AGNO(mp, args->tp->t_firstblock); /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure @@ -3201,6 +3204,13 @@ xfs_alloc_vextent( */ args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->pag = xfs_perag_get(mp, args->agno); + + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + error = 0; + break; + } + error = xfs_alloc_fix_freelist(args, 0); if (error) { trace_xfs_alloc_vextent_nofix(args); @@ -3232,6 +3242,8 @@ xfs_alloc_vextent( case XFS_ALLOCTYPE_FIRST_AG: /* * Rotate through the allocation groups looking for a winner. + * If we are blocking, we must obey minimum_agno contraints for + * avoiding ABBA deadlocks on AGF locking. */ if (type == XFS_ALLOCTYPE_FIRST_AG) { /* @@ -3239,7 +3251,7 @@ xfs_alloc_vextent( */ args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_THIS_AG; - sagno = 0; + sagno = minimum_agno; flags = 0; } else { /* @@ -3248,6 +3260,7 @@ xfs_alloc_vextent( args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno); flags = XFS_ALLOC_FLAG_TRYLOCK; } + /* * Loop over allocation groups twice; first time with * trylock set, second time without. @@ -3276,19 +3289,21 @@ xfs_alloc_vextent( if (args->agno == sagno && type == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; + /* - * For the first allocation, we can try any AG to get - * space. However, if we already have allocated a - * block, we don't want to try AGs whose number is below - * sagno. Otherwise, we may end up with out-of-order - * locking of AGF, which might cause deadlock. - */ + * If we are try-locking, we can't deadlock on AGF + * locks, so we can wrap all the way back to the first + * AG. Otherwise, wrap back to the start AG so we can't + * deadlock, and let the end of scan handler decide what + * to do next. + */ if (++(args->agno) == mp->m_sb.sb_agcount) { - if (args->tp->t_firstblock != NULLFSBLOCK) - args->agno = sagno; - else + if (flags & XFS_ALLOC_FLAG_TRYLOCK) args->agno = 0; + else + args->agno = sagno; } + /* * Reached the starting a.g., must either be done * or switch to non-trylock mode. @@ -3300,7 +3315,14 @@ xfs_alloc_vextent( break; } + /* + * Blocking pass next, so we must obey minimum + * agno constraints to avoid ABBA AGF deadlocks. + */ flags = 0; + if (minimum_agno > sagno) + sagno = minimum_agno; + if (type == XFS_ALLOCTYPE_START_BNO) { args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); @@ -3322,9 +3344,9 @@ xfs_alloc_vextent( ASSERT(0); /* NOTREACHED */ } - if (args->agbno == NULLAGBLOCK) + if (args->agbno == NULLAGBLOCK) { args->fsbno = NULLFSBLOCK; - else { + } else { args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); #ifdef DEBUG ASSERT(args->len >= args->minlen); @@ -3335,6 +3357,29 @@ xfs_alloc_vextent( #endif } + + /* + * We end up here with a locked AGF. If we failed, the caller is likely + * going to try to allocate again with different parameters, and that + * can widen the AGs that are searched for free space. If we have to do + * BMBT block allocation, we have to do a new allocation. + * + * Hence leaving this function with the AGF locked opens up potential + * ABBA AGF deadlocks because a future allocation attempt in this + * transaction may attempt to lock a lower number AGF. + * + * We can't release the AGF until the transaction is commited, so at + * this point we must update the "firstblock" tracker to point at this + * AG if the tracker is empty or points to a lower AG. This allows the + * next allocation attempt to be modified appropriately to avoid + * deadlocks. + */ + if (args->agbp && + (args->tp->t_firstblock == NULLFSBLOCK || + args->pag->pag_agno > minimum_agno)) { + args->tp->t_firstblock = XFS_AGB_TO_FSB(mp, + args->pag->pag_agno, 0); + } xfs_perag_put(args->pag); return 0; error0: diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 0d56a8d862e8..018837bd72c8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3413,21 +3413,7 @@ xfs_bmap_process_allocated_extent( xfs_fileoff_t orig_offset, xfs_extlen_t orig_length) { - int nullfb; - - nullfb = ap->tp->t_firstblock == NULLFSBLOCK; - - /* - * check the allocation happened at the same or higher AG than - * the first block that was allocated. - */ - ASSERT(nullfb || - XFS_FSB_TO_AGNO(args->mp, ap->tp->t_firstblock) <= - XFS_FSB_TO_AGNO(args->mp, args->fsbno)); - ap->blkno = args->fsbno; - if (nullfb) - ap->tp->t_firstblock = args->fsbno; ap->length = args->len; /* * If the extent size hint is active, we tried to round the diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 421d1e504ac4..918e778fdd55 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1877,6 +1877,7 @@ DEFINE_ALLOC_EVENT(xfs_alloc_small_notenough); DEFINE_ALLOC_EVENT(xfs_alloc_small_done); DEFINE_ALLOC_EVENT(xfs_alloc_small_error); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_badargs); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_skip_deadlock); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_nofix); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed); From patchwork Wed Jan 18 22:44:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107120 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA53DC38147 for ; Wed, 18 Jan 2023 22:45:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229603AbjARWpU (ORCPT ); Wed, 18 Jan 2023 17:45:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229496AbjARWpP (ORCPT ); Wed, 18 Jan 2023 17:45:15 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3FE035F3BA for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id v10-20020a17090abb8a00b00229c517a6eeso3992677pjr.5 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+XhOUABUrwg/JfEwItPd+UcaDxpn/yLUV8KJI364MO8=; b=5qBLwiYm7I+ze5BHggBhVap0fYmry9CNc758puQ6LwCTMd5PjMQ8wGk6dyljsE/YMo qw+J9UH89tJJL96XWq+aLxVevGbvu+4P6YrGAROpytqaFZl2NEaYIwZWDvwkaX84kN0E hqyVVT5RUeK4AvMVx+4Oj5fWkqwx8MvYSn0UHEvlmwcYyDsXIq3tMhxIfNN9w417dmeX oC8nfGaqHq8DnpsCC6B864YTN3YEELEyVhzIAAEcqNSMJB00juI4EW4Nc94wVYrKwPO5 RTsO8CTgV1GEh+m/+QxxxCoeMw41bggaPusbmjgvSiAxEDWVdidioY5redqXpgMdCQNM dp9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+XhOUABUrwg/JfEwItPd+UcaDxpn/yLUV8KJI364MO8=; b=ta8iHIQsw+vSYR/1f/2XqlITCVNpEV52Lbq6wVOE3h5UiTvgOTm9YDnTZLnFkk0EU4 iStioNBO7pOz/Uetf+qdNwxZVPqB0nHLAtdCe8mHPRw5kw1DnEpnzVroOHZuebQpvesx 2EbrCpDxlYw3I/5ueZezX9BHSAGtHU/pjHuGm0QdOcaxFYQJxbUn+0r3zNuBKS4vSP5Z RPySWGpxZlwT7OP9Ei2B6CLxfB71EeaoWxQCtlx/jmZFLpDGDfB9HQhQXAETVP/xN1e3 6VHVjKksDt2ApnXwZWj8b+XfGdP7mXfn6CA90Dh3QF+J/LfuKPxib++craWF+Amklenv K19Q== X-Gm-Message-State: AFqh2kpzju26c+P+68HCDPyMNG3M0SBUyDbCuJreBDlsJFFKFLJcIjIK Ilm+jP+b3xS2SKp7VLtwXnWp+lVWPBDX62I3 X-Google-Smtp-Source: AMrXdXu7hRXchv1y7xJeb92RD0RJCWrfWXl0tMN6Ul0Gz5scepZ28bRj14ZBjQ+9RKHr13ZuLkWnpA== X-Received: by 2002:a17:902:7894:b0:189:cf92:6f5c with SMTP id q20-20020a170902789400b00189cf926f5cmr8942348pll.52.1674081913808; Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id b15-20020a170902650f00b00188f3970d4asm23661258plk.163.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWf-RY for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCf-2m for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 02/42] xfs: prefer free inodes at ENOSPC over chunk allocation Date: Thu, 19 Jan 2023 09:44:25 +1100 Message-Id: <20230118224505.1964941-3-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner When an XFS filesystem has free inodes in chunks already allocated on disk, it will still allocate new inode chunks if the target AG has no free inodes in it. Normally, this is a good idea as it preserves locality of all the inodes in a given directory. However, at ENOSPC this can lead to using the last few remaining free filesystem blocks to allocate a new chunk when there are many, many free inodes that could be allocated without consuming free space. This results in speeding up the consumption of the last few blocks and inode create operations then returning ENOSPC when there free inodes available because we don't have enough block left in the filesystem for directory creation reservations to proceed. Hence when we are near ENOSPC, we should be attempting to preserve the remaining blocks for directory block allocation rather than using them for unnecessary inode chunk creation. This particular behaviour is exposed by xfs/294, when it drives to ENOSPC on empty file creation whilst there are still thousands of free inodes available for allocation in other AGs in the filesystem. Hence, when we are within 1% of ENOSPC, change the inode allocation behaviour to prefer to use existing free inodes over allocating new inode chunks, even though it results is poorer locality of the data set. It is more important for the allocations to be space efficient near ENOSPC than to have optimal locality for performance, so lets modify the inode AG selection code to reflect that fact. This allows generic/294 to not only pass with this allocator rework patchset, but to increase the number of post-ENOSPC empty inode allocations to from ~600 to ~9080 before we hit ENOSPC on the directory create transaction reservation. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ialloc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 5118dedf9267..e8068422aa21 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1737,6 +1737,7 @@ xfs_dialloc( struct xfs_perag *pag; struct xfs_ino_geometry *igeo = M_IGEO(mp); bool ok_alloc = true; + bool low_space = false; int flags; xfs_ino_t ino; @@ -1767,6 +1768,20 @@ xfs_dialloc( ok_alloc = false; } + /* + * If we are near to ENOSPC, we want to prefer allocation from AGs that + * have free inodes in them rather than use up free space allocating new + * inode chunks. Hence we turn off allocation for the first non-blocking + * pass through the AGs if we are near ENOSPC to consume free inodes + * that we can immediately allocate, but then we allow allocation on the + * second pass if we fail to find an AG with free inodes in it. + */ + if (percpu_counter_read_positive(&mp->m_fdblocks) < + mp->m_low_space[XFS_LOWSP_1_PCNT]) { + ok_alloc = false; + low_space = true; + } + /* * Loop until we find an allocation group that either has free inodes * or in which we can allocate some inodes. Iterate through the @@ -1795,6 +1810,8 @@ xfs_dialloc( break; } flags = 0; + if (low_space) + ok_alloc = true; } xfs_perag_put(pag); } From patchwork Wed Jan 18 22:44:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1749C678D6 for ; Wed, 18 Jan 2023 22:45:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229766AbjARWp3 (ORCPT ); Wed, 18 Jan 2023 17:45:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229813AbjARWpR (ORCPT ); Wed, 18 Jan 2023 17:45:17 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0B5D63E3A for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id v10-20020a17090abb8a00b00229c517a6eeso3992728pjr.5 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ESNl4gcmMvqESi3nyV6w/UdCrWaFMG1IJcQBAioCf04=; b=YcLQeofUPNrSxh+tVow59ikNuz3M4fehaOHecVgKm0XRBAcpghP6jF3p8dc3v93fOg 1WJDl1m8WigyPvfgbMFZi28Bb3OISkqlyWfQZSvZTyJPqzBnagtONZQivX5gFzqjOvMu wKepWsS25NqrdqK3LPFIB8OKth8xxe+pXbDF1aa7uGr37AmGTBYM8xmnuHpEvM11HK/5 MDZdTteMxXvgfwiZewDW6l390wn9K6ssg7dkPZ6mMXrdeheHrT/2hMzhmdk+42rNa4fK MgSwKTwWGj8COu/+9dUF/DMz6ElqJ3pnZMpi1JihjvGQDwCV1pCqKrOPloSw9Oqzj5JS WRGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ESNl4gcmMvqESi3nyV6w/UdCrWaFMG1IJcQBAioCf04=; b=s02YjAN4joa5imFZirR23sUlLiggKMZXlBebYuodcP9AAcQeZk9IYGSZbc/HrLIxgI 2vbRUM9tdJouZyCILoWahPn9aN+MsiKBr8pn0f210kMWUl6xxGpvFSmxKhB8nRRLHVQO VqAb8avgKCzk2z69DZRkKCtSUe9XSkoOPAGvZsKNEV2WVLeYxZszmy6D/DtKlvTjYKaZ JpbagHMs07Gq9JKjgsigZbWkcKAaXLetYHUiQEP90bNWVkGhHWGKZGqZmaipVxF3xoTc akxwjXC4ToXIl0eJsVnnhT1W9cBubH8KK7boVo0/Egztxl4HyiYyPGdB5jY82SFgAR42 2l0w== X-Gm-Message-State: AFqh2kqRKyGBHgCBlbfhuv/9suKYruCA3fkFwesUDm1Z9jGnpPvW5Pfk 4BhvrzV8bOicJtRDquyeu8tg52Igzjd7v8Rk X-Google-Smtp-Source: AMrXdXvu66FCtqYVOUt05zCVXmIR48GZPjUYo3SqQiWjsuoKBn6sRS9cnGffFeBAz894KrUwEAh6Aw== X-Received: by 2002:a17:903:2345:b0:193:3155:ebcf with SMTP id c5-20020a170903234500b001933155ebcfmr15858466plh.3.1674081915502; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id k6-20020a170902c40600b0017f8094a52asm6611009plk.29.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWh-SX for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCj-2q for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 03/42] xfs: block reservation too large for minleft allocation Date: Thu, 19 Jan 2023 09:44:26 +1100 Message-Id: <20230118224505.1964941-4-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner When we enter xfs_bmbt_alloc_block() without having first allocated a data extent (i.e. tp->t_firstblock == NULLFSBLOCK) because we are doing something like unwritten extent conversion, the transaction block reservation is used as the minleft value. This works for operations like unwritten extent conversion, but it assumes that the block reservation is only for a BMBT split. THis is not always true, and sometimes results in larger than necessary minleft values being set. We only actually need enough space for a btree split, something we already handle correctly in xfs_bmapi_write() via the xfs_bmapi_minleft() calculation. We should use xfs_bmapi_minleft() in xfs_bmbt_alloc_block() to calculate the number of blocks a BMBT split on this inode is going to require, not use the transaction block reservation that contains the maximum number of blocks this transaction may consume in it... Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_bmap.h | 2 ++ fs/xfs/libxfs/xfs_bmap_btree.c | 19 +++++++++---------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 018837bd72c8..9dc33cdc2ab9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4242,7 +4242,7 @@ xfs_bmapi_convert_unwritten( return 0; } -static inline xfs_extlen_t +xfs_extlen_t xfs_bmapi_minleft( struct xfs_trans *tp, struct xfs_inode *ip, diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 16db95b11589..08c16e4edc0f 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -220,6 +220,8 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp, struct xfs_bmbt_irec *new, int *logflagsp); +xfs_extlen_t xfs_bmapi_minleft(struct xfs_trans *tp, struct xfs_inode *ip, + int fork); enum xfs_bmap_intent_type { XFS_BMAP_MAP = 1, diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index cfa052d40105..18de4fbfef4e 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -213,18 +213,16 @@ xfs_bmbt_alloc_block( if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); args.type = XFS_ALLOCTYPE_START_BNO; + /* - * Make sure there is sufficient room left in the AG to - * complete a full tree split for an extent insert. If - * we are converting the middle part of an extent then - * we may need space for two tree splits. - * - * We are relying on the caller to make the correct block - * reservation for this operation to succeed. If the - * reservation amount is insufficient then we may fail a - * block allocation here and corrupt the filesystem. + * If we are coming here from something like unwritten extent + * conversion, there has been no data extent allocation already + * done, so we have to ensure that we attempt to locate the + * entire set of bmbt allocations in the same AG, as + * xfs_bmapi_write() would have reserved. */ - args.minleft = args.tp->t_blk_res; + args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, + cur->bc_ino.whichfork); } else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) { args.type = XFS_ALLOCTYPE_START_BNO; } else { @@ -248,6 +246,7 @@ xfs_bmbt_alloc_block( * successful activate the lowspace algorithm. */ args.fsbno = 0; + args.minleft = 0; args.type = XFS_ALLOCTYPE_FIRST_AG; error = xfs_alloc_vextent(&args); if (error) From patchwork Wed Jan 18 22:44:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6F2EC38147 for ; Wed, 18 Jan 2023 22:45:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229758AbjARWpa (ORCPT ); Wed, 18 Jan 2023 17:45:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0AE185F395 for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id 78so92594pgb.8 for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gMejnVgrbPmkzLpcSjDMUCL+ynfiDTVQd/geV+mcHw8=; b=dVwgtPmlrDoNIHKKKEipvjyB7hKXrj4mPFJKRjicvs/SN9d9qup15izYa1p5sNM1/k QOQC47V+o5vUjvLqW28GroxXNNq9GKsO5d6ozrrP3W/7oC4Scn3SNZaXSzjoOTaq3xfb aHLWcoaYQ7Jhtc9SKlloYllgEJbFpEtqyLTY2rlaixCbe1dasIELm0GSTudPU8wbxkqg WF27Pai6xDnoFG12CYdbtKw6w3fo7BVIWCdYbFVaf/LXE/0Q2cNvUHS6PTR9jxPQbGKG Rf2DCTI6IoV0cHwP012+/0o+nl5xLvO2jFFekdIkwKYILxBaItLF8RJeKxoyTmgbjtl7 RJEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gMejnVgrbPmkzLpcSjDMUCL+ynfiDTVQd/geV+mcHw8=; b=PcxeZO6xPBUnUAR2nJ60E3MHNf/WUQ0+2v/k0blhEEZlf4Uc+QZ38AzF3KRBRfqOsy Q2vfjt8agu29UXBPL6DrrDyqXyGNhsRLYIlsmHiNF2X2VtFrouZhRYTmxwyNxbPUXZ3a tt8pLj/0jBWekdqyazGa2OIHODd/TXle2eTueP03jQT1qRIO5A4w4N4FB8VaylAF5RLz 7AJ3r5pgzuvIOzHeiSEWeSAODtBWUMVZ5t9uIYv6llW04GLI4Y0MvXVFd4pXmG1s7TLH EW05Cu5vPBDfcU+3HijpJZRJTNSSMq4P0d+5W3dYePEvleNd3hKI8r+2bRaJzYRf5IAN jMmw== X-Gm-Message-State: AFqh2kqkeoY7mD2A1uftztRQ2+o9iR725h2ExuU5KCdqYcZf+O9SIaEL 8M3QPXpSxw4vpoyCD7f0m37hUkW8tB3Nrr5a X-Google-Smtp-Source: AMrXdXttqyTfsBx5kl1m9QwstD6ZQUPGmssykAXAGDc51R1dtiBBnN+RZsnja4CxcMrCV08EnruSAw== X-Received: by 2002:a62:5ec2:0:b0:580:963d:8064 with SMTP id s185-20020a625ec2000000b00580963d8064mr6978204pfb.20.1674081916416; Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id a6-20020aa79706000000b0058d9e915891sm6763406pfg.57.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWj-TL for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCp-2x for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 04/42] xfs: drop firstblock constraints from allocation setup Date: Thu, 19 Jan 2023 09:44:27 +1100 Message-Id: <20230118224505.1964941-5-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that xfs_alloc_vextent() does all the AGF deadlock prevention filtering for multiple allocations in a single transaction, we no longer need the allocation setup code to care about what AGs we might already have locked. Hence we can remove all the "nullfb" conditional logic in places like xfs_bmap_btalloc() and instead have them focus simply on setting up locality constraints. If the allocation fails due to AGF lock filtering in xfs_alloc_vextent, then we just fall back as we normally do to more relaxed allocation constraints. As a result, any allocation that allows AG scanning (i.e. not confined to a single AG) and does not force a worst case full filesystem scan will now be able to attempt allocation from AGs lower than that defined by tp->t_firstblock. This is because xfs_alloc_vextent() allows try-locking of the AGFs and hence enables low space algorithms to at least -try- to get space from AGs lower than the one that we have currently locked and allocated from. This is a significant improvement in the low space allocation algorithm. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_bmap.c | 168 +++++++++++---------------------- fs/xfs/libxfs/xfs_bmap.h | 1 + fs/xfs/libxfs/xfs_bmap_btree.c | 30 +++--- 3 files changed, 67 insertions(+), 132 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 9dc33cdc2ab9..bc566aae4246 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -645,16 +645,9 @@ xfs_bmap_extents_to_btree( args.tp = tp; args.mp = mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); - if (tp->t_firstblock == NULLFSBLOCK) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); - } else if (tp->t_flags & XFS_TRANS_LOWMODE) { - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = tp->t_firstblock; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = tp->t_firstblock; - } + + args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); args.minlen = args.maxlen = args.prod = 1; args.wasdel = wasdel; *logflagsp = 0; @@ -662,17 +655,14 @@ xfs_bmap_extents_to_btree( if (error) goto out_root_realloc; + /* + * Allocation can't fail, the space was reserved. + */ if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { error = -ENOSPC; goto out_root_realloc; } - /* - * Allocation can't fail, the space was reserved. - */ - ASSERT(tp->t_firstblock == NULLFSBLOCK || - args.agno >= XFS_FSB_TO_AGNO(mp, tp->t_firstblock)); - tp->t_firstblock = args.fsbno; cur->bc_ino.allocated++; ip->i_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); @@ -804,13 +794,8 @@ xfs_bmap_local_to_extents( * Allocate a block. We know we need only one, since the * file currently fits in an inode. */ - if (tp->t_firstblock == NULLFSBLOCK) { - args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); - args.type = XFS_ALLOCTYPE_START_BNO; - } else { - args.fsbno = tp->t_firstblock; - args.type = XFS_ALLOCTYPE_NEAR_BNO; - } + args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); + args.type = XFS_ALLOCTYPE_START_BNO; args.total = total; args.minlen = args.maxlen = args.prod = 1; error = xfs_alloc_vextent(&args); @@ -820,7 +805,6 @@ xfs_bmap_local_to_extents( /* Can't fail, the space was reserved. */ ASSERT(args.fsbno != NULLFSBLOCK); ASSERT(args.len == 1); - tp->t_firstblock = args.fsbno; error = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, XFS_FSB_TO_DADDR(args.mp, args.fsbno), args.mp->m_bsize, 0, &bp); @@ -854,8 +838,7 @@ xfs_bmap_local_to_extents( ifp->if_nextents = 1; ip->i_nblocks = 1; - xfs_trans_mod_dquot_byino(tp, ip, - XFS_TRANS_DQ_BCOUNT, 1L); + xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); flags |= xfs_ilog_fext(whichfork); done: @@ -3025,9 +3008,7 @@ xfs_bmap_adjacent( struct xfs_bmalloca *ap) /* bmap alloc argument struct */ { xfs_fsblock_t adjust; /* adjustment to block numbers */ - xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_mount_t *mp; /* mount point structure */ - int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ #define ISVALID(x,y) \ @@ -3038,11 +3019,8 @@ xfs_bmap_adjacent( XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) mp = ap->ip->i_mount; - nullfb = ap->tp->t_firstblock == NULLFSBLOCK; rt = XFS_IS_REALTIME_INODE(ap->ip) && (ap->datatype & XFS_ALLOC_USERDATA); - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, - ap->tp->t_firstblock); /* * If allocating at eof, and there's a previous real block, * try to use its last block as our starting point. @@ -3101,13 +3079,6 @@ xfs_bmap_adjacent( prevbno += adjust; else prevdiff += adjust; - /* - * If the firstblock forbids it, can't use it, - * must use default. - */ - if (!rt && !nullfb && - XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) - prevbno = NULLFSBLOCK; } /* * No previous block or can't follow it, just default. @@ -3143,13 +3114,6 @@ xfs_bmap_adjacent( gotdiff += adjust - ap->length; } else gotdiff += adjust; - /* - * If the firstblock forbids it, can't use it, - * must use default. - */ - if (!rt && !nullfb && - XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) - gotbno = NULLFSBLOCK; } /* * No next block, just default. @@ -3236,7 +3200,7 @@ xfs_bmap_select_minlen( } STATIC int -xfs_bmap_btalloc_nullfb( +xfs_bmap_btalloc_select_lengths( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen) @@ -3247,8 +3211,13 @@ xfs_bmap_btalloc_nullfb( int error; args->type = XFS_ALLOCTYPE_START_BNO; - args->total = ap->total; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + args->total = ap->minlen; + args->minlen = ap->minlen; + return 0; + } + args->total = ap->total; startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); if (startag == NULLAGNUMBER) startag = ag = 0; @@ -3280,6 +3249,13 @@ xfs_bmap_btalloc_filestreams( int notinit = 0; int error; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + args->type = XFS_ALLOCTYPE_FIRST_AG; + args->total = ap->minlen; + args->minlen = ap->minlen; + return 0; + } + args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; @@ -3460,19 +3436,15 @@ xfs_bmap_exact_minlen_extent_alloc( xfs_bmap_compute_alignments(ap, &args); - if (ap->tp->t_firstblock == NULLFSBLOCK) { - /* - * Unlike the longest extent available in an AG, we don't track - * the length of an AG's shortest extent. - * XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT is a debug only knob and - * hence we can afford to start traversing from the 0th AG since - * we need not be concerned about a drop in performance in - * "debug only" code paths. - */ - ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); - } else { - ap->blkno = ap->tp->t_firstblock; - } + /* + * Unlike the longest extent available in an AG, we don't track + * the length of an AG's shortest extent. + * XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT is a debug only knob and + * hence we can afford to start traversing from the 0th AG since + * we need not be concerned about a drop in performance in + * "debug only" code paths. + */ + ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3515,13 +3487,11 @@ xfs_bmap_btalloc( struct xfs_mount *mp = ap->ip->i_mount; struct xfs_alloc_arg args = { .tp = ap->tp, .mp = mp }; xfs_alloctype_t atype = 0; - xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_agnumber_t ag; xfs_fileoff_t orig_offset; xfs_extlen_t orig_length; xfs_extlen_t blen; xfs_extlen_t nextminlen = 0; - int nullfb; /* true if ap->firstblock isn't set */ int isaligned; int tryagain; int error; @@ -3533,34 +3503,17 @@ xfs_bmap_btalloc( stripe_align = xfs_bmap_compute_alignments(ap, &args); - nullfb = ap->tp->t_firstblock == NULLFSBLOCK; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, - ap->tp->t_firstblock); - if (nullfb) { - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) { - ag = xfs_filestream_lookup_ag(ap->ip); - ag = (ag != NULLAGNUMBER) ? ag : 0; - ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); - } else { - ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); - } - } else - ap->blkno = ap->tp->t_firstblock; + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) { + ag = xfs_filestream_lookup_ag(ap->ip); + ag = (ag != NULLAGNUMBER) ? ag : 0; + ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); + } else { + ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); + } xfs_bmap_adjacent(ap); - /* - * If allowed, use ap->blkno; otherwise must use firstblock since - * it's in the right allocation group. - */ - if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno) - ; - else - ap->blkno = ap->tp->t_firstblock; - /* - * Normal allocation, done through xfs_alloc_vextent. - */ tryagain = isaligned = 0; args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3568,30 +3521,19 @@ xfs_bmap_btalloc( /* Trim the allocation back to the maximum an AG can fit. */ args.maxlen = min(ap->length, mp->m_ag_max_usable); blen = 0; - if (nullfb) { - /* - * Search for an allocation group with a single extent large - * enough for the request. If one isn't found, then adjust - * the minimum allocation size to the largest space found. - */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) - error = xfs_bmap_btalloc_filestreams(ap, &args, &blen); - else - error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); - if (error) - return error; - } else if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { - if (xfs_inode_is_filestream(ap->ip)) - args.type = XFS_ALLOCTYPE_FIRST_AG; - else - args.type = XFS_ALLOCTYPE_START_BNO; - args.total = args.minlen = ap->minlen; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.total = ap->total; - args.minlen = ap->minlen; - } + + /* + * Search for an allocation group with a single extent large + * enough for the request. If one isn't found, then adjust + * the minimum allocation size to the largest space found. + */ + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) + error = xfs_bmap_btalloc_filestreams(ap, &args, &blen); + else + error = xfs_bmap_btalloc_select_lengths(ap, &args, &blen); + if (error) + return error; /* * If we are not low on available data blocks, and the underlying @@ -3678,7 +3620,7 @@ xfs_bmap_btalloc( if ((error = xfs_alloc_vextent(&args))) return error; } - if (args.fsbno == NULLFSBLOCK && nullfb && + if (args.fsbno == NULLFSBLOCK && args.minlen > ap->minlen) { args.minlen = ap->minlen; args.type = XFS_ALLOCTYPE_START_BNO; @@ -3686,7 +3628,7 @@ xfs_bmap_btalloc( if ((error = xfs_alloc_vextent(&args))) return error; } - if (args.fsbno == NULLFSBLOCK && nullfb) { + if (args.fsbno == NULLFSBLOCK) { args.fsbno = 0; args.type = XFS_ALLOCTYPE_FIRST_AG; args.total = ap->minlen; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 08c16e4edc0f..0ffc0d998850 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -269,4 +269,5 @@ extern struct kmem_cache *xfs_bmap_intent_cache; int __init xfs_bmap_intent_init_cache(void); void xfs_bmap_intent_destroy_cache(void); + #endif /* __XFS_BMAP_H__ */ diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 18de4fbfef4e..76a0f0d260a4 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -206,28 +206,21 @@ xfs_bmbt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; - args.fsbno = cur->bc_tp->t_firstblock; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino, cur->bc_ino.whichfork); - if (args.fsbno == NULLFSBLOCK) { - args.fsbno = be64_to_cpu(start->l); - args.type = XFS_ALLOCTYPE_START_BNO; + args.fsbno = be64_to_cpu(start->l); + args.type = XFS_ALLOCTYPE_START_BNO; - /* - * If we are coming here from something like unwritten extent - * conversion, there has been no data extent allocation already - * done, so we have to ensure that we attempt to locate the - * entire set of bmbt allocations in the same AG, as - * xfs_bmapi_write() would have reserved. - */ + /* + * If we are coming here from something like unwritten extent + * conversion, there has been no data extent allocation already done, so + * we have to ensure that we attempt to locate the entire set of bmbt + * allocations in the same AG, as xfs_bmapi_write() would have reserved. + */ + if (cur->bc_tp->t_firstblock == NULLFSBLOCK) args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, - cur->bc_ino.whichfork); - } else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) { - args.type = XFS_ALLOCTYPE_START_BNO; - } else { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - } + cur->bc_ino.whichfork); args.minlen = args.maxlen = args.prod = 1; args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; @@ -247,7 +240,7 @@ xfs_bmbt_alloc_block( */ args.fsbno = 0; args.minleft = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; + args.type = XFS_ALLOCTYPE_START_BNO; error = xfs_alloc_vextent(&args); if (error) goto error0; @@ -259,7 +252,6 @@ xfs_bmbt_alloc_block( } ASSERT(args.len == 1); - cur->bc_tp->t_firstblock = args.fsbno; cur->bc_ino.allocated++; cur->bc_ino.ip->i_nblocks++; xfs_trans_log_inode(args.tp, cur->bc_ino.ip, XFS_ILOG_CORE); From patchwork Wed Jan 18 22:44:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107124 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FE5DC38159 for ; Wed, 18 Jan 2023 22:45:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229544AbjARWpW (ORCPT ); Wed, 18 Jan 2023 17:45:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229654AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 811A161D4A for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pj1-x1033.google.com with SMTP id y3-20020a17090a390300b00229add7bb36so49746pjb.4 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=5Wk19nqjItmb7/nEJAS5MYPkA5nXbup5O1XuVw11F1k=; b=QqeBT803qiNQhdgXUBJKL4dnWBe8OX/wiz+LhC7hyau42oPv7BLKH4J1qEyuLfakjQ KtgIkA3OAETQXg37Um2LAqEngRzXDSsiHfjlXHXY+PgP+JZjMw2hOh3CvN9jPEXDIlyK Ozl+h+nhqY5eIHijlTX+iBtvPPTsjfKsyJTk2NuiVR2jpotSb/VesHs1vGMwlyUXN8Br WKdfLo1o/3rK7MSvjCb3XFKZ+wF2GHv4BRJy1Ah1tEdBb6x3Tq1I7ll2saPLN4Zlrjjm EoPmCTZMnSQMfOXor+dRy7tijgW+RQTOPZFVZeOlDo0Mm2ZdbLqE2Hd9oBgqhLa+V1P7 OG1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5Wk19nqjItmb7/nEJAS5MYPkA5nXbup5O1XuVw11F1k=; b=pHC0/tXDrMCcwcOj4wB/WHYzVdIGpVMvfJ0eDVVmRBhfkMYtCDGFBKu4+a2DU2f4pK IdALqaPP6jf0ov3ObLObsHPbs3WCDZolyyHi9Gx0ZW9p00FjC46y4Gd11m+gLIgG7GTs q48TZAGS3+X+ud/sGUSC9HsMN85GsozUOGmdCQMVmgPLCTTum426JS7ACw/Y6cFgx6wA Jt28iOk7OJu0bU/PRl62Ob8oD85/tdFqILdhVxm6ioegTQ9rCscQonUytT/6SeMyzcKb NW+6IX6C9J1FEQbJbtHry0wylhM9HIYqJ5Q6K43yqSds+N6W7bbIkicTXn7xWgexFstq 6DTA== X-Gm-Message-State: AFqh2kpWYjbe7RSasoosMuNMXPOwQhc13Wn84/rA/5cDWxjM+HeULhql 7cULt6y1AKRNjyvTpRKfScHhVouuFJ3XKrId X-Google-Smtp-Source: AMrXdXsfOS1t++iEyld62MIyDAdlYGFc8Xthg2EnTsbW7+uCR67FrKQYElb/j8OxhTuCwd8oiNr0Xw== X-Received: by 2002:a17:902:7088:b0:192:52d7:b574 with SMTP id z8-20020a170902708800b0019252d7b574mr8647272plk.63.1674081914036; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id n14-20020a170902d2ce00b00192fe452e17sm6195719plc.162.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWm-UH for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCt-32 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 05/42] xfs: t_firstblock is tracking AGs not blocks Date: Thu, 19 Jan 2023 09:44:28 +1100 Message-Id: <20230118224505.1964941-6-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The tp->t_firstblock field is now raelly tracking the highest AG we have locked, not the block number of the highest allocation we've made. It's purpose is to prevent AGF locking deadlocks, so rename it to "highest AG" and simplify the implementation to just track the agno rather than a fsbno. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_alloc.c | 12 +++++------- fs/xfs/libxfs/xfs_bmap.c | 4 ++-- fs/xfs/libxfs/xfs_bmap_btree.c | 6 +++--- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_reflink.c | 2 +- fs/xfs/xfs_trace.h | 8 ++++---- fs/xfs/xfs_trans.c | 4 ++-- fs/xfs/xfs_trans.h | 2 +- 9 files changed, 20 insertions(+), 22 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index c2f38f595d7f..9f26a9368eeb 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3169,8 +3169,8 @@ xfs_alloc_vextent( mp = args->mp; type = args->otype = args->type; args->agbno = NULLAGBLOCK; - if (args->tp->t_firstblock != NULLFSBLOCK) - minimum_agno = XFS_FSB_TO_AGNO(mp, args->tp->t_firstblock); + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure @@ -3375,11 +3375,9 @@ xfs_alloc_vextent( * deadlocks. */ if (args->agbp && - (args->tp->t_firstblock == NULLFSBLOCK || - args->pag->pag_agno > minimum_agno)) { - args->tp->t_firstblock = XFS_AGB_TO_FSB(mp, - args->pag->pag_agno, 0); - } + (args->tp->t_highest_agno == NULLAGNUMBER || + args->pag->pag_agno > minimum_agno)) + args->tp->t_highest_agno = args->pag->pag_agno; xfs_perag_put(args->pag); return 0; error0: diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index bc566aae4246..f15d45af661f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4192,7 +4192,7 @@ xfs_bmapi_minleft( { struct xfs_ifork *ifp = xfs_ifork_ptr(ip, fork); - if (tp && tp->t_firstblock != NULLFSBLOCK) + if (tp && tp->t_highest_agno != NULLAGNUMBER) return 0; if (ifp->if_format != XFS_DINODE_FMT_BTREE) return 1; @@ -6084,7 +6084,7 @@ xfs_bmap_finish_one( { int error = 0; - ASSERT(tp->t_firstblock == NULLFSBLOCK); + ASSERT(tp->t_highest_agno == NULLAGNUMBER); trace_xfs_bmap_deferred(tp->t_mountp, XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type, diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 76a0f0d260a4..afd9b2d962a3 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -184,11 +184,11 @@ xfs_bmbt_update_cursor( struct xfs_btree_cur *src, struct xfs_btree_cur *dst) { - ASSERT((dst->bc_tp->t_firstblock != NULLFSBLOCK) || + ASSERT((dst->bc_tp->t_highest_agno != NULLAGNUMBER) || (dst->bc_ino.ip->i_diflags & XFS_DIFLAG_REALTIME)); dst->bc_ino.allocated += src->bc_ino.allocated; - dst->bc_tp->t_firstblock = src->bc_tp->t_firstblock; + dst->bc_tp->t_highest_agno = src->bc_tp->t_highest_agno; src->bc_ino.allocated = 0; } @@ -218,7 +218,7 @@ xfs_bmbt_alloc_block( * we have to ensure that we attempt to locate the entire set of bmbt * allocations in the same AG, as xfs_bmapi_write() would have reserved. */ - if (cur->bc_tp->t_firstblock == NULLFSBLOCK) + if (cur->bc_tp->t_highest_agno == NULLAGNUMBER) args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, cur->bc_ino.whichfork); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 867645b74d88..a09dd2606479 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1410,7 +1410,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - ASSERT(tp->t_firstblock == NULLFSBLOCK); + ASSERT(tp->t_highest_agno == NULLAGNUMBER); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d354ea2b74f9..dbe274b8065d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1367,7 +1367,7 @@ xfs_itruncate_extents_flags( unmap_len = XFS_MAX_FILEOFF - first_unmap_block + 1; while (unmap_len > 0) { - ASSERT(tp->t_firstblock == NULLFSBLOCK); + ASSERT(tp->t_highest_agno == NULLAGNUMBER); error = __xfs_bunmapi(tp, ip, first_unmap_block, &unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS); if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 5535778a98f9..57bf59ff4854 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -610,7 +610,7 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - ASSERT((*tpp)->t_firstblock == NULLFSBLOCK); + ASSERT((*tpp)->t_highest_agno == NULLAGNUMBER); /* Free the CoW orphan record. */ xfs_refcount_free_cow_extent(*tpp, del.br_startblock, diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 918e778fdd55..7dc57db6aa42 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1801,7 +1801,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __field(char, wasfromfl) __field(int, resv) __field(int, datatype) - __field(xfs_fsblock_t, firstblock) + __field(xfs_agnumber_t, highest_agno) ), TP_fast_assign( __entry->dev = args->mp->m_super->s_dev; @@ -1822,12 +1822,12 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->wasfromfl = args->wasfromfl; __entry->resv = args->resv; __entry->datatype = args->datatype; - __entry->firstblock = args->tp->t_firstblock; + __entry->highest_agno = args->tp->t_highest_agno; ), TP_printk("dev %d:%d agno 0x%x agbno 0x%x minlen %u maxlen %u mod %u " "prod %u minleft %u total %u alignment %u minalignslop %u " "len %u type %s otype %s wasdel %d wasfromfl %d resv %d " - "datatype 0x%x firstblock 0x%llx", + "datatype 0x%x highest_agno 0x%x", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, __entry->agbno, @@ -1846,7 +1846,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->wasfromfl, __entry->resv, __entry->datatype, - (unsigned long long)__entry->firstblock) + __entry->highest_agno) ) #define DEFINE_ALLOC_EVENT(name) \ diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7bd16fbff534..53ab544e4c2c 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -102,7 +102,7 @@ xfs_trans_dup( INIT_LIST_HEAD(&ntp->t_items); INIT_LIST_HEAD(&ntp->t_busy); INIT_LIST_HEAD(&ntp->t_dfops); - ntp->t_firstblock = NULLFSBLOCK; + ntp->t_highest_agno = NULLAGNUMBER; ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); ASSERT(tp->t_ticket != NULL); @@ -278,7 +278,7 @@ xfs_trans_alloc( INIT_LIST_HEAD(&tp->t_items); INIT_LIST_HEAD(&tp->t_busy); INIT_LIST_HEAD(&tp->t_dfops); - tp->t_firstblock = NULLFSBLOCK; + tp->t_highest_agno = NULLAGNUMBER; error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error == -ENOSPC && want_retry) { diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 55819785941c..6e3646d524ce 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -132,7 +132,7 @@ typedef struct xfs_trans { unsigned int t_rtx_res; /* # of rt extents resvd */ unsigned int t_rtx_res_used; /* # of resvd rt extents used */ unsigned int t_flags; /* misc flags */ - xfs_fsblock_t t_firstblock; /* first block allocated */ + xfs_agnumber_t t_highest_agno; /* highest AGF locked */ struct xlog_ticket *t_ticket; /* log mgr ticket */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ From patchwork Wed Jan 18 22:44:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107132 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 777A9C54EBE for ; Wed, 18 Jan 2023 22:45:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229710AbjARWp2 (ORCPT ); Wed, 18 Jan 2023 17:45:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229830AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99B6C5F38D for ; Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: by mail-pj1-x1034.google.com with SMTP id 7-20020a17090a098700b002298931e366so67321pjo.2 for ; Wed, 18 Jan 2023 14:45:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=zEMct9Zqrd13A6nzsqLIu04c0gI3Nv0cf7YVOTPO3rY=; b=ZTYbuE5VWxqg6wGLlAJ2Gjs0KMwmYFTi8coleZdcx13NLkq/GYZf/JwDPu5DzyBqxI bdFNCEsXfyODt9idLVHGb0mf0sCb+s7AwASNCWMB19RQU6EmovgxvsXPo5djBKfXfvRq veNw4KHVVpXbvPEAFUMz83uRslgmXY/osk4BPY+VukdpdItw4olJ0MDEBDru/zHfUVcH VRTTW1b0aFc02iC6KnC51VP1hn8A/G3b/YoU1ceRLH6EMV0rqlb8obONKq0q7l9qgvtZ 4Td28wQYTu+fC9x9B9dfpYl1GkT43o5Cbxuyfsjvd1hA+/TRj8chtvYZxOKIWZSAgt61 v1Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zEMct9Zqrd13A6nzsqLIu04c0gI3Nv0cf7YVOTPO3rY=; b=q+LGthsMOVMBpF/0WW+7lsXWv87Gn8in4J1JWBX6eR1+DCgSCaObySKe8/KcO4Kgcw CZDAZ79HzEDXi6t39j0MWTzAWfisc2MGxVhCdf46Vwuy1fSdQ3vuPSRq8jDup+UwN9EQ fy4Qq/r4bBkmHY3UkCpFRmiV02OXlqL6qbQ+yDb0hlAy78ZTR6NXOvw0lL/UdL7NSzKq Me6bEzIy5nPbMhd8yQDX4JoPMY9JIdvsJiyqO4r/DScv9Tzzy4Je66h+g13hl0OG69JG 90mtzsmLepY8gIGCsCcR1WkEapxIkSZbczdXAAaiU4CPsgQ+MpO0CqRvvO12Z0IbLLYD CpSQ== X-Gm-Message-State: AFqh2kqMW4ToItKcjH/NCHUrlrfeulS3tA0flZUFKYe6HAYzdvZYPx5L BxO2yJdmjKlGOKbtQON/LRCsXCz4wFVX+5Fv X-Google-Smtp-Source: AMrXdXuMxKZGCffA32+IsKGgdfn0qxyHHkTr3CB8xhxxtQR3bn/NbPA3+HPdFEGlA8f4beeP9885NQ== X-Received: by 2002:a17:902:bd41:b0:194:3cef:31 with SMTP id b1-20020a170902bd4100b001943cef0031mr9044498plx.49.1674081916118; Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id t12-20020a170902e84c00b0019327a6abc2sm3878852plg.44.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWs-V3 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FCz-38 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:10 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 06/42] xfs: don't assert fail on transaction cancel with deferred ops Date: Thu, 19 Jan 2023 09:44:29 +1100 Message-Id: <20230118224505.1964941-7-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We can error out of an allocation transaction when updating BMBT blocks when things go wrong. This can be a btree corruption, and unexpected ENOSPC, etc. In these cases, we already have deferred ops queued for the first allocation that has been done, and we just want to cancel out the transaction and shut down the filesystem on error. In fact, we do just that for production systems - the assert that we can't have a transaction with defer ops attached unless we are already shut down is bogus and gets in the way of debugging whatever issue is actually causing the transaction to be cancelled. Remove the assert because it is causing spurious test failures to hang test machines. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/xfs_trans.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 53ab544e4c2c..8afc0c080861 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1078,10 +1078,10 @@ xfs_trans_cancel( /* * It's never valid to cancel a transaction with deferred ops attached, * because the transaction is effectively dirty. Complain about this - * loudly before freeing the in-memory defer items. + * loudly before freeing the in-memory defer items and shutting down the + * filesystem. */ if (!list_empty(&tp->t_dfops)) { - ASSERT(xfs_is_shutdown(mp) || list_empty(&tp->t_dfops)); ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); dirty = true; xfs_defer_cancel(tp); From patchwork Wed Jan 18 22:44:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107134 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0E4DC32793 for ; Wed, 18 Jan 2023 22:45:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229798AbjARWp3 (ORCPT ); Wed, 18 Jan 2023 17:45:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43604 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229824AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 701AA63E37 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id d8so554681pjc.3 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Ly/jS9/5RaSRPVrpPHMId5HTDzeZZNrP+19hXgBzcaQ=; b=LaZotMHzH8jDORzVv61p/LFhg1rAqPVmsjrI1EaMFT0n0ls3TKgU3cugudDoM8KAIC oe1lAa29tfrrzsPFF6H3MJyAESxNLR/cT+nGj4Z7/nTuxUOG//AusT//xyVPloJ32VQ2 3gPAtizlZum71gOiaUFkbf/5weDVmL6KygDIreYKrDCnGCxJwA2B/S+1fdkUGKm6T+1W o+VaqOowCWiWadcPj9SkTSNFAOit3k1cc0hpTSJggq8rB0wjevZU6gGkBjBXRCx0qkwB jBeg8L95v1sVbk9kU33gow6mwhzANHducrbnCbhQzL1b/tBWufDbK6TVF9Jj+64AK1dB hGhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ly/jS9/5RaSRPVrpPHMId5HTDzeZZNrP+19hXgBzcaQ=; b=DJKLDVpiK1/X4ou4yhL574J8yILh/yg155eH0gy8aTy0i4QiekYN90EDGxFlSQqwhv rIKoPZFatKY78IxBjySsTpYZSrurb7mXYprovmKAx4oFz38RQZX4AOeU4He3CpqzhPov Kn/VxMmQeAJan7eN9ztVbuvX4EU/aIxgqNn81w0yDqOmVI9p50f6CAglaQobhSnO+0NN ONpbOh4zrr3nOUHaMYN+FP/vKHP96HdmnDCsPIhP4lMHLk1n8VZ0/3l3iIEsjeP04A7D FbYNpT+810uC4mpypsfZdgxc6dhqHuSUDPJJiuYrPgVMmX33UvzQaM3xNhC0xPUSGzN/ Jaew== X-Gm-Message-State: AFqh2kpD2nIFMmM+8DWL9L6ZAWr9VwFQMW1bixyb1YeSjhCy9c2yyW4E o/Hx/RDlOIMuLz/sbohcrLQ8OrsbsJQLXZhS X-Google-Smtp-Source: AMrXdXt10hf7gfyVNqQIbWt8XeChJwDl5/aUnw8YVTvuFx5DBdjzM00jWa/9pjsYuvpR1nMDMnIIew== X-Received: by 2002:a05:6a20:9e4a:b0:af:ee05:fd0b with SMTP id mt10-20020a056a209e4a00b000afee05fd0bmr8554987pzb.3.1674081914842; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id q7-20020aa78427000000b00580978caca7sm16326716pfn.45.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB8-004iWv-W3 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB8-008FD4-3D for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 07/42] xfs: active perag reference counting Date: Thu, 19 Jan 2023 09:44:30 +1100 Message-Id: <20230118224505.1964941-8-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We need to be able to dynamically remove instantiated AGs from memory safely, either for shrinking the filesystem or paging AG state in and out of memory (e.g. supporting millions of AGs). This means we need to be able to safely exclude operations from accessing perags while dynamic removal is in progress. To do this, introduce the concept of active and passive references. Active references are required for high level operations that make use of an AG for a given operation (e.g. allocation) and pin the perag in memory for the duration of the operation that is operating on the perag (e.g. transaction scope). This means we can fail to get an active reference to an AG, hence callers of the new active reference API must be able to handle lookup failure gracefully. Passive references are used in low level code, where we might need to access the perag structure for the purposes of completing high level operations. For example, buffers need to use passive references because: - we need to be able to do metadata IO during operations like grow and shrink transactions where high level active references to the AG have already been blocked - buffers need to pin the perag until they are reclaimed from memory, something that high level code has no direct control over. - unused cached buffers should not prevent a shrink from being started. Hence we have active references that will form exclusion barriers for operations to be performed on an AG, and passive references that will prevent reclaim of the perag until all objects with passive references have been reclaimed themselves. This patch introduce xfs_perag_grab()/xfs_perag_rele() as the API for active AG reference functionality. We also need to convert the for_each_perag*() iterators to use active references, which will start the process of converting high level code over to using active references. Conversion of non-iterator based code to active references will be done in followup patches. Note that the implementation using reference counting is really just a development vehicle for the API to ensure we don't have any leaks in the callers. Once we need to remove perag structures from memory dyanmically, we will need a much more robust per-ag state transition mechanism for preventing new references from being taken while we wait for existing references to drain before removal from memory can occur.... Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ag.c | 70 +++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_ag.h | 31 ++++++++++++----- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/fscounters.c | 4 +-- fs/xfs/xfs_fsmap.c | 4 +-- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_iwalk.c | 6 ++-- fs/xfs/xfs_reflink.c | 2 +- fs/xfs/xfs_trace.h | 3 ++ 9 files changed, 105 insertions(+), 19 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index bb0c700afe3c..46e25c682bf4 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -94,6 +94,68 @@ xfs_perag_put( trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); } +/* + * Active references for perag structures. This is for short term access to the + * per ag structures for walking trees or accessing state. If an AG is being + * shrunk or is offline, then this will fail to find that AG and return NULL + * instead. + */ +struct xfs_perag * +xfs_perag_grab( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_perag *pag; + + rcu_read_lock(); + pag = radix_tree_lookup(&mp->m_perag_tree, agno); + if (pag) { + trace_xfs_perag_grab(mp, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (!atomic_inc_not_zero(&pag->pag_active_ref)) + pag = NULL; + } + rcu_read_unlock(); + return pag; +} + +/* + * search from @first to find the next perag with the given tag set. + */ +struct xfs_perag * +xfs_perag_grab_tag( + struct xfs_mount *mp, + xfs_agnumber_t first, + int tag) +{ + struct xfs_perag *pag; + int found; + + rcu_read_lock(); + found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, + (void **)&pag, first, 1, tag); + if (found <= 0) { + rcu_read_unlock(); + return NULL; + } + trace_xfs_perag_grab_tag(mp, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (!atomic_inc_not_zero(&pag->pag_active_ref)) + pag = NULL; + rcu_read_unlock(); + return pag; +} + +void +xfs_perag_rele( + struct xfs_perag *pag) +{ + trace_xfs_perag_rele(pag->pag_mount, pag->pag_agno, + atomic_read(&pag->pag_active_ref), _RET_IP_); + if (atomic_dec_and_test(&pag->pag_active_ref)) + wake_up(&pag->pag_active_wq); +} + /* * xfs_initialize_perag_data * @@ -196,6 +258,10 @@ xfs_free_perag( cancel_delayed_work_sync(&pag->pag_blockgc_work); xfs_buf_hash_destroy(pag); + /* drop the mount's active reference */ + xfs_perag_rele(pag); + XFS_IS_CORRUPT(pag->pag_mount, + atomic_read(&pag->pag_active_ref) != 0); call_rcu(&pag->rcu_head, __xfs_free_perag); } } @@ -314,6 +380,7 @@ xfs_initialize_perag( INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker); INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); init_waitqueue_head(&pag->pagb_wait); + init_waitqueue_head(&pag->pag_active_wq); pag->pagb_count = 0; pag->pagb_tree = RB_ROOT; #endif /* __KERNEL__ */ @@ -322,6 +389,9 @@ xfs_initialize_perag( if (error) goto out_remove_pag; + /* Active ref owned by mount indicates AG is online. */ + atomic_set(&pag->pag_active_ref, 1); + /* first new pag is fully initialized */ if (first_initialised == NULLAGNUMBER) first_initialised = index; diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 191b22b9a35b..aeb21c8df201 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -32,7 +32,9 @@ struct xfs_ag_resv { struct xfs_perag { struct xfs_mount *pag_mount; /* owner filesystem */ xfs_agnumber_t pag_agno; /* AG this structure belongs to */ - atomic_t pag_ref; /* perag reference count */ + atomic_t pag_ref; /* passive reference count */ + atomic_t pag_active_ref; /* active reference count */ + wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */ char pagf_init; /* this agf's entry is initialized */ char pagi_init; /* this agi's entry is initialized */ char pagf_metadata; /* the agf is preferred to be metadata */ @@ -111,11 +113,18 @@ int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); void xfs_free_perag(struct xfs_mount *mp); +/* Passive AG references */ struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int tag); void xfs_perag_put(struct xfs_perag *pag); +/* Active AG references */ +struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t); +struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t, + int tag); +void xfs_perag_rele(struct xfs_perag *pag); + /* * Per-ag geometry infomation and validation */ @@ -193,14 +202,18 @@ xfs_perag_next( struct xfs_mount *mp = pag->pag_mount; *agno = pag->pag_agno + 1; - xfs_perag_put(pag); - if (*agno > end_agno) - return NULL; - return xfs_perag_get(mp, *agno); + xfs_perag_rele(pag); + while (*agno <= end_agno) { + pag = xfs_perag_grab(mp, *agno); + if (pag) + return pag; + (*agno)++; + } + return NULL; } #define for_each_perag_range(mp, agno, end_agno, pag) \ - for ((pag) = xfs_perag_get((mp), (agno)); \ + for ((pag) = xfs_perag_grab((mp), (agno)); \ (pag) != NULL; \ (pag) = xfs_perag_next((pag), &(agno), (end_agno))) @@ -213,11 +226,11 @@ xfs_perag_next( for_each_perag_from((mp), (agno), (pag)) #define for_each_perag_tag(mp, agno, pag, tag) \ - for ((agno) = 0, (pag) = xfs_perag_get_tag((mp), 0, (tag)); \ + for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \ (pag) != NULL; \ (agno) = (pag)->pag_agno + 1, \ - xfs_perag_put(pag), \ - (pag) = xfs_perag_get_tag((mp), (agno), (tag))) + xfs_perag_rele(pag), \ + (pag) = xfs_perag_grab_tag((mp), (agno), (tag))) struct aghdr_init_data { /* per ag data */ diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index d50d0eab196a..dbbc7037074c 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -662,7 +662,7 @@ xchk_bmap_check_rmaps( error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag); if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) { - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } } diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 4777e7b89fdc..ef97670970c3 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -117,7 +117,7 @@ xchk_fscount_warmup( if (agi_bp) xfs_buf_relse(agi_bp); if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } @@ -249,7 +249,7 @@ xchk_fscount_aggregate_agcounts( } if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); if (error) { xchk_set_incomplete(sc); return error; diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 88a88506ffff..120d284a03fe 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -688,11 +688,11 @@ __xfs_getfsmap_datadev( info->agf_bp = NULL; } if (info->pag) { - xfs_perag_put(info->pag); + xfs_perag_rele(info->pag); info->pag = NULL; } else if (pag) { /* loop termination case */ - xfs_perag_put(pag); + xfs_perag_rele(pag); } return error; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index ddeaccc04aec..0f4a014dded3 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1767,7 +1767,7 @@ xfs_icwalk( if (error) { last_error = error; if (error == -EFSCORRUPTED) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } } diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index 7558486f4937..c31857d903a4 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -591,7 +591,7 @@ xfs_iwalk( } if (iwag.pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); xfs_iwalk_free(&iwag); return error; } @@ -683,7 +683,7 @@ xfs_iwalk_threaded( break; } if (pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); if (polled) xfs_pwork_poll(&pctl); return xfs_pwork_destroy(&pctl); @@ -776,7 +776,7 @@ xfs_inobt_walk( } if (iwag.pag) - xfs_perag_put(pag); + xfs_perag_rele(pag); xfs_iwalk_free(&iwag); return error; } diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 57bf59ff4854..f5dc46ce9803 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -927,7 +927,7 @@ xfs_reflink_recover_cow( for_each_perag(mp, agno, pag) { error = xfs_refcount_recover_cow_leftovers(mp, pag); if (error) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7dc57db6aa42..f0b62054ea68 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -189,6 +189,9 @@ DEFINE_EVENT(xfs_perag_class, name, \ DEFINE_PERAG_REF_EVENT(xfs_perag_get); DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_put); +DEFINE_PERAG_REF_EVENT(xfs_perag_grab); +DEFINE_PERAG_REF_EVENT(xfs_perag_grab_tag); +DEFINE_PERAG_REF_EVENT(xfs_perag_rele); DEFINE_PERAG_REF_EVENT(xfs_perag_set_inode_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_clear_inode_tag); From patchwork Wed Jan 18 22:44:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107129 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAFFEC38147 for ; Wed, 18 Jan 2023 22:45:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229693AbjARWp0 (ORCPT ); Wed, 18 Jan 2023 17:45:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229699AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD08E63E30 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pl1-x62b.google.com with SMTP id jm10so527700plb.13 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ZlJuun7fbj9t0bGBLGRzQARvJ3Wnft9vSoK15nvUeHo=; b=ZJCdUGc3MMXR6hCQyWJBQ+hSE2m0qEEp7pfOXILH/JQDAki055OKjgCu29TN6xXCZd R+GB5yy8ME7kcLZtFFPOG2x1ACHE8nbZeU7/KQueVgbuSeWwmvsZln5HXM6qm6YcFuzJ B9R0z0pdVSxjA0Ja72VQykiDjFPOraeT0miImmSWT97Szw2Q1m3uPNvNBRP1Fj9CCaq5 jcVAYHgFWai6koo4xs/aOqzdUQDsKEeEHSrq+0EmtAK4FpS8DrZAIfFIHDRShqqn0iC6 xRrM5KAKTOFQ44cBXHhCr0lSMxoD3TaJiSMZzbIBkD+anrj/efpoPaRzpBsCRCGphjSy EYOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZlJuun7fbj9t0bGBLGRzQARvJ3Wnft9vSoK15nvUeHo=; b=bA9WkNivIpYhoBlEAVlXC2nBBUlJOcxUqJ8OEJy3YtO+wlDi8tCRb9EGMEzhO/XBpi Oci+8MPEyS5rgdQAMHmvyG2MD80X42gm1lNeLGlRVDfn30SLVGJLAcVk4Xd8PH65IDgq bt1HfUZFcqqX8QI6C2XVUkSs3WkSgC1LB/rQhbcj3k0WUIBpa6UTSqkAgLN4wUO4r/mH 3YJZpvz/vSknnhiZF4K7CcDni7odoJRl4lCHj9USAvpPFdj1HIH1cENQrr9t1wJ20cCk Q85JNmf+400Zk6ibIx2WwJuAJY0orthnAgJnm65Nsy98NxTSBl5Ui/FzuCBUTWWKT22T emdg== X-Gm-Message-State: AFqh2kriv0T+vPKyY8CLoefDxdOCR0d28GzHAWBcb90tJoGkVRYhN/Mn 3EjXpRrP5NkxGhOmSmBxIfpK+nP83HOAVED/ X-Google-Smtp-Source: AMrXdXuoHQZf2EIyKVLKZNkz1WcH81/aGOX2gwKas1V9MPmScMLw+Cl7bFebRiIm8VOADZty/NFokQ== X-Received: by 2002:a05:6a21:9998:b0:b8:2e75:c973 with SMTP id ve24-20020a056a21999800b000b82e75c973mr13376476pzb.49.1674081914187; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id 8-20020a631448000000b004b25a51d6f4sm16526185pgu.36.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iWz-0f for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FD9-05 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 08/42] xfs: rework the perag trace points to be perag centric Date: Thu, 19 Jan 2023 09:44:31 +1100 Message-Id: <20230118224505.1964941-9-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner So that they all output the same information in the traces to make debugging refcount issues easier. This means that all the lookup/drop functions no longer need to use the full memory barrier atomic operations (atomic*_return()) so will have less overhead when tracing is off. The set/clear tag tracepoints no longer abuse the reference count to pass the tag - the tag being cleared is obvious from the _RET_IP_ that is recorded in the trace point. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ag.c | 25 +++++++++---------------- fs/xfs/xfs_icache.c | 4 ++-- fs/xfs/xfs_trace.h | 21 +++++++++++---------- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 46e25c682bf4..7cff61875340 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -44,16 +44,15 @@ xfs_perag_get( xfs_agnumber_t agno) { struct xfs_perag *pag; - int ref = 0; rcu_read_lock(); pag = radix_tree_lookup(&mp->m_perag_tree, agno); if (pag) { + trace_xfs_perag_get(pag, _RET_IP_); ASSERT(atomic_read(&pag->pag_ref) >= 0); - ref = atomic_inc_return(&pag->pag_ref); + atomic_inc(&pag->pag_ref); } rcu_read_unlock(); - trace_xfs_perag_get(mp, agno, ref, _RET_IP_); return pag; } @@ -68,7 +67,6 @@ xfs_perag_get_tag( { struct xfs_perag *pag; int found; - int ref; rcu_read_lock(); found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, @@ -77,9 +75,9 @@ xfs_perag_get_tag( rcu_read_unlock(); return NULL; } - ref = atomic_inc_return(&pag->pag_ref); + trace_xfs_perag_get_tag(pag, _RET_IP_); + atomic_inc(&pag->pag_ref); rcu_read_unlock(); - trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_); return pag; } @@ -87,11 +85,9 @@ void xfs_perag_put( struct xfs_perag *pag) { - int ref; - + trace_xfs_perag_put(pag, _RET_IP_); ASSERT(atomic_read(&pag->pag_ref) > 0); - ref = atomic_dec_return(&pag->pag_ref); - trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); + atomic_dec(&pag->pag_ref); } /* @@ -110,8 +106,7 @@ xfs_perag_grab( rcu_read_lock(); pag = radix_tree_lookup(&mp->m_perag_tree, agno); if (pag) { - trace_xfs_perag_grab(mp, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_grab(pag, _RET_IP_); if (!atomic_inc_not_zero(&pag->pag_active_ref)) pag = NULL; } @@ -138,8 +133,7 @@ xfs_perag_grab_tag( rcu_read_unlock(); return NULL; } - trace_xfs_perag_grab_tag(mp, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_grab_tag(pag, _RET_IP_); if (!atomic_inc_not_zero(&pag->pag_active_ref)) pag = NULL; rcu_read_unlock(); @@ -150,8 +144,7 @@ void xfs_perag_rele( struct xfs_perag *pag) { - trace_xfs_perag_rele(pag->pag_mount, pag->pag_agno, - atomic_read(&pag->pag_active_ref), _RET_IP_); + trace_xfs_perag_rele(pag, _RET_IP_); if (atomic_dec_and_test(&pag->pag_active_ref)) wake_up(&pag->pag_active_wq); } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0f4a014dded3..8b2823d85a68 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -255,7 +255,7 @@ xfs_perag_set_inode_tag( break; } - trace_xfs_perag_set_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); + trace_xfs_perag_set_inode_tag(pag, _RET_IP_); } /* Clear a tag on both the AG incore inode tree and the AG radix tree. */ @@ -289,7 +289,7 @@ xfs_perag_clear_inode_tag( radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno, tag); spin_unlock(&mp->m_perag_lock); - trace_xfs_perag_clear_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); + trace_xfs_perag_clear_inode_tag(pag, _RET_IP_); } /* diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index f0b62054ea68..c921e9a5256d 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -159,33 +159,34 @@ TRACE_EVENT(xlog_intent_recovery_failed, ); DECLARE_EVENT_CLASS(xfs_perag_class, - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, - unsigned long caller_ip), - TP_ARGS(mp, agno, refcount, caller_ip), + TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), + TP_ARGS(pag, caller_ip), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_agnumber_t, agno) __field(int, refcount) + __field(int, active_refcount) __field(unsigned long, caller_ip) ), TP_fast_assign( - __entry->dev = mp->m_super->s_dev; - __entry->agno = agno; - __entry->refcount = refcount; + __entry->dev = pag->pag_mount->m_super->s_dev; + __entry->agno = pag->pag_agno; + __entry->refcount = atomic_read(&pag->pag_ref); + __entry->active_refcount = atomic_read(&pag->pag_active_ref); __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d agno 0x%x refcount %d caller %pS", + TP_printk("dev %d:%d agno 0x%x passive refs %d active refs %d caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, __entry->refcount, + __entry->active_refcount, (char *)__entry->caller_ip) ); #define DEFINE_PERAG_REF_EVENT(name) \ DEFINE_EVENT(xfs_perag_class, name, \ - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ - unsigned long caller_ip), \ - TP_ARGS(mp, agno, refcount, caller_ip)) + TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), \ + TP_ARGS(pag, caller_ip)) DEFINE_PERAG_REF_EVENT(xfs_perag_get); DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_put); From patchwork Wed Jan 18 22:44:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107121 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FA18C46467 for ; Wed, 18 Jan 2023 22:45:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229524AbjARWpW (ORCPT ); Wed, 18 Jan 2023 17:45:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbjARWpP (ORCPT ); Wed, 18 Jan 2023 17:45:15 -0500 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BE0C5F395 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pl1-x634.google.com with SMTP id k13so625778plg.0 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=5T1bfDsbGdhVMB2lsfgPkUTh9GCy7S6mNQWMFcU6DDs=; b=yCvOs/+WVbT3ifvE9WYBwnHPmoXBnQz5DeNQzrhBYy5uY5kt0bqgNDQKM08fbzeNSX kJil7TuTW+QNZL0eSjb8AkVBXsvHBoNqvNa3ffkcemVkYOf/2POLg2NiZBq/a4wSq3UV l8hVg0itsDQpAovtFcLdxdYdAr3hzpbl+qG6vEx38ifv53fl7N2uLn5HKQQfBiymd3fC h7ThPYOrm6vO9MmfwPT6K7LzR9ucpGTPGYk6fLZZKJyX+M1qa4Z/W/uzM/0s/vVxE1Vf EC7Heb6EZEBXTISbUaipPgQIBn5TtvJV3Kvvem3qvGU8hEva0FA8u27KZTXN3uMeVfsh oxtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5T1bfDsbGdhVMB2lsfgPkUTh9GCy7S6mNQWMFcU6DDs=; b=Mg3dKsWH1Dp7eQNcQIcBcMQX3fZbrvG8TFLWnnhWyw42UC5i32RIAzyynayLoreDvd 5y3J+PRguN6QGIqm9GPA8GsoX3iEM6DZ+V5MpPilSVxOPn40dgceeE7yVbnKIrP+X4ro Qy8yZTo0kuPRt/ns3ENBLSB4lW6zvbz1pHyiUMk4fD3Sz+ECokebYeNPdcX/S06Rvjld hwAo43EQ0AauxDMoBtbHbQcxAgqmqK8QAwfXxuZyBydZvEL9RbKi9EBh47GvPQRnOAbe ycQQOYQ2aQvLx1g31WfetnshI1Oso8GaZPbcO9cNFl+35/FQPfDnvpt40/HU5JXke0ug xY7A== X-Gm-Message-State: AFqh2kqItbAuaCdx+/nEbBzHWxx3MqIRgi0JpeOFggcdYvLhezk7iR+B tzB1XUssqtBz/NsXpZXMcDkHgW3sCUYY3Hje X-Google-Smtp-Source: AMrXdXst/sUiPujZc0lU4XBoKNEkstrTOm3kWVFoKSa6vIJ/ZjQ8YdJpQBXqMU+vesY3rK5Izpt6EQ== X-Received: by 2002:a05:6a20:9585:b0:9d:efbe:52ae with SMTP id iu5-20020a056a20958500b0009defbe52aemr9258340pzb.30.1674081913730; Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id z7-20020a17090a540700b002290be2732fsm1797333pjh.44.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iX1-1X for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDE-0A for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 09/42] xfs: convert xfs_imap() to take a perag Date: Thu, 19 Jan 2023 09:44:32 +1100 Message-Id: <20230118224505.1964941-10-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Callers have referenced perags but they don't pass it into xfs_imap() so it takes it's own reference. Fix that so we can change inode allocation over to using active references. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ialloc.c | 43 +++++++++++++------------------------- fs/xfs/libxfs/xfs_ialloc.h | 3 ++- fs/xfs/scrub/common.c | 13 ++++++++---- fs/xfs/xfs_icache.c | 2 +- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index e8068422aa21..2b4961ff2e24 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2217,15 +2217,15 @@ xfs_difree( STATIC int xfs_imap_lookup( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_agino_t agino, xfs_agblock_t agbno, xfs_agblock_t *chunk_agbno, xfs_agblock_t *offset_agbno, int flags) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; struct xfs_buf *agbp; @@ -2280,12 +2280,13 @@ xfs_imap_lookup( */ int xfs_imap( - struct xfs_mount *mp, /* file system mount structure */ + struct xfs_perag *pag, struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ uint flags) /* flags for inode btree lookup */ { + struct xfs_mount *mp = pag->pag_mount; xfs_agblock_t agbno; /* block number of inode in the alloc group */ xfs_agino_t agino; /* inode number within alloc group */ xfs_agblock_t chunk_agbno; /* first block in inode chunk */ @@ -2293,17 +2294,15 @@ xfs_imap( int error; /* error code */ int offset; /* index of inode in its buffer */ xfs_agblock_t offset_agbno; /* blks from chunk start to inode */ - struct xfs_perag *pag; ASSERT(ino != NULLFSINO); /* * Split up the inode number into its parts. */ - pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); - if (!pag || agbno >= mp->m_sb.sb_agblocks || + if (agbno >= mp->m_sb.sb_agblocks || ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { error = -EINVAL; #ifdef DEBUG @@ -2312,20 +2311,14 @@ xfs_imap( * as they can be invalid without implying corruption. */ if (flags & XFS_IGET_UNTRUSTED) - goto out_drop; - if (!pag) { - xfs_alert(mp, - "%s: agno (%d) >= mp->m_sb.sb_agcount (%d)", - __func__, XFS_INO_TO_AGNO(mp, ino), - mp->m_sb.sb_agcount); - } + return error; if (agbno >= mp->m_sb.sb_agblocks) { xfs_alert(mp, "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)", __func__, (unsigned long long)agbno, (unsigned long)mp->m_sb.sb_agblocks); } - if (pag && ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { + if (ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) { xfs_alert(mp, "%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)", __func__, ino, @@ -2333,7 +2326,7 @@ xfs_imap( } xfs_stack_trace(); #endif /* DEBUG */ - goto out_drop; + return error; } /* @@ -2344,10 +2337,10 @@ xfs_imap( * in all cases where an untrusted inode number is passed. */ if (flags & XFS_IGET_UNTRUSTED) { - error = xfs_imap_lookup(mp, tp, pag, agino, agbno, + error = xfs_imap_lookup(pag, tp, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) - goto out_drop; + return error; goto out_map; } @@ -2363,8 +2356,7 @@ xfs_imap( imap->im_len = XFS_FSB_TO_BB(mp, 1); imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog); - error = 0; - goto out_drop; + return 0; } /* @@ -2376,10 +2368,10 @@ xfs_imap( offset_agbno = agbno & M_IGEO(mp)->inoalign_mask; chunk_agbno = agbno - offset_agbno; } else { - error = xfs_imap_lookup(mp, tp, pag, agino, agbno, + error = xfs_imap_lookup(pag, tp, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) - goto out_drop; + return error; } out_map: @@ -2407,14 +2399,9 @@ xfs_imap( __func__, (unsigned long long) imap->im_blkno, (unsigned long long) imap->im_len, XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); - error = -EINVAL; - goto out_drop; + return -EINVAL; } - error = 0; -out_drop: - if (pag) - xfs_perag_put(pag); - return error; + return 0; } /* diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 9bbbca6ac4ed..4cfce2eebe7e 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -12,6 +12,7 @@ struct xfs_imap; struct xfs_mount; struct xfs_trans; struct xfs_btree_cur; +struct xfs_perag; /* Move inodes in clusters of this size */ #define XFS_INODE_BIG_CLUSTER_SIZE 8192 @@ -47,7 +48,7 @@ int xfs_difree(struct xfs_trans *tp, struct xfs_perag *pag, */ int xfs_imap( - struct xfs_mount *mp, /* file system mount structure */ + struct xfs_perag *pag, struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 613260b04a3d..033bf6730ece 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -636,6 +636,7 @@ xchk_get_inode( { struct xfs_imap imap; struct xfs_mount *mp = sc->mp; + struct xfs_perag *pag; struct xfs_inode *ip_in = XFS_I(file_inode(sc->file)); struct xfs_inode *ip = NULL; int error; @@ -671,10 +672,14 @@ xchk_get_inode( * Otherwise, we really couldn't find it so tell userspace * that it no longer exists. */ - error = xfs_imap(sc->mp, sc->tp, sc->sm->sm_ino, &imap, - XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE); - if (error) - return -ENOENT; + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, sc->sm->sm_ino)); + if (pag) { + error = xfs_imap(pag, sc->tp, sc->sm->sm_ino, &imap, + XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE); + xfs_perag_put(pag); + if (error) + return -ENOENT; + } error = -EFSCORRUPTED; fallthrough; default: diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 8b2823d85a68..c9a7e270a428 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -586,7 +586,7 @@ xfs_iget_cache_miss( if (!ip) return -ENOMEM; - error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, flags); + error = xfs_imap(pag, tp, ip->i_ino, &ip->i_imap, flags); if (error) goto out_destroy; From patchwork Wed Jan 18 22:44:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107122 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 737E0C54EBE for ; Wed, 18 Jan 2023 22:45:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229496AbjARWpV (ORCPT ); Wed, 18 Jan 2023 17:45:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229615AbjARWpP (ORCPT ); Wed, 18 Jan 2023 17:45:15 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 525FF5FD60 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id o13so574265pjg.2 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Y25zJwP0StYPGXgFaiX2SPH81kZh9kcaa464zrV/Cx4=; b=2/JA8lApyH0HBFGe0KPxCROww1e0qbqxMRvoIGJReRQZe5To718zs69i78zVeQS23A l6r+DFnEFo5MTdMemuqBFB7uvcAfoCGqsZ3lLa7KqS8kk0SzTtf0MON7mMbDKur5FbaP nVO2XiLMRZ0dqJZ1phxek737AOhEj+u95EMs9Sb/fKP8mr0r3M3JUFZxTAlykRWLpGxc dXQXthnTt8SKtOi/YTKUHGwznLAIpcLbhFnxl9yGZk4IYckDZBU7TIlLigpBGp1WRfyZ MZ/rEfo6WHNFNTMliBIWGxu9FP5o3mYXfeBElQiaWmBMjB1smpD15LsinY4boUBv4Scg KlOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Y25zJwP0StYPGXgFaiX2SPH81kZh9kcaa464zrV/Cx4=; b=YQZZwpFmFZXm7cdN3hGVbRovUfg5v1+mxnb0QEzz+OFaArsyk/yDr9Zh/g1Vz5nn68 Wp2LxBYhAxRTM/7s5TMphyw3wC8k7J0wnz3ycw1DNVUCBV9DUTHGoo5/XU8V6NEieBm+ k9MDZbBikOEECqwX/xmApOGegDDpSFieff1OCKaUyM5egva+NEQVUOUE1qgBadApiS0X FnPdnugFecULsgPTCOdY+UzOpLnMiIWBoeNB8S3TxRXvClpq/8+ZlXVZgRKViCTKuOol BzzRrz6lfCDnh1JlficmYLByv119UP1PFt7uRDO8Plem7pLT1n/djVCpJusYK0MuXeEH PkIg== X-Gm-Message-State: AFqh2kquL6ojOLRsjBUgafbwqSfyVQvXJyqYcjsmJNlrutF/RhmjzT5F Ah5s1amxnAIgy1wXTa7/EGors7Ja/B8XDfBL X-Google-Smtp-Source: AMrXdXuUU3ubz/Ir3WDgZaYjShbncomYxI522up/e3B1PmpCNegqOoTNMwvrdr+VXoN8AjbHBg7n3g== X-Received: by 2002:a17:902:ec82:b0:194:3fd8:f56a with SMTP id x2-20020a170902ec8200b001943fd8f56amr11709963plg.55.1674081913884; Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id s1-20020a170902ea0100b001913c5fc051sm12471753plg.274.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iX4-2S for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDJ-0F for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 10/42] xfs: use active perag references for inode allocation Date: Thu, 19 Jan 2023 09:44:33 +1100 Message-Id: <20230118224505.1964941-11-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Convert the inode allocation routines to use active perag references or references held by callers rather than grab their own. Also drive the perag further inwards to replace xfs_mounts when doing operations on a specific AG. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ag.c | 3 +- fs/xfs/libxfs/xfs_ialloc.c | 63 +++++++++++++++++++------------------- fs/xfs/libxfs/xfs_ialloc.h | 2 +- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 7cff61875340..a3bdcde95845 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -925,8 +925,7 @@ xfs_ag_shrink_space( * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. */ - error = xfs_ialloc_check_shrink(*tpp, pag->pag_agno, agibp, - aglen - delta); + error = xfs_ialloc_check_shrink(pag, *tpp, agibp, aglen - delta); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 2b4961ff2e24..a1a482ec3065 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -169,14 +169,14 @@ xfs_inobt_insert_rec( */ STATIC int xfs_inobt_insert( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t newino, xfs_agino_t newlen, xfs_btnum_t btnum) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; xfs_agino_t thisino; int i; @@ -514,14 +514,14 @@ __xfs_inobt_rec_merge( */ STATIC int xfs_inobt_insert_sprec( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, int btnum, struct xfs_inobt_rec_incore *nrec, /* in/out: new/merged rec. */ bool merge) /* merge or replace */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; int error; int i; @@ -609,9 +609,9 @@ xfs_inobt_insert_sprec( */ STATIC int xfs_ialloc_ag_alloc( + struct xfs_perag *pag, struct xfs_trans *tp, - struct xfs_buf *agbp, - struct xfs_perag *pag) + struct xfs_buf *agbp) { struct xfs_agi *agi; struct xfs_alloc_arg args; @@ -831,7 +831,7 @@ xfs_ialloc_ag_alloc( * if necessary. If a merge does occur, rec is updated to the * merged record. */ - error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag, + error = xfs_inobt_insert_sprec(pag, tp, agbp, XFS_BTNUM_INO, &rec, true); if (error == -EFSCORRUPTED) { xfs_alert(args.mp, @@ -856,20 +856,20 @@ xfs_ialloc_ag_alloc( * existing record with this one. */ if (xfs_has_finobt(args.mp)) { - error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag, + error = xfs_inobt_insert_sprec(pag, tp, agbp, XFS_BTNUM_FINO, &rec, false); if (error) return error; } } else { /* full chunk - insert new records to both btrees */ - error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, newlen, + error = xfs_inobt_insert(pag, tp, agbp, newino, newlen, XFS_BTNUM_INO); if (error) return error; if (xfs_has_finobt(args.mp)) { - error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, + error = xfs_inobt_insert(pag, tp, agbp, newino, newlen, XFS_BTNUM_FINO); if (error) return error; @@ -981,9 +981,9 @@ xfs_inobt_first_free_inode( */ STATIC int xfs_dialloc_ag_inobt( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_ino_t parent, xfs_ino_t *inop) { @@ -1429,9 +1429,9 @@ xfs_dialloc_ag_update_inobt( */ static int xfs_dialloc_ag( + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_ino_t parent, xfs_ino_t *inop) { @@ -1448,7 +1448,7 @@ xfs_dialloc_ag( int i; if (!xfs_has_finobt(mp)) - return xfs_dialloc_ag_inobt(tp, agbp, pag, parent, inop); + return xfs_dialloc_ag_inobt(pag, tp, agbp, parent, inop); /* * If pagino is 0 (this is the root inode allocation) use newino. @@ -1594,8 +1594,8 @@ xfs_ialloc_next_ag( static bool xfs_dialloc_good_ag( - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, umode_t mode, int flags, bool ok_alloc) @@ -1606,6 +1606,8 @@ xfs_dialloc_good_ag( int needspace; int error; + if (!pag) + return false; if (!pag->pagi_inodeok) return false; @@ -1665,8 +1667,8 @@ xfs_dialloc_good_ag( static int xfs_dialloc_try_ag( - struct xfs_trans **tpp, struct xfs_perag *pag, + struct xfs_trans **tpp, xfs_ino_t parent, xfs_ino_t *new_ino, bool ok_alloc) @@ -1689,7 +1691,7 @@ xfs_dialloc_try_ag( goto out_release; } - error = xfs_ialloc_ag_alloc(*tpp, agbp, pag); + error = xfs_ialloc_ag_alloc(pag, *tpp, agbp); if (error < 0) goto out_release; @@ -1705,7 +1707,7 @@ xfs_dialloc_try_ag( } /* Allocate an inode in the found AG */ - error = xfs_dialloc_ag(*tpp, agbp, pag, parent, &ino); + error = xfs_dialloc_ag(pag, *tpp, agbp, parent, &ino); if (!error) *new_ino = ino; return error; @@ -1790,9 +1792,9 @@ xfs_dialloc( agno = start_agno; flags = XFS_ALLOC_FLAG_TRYLOCK; for (;;) { - pag = xfs_perag_get(mp, agno); - if (xfs_dialloc_good_ag(*tpp, pag, mode, flags, ok_alloc)) { - error = xfs_dialloc_try_ag(tpp, pag, parent, + pag = xfs_perag_grab(mp, agno); + if (xfs_dialloc_good_ag(pag, *tpp, mode, flags, ok_alloc)) { + error = xfs_dialloc_try_ag(pag, tpp, parent, &ino, ok_alloc); if (error != -EAGAIN) break; @@ -1813,12 +1815,12 @@ xfs_dialloc( if (low_space) ok_alloc = true; } - xfs_perag_put(pag); + xfs_perag_rele(pag); } if (!error) *new_ino = ino; - xfs_perag_put(pag); + xfs_perag_rele(pag); return error; } @@ -1902,14 +1904,14 @@ xfs_difree_inode_chunk( STATIC int xfs_difree_inobt( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t agino, struct xfs_icluster *xic, struct xfs_inobt_rec_incore *orec) { + struct xfs_mount *mp = pag->pag_mount; struct xfs_agi *agi = agbp->b_addr; struct xfs_btree_cur *cur; struct xfs_inobt_rec_incore rec; @@ -2036,13 +2038,13 @@ xfs_difree_inobt( */ STATIC int xfs_difree_finobt( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_agino_t agino, struct xfs_inobt_rec_incore *ibtrec) /* inobt record */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; struct xfs_inobt_rec_incore rec; int offset = agino - ibtrec->ir_startino; @@ -2196,7 +2198,7 @@ xfs_difree( /* * Fix up the inode allocation btree. */ - error = xfs_difree_inobt(mp, tp, agbp, pag, agino, xic, &rec); + error = xfs_difree_inobt(pag, tp, agbp, agino, xic, &rec); if (error) goto error0; @@ -2204,7 +2206,7 @@ xfs_difree( * Fix up the free inode btree. */ if (xfs_has_finobt(mp)) { - error = xfs_difree_finobt(mp, tp, agbp, pag, agino, &rec); + error = xfs_difree_finobt(pag, tp, agbp, agino, &rec); if (error) goto error0; } @@ -2928,15 +2930,14 @@ xfs_ialloc_calc_rootino( */ int xfs_ialloc_check_shrink( + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t agno, struct xfs_buf *agibp, xfs_agblock_t new_length) { struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; xfs_agino_t agino = XFS_AGB_TO_AGINO(mp, new_length); int has; int error; @@ -2944,7 +2945,6 @@ xfs_ialloc_check_shrink( if (!xfs_has_sparseinodes(mp)) return 0; - pag = xfs_perag_get(mp, agno); cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO); /* Look up the inobt record that would correspond to the new EOFS. */ @@ -2968,6 +2968,5 @@ xfs_ialloc_check_shrink( } out: xfs_btree_del_cursor(cur, error); - xfs_perag_put(pag); return error; } diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 4cfce2eebe7e..ab8c30b4ec22 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -107,7 +107,7 @@ int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); void xfs_ialloc_setup_geometry(struct xfs_mount *mp); xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit); -int xfs_ialloc_check_shrink(struct xfs_trans *tp, xfs_agnumber_t agno, +int xfs_ialloc_check_shrink(struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agibp, xfs_agblock_t new_length); #endif /* __XFS_IALLOC_H__ */ From patchwork Wed Jan 18 22:44:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107127 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 941DDC46467 for ; Wed, 18 Jan 2023 22:45:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229615AbjARWpZ (ORCPT ); Wed, 18 Jan 2023 17:45:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229716AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A5C2863E28 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pj1-x1036.google.com with SMTP id o13so574275pjg.2 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=oXnxHrvjcJHOMBDVifrePCdCYpjGFbtO/BsKk6T+P44=; b=ke2kCbVvecD0iRD3u/6jU43iv1FFE1b4vtcUzfufWWvtQtmC83uxyKRvhQotwrFoB2 3dgWIyA3cyCUmETZpAv2nuE6HxqAI4wZf/ToEhRjWhHfyaPcFI0a6ZKcJaHG8Lo63H2Q yuV4Gs9IQ1pfbYGAzv2STDwBjbAmZVxcL1iZPeyLh35+3Ezoh3GwVayLOScVsgmYUfV+ YgoP8BXx45SqRfmLKA/gRXyLHyfoPaUW517c9GM667VhN5GDq+3N0zQYPXJRkdKuXYun DffUqK4rlNtDXI10JA7esqwGZu/mCigvYU4if1eqDz8mcyPan+VEFdxGlV+wPhidslvJ 0GOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oXnxHrvjcJHOMBDVifrePCdCYpjGFbtO/BsKk6T+P44=; b=2BGW+K05YTFB7XI5qUsZV1SynUKyCww8Hi8kB56hP/rkF6gsvSmWxW+cBNwWHGXivB enWH9QonOOM439R2PmFukTiOgFNLjfUQU5cIz8trQjBACXxAJ450Jv9cek61Cu7VssGl yq92ZZJKTlufjLaYhaicahICa9PV1cSpPpbjEP/pVIs+mX3aNdH27RZKkWU0lX5OyXi8 lUl5Zuztp+UWg6p8LTyIEdyTihANufajthSpBzSWglYwRGMAd/2QPnbp5T0vfXEilB3n +CuUCsji3BlJ+zZ6Q7a+M8rXVdB0Eb+HVRduRxVlgppC4YyaVdFWaqOyWlAneC6LrGd9 cGvA== X-Gm-Message-State: AFqh2kqOSj/YdH3todKmE3wPorOycRHvq8gvDwAuVM07jGwwIMW1pjYv OC6yRN3sbZz/mTe/W17zsEkU3JixfT86OJuv X-Google-Smtp-Source: AMrXdXtHyTubo9AdPm1NARBUXtqr7bxfsMQpzsz3Rk5RTDQBv/DKvAw6ayVfotD5YwaHfOZX0wKIdQ== X-Received: by 2002:a05:6a21:7888:b0:b5:d63e:a9d7 with SMTP id bf8-20020a056a21788800b000b5d63ea9d7mr12351022pzc.60.1674081914162; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id i22-20020a63e456000000b004a4dc6aeae3sm19570879pgk.74.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iX8-3O for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDO-0L for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 11/42] xfs: inobt can use perags in many more places than it does Date: Thu, 19 Jan 2023 09:44:34 +1100 Message-Id: <20230118224505.1964941-12-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Lots of code in the inobt infrastructure is passed both xfs_mount and perags. We only need perags for the per-ag inode allocation code, so reduce the duplication by passing only the perags as the primary object. This ends up reducing the code size by a bit: text data bss dec hex filename orig 1138878 323979 548 1463405 16546d (TOTALS) patched 1138709 323979 548 1463236 1653c4 (TOTALS) Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ag_resv.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 25 +++++++++++---------- fs/xfs/libxfs/xfs_ialloc_btree.c | 37 ++++++++++++++------------------ fs/xfs/libxfs/xfs_ialloc_btree.h | 20 ++++++++--------- fs/xfs/scrub/agheader_repair.c | 7 +++--- fs/xfs/scrub/common.c | 8 +++---- fs/xfs/xfs_iwalk.c | 4 ++-- 7 files changed, 47 insertions(+), 56 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index 5af123d13a63..7fd1fea95552 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -264,7 +264,7 @@ xfs_ag_resv_init( if (error) goto out; - error = xfs_finobt_calc_reserves(mp, tp, pag, &ask, &used); + error = xfs_finobt_calc_reserves(pag, tp, &ask, &used); if (error) goto out; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index a1a482ec3065..5b8401038bab 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -176,13 +176,12 @@ xfs_inobt_insert( xfs_agino_t newlen, xfs_btnum_t btnum) { - struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; xfs_agino_t thisino; int i; int error; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum); + cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum); for (thisino = newino; thisino < newino + newlen; @@ -527,7 +526,7 @@ xfs_inobt_insert_sprec( int i; struct xfs_inobt_rec_incore rec; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum); + cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum); /* the new record is pre-aligned so we know where to look */ error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i); @@ -1004,7 +1003,7 @@ xfs_dialloc_ag_inobt( ASSERT(pag->pagi_freecount > 0); restart_pagno: - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); /* * If pagino is 0 (this is the root inode allocation) use newino. * This must work because we've just allocated some. @@ -1457,7 +1456,7 @@ xfs_dialloc_ag( if (!pagino) pagino = be32_to_cpu(agi->agi_newino); - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO); error = xfs_check_agi_freecount(cur); if (error) @@ -1500,7 +1499,7 @@ xfs_dialloc_ag( * the original freecount. If all is well, make the equivalent update to * the inobt using the finobt record and offset information. */ - icur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + icur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_check_agi_freecount(icur); if (error) @@ -1926,7 +1925,7 @@ xfs_difree_inobt( /* * Initialize the cursor. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_check_agi_freecount(cur); if (error) @@ -2051,7 +2050,7 @@ xfs_difree_finobt( int error; int i; - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO); error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i); if (error) @@ -2248,7 +2247,7 @@ xfs_imap_lookup( * we have a record, we need to ensure it contains the inode number * we are looking up. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); if (!error) { if (i) @@ -2937,17 +2936,17 @@ xfs_ialloc_check_shrink( { struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; - struct xfs_mount *mp = tp->t_mountp; - xfs_agino_t agino = XFS_AGB_TO_AGINO(mp, new_length); + xfs_agino_t agino; int has; int error; - if (!xfs_has_sparseinodes(mp)) + if (!xfs_has_sparseinodes(pag->pag_mount)) return 0; - cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(pag, tp, agibp, XFS_BTNUM_INO); /* Look up the inobt record that would correspond to the new EOFS. */ + agino = XFS_AGB_TO_AGINO(pag->pag_mount, new_length); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has); if (error || !has) goto out; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 8c83e265770c..d657af2ec350 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -36,8 +36,8 @@ STATIC struct xfs_btree_cur * xfs_inobt_dup_cursor( struct xfs_btree_cur *cur) { - return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, - cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum); + return xfs_inobt_init_cursor(cur->bc_ag.pag, cur->bc_tp, + cur->bc_ag.agbp, cur->bc_btnum); } STATIC void @@ -427,11 +427,11 @@ static const struct xfs_btree_ops xfs_finobt_ops = { */ static struct xfs_btree_cur * xfs_inobt_init_common( - struct xfs_mount *mp, /* file system mount point */ - struct xfs_trans *tp, /* transaction pointer */ struct xfs_perag *pag, + struct xfs_trans *tp, /* transaction pointer */ xfs_btnum_t btnum) /* ialloc or free ino btree */ { + struct xfs_mount *mp = pag->pag_mount; struct xfs_btree_cur *cur; cur = xfs_btree_alloc_cursor(mp, tp, btnum, @@ -456,16 +456,15 @@ xfs_inobt_init_common( /* Create an inode btree cursor. */ struct xfs_btree_cur * xfs_inobt_init_cursor( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_btnum_t btnum) { struct xfs_btree_cur *cur; struct xfs_agi *agi = agbp->b_addr; - cur = xfs_inobt_init_common(mp, tp, pag, btnum); + cur = xfs_inobt_init_common(pag, tp, btnum); if (btnum == XFS_BTNUM_INO) cur->bc_nlevels = be32_to_cpu(agi->agi_level); else @@ -477,14 +476,13 @@ xfs_inobt_init_cursor( /* Create an inode btree cursor with a fake root for staging. */ struct xfs_btree_cur * xfs_inobt_stage_cursor( - struct xfs_mount *mp, - struct xbtree_afakeroot *afake, struct xfs_perag *pag, + struct xbtree_afakeroot *afake, xfs_btnum_t btnum) { struct xfs_btree_cur *cur; - cur = xfs_inobt_init_common(mp, NULL, pag, btnum); + cur = xfs_inobt_init_common(pag, NULL, btnum); xfs_btree_stage_afakeroot(cur, afake); return cur; } @@ -708,9 +706,8 @@ xfs_inobt_max_size( /* Read AGI and create inobt cursor. */ int xfs_inobt_cur( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_btnum_t which, struct xfs_btree_cur **curpp, struct xfs_buf **agi_bpp) @@ -725,16 +722,15 @@ xfs_inobt_cur( if (error) return error; - cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, pag, which); + cur = xfs_inobt_init_cursor(pag, tp, *agi_bpp, which); *curpp = cur; return 0; } static int xfs_inobt_count_blocks( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_btnum_t btnum, xfs_extlen_t *tree_blocks) { @@ -742,7 +738,7 @@ xfs_inobt_count_blocks( struct xfs_btree_cur *cur = NULL; int error; - error = xfs_inobt_cur(mp, tp, pag, btnum, &cur, &agbp); + error = xfs_inobt_cur(pag, tp, btnum, &cur, &agbp); if (error) return error; @@ -779,22 +775,21 @@ xfs_finobt_read_blocks( */ int xfs_finobt_calc_reserves( - struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_trans *tp, xfs_extlen_t *ask, xfs_extlen_t *used) { xfs_extlen_t tree_len = 0; int error; - if (!xfs_has_finobt(mp)) + if (!xfs_has_finobt(pag->pag_mount)) return 0; - if (xfs_has_inobtcounts(mp)) + if (xfs_has_inobtcounts(pag->pag_mount)) error = xfs_finobt_read_blocks(pag, tp, &tree_len); else - error = xfs_inobt_count_blocks(mp, tp, pag, XFS_BTNUM_FINO, + error = xfs_inobt_count_blocks(pag, tp, XFS_BTNUM_FINO, &tree_len); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index 26451cb76b98..e859a6e05230 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -46,12 +46,10 @@ struct xfs_perag; (maxrecs) * sizeof(xfs_inobt_key_t) + \ ((index) - 1) * sizeof(xfs_inobt_ptr_t))) -extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_buf *agbp, - struct xfs_perag *pag, xfs_btnum_t btnum); -struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_mount *mp, - struct xbtree_afakeroot *afake, struct xfs_perag *pag, - xfs_btnum_t btnum); +extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_perag *pag, + struct xfs_trans *tp, struct xfs_buf *agbp, xfs_btnum_t btnum); +struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_perag *pag, + struct xbtree_afakeroot *afake, xfs_btnum_t btnum); extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); /* ir_holemask to inode allocation bitmap conversion */ @@ -64,13 +62,13 @@ int xfs_inobt_rec_check_count(struct xfs_mount *, #define xfs_inobt_rec_check_count(mp, rec) 0 #endif /* DEBUG */ -int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, - struct xfs_perag *pag, xfs_extlen_t *ask, xfs_extlen_t *used); +int xfs_finobt_calc_reserves(struct xfs_perag *perag, struct xfs_trans *tp, + xfs_extlen_t *ask, xfs_extlen_t *used); extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, unsigned long long len); -int xfs_inobt_cur(struct xfs_mount *mp, struct xfs_trans *tp, - struct xfs_perag *pag, xfs_btnum_t btnum, - struct xfs_btree_cur **curpp, struct xfs_buf **agi_bpp); +int xfs_inobt_cur(struct xfs_perag *pag, struct xfs_trans *tp, + xfs_btnum_t btnum, struct xfs_btree_cur **curpp, + struct xfs_buf **agi_bpp); void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index d75d82151eeb..b80b9111e781 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -873,8 +873,7 @@ xrep_agi_calc_from_btrees( xfs_agino_t freecount; int error; - cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, - sc->sa.pag, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, XFS_BTNUM_INO); error = xfs_ialloc_count_inodes(cur, &count, &freecount); if (error) goto err; @@ -894,8 +893,8 @@ xrep_agi_calc_from_btrees( if (xfs_has_finobt(mp) && xfs_has_inobtcounts(mp)) { xfs_agblock_t blocks; - cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, - sc->sa.pag, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, + XFS_BTNUM_FINO); error = xfs_btree_count_blocks(cur, &blocks); if (error) goto err; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 033bf6730ece..848a8e32e56f 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -478,15 +478,15 @@ xchk_ag_btcur_init( /* Set up a inobt cursor for cross-referencing. */ if (sa->agi_bp && xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) { - sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - sa->pag, XFS_BTNUM_INO); + sa->ino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp, + XFS_BTNUM_INO); } /* Set up a finobt cursor for cross-referencing. */ if (sa->agi_bp && xfs_has_finobt(mp) && xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) { - sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - sa->pag, XFS_BTNUM_FINO); + sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp, + XFS_BTNUM_FINO); } /* Set up a rmapbt cursor for cross-referencing. */ diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index c31857d903a4..21be93bf006d 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -275,7 +275,7 @@ xfs_iwalk_ag_start( /* Set up a fresh cursor and empty the inobt cache. */ iwag->nr_recs = 0; - error = xfs_inobt_cur(mp, tp, pag, XFS_BTNUM_INO, curpp, agi_bpp); + error = xfs_inobt_cur(pag, tp, XFS_BTNUM_INO, curpp, agi_bpp); if (error) return error; @@ -390,7 +390,7 @@ xfs_iwalk_run_callbacks( } /* ...and recreate the cursor just past where we left off. */ - error = xfs_inobt_cur(mp, iwag->tp, iwag->pag, XFS_BTNUM_INO, curpp, + error = xfs_inobt_cur(iwag->pag, iwag->tp, XFS_BTNUM_INO, curpp, agi_bpp); if (error) return error; From patchwork Wed Jan 18 22:44:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107130 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62B90C38159 for ; Wed, 18 Jan 2023 22:45:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229699AbjARWp1 (ORCPT ); Wed, 18 Jan 2023 17:45:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229820AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 44E8763E3D for ; Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: by mail-pf1-x436.google.com with SMTP id z3so126927pfb.2 for ; Wed, 18 Jan 2023 14:45:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=AM/yFw9DPN4KIAGOss3si3SHWCLwKSOHyX05QXq/+Rc=; b=aMGGe3rq0NW16xm9yj1KDr3HF6WXXa5zVEzYJrskcWxGOtooZfi5+OH86NoOuNDM74 UngDWNWiWmdosdvmqkelj2nV4xW1FehXh0tVO1G+QeOiIOGNvcdeIP/Rl84v+llAG7LA jCUotXOvs+1JVcwk0yZxzPCCUOak/ysNbHECd3g6kwaa/Tk8Va4mkaFV2U3lxjOndrZN rWhfKkjG4u6C1rxl2Ab41PzVn6KscfuMWkflV4NPOsaAXfODSLyo63XyY8QC1FTJeiUu npDwJNLr/cgSqH8ytunBYbZcDC8eUqx54YaiaTalruAGWpnPUBKZ1EdEIZ+zUMmljCAr yoSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AM/yFw9DPN4KIAGOss3si3SHWCLwKSOHyX05QXq/+Rc=; b=oKsVvG10S9EbpiyqJX2Qhm/xo/KCnNBvMFkpGt79VPr+iHr/HpM9HlYKJUeakDTThC nJshOU5V47EP6gqVaofQOSbLCF5n2kn7+NRlzfCwSX6lY26BlsXKIFYgWzfIpn1uqi4N uWbc5qFXob3o903mlWaV8mzc/M/pDh1diCbKZYLh+wTtzmgOck1tZtTLvTie01ksjggc a9r4ZAlfe8lBIPvZX40mh9jsYMdkCeLrmG5f6aK+uR4ZXsMeUMsLwrCqT1st2HuvtW1/ vE1FVP+wZ+2mFsgXscNuzzGuygGhUUKeZkAOTilTVIILx/alnmgvfhrCVtrLbcdGxhDV O5kw== X-Gm-Message-State: AFqh2kqUsGMhKsFHsMvKEJY4H2JMa9QZnXgooiIOwKExtdVZCH9o/5AS oWy/wgzMmMfisFzOEmCJSsU8gGZWnwm0OFI8 X-Google-Smtp-Source: AMrXdXtdsZoZUQfXdxaz1gbaJM60ep3Ml4b34C2P8STJd5Zsb6UbTauwM1dJA72DXEgaBIBpiC5A9w== X-Received: by 2002:a05:6a00:3495:b0:58d:d7b6:cf58 with SMTP id cp21-20020a056a00349500b0058dd7b6cf58mr7622217pfb.7.1674081915799; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id 3-20020a621503000000b00581c741f95csm20795520pfv.46.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXA-4H for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDT-0R for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 12/42] xfs: convert xfs_ialloc_next_ag() to an atomic Date: Thu, 19 Jan 2023 09:44:35 +1100 Message-Id: <20230118224505.1964941-13-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner This is currently a spinlock lock protected rotor which can be implemented with a single atomic operation. Change it to be more efficient and get rid of the m_agirotor_lock. Noticed while converting the inode allocation AG selection loop to active perag references. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ialloc.c | 17 +---------------- fs/xfs/libxfs/xfs_sb.c | 3 ++- fs/xfs/xfs_mount.h | 3 +-- fs/xfs/xfs_super.c | 1 - 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 5b8401038bab..c8d837d8876f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1576,21 +1576,6 @@ xfs_dialloc_roll( return error; } -static xfs_agnumber_t -xfs_ialloc_next_ag( - xfs_mount_t *mp) -{ - xfs_agnumber_t agno; - - spin_lock(&mp->m_agirotor_lock); - agno = mp->m_agirotor; - if (++mp->m_agirotor >= mp->m_maxagi) - mp->m_agirotor = 0; - spin_unlock(&mp->m_agirotor_lock); - - return agno; -} - static bool xfs_dialloc_good_ag( struct xfs_perag *pag, @@ -1748,7 +1733,7 @@ xfs_dialloc( * an AG has enough space for file creation. */ if (S_ISDIR(mode)) - start_agno = xfs_ialloc_next_ag(mp); + start_agno = atomic_inc_return(&mp->m_agirotor) % mp->m_maxagi; else { start_agno = XFS_INO_TO_AGNO(mp, parent); if (start_agno >= mp->m_maxagi) diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 1eeecf2eb2a7..99cc03a298e2 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -909,7 +909,8 @@ xfs_sb_mount_common( struct xfs_mount *mp, struct xfs_sb *sbp) { - mp->m_agfrotor = mp->m_agirotor = 0; + mp->m_agfrotor = 0; + atomic_set(&mp->m_agirotor, 0); mp->m_maxagi = mp->m_sb.sb_agcount; mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8aca2cc173ac..f3269c0626f0 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -210,8 +210,7 @@ typedef struct xfs_mount { struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX]; struct xstats m_stats; /* per-fs stats */ xfs_agnumber_t m_agfrotor; /* last ag where space found */ - xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ - spinlock_t m_agirotor_lock;/* .. and lock protecting it */ + atomic_t m_agirotor; /* last ag dir inode alloced */ /* Memory shrinker to throttle and reprioritize inodegc */ struct shrinker m_inodegc_shrinker; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 0c4b73e9b29d..96375b5622fd 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1922,7 +1922,6 @@ static int xfs_init_fs_context( return -ENOMEM; spin_lock_init(&mp->m_sb_lock); - spin_lock_init(&mp->m_agirotor_lock); INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); spin_lock_init(&mp->m_perag_lock); mutex_init(&mp->m_growlock); From patchwork Wed Jan 18 22:44:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107126 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18299C678DB for ; Wed, 18 Jan 2023 22:45:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229569AbjARWpY (ORCPT ); Wed, 18 Jan 2023 17:45:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229710AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8206461D4E for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pf1-x436.google.com with SMTP id s3so91051pfd.12 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=AVelVzwO91snn4PzAhF9uDHStdiBUaJ/Y7lIbfytOdE=; b=sEmh9qVSo7Zb+J7YJCCNKJ0exSKAHmBKTMO5sizLAEByvOICLyjsm5Ftu8yKK4YGsK MQGdtotkpeh5gAGttAAs4aCyGwE8qpPdzzHZ1fpNaYiDvaPoo0bkmmn0g1uTZag/aT9W QqCZzjXw17e2w7v0utYG/+zx0ScyTTYApZzk1vRvjs763r6KwvPV2Iy4WBS7YRiLM6gp hpNH2r+o6dP01FLdizXjrntSj/iUDmHMloFF1KZAyWYvhwCIt5biFNV2WBfBUBNei7/C hOHFfeChZveHP/HW05EUeyaVtm81YTBniSggE2xBtE7zkHJFb3O7wPg63viKVUhVCyuF gNNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AVelVzwO91snn4PzAhF9uDHStdiBUaJ/Y7lIbfytOdE=; b=64Ir3svex3ZRa3CBy6A22da+hW5Ya1yFMtR2k0w1wGcZO4vYVolaJg6QY6zhxhOt7s oEcXaCPycefzVdWLyVk94FJDON4iBYEs2Mxx1BIUS3k0bRPf8d5fS9y3EYtZwN2Spgae QTZx94vxuv+qgAIi4S1c8ekcza64IgSnfHBrQdv5pBN3q1KyD1upRvunCJRLd1z+f1f3 Z04euPg77/zkfATXaE4/gtgc8SoOlOQUeizZHhIfut6vZ2erPkfHXa2ilFiE+NKFaAdN c8bOUsjztI8fikX3Ko5Khtr63AKYPtzeSRbMpI34WdgfxYGyn62YGjC7PehFRAfq5MmT /nfg== X-Gm-Message-State: AFqh2kqhDnC61o7Wx7kUE+QCLLzVucg7ZHTMMo3LT8RkRwHoMrACXNCK lNZ998GM1pBYp4dVP3+YHmKtLGtSwZAmOFRy X-Google-Smtp-Source: AMrXdXuzN+aUkRBmMd6FF66E6vwAigW0ubemPWXESWqXyIuKYvaB2zihlDefrPurPECFqlLeuj8TWQ== X-Received: by 2002:a05:6a00:f07:b0:581:61a7:c8f0 with SMTP id cr7-20020a056a000f0700b0058161a7c8f0mr9531385pfb.4.1674081913878; Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id h28-20020a056a00001c00b0058bba6f06c5sm10112235pfk.8.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXD-5E for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDY-0W for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 13/42] xfs: perags need atomic operational state Date: Thu, 19 Jan 2023 09:44:36 +1100 Message-Id: <20230118224505.1964941-14-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We currently don't have any flags or operational state in the xfs_perag except for the pagf_init and pagi_init flags. And the agflreset flag. Oh, there's also the pagf_metadata and pagi_inodeok flags, too. For controlling per-ag operations, we are going to need some atomic state flags. Hence add an opstate field similar to what we already have in the mount and log, and convert all these state flags across to atomic bit operations. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_ag.h | 27 ++++++++++++++---- fs/xfs/libxfs/xfs_alloc.c | 23 ++++++++------- fs/xfs/libxfs/xfs_alloc_btree.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 14 ++++----- fs/xfs/libxfs/xfs_ialloc_btree.c | 4 +-- fs/xfs/libxfs/xfs_refcount_btree.c | 2 +- fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- fs/xfs/scrub/agheader_repair.c | 28 +++++++++--------- fs/xfs/scrub/fscounters.c | 9 ++++-- fs/xfs/scrub/repair.c | 2 +- fs/xfs/xfs_filestream.c | 5 ++-- fs/xfs/xfs_super.c | 46 ++++++++++++++++++------------ 13 files changed, 101 insertions(+), 65 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index aeb21c8df201..187d30d9bb13 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -35,13 +35,9 @@ struct xfs_perag { atomic_t pag_ref; /* passive reference count */ atomic_t pag_active_ref; /* active reference count */ wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */ - char pagf_init; /* this agf's entry is initialized */ - char pagi_init; /* this agi's entry is initialized */ - char pagf_metadata; /* the agf is preferred to be metadata */ - char pagi_inodeok; /* The agi is ok for inodes */ + unsigned long pag_opstate; uint8_t pagf_levels[XFS_BTNUM_AGF]; /* # of levels in bno & cnt btree */ - bool pagf_agflreset; /* agfl requires reset before use */ uint32_t pagf_flcount; /* count of blocks in freelist */ xfs_extlen_t pagf_freeblks; /* total free blocks */ xfs_extlen_t pagf_longest; /* longest free space */ @@ -108,6 +104,27 @@ struct xfs_perag { #endif /* __KERNEL__ */ }; +/* + * Per-AG operational state. These are atomic flag bits. + */ +#define XFS_AGSTATE_AGF_INIT 0 +#define XFS_AGSTATE_AGI_INIT 1 +#define XFS_AGSTATE_PREFERS_METADATA 2 +#define XFS_AGSTATE_ALLOWS_INODES 3 +#define XFS_AGSTATE_AGFL_NEEDS_RESET 4 + +#define __XFS_AG_OPSTATE(name, NAME) \ +static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \ +{ \ + return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \ +} + +__XFS_AG_OPSTATE(initialised_agf, AGF_INIT) +__XFS_AG_OPSTATE(initialised_agi, AGI_INIT) +__XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA) +__XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES) +__XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET) + int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi); int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 9f26a9368eeb..246c2e7d9e7a 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2435,7 +2435,7 @@ xfs_agfl_reset( struct xfs_mount *mp = tp->t_mountp; struct xfs_agf *agf = agbp->b_addr; - ASSERT(pag->pagf_agflreset); + ASSERT(xfs_perag_agfl_needs_reset(pag)); trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_); xfs_warn(mp, @@ -2450,7 +2450,7 @@ xfs_agfl_reset( XFS_AGF_FLCOUNT); pag->pagf_flcount = 0; - pag->pagf_agflreset = false; + clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate); } /* @@ -2605,7 +2605,7 @@ xfs_alloc_fix_freelist( /* deferred ops (AGFL block frees) require permanent transactions */ ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ @@ -2620,7 +2620,8 @@ xfs_alloc_fix_freelist( * somewhere else if we are not being asked to try harder at this * point */ - if (pag->pagf_metadata && (args->datatype & XFS_ALLOC_USERDATA) && + if (xfs_perag_prefers_metadata(pag) && + (args->datatype & XFS_ALLOC_USERDATA) && (flags & XFS_ALLOC_FLAG_TRYLOCK)) { ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); goto out_agbp_relse; @@ -2646,7 +2647,7 @@ xfs_alloc_fix_freelist( } /* reset a padding mismatched agfl before final free space check */ - if (pag->pagf_agflreset) + if (xfs_perag_agfl_needs_reset(pag)) xfs_agfl_reset(tp, agbp, pag); /* If there isn't enough total space or single-extent, reject it. */ @@ -2803,7 +2804,7 @@ xfs_alloc_get_freelist( if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp)) agf->agf_flfirst = 0; - ASSERT(!pag->pagf_agflreset); + ASSERT(!xfs_perag_agfl_needs_reset(pag)); be32_add_cpu(&agf->agf_flcount, -1); pag->pagf_flcount--; @@ -2892,7 +2893,7 @@ xfs_alloc_put_freelist( if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp)) agf->agf_fllast = 0; - ASSERT(!pag->pagf_agflreset); + ASSERT(!xfs_perag_agfl_needs_reset(pag)); be32_add_cpu(&agf->agf_flcount, 1); pag->pagf_flcount++; @@ -3099,7 +3100,7 @@ xfs_alloc_read_agf( return error; agf = agfbp->b_addr; - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); @@ -3111,8 +3112,8 @@ xfs_alloc_read_agf( pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); - pag->pagf_init = 1; - pag->pagf_agflreset = xfs_agfl_needs_reset(pag->pag_mount, agf); + if (xfs_agfl_needs_reset(pag->pag_mount, agf)) + set_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate); /* * Update the in-core allocbt counter. Filter out the rmapbt @@ -3127,6 +3128,8 @@ xfs_alloc_read_agf( if (allocbt_blks > 0) atomic64_add(allocbt_blks, &pag->pag_mount->m_allocbt_blks); + + set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); } #ifdef DEBUG else if (!xfs_is_shutdown(pag->pag_mount)) { diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 549a3cba0234..0f29c7b1b39f 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -315,7 +315,7 @@ xfs_allocbt_verify( level = be16_to_cpu(block->bb_level); if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) btnum = XFS_BTNUM_CNTi; - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_levels[btnum]) return __this_address; } else if (level >= mp->m_alloc_maxlevels) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index f15d45af661f..6aad0ea5e606 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3147,7 +3147,7 @@ xfs_bmap_longest_free_extent( int error = 0; pag = xfs_perag_get(mp, ag); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); if (error) { diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c8d837d8876f..2a323ffa5ba9 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -998,8 +998,8 @@ xfs_dialloc_ag_inobt( int i, j; int searchdistance = 10; - ASSERT(pag->pagi_init); - ASSERT(pag->pagi_inodeok); + ASSERT(xfs_perag_initialised_agi(pag)); + ASSERT(xfs_perag_allows_inodes(pag)); ASSERT(pag->pagi_freecount > 0); restart_pagno: @@ -1592,10 +1592,10 @@ xfs_dialloc_good_ag( if (!pag) return false; - if (!pag->pagi_inodeok) + if (!xfs_perag_allows_inodes(pag)) return false; - if (!pag->pagi_init) { + if (!xfs_perag_initialised_agi(pag)) { error = xfs_ialloc_read_agi(pag, tp, NULL); if (error) return false; @@ -1606,7 +1606,7 @@ xfs_dialloc_good_ag( if (!ok_alloc) return false; - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, flags, NULL); if (error) return false; @@ -2603,10 +2603,10 @@ xfs_ialloc_read_agi( return error; agi = agibp->b_addr; - if (!pag->pagi_init) { + if (!xfs_perag_initialised_agi(pag)) { pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); pag->pagi_count = be32_to_cpu(agi->agi_count); - pag->pagi_init = 1; + set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); } /* diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index d657af2ec350..3675a0d29310 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -291,8 +291,8 @@ xfs_inobt_verify( * Similarly, during log recovery we will have a perag structure * attached, but the agi information will not yet have been initialised * from the on disk AGI. We don't currently use any of this information, - * but beware of the landmine (i.e. need to check pag->pagi_init) if we - * ever do. + * but beware of the landmine (i.e. need to check + * xfs_perag_initialised_agi(pag)) if we ever do. */ if (xfs_has_crc(mp)) { fa = xfs_btree_sblock_v5hdr_verify(bp); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index e1f789866683..d20abf0390fc 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -227,7 +227,7 @@ xfs_refcountbt_verify( return fa; level = be16_to_cpu(block->bb_level); - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_refcount_level) return __this_address; } else if (level >= mp->m_refc_maxlevels) diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 7f83f62e51e0..d3285684bb5e 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -313,7 +313,7 @@ xfs_rmapbt_verify( return fa; level = be16_to_cpu(block->bb_level); - if (pag && pag->pagf_init) { + if (pag && xfs_perag_initialised_agf(pag)) { if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) return __this_address; } else if (level >= mp->m_rmap_maxlevels) diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index b80b9111e781..c37e6d72760b 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -191,14 +191,15 @@ xrep_agf_init_header( struct xfs_agf *old_agf) { struct xfs_mount *mp = sc->mp; + struct xfs_perag *pag = sc->sa.pag; struct xfs_agf *agf = agf_bp->b_addr; memcpy(old_agf, agf, sizeof(*old_agf)); memset(agf, 0, BBTOB(agf_bp->b_length)); agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); - agf->agf_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agf->agf_length = cpu_to_be32(sc->sa.pag->block_count); + agf->agf_seqno = cpu_to_be32(pag->pag_agno); + agf->agf_length = cpu_to_be32(pag->block_count); agf->agf_flfirst = old_agf->agf_flfirst; agf->agf_fllast = old_agf->agf_fllast; agf->agf_flcount = old_agf->agf_flcount; @@ -206,8 +207,8 @@ xrep_agf_init_header( uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); /* Mark the incore AGF data stale until we're done fixing things. */ - ASSERT(sc->sa.pag->pagf_init); - sc->sa.pag->pagf_init = 0; + ASSERT(xfs_perag_initialised_agf(pag)); + clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); } /* Set btree root information in an AGF. */ @@ -333,7 +334,7 @@ xrep_agf_commit_new( pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); - pag->pagf_init = 1; + set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); return 0; } @@ -434,7 +435,7 @@ xrep_agf( out_revert: /* Mark the incore AGF state stale and revert the AGF. */ - sc->sa.pag->pagf_init = 0; + clear_bit(XFS_AGSTATE_AGF_INIT, &sc->sa.pag->pag_opstate); memcpy(agf, &old_agf, sizeof(old_agf)); return error; } @@ -618,7 +619,7 @@ xrep_agfl_update_agf( xfs_force_summary_recalc(sc->mp); /* Update the AGF counters. */ - if (sc->sa.pag->pagf_init) + if (xfs_perag_initialised_agf(sc->sa.pag)) sc->sa.pag->pagf_flcount = flcount; agf->agf_flfirst = cpu_to_be32(0); agf->agf_flcount = cpu_to_be32(flcount); @@ -822,14 +823,15 @@ xrep_agi_init_header( struct xfs_agi *old_agi) { struct xfs_agi *agi = agi_bp->b_addr; + struct xfs_perag *pag = sc->sa.pag; struct xfs_mount *mp = sc->mp; memcpy(old_agi, agi, sizeof(*old_agi)); memset(agi, 0, BBTOB(agi_bp->b_length)); agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); - agi->agi_seqno = cpu_to_be32(sc->sa.pag->pag_agno); - agi->agi_length = cpu_to_be32(sc->sa.pag->block_count); + agi->agi_seqno = cpu_to_be32(pag->pag_agno); + agi->agi_length = cpu_to_be32(pag->block_count); agi->agi_newino = cpu_to_be32(NULLAGINO); agi->agi_dirino = cpu_to_be32(NULLAGINO); if (xfs_has_crc(mp)) @@ -840,8 +842,8 @@ xrep_agi_init_header( sizeof(agi->agi_unlinked)); /* Mark the incore AGF data stale until we're done fixing things. */ - ASSERT(sc->sa.pag->pagi_init); - sc->sa.pag->pagi_init = 0; + ASSERT(xfs_perag_initialised_agi(pag)); + clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); } /* Set btree root information in an AGI. */ @@ -928,7 +930,7 @@ xrep_agi_commit_new( pag = sc->sa.pag; pag->pagi_count = be32_to_cpu(agi->agi_count); pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); - pag->pagi_init = 1; + set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); return 0; } @@ -993,7 +995,7 @@ xrep_agi( out_revert: /* Mark the incore AGI state stale and revert the AGI. */ - sc->sa.pag->pagi_init = 0; + clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate); memcpy(agi, &old_agi, sizeof(old_agi)); return error; } diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index ef97670970c3..f0c7f41897b9 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -86,7 +86,8 @@ xchk_fscount_warmup( for_each_perag(mp, agno, pag) { if (xchk_should_terminate(sc, &error)) break; - if (pag->pagi_init && pag->pagf_init) + if (xfs_perag_initialised_agi(pag) && + xfs_perag_initialised_agf(pag)) continue; /* Lock both AG headers. */ @@ -101,7 +102,8 @@ xchk_fscount_warmup( * These are supposed to be initialized by the header read * function. */ - if (!pag->pagi_init || !pag->pagf_init) { + if (!xfs_perag_initialised_agi(pag) || + !xfs_perag_initialised_agf(pag)) { error = -EFSCORRUPTED; break; } @@ -220,7 +222,8 @@ xchk_fscount_aggregate_agcounts( break; /* This somehow got unset since the warmup? */ - if (!pag->pagi_init || !pag->pagf_init) { + if (!xfs_perag_initialised_agi(pag) || + !xfs_perag_initialised_agf(pag)) { error = -EFSCORRUPTED; break; } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 4b92f9253ccd..d0b1644efb89 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -206,7 +206,7 @@ xrep_calc_ag_resblks( return 0; pag = xfs_perag_get(mp, sm->sm_agno); - if (pag->pagi_init) { + if (xfs_perag_initialised_agi(pag)) { /* Use in-core icount if possible. */ icount = pag->pagi_count; } else { diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 34b21a29c39b..7e8b25ab6c46 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -125,7 +125,7 @@ xfs_filestream_pick_ag( pag = xfs_perag_get(mp, ag); - if (!pag->pagf_init) { + if (!xfs_perag_initialised_agf(pag)) { err = xfs_alloc_read_agf(pag, NULL, trylock, NULL); if (err) { if (err != -EAGAIN) { @@ -159,7 +159,8 @@ xfs_filestream_pick_ag( xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE)); if (((minlen && longest >= minlen) || (!minlen && pag->pagf_freeblks >= minfree)) && - (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) || + (!xfs_perag_prefers_metadata(pag) || + !(flags & XFS_PICK_USERDATA) || (flags & XFS_PICK_LOWSPACE))) { /* Break out, retaining the reference on the AG. */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 96375b5622fd..2479b5cbd75e 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -247,6 +247,32 @@ xfs_fs_show_options( return 0; } +static bool +xfs_set_inode_alloc_perag( + struct xfs_perag *pag, + xfs_ino_t ino, + xfs_agnumber_t max_metadata) +{ + if (!xfs_is_inode32(pag->pag_mount)) { + set_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return false; + } + + if (ino > XFS_MAXINUMBER_32) { + clear_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return false; + } + + set_bit(XFS_AGSTATE_ALLOWS_INODES, &pag->pag_opstate); + if (pag->pag_agno < max_metadata) + set_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + else + clear_bit(XFS_AGSTATE_PREFERS_METADATA, &pag->pag_opstate); + return true; +} + /* * Set parameters for inode allocation heuristics, taking into account * filesystem size and inode32/inode64 mount options; i.e. specifically @@ -310,24 +336,8 @@ xfs_set_inode_alloc( ino = XFS_AGINO_TO_INO(mp, index, agino); pag = xfs_perag_get(mp, index); - - if (xfs_is_inode32(mp)) { - if (ino > XFS_MAXINUMBER_32) { - pag->pagi_inodeok = 0; - pag->pagf_metadata = 0; - } else { - pag->pagi_inodeok = 1; - maxagi++; - if (index < max_metadata) - pag->pagf_metadata = 1; - else - pag->pagf_metadata = 0; - } - } else { - pag->pagi_inodeok = 1; - pag->pagf_metadata = 0; - } - + if (xfs_set_inode_alloc_perag(pag, ino, max_metadata)) + maxagi++; xfs_perag_put(pag); } From patchwork Wed Jan 18 22:44:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6714FC32793 for ; Wed, 18 Jan 2023 22:45:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229792AbjARWpc (ORCPT ); Wed, 18 Jan 2023 17:45:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229850AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 485195F3BA for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: by mail-pl1-x636.google.com with SMTP id 20so582669plo.3 for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qKgQDo/9MVsL9yPc8K2YMQ5ETmZey0VVyTWNCZQ+Keo=; b=3tFFkINLcMnk+3I365mA761KjQTTW8QVbQAxQ+gZBMzLJ8/WZr7n4Fmtl4MmQxR0Lk 3mRZ11dkx5fclwoHS8+Jo39xstUPvpHJCmsML+Oe6Ht8zLKzC5kqjHvZQbvxhLWQY3ts Aj/NjMTtf2s5ABvqRsQ1ojFPp/0dSAJRjIf2mLMJIL2qfeMLhaGASDvxmw73RDZKs806 NwnMDaodXfrrswl7lWAcsszyVJXLjOKVp8XT2HkWrWwwrLQ/6cvcoBnr2LGAPOdeR0Fo gDuMJUjm0q9bmDIicwK54Fbh5LjL9fRwiFLxz/OjhlVjjhCSWXacKjQQT3X9IejvmbZ6 qhWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qKgQDo/9MVsL9yPc8K2YMQ5ETmZey0VVyTWNCZQ+Keo=; b=8NZD9Xrc44FO+lXBR2MgwD2VWnD1TYqxnvhBjts1kcQTb8DYm9C0SCZzahWx6K3iFt A97uTDLaajbirsyeocQEt8lBWxu5eqC1kQHD2B5H3mijkC8seSCnRXIxRxb1fup6bYN9 aZdnPTkObCyM7J/J7vNhGM6gQ+Vqqqk2Jiztkk1jndzRJQ8vJadkxQezw6LWLMQeaROp IJYo/EyEi1n1Bi58Mm7UzESlRKxXdZKRm+l708OwEBZ1kaFg2CO/gE0EYMfrcgN4jw5C NoGp697ub8C67jZc0wvOKy32fRpu5BwwCs1uqjSlkzB2CfI4Z6XLmH9xOSzho1QpDd4s cWpA== X-Gm-Message-State: AFqh2ko5PGXW9HL2jAPHmL6Vf54lQdNi6i56TeDCu5ToW3YANYALvKsF q/eSGqE/w0n7hx9f1Vur7q0sc3OqKjDVJzt+ X-Google-Smtp-Source: AMrXdXvO0ufQoMMbI7zYib//fF7fbyrtMBEhBAH45sM2Ro4d05+fgn4kjkryxPAgSHcf2X2WVFpQ1Q== X-Received: by 2002:a17:90b:3d0c:b0:229:4fc8:54eb with SMTP id pt12-20020a17090b3d0c00b002294fc854ebmr9184609pjb.19.1674081916731; Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id e15-20020a17090a684f00b00223ed94759csm1784175pjm.39.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXG-6A for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDd-0c for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 14/42] xfs: introduce xfs_for_each_perag_wrap() Date: Thu, 19 Jan 2023 09:44:37 +1100 Message-Id: <20230118224505.1964941-15-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner In several places we iterate every AG from a specific start agno and wrap back to the first AG when we reach the end of the filesystem to continue searching. We don't have a primitive for this iteration yet, so add one for conversion of these algorithms to per-ag based iteration. The filestream AG select code is a mess, and this initially makes it worse. The per-ag selection needs to be driven completely into the filestream code to clean this up and it will be done in a future patch that makes the filestream allocator use active per-ag references correctly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.h | 45 +++++++++++++++++++++- fs/xfs/libxfs/xfs_bmap.c | 76 ++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_ialloc.c | 32 ++++++++-------- 3 files changed, 104 insertions(+), 49 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 187d30d9bb13..8f43b91d4cf3 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -237,7 +237,6 @@ xfs_perag_next( #define for_each_perag_from(mp, agno, pag) \ for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag)) - #define for_each_perag(mp, agno, pag) \ (agno) = 0; \ for_each_perag_from((mp), (agno), (pag)) @@ -249,6 +248,50 @@ xfs_perag_next( xfs_perag_rele(pag), \ (pag) = xfs_perag_grab_tag((mp), (agno), (tag))) +static inline struct xfs_perag * +xfs_perag_next_wrap( + struct xfs_perag *pag, + xfs_agnumber_t *agno, + xfs_agnumber_t stop_agno, + xfs_agnumber_t wrap_agno) +{ + struct xfs_mount *mp = pag->pag_mount; + + *agno = pag->pag_agno + 1; + xfs_perag_rele(pag); + while (*agno != stop_agno) { + if (*agno >= wrap_agno) + *agno = 0; + if (*agno == stop_agno) + break; + + pag = xfs_perag_grab(mp, *agno); + if (pag) + return pag; + (*agno)++; + } + return NULL; +} + +/* + * Iterate all AGs from start_agno through wrap_agno, then 0 through + * (start_agno - 1). + */ +#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ + for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \ + (pag) != NULL; \ + (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \ + (wrap_agno))) + +/* + * Iterate all AGs from start_agno through to the end of the filesystem, then 0 + * through (start_agno - 1). + */ +#define for_each_perag_wrap(mp, start_agno, agno, pag) \ + for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \ + (agno), (pag)) + + struct aghdr_init_data { /* per ag data */ xfs_agblock_t agno; /* ag to init */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6aad0ea5e606..e5519abbfa0d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3136,17 +3136,14 @@ xfs_bmap_adjacent( static int xfs_bmap_longest_free_extent( + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t ag, xfs_extlen_t *blen, int *notinit) { - struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; xfs_extlen_t longest; int error = 0; - pag = xfs_perag_get(mp, ag); if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); @@ -3156,19 +3153,17 @@ xfs_bmap_longest_free_extent( *notinit = 1; error = 0; } - goto out; + return error; } } longest = xfs_alloc_longest_free_extent(pag, - xfs_alloc_min_freelist(mp, pag), + xfs_alloc_min_freelist(pag->pag_mount, pag), xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE)); if (*blen < longest) *blen = longest; -out: - xfs_perag_put(pag); - return error; + return 0; } static void @@ -3206,9 +3201,10 @@ xfs_bmap_btalloc_select_lengths( xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; - xfs_agnumber_t ag, startag; + struct xfs_perag *pag; + xfs_agnumber_t agno, startag; int notinit = 0; - int error; + int error = 0; args->type = XFS_ALLOCTYPE_START_BNO; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { @@ -3218,21 +3214,21 @@ xfs_bmap_btalloc_select_lengths( } args->total = ap->total; - startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); + startag = XFS_FSB_TO_AGNO(mp, args->fsbno); if (startag == NULLAGNUMBER) - startag = ag = 0; + startag = 0; - while (*blen < args->maxlen) { - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, + *blen = 0; + for_each_perag_wrap(mp, startag, agno, pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen, ¬init); if (error) - return error; - - if (++ag == mp->m_sb.sb_agcount) - ag = 0; - if (ag == startag) + break; + if (*blen >= args->maxlen) break; } + if (pag) + xfs_perag_rele(pag); xfs_bmap_select_minlen(ap, args, blen, notinit); return 0; @@ -3245,7 +3241,8 @@ xfs_bmap_btalloc_filestreams( xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; - xfs_agnumber_t ag; + struct xfs_perag *pag; + xfs_agnumber_t start_agno; int notinit = 0; int error; @@ -3259,33 +3256,50 @@ xfs_bmap_btalloc_filestreams( args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; - ag = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (ag == NULLAGNUMBER) - ag = 0; + start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (start_agno == NULLAGNUMBER) + start_agno = 0; - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, ¬init); - if (error) - return error; + pag = xfs_perag_grab(mp, start_agno); + if (pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen, + ¬init); + xfs_perag_rele(pag); + if (error) + return error; + } if (*blen < args->maxlen) { - error = xfs_filestream_new_ag(ap, &ag); + xfs_agnumber_t agno = start_agno; + + error = xfs_filestream_new_ag(ap, &agno); if (error) return error; + if (agno == NULLAGNUMBER) + goto out_select; - error = xfs_bmap_longest_free_extent(args->tp, ag, blen, - ¬init); + pag = xfs_perag_grab(mp, agno); + if (!pag) + goto out_select; + + error = xfs_bmap_longest_free_extent(pag, args->tp, + blen, ¬init); + xfs_perag_rele(pag); if (error) return error; + start_agno = agno; + } +out_select: xfs_bmap_select_minlen(ap, args, blen, notinit); /* * Set the failure fallback case to look in the selected AG as stream * may have moved. */ - ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); + ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0); return 0; } diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 2a323ffa5ba9..50fef3f5af51 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1725,7 +1725,7 @@ xfs_dialloc( bool ok_alloc = true; bool low_space = false; int flags; - xfs_ino_t ino; + xfs_ino_t ino = NULLFSINO; /* * Directories, symlinks, and regular files frequently allocate at least @@ -1773,39 +1773,37 @@ xfs_dialloc( * or in which we can allocate some inodes. Iterate through the * allocation groups upward, wrapping at the end. */ - agno = start_agno; flags = XFS_ALLOC_FLAG_TRYLOCK; - for (;;) { - pag = xfs_perag_grab(mp, agno); +retry: + for_each_perag_wrap_at(mp, start_agno, mp->m_maxagi, agno, pag) { if (xfs_dialloc_good_ag(pag, *tpp, mode, flags, ok_alloc)) { error = xfs_dialloc_try_ag(pag, tpp, parent, &ino, ok_alloc); if (error != -EAGAIN) break; + error = 0; } if (xfs_is_shutdown(mp)) { error = -EFSCORRUPTED; break; } - if (++agno == mp->m_maxagi) - agno = 0; - if (agno == start_agno) { - if (!flags) { - error = -ENOSPC; - break; - } + } + if (pag) + xfs_perag_rele(pag); + if (error) + return error; + if (ino == NULLFSINO) { + if (flags) { flags = 0; if (low_space) ok_alloc = true; + goto retry; } - xfs_perag_rele(pag); + return -ENOSPC; } - - if (!error) - *new_ino = ino; - xfs_perag_rele(pag); - return error; + *new_ino = ino; + return 0; } /* From patchwork Wed Jan 18 22:44:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107128 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1250EC32793 for ; Wed, 18 Jan 2023 22:45:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229654AbjARWp0 (ORCPT ); Wed, 18 Jan 2023 17:45:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43622 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229766AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A571563E1F for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id o7-20020a17090a0a0700b00226c9b82c3aso53519pjo.3 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=D7o6UfQsnAtjBR7SeLr9Zc4Msd8I2/kH0fTTZKIXwXk=; b=ACXupMryS9oGvMV0ZBUUaL3q9scZbg1gCoTZWpU0XlumN+68WA0uTqLpy8ej9YzjBA 5uanLM9YUL02WttclxhryVKvFncevcxxdIRxj86gSrLROvgYnGLXFCVdtfE8PwYBJKYW vIR9rUh1Hzssg4K6y0KrKyUJGQS0NI5cgCuVoPhB8HrvZ63OBk6zLY0v16eQI0GlW5lB 6Ke14f7eSc1ML5hUHDjQ+6g2kTFw1cfAwxb/mY8MujfVCGd7ruYioYuTY3cwo2/kpU7M veXxg05Ci6uDhW3cR2dgLJHTqXHrLvFLuVmbm/dRZrcQtDMdHxMuCCAuXRknUV88HRoE AM9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D7o6UfQsnAtjBR7SeLr9Zc4Msd8I2/kH0fTTZKIXwXk=; b=AuPbGAjOj9VhBT4dYiibMuJM79r9rJ6e+lPb+oVCrNLIWK/mEjx9RyF+/o7FKa6FUj AyhQcfpjWCjvdKtVOk40XtqC8uMiLGvWYMUtH0FYb5zMXbUZ5MidfdGSSfRrveTC0uZM /VLVbyqlq7CiiC1sCR3/h288fPmk/3tzkbEKTOLw36lXIOYbroR413AYn5bUlrbqcA81 6BqWF0J+OH5jNOGFMJtz4kDGOA93fv0xfW0n9OHZRzY3Cy57Q13W6om7/iXoWVsbSFoJ v0KkRlsMydLkzjilNA6hLzgx/U8RxUXOMH8ZKwBQDU6/PITwRXdIGnNJXfwq+9GcI0oR Mu1g== X-Gm-Message-State: AFqh2koCEYFi36LHvAIKLrbwnN719i6WaqaJoFQJh5LSji3PRj32v1yp Tma49h5bSqFKK0rcrEF6ZlGKY8dQYmwdqQR4 X-Google-Smtp-Source: AMrXdXuawooRGBzLGwOhu3Wn2Okt/t530dstG3368a/DtBtRcJa3Tc+Az9KNIywHAYO8B7cR+iZoAw== X-Received: by 2002:a17:902:e04b:b0:194:beaf:f652 with SMTP id x11-20020a170902e04b00b00194beaff652mr2916184plx.20.1674081914250; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id l17-20020a170903245100b001890cbd1ff1sm23727811pls.149.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXK-76 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDi-0i for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 15/42] xfs: rework xfs_alloc_vextent() Date: Thu, 19 Jan 2023 09:44:38 +1100 Message-Id: <20230118224505.1964941-16-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner It's a multiplexing mess that can be greatly simplified, and really needs to be simplified to allow active per-ag references to propagate from initial AG selection code the the bmapi code. This splits the code out into separate a parameter checking function, an iterator function, and allocation completion functions and then implements the individual policies using these functions. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 464 +++++++++++++++++++++++--------------- 1 file changed, 285 insertions(+), 179 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 246c2e7d9e7a..39e34a1bfa31 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3151,29 +3151,20 @@ xfs_alloc_read_agf( } /* - * Allocate an extent (variable-size). - * Depending on the allocation type, we either look in a single allocation - * group or loop over the allocation groups to find the result. + * Pre-proces allocation arguments to set initial state that we don't require + * callers to set up correctly, as well as bounds check the allocation args + * that are set up. */ -int /* error */ -xfs_alloc_vextent( - struct xfs_alloc_arg *args) /* allocation argument structure */ +static int +xfs_alloc_vextent_check_args( + struct xfs_alloc_arg *args) { - xfs_agblock_t agsize; /* allocation group size */ - int error; - int flags; /* XFS_ALLOC_FLAG_... locking flags */ - struct xfs_mount *mp; /* mount structure pointer */ - xfs_agnumber_t sagno; /* starting allocation group number */ - xfs_alloctype_t type; /* input allocation type */ - int bump_rotor = 0; - xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ - xfs_agnumber_t minimum_agno = 0; + struct xfs_mount *mp = args->mp; + xfs_agblock_t agsize; - mp = args->mp; - type = args->otype = args->type; + args->otype = args->type; args->agbno = NULLAGBLOCK; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; + /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure @@ -3195,199 +3186,314 @@ xfs_alloc_vextent( args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; trace_xfs_alloc_vextent_badargs(args); + return -ENOSPC; + } + return 0; +} + +/* + * Post-process allocation results to set the allocated block number correctly + * for the caller. + * + * XXX: xfs_alloc_vextent() should really be returning ENOSPC for ENOSPC, not + * hiding it behind a "successful" NULLFSBLOCK allocation. + */ +static void +xfs_alloc_vextent_set_fsbno( + struct xfs_alloc_arg *args, + xfs_agnumber_t minimum_agno) +{ + struct xfs_mount *mp = args->mp; + + /* + * We can end up here with a locked AGF. If we failed, the caller is + * likely going to try to allocate again with different parameters, and + * that can widen the AGs that are searched for free space. If we have + * to do BMBT block allocation, we have to do a new allocation. + * + * Hence leaving this function with the AGF locked opens up potential + * ABBA AGF deadlocks because a future allocation attempt in this + * transaction may attempt to lock a lower number AGF. + * + * We can't release the AGF until the transaction is commited, so at + * this point we must update the "first allocation" tracker to point at + * this AG if the tracker is empty or points to a lower AG. This allows + * the next allocation attempt to be modified appropriately to avoid + * deadlocks. + */ + if (args->agbp && + (args->tp->t_highest_agno == NULLAGNUMBER || + args->agno > minimum_agno)) + args->tp->t_highest_agno = args->agno; + + /* Allocation failed with ENOSPC if NULLAGBLOCK was returned. */ + if (args->agbno == NULLAGBLOCK) { + args->fsbno = NULLFSBLOCK; + return; + } + + args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); +#ifdef DEBUG + ASSERT(args->len >= args->minlen); + ASSERT(args->len <= args->maxlen); + ASSERT(args->agbno % args->alignment == 0); + XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); +#endif +} + +/* + * Allocate within a single AG only. + */ +static int +xfs_alloc_vextent_this_ag( + struct xfs_alloc_arg *args, + xfs_agnumber_t minimum_agno) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; return 0; } - switch (type) { - case XFS_ALLOCTYPE_THIS_AG: - case XFS_ALLOCTYPE_NEAR_BNO: - case XFS_ALLOCTYPE_THIS_BNO: - /* - * These three force us into a single a.g. - */ - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - args->pag = xfs_perag_get(mp, args->agno); + args->pag = xfs_perag_get(mp, args->agno); + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + goto out_error; + } + if (!args->agbp) { + trace_xfs_alloc_vextent_noagbp(args); + args->fsbno = NULLFSBLOCK; + goto out_error; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + error = xfs_alloc_ag_vextent(args); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - error = 0; - break; - } + xfs_alloc_vextent_set_fsbno(args, minimum_agno); +out_error: + xfs_perag_put(args->pag); + return error; +} + +/* + * Iterate all AGs trying to allocate an extent starting from @start_ag. + * + * If the incoming allocation type is XFS_ALLOCTYPE_NEAR_BNO, it means the + * allocation attempts in @start_agno have locality information. If we fail to + * allocate in that AG, then we revert to anywhere-in-AG for all the other AGs + * we attempt to allocation in as there is no locality optimisation possible for + * those allocations. + * + * When we wrap the AG iteration at the end of the filesystem, we have to be + * careful not to wrap into AGs below ones we already have locked in the + * transaction if we are doing a blocking iteration. This will result in an + * out-of-order locking of AGFs and hence can cause deadlocks. + */ +static int +xfs_alloc_vextent_iterate_ags( + struct xfs_alloc_arg *args, + xfs_agnumber_t minimum_agno, + xfs_agnumber_t start_agno, + uint32_t flags) +{ + struct xfs_mount *mp = args->mp; + int error = 0; - error = xfs_alloc_fix_freelist(args, 0); + ASSERT(start_agno >= minimum_agno); + + /* + * Loop over allocation groups twice; first time with + * trylock set, second time without. + */ + args->agno = start_agno; + for (;;) { + args->pag = xfs_perag_get(mp, args->agno); + error = xfs_alloc_fix_freelist(args, flags); if (error) { trace_xfs_alloc_vextent_nofix(args); - goto error0; - } - if (!args->agbp) { - trace_xfs_alloc_vextent_noagbp(args); break; } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - if ((error = xfs_alloc_ag_vextent(args))) - goto error0; - break; - case XFS_ALLOCTYPE_START_BNO: /* - * Try near allocation first, then anywhere-in-ag after - * the first a.g. fails. + * If we get a buffer back then the allocation will fly. */ - if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && - xfs_is_inode32(mp)) { - args->fsbno = XFS_AGB_TO_FSB(mp, - ((mp->m_agfrotor / rotorstep) % - mp->m_sb.sb_agcount), 0); - bump_rotor = 1; + if (args->agbp) { + error = xfs_alloc_ag_vextent(args); + break; } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - fallthrough; - case XFS_ALLOCTYPE_FIRST_AG: + + trace_xfs_alloc_vextent_loopfailed(args); + /* - * Rotate through the allocation groups looking for a winner. - * If we are blocking, we must obey minimum_agno contraints for - * avoiding ABBA deadlocks on AGF locking. + * Didn't work, figure out the next iteration. */ - if (type == XFS_ALLOCTYPE_FIRST_AG) { - /* - * Start with allocation group given by bno. - */ - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + if (args->agno == start_agno && + args->otype == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; - sagno = minimum_agno; - flags = 0; - } else { - /* - * Start with the given allocation group. - */ - args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno); - flags = XFS_ALLOC_FLAG_TRYLOCK; + + /* + * If we are try-locking, we can't deadlock on AGF locks so we + * can wrap all the way back to the first AG. Otherwise, wrap + * back to the start AG so we can't deadlock and let the end of + * scan handler decide what to do next. + */ + if (++(args->agno) == mp->m_sb.sb_agcount) { + if (flags & XFS_ALLOC_FLAG_TRYLOCK) + args->agno = 0; + else + args->agno = minimum_agno; } /* - * Loop over allocation groups twice; first time with - * trylock set, second time without. + * Reached the starting a.g., must either be done + * or switch to non-trylock mode. */ - for (;;) { - args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, flags); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - goto error0; - } - /* - * If we get a buffer back then the allocation will fly. - */ - if (args->agbp) { - if ((error = xfs_alloc_ag_vextent(args))) - goto error0; + if (args->agno == start_agno) { + if (flags == 0) { + args->agbno = NULLAGBLOCK; + trace_xfs_alloc_vextent_allfailed(args); break; } - trace_xfs_alloc_vextent_loopfailed(args); + flags = 0; + if (args->otype == XFS_ALLOCTYPE_START_BNO) { + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->type = XFS_ALLOCTYPE_NEAR_BNO; + } + } + xfs_perag_put(args->pag); + args->pag = NULL; + } + if (args->pag) { + xfs_perag_put(args->pag); + args->pag = NULL; + } + return error; +} - /* - * Didn't work, figure out the next iteration. - */ - if (args->agno == sagno && - type == XFS_ALLOCTYPE_START_BNO) - args->type = XFS_ALLOCTYPE_THIS_AG; +/* + * Iterate from the AGs from the start AG to the end of the filesystem, trying + * to allocate blocks. It starts with a near allocation attempt in the initial + * AG, then falls back to anywhere-in-ag after the first AG fails. It will wrap + * back to zero if allowed by previous allocations in this transaction, + * otherwise will wrap back to the start AG and run a second blocking pass to + * the end of the filesystem. + */ +static int +xfs_alloc_vextent_start_ag( + struct xfs_alloc_arg *args, + xfs_agnumber_t minimum_agno) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t start_agno; + xfs_agnumber_t rotorstep = xfs_rotorstep; + bool bump_rotor = false; + int error; - /* - * If we are try-locking, we can't deadlock on AGF - * locks, so we can wrap all the way back to the first - * AG. Otherwise, wrap back to the start AG so we can't - * deadlock, and let the end of scan handler decide what - * to do next. - */ - if (++(args->agno) == mp->m_sb.sb_agcount) { - if (flags & XFS_ALLOC_FLAG_TRYLOCK) - args->agno = 0; - else - args->agno = sagno; - } + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } - /* - * Reached the starting a.g., must either be done - * or switch to non-trylock mode. - */ - if (args->agno == sagno) { - if (flags == 0) { - args->agbno = NULLAGBLOCK; - trace_xfs_alloc_vextent_allfailed(args); - break; - } + if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && + xfs_is_inode32(mp)) { + args->fsbno = XFS_AGB_TO_FSB(mp, + ((mp->m_agfrotor / rotorstep) % + mp->m_sb.sb_agcount), 0); + bump_rotor = 1; + } + start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, args->fsbno)); + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->type = XFS_ALLOCTYPE_NEAR_BNO; - /* - * Blocking pass next, so we must obey minimum - * agno constraints to avoid ABBA AGF deadlocks. - */ - flags = 0; - if (minimum_agno > sagno) - sagno = minimum_agno; - - if (type == XFS_ALLOCTYPE_START_BNO) { - args->agbno = XFS_FSB_TO_AGBNO(mp, - args->fsbno); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - } - } - xfs_perag_put(args->pag); - } - if (bump_rotor) { - if (args->agno == sagno) - mp->m_agfrotor = (mp->m_agfrotor + 1) % - (mp->m_sb.sb_agcount * rotorstep); - else - mp->m_agfrotor = (args->agno * rotorstep + 1) % - (mp->m_sb.sb_agcount * rotorstep); - } - break; - default: - ASSERT(0); - /* NOTREACHED */ + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, + XFS_ALLOC_FLAG_TRYLOCK); + if (bump_rotor) { + if (args->agno == start_agno) + mp->m_agfrotor = (mp->m_agfrotor + 1) % + (mp->m_sb.sb_agcount * rotorstep); + else + mp->m_agfrotor = (args->agno * rotorstep + 1) % + (mp->m_sb.sb_agcount * rotorstep); } - if (args->agbno == NULLAGBLOCK) { - args->fsbno = NULLFSBLOCK; - } else { - args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); -#ifdef DEBUG - ASSERT(args->len >= args->minlen); - ASSERT(args->len <= args->maxlen); - ASSERT(args->agbno % args->alignment == 0); - XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), - args->len); -#endif + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return error; +} + +/* + * Iterate from the agno indicated from args->fsbno through to the end of the + * filesystem attempting blocking allocation. This does not wrap or try a second + * pass, so will not recurse into AGs lower than indicated by fsbno. + */ +static int +xfs_alloc_vextent_first_ag( + struct xfs_alloc_arg *args, + xfs_agnumber_t minimum_agno) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t start_agno; + int error; + + error = xfs_alloc_vextent_check_args(args); + if (error) { + if (error == -ENOSPC) + return 0; + return error; } - /* - * We end up here with a locked AGF. If we failed, the caller is likely - * going to try to allocate again with different parameters, and that - * can widen the AGs that are searched for free space. If we have to do - * BMBT block allocation, we have to do a new allocation. - * - * Hence leaving this function with the AGF locked opens up potential - * ABBA AGF deadlocks because a future allocation attempt in this - * transaction may attempt to lock a lower number AGF. - * - * We can't release the AGF until the transaction is commited, so at - * this point we must update the "firstblock" tracker to point at this - * AG if the tracker is empty or points to a lower AG. This allows the - * next allocation attempt to be modified appropriately to avoid - * deadlocks. - */ - if (args->agbp && - (args->tp->t_highest_agno == NULLAGNUMBER || - args->pag->pag_agno > minimum_agno)) - args->tp->t_highest_agno = args->pag->pag_agno; - xfs_perag_put(args->pag); - return 0; -error0: - xfs_perag_put(args->pag); + start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, args->fsbno)); + + args->type = XFS_ALLOCTYPE_THIS_AG; + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, + start_agno, 0); + xfs_alloc_vextent_set_fsbno(args, minimum_agno); return error; } +/* + * Allocate an extent (variable-size). + * Depending on the allocation type, we either look in a single allocation + * group or loop over the allocation groups to find the result. + */ +int +xfs_alloc_vextent( + struct xfs_alloc_arg *args) +{ + xfs_agnumber_t minimum_agno = 0; + + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + switch (args->type) { + case XFS_ALLOCTYPE_THIS_AG: + case XFS_ALLOCTYPE_NEAR_BNO: + case XFS_ALLOCTYPE_THIS_BNO: + return xfs_alloc_vextent_this_ag(args, minimum_agno); + case XFS_ALLOCTYPE_START_BNO: + return xfs_alloc_vextent_start_ag(args, minimum_agno); + case XFS_ALLOCTYPE_FIRST_AG: + return xfs_alloc_vextent_first_ag(args, minimum_agno); + default: + ASSERT(0); + /* NOTREACHED */ + } + /* Should never get here */ + return -EFSCORRUPTED; +} + /* Ensure that the freelist is at full capacity. */ int xfs_free_extent_fix_freelist( From patchwork Wed Jan 18 22:44:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107123 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC32CC32793 for ; Wed, 18 Jan 2023 22:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229832AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229463AbjARWpO (ORCPT ); Wed, 18 Jan 2023 17:45:14 -0500 Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 265E35F38D for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pg1-x534.google.com with SMTP id s67so109150pgs.3 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Ov9bhFS8pKfhJk0aMdPqZ2dmp6OGyvqPU45nRBLq+DI=; b=yPy776//fUVAjqeRkLrLGlGkqQnr38nEKbARglJymHm7DYOGD/JH0tJqqVV8DeTCf8 GY8P3KSH13quVZvBeNOrbdn03cBU0WwqeNT2X5gWb7hzIhRdev+/PbSpRyOiNxEFUfFI nJLNjpnQoJZpWekl0G/EGq2+DNsW/W/xO0PXZyjHxBCQy42AmSeOx7mhvt4aPlp9V2bT D1vO6b/ke+G2gmvFnfSTb47tVr6gFs+0vfMiKYw/zKKohpxCnXu6q8DJVQPNHtN4JMek 7f84XRJFRgXFYw7xzBXXFYm7ARzN4TLEfxObwWJ+d718jmijXhOkj3FYHWiO/RFltTx8 qnFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ov9bhFS8pKfhJk0aMdPqZ2dmp6OGyvqPU45nRBLq+DI=; b=1XNRQWKVpr4BCew1qFRNj3JDBQGQgcA5fEnJLbBhT9wZCEWR5UwIUo7iQ94+wqTsU/ p/0uh7fPx6SRTq6OBu/R0BLNDZgo9of0XA7FXjjHsLdDX3mc1spi8HgV2aZtvb9Hpx5E t3os4MDKnqXYVcZugxMr5iqDI3dYbRMSGq+Yhehz52k8JxTtF5w0QBu/WahMYhzbisx9 3+WLCq5HAlWJbhrgfLYSQHwr8YobKQGhAhDB28ZGrotN5pSp/Uta3G2NRMnjQJSEtjuw ccVnY/t783uYfMKQclbygpo+jWZa421Ads8X0G6klwhvKjRj8QPGeDpg4UNY0C5Kn5C2 xFxw== X-Gm-Message-State: AFqh2kqEN0KqUsdKyG6pHwMHU27MA1ly1XoVWJxU7n8Hp2g9uXmXawzF L8wxUcUO5RE3cSyMOHEphjpRWBSbuS9EOVq3 X-Google-Smtp-Source: AMrXdXt8BDy+8UDLFXUQQlVOKavTbWibM/MSpg2d2sYXiLZUO249kp4vnf8P0XmKOoA5Y+WyrRNu6Q== X-Received: by 2002:a05:6a00:d5e:b0:589:a782:470c with SMTP id n30-20020a056a000d5e00b00589a782470cmr26019719pfv.2.1674081913697; Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id v15-20020aa799cf000000b0056bc5ad4862sm14277283pfi.28.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXM-7y for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDn-0o for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 16/42] xfs: factor xfs_alloc_vextent_this_ag() for _iterate_ags() Date: Thu, 19 Jan 2023 09:44:39 +1100 Message-Id: <20230118224505.1964941-17-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The core of the per-ag iteration is effectively doing a "this ag" allocation on one AG at a time. Use the same code to implement the core "this ag" allocation in both xfs_alloc_vextent_this_ag() and xfs_alloc_vextent_iterate_ags(). This means we only call xfs_alloc_ag_vextent() from one place so we can easily collapse the call stack in future patches. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 50 ++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 39e34a1bfa31..2dec95f35562 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3244,6 +3244,28 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ +static int +__xfs_alloc_vextent_this_ag( + struct xfs_alloc_arg *args) +{ + struct xfs_mount *mp = args->mp; + int error; + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + return xfs_alloc_ag_vextent(args); +} + static int xfs_alloc_vextent_this_ag( struct xfs_alloc_arg *args, @@ -3267,21 +3289,9 @@ xfs_alloc_vextent_this_ag( } args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - goto out_error; - } - if (!args->agbp) { - trace_xfs_alloc_vextent_noagbp(args); - args->fsbno = NULLFSBLOCK; - goto out_error; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - error = xfs_alloc_ag_vextent(args); + error = __xfs_alloc_vextent_this_ag(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); -out_error: xfs_perag_put(args->pag); return error; } @@ -3319,24 +3329,16 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_fix_freelist(args, flags); + error = __xfs_alloc_vextent_this_ag(args); if (error) { - trace_xfs_alloc_vextent_nofix(args); + args->agbno = NULLAGBLOCK; break; } - /* - * If we get a buffer back then the allocation will fly. - */ - if (args->agbp) { - error = xfs_alloc_ag_vextent(args); + if (args->agbp) break; - } trace_xfs_alloc_vextent_loopfailed(args); - /* - * Didn't work, figure out the next iteration. - */ if (args->agno == start_agno && args->otype == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; From patchwork Wed Jan 18 22:44:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107137 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0423C54EBE for ; Wed, 18 Jan 2023 22:45:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229824AbjARWpb (ORCPT ); Wed, 18 Jan 2023 17:45:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229792AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1775763E33 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: by mail-pj1-x102e.google.com with SMTP id o7-20020a17090a0a0700b00226c9b82c3aso53532pjo.3 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=hnuflYs+BfGSJanOhbybJAm2JtL16RGB8F5JipMIgL0=; b=5Fq0DEMRbbG58HJ7PPxkvJn++SXOA3fPyDBW7hJcdjr9XuBcCdDYOfwtHMZSxme3Zm cpQcKe88hgs+lbemJulxoj2AXCMZV2wt4EdT7eCVoihWtQKu+n0l4xQGyTxyOTsNNmal QoaOlU8H/hf8z5EnEHnH3i55mj/q81PQ9e4oGWVKA9/A1UEF1TxJgAHh697LBIwIhuYm 6Ok1JgGB0DJpoHsctWJuzpkHnyIZilnWgj316gEF3nsKN7XdX9VhsdBxP32Oxln/Hbgz REKJI12h0BuU90Z8gwbWtfys3Bt8t94qn9bMPFd3cHOhSKRxxpzAlMZXST6OAOkmwBYZ 7p8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hnuflYs+BfGSJanOhbybJAm2JtL16RGB8F5JipMIgL0=; b=XeNMlNsx7QQVYTdQ1ZF0KCfjTcl/lLdP5r3ig7DWknakaEE1xUDSE94z0S8OVu0rbG +qg2o8NHxs7zgHTl0hMlV7GNpZCh/Yg7Kg5PKJ83fNHGvuvhXqB9g/dqnj8eBAb0Z396 jE3gbjIu/VEUdSAti5ar8iL/OS5Rdh+BrqkWGRZcJK3eEKRQknIhICfaSQM/e8G4bmVv loXExeslGpPRPdSBOqO+JD/mFJMJt6G1CpXtBNTOFyr8YOrpUbl3sLGJKW0whsI6ihDW hHm/v8pSTXTecq/BpmhzwmVdDmZdN04Il2osFINF2ouU6Zyvf74qxbRDzs6Gef/nCB6G MaRg== X-Gm-Message-State: AFqh2koms6xSP3cEyN3M6QCCARdOF+wP56G5ucwe3Vd4emurkmKJGtyJ /IoUeGbI1vz7l5VmZkb9tLuOU81zZdAfnOdx X-Google-Smtp-Source: AMrXdXsbaNeFa9pd7a7j8/2kyhKnTFPoAPLCgQ1zdgXfaurPg7iP1LH/p9xNL5Wl/LTBmRr6r375dQ== X-Received: by 2002:a17:902:e9cd:b0:194:5de4:52d0 with SMTP id 13-20020a170902e9cd00b001945de452d0mr9906567plk.41.1674081914520; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id a4-20020a170902710400b00192c7f19778sm9189346pll.31.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:13 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXQ-8t for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDs-0t for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 17/42] xfs: combine __xfs_alloc_vextent_this_ag and xfs_alloc_ag_vextent Date: Thu, 19 Jan 2023 09:44:40 +1100 Message-Id: <20230118224505.1964941-18-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There's a bit of a recursive conundrum around xfs_alloc_ag_vextent(). We can't first call xfs_alloc_ag_vextent() without preparing the AGFL for the allocation, and preparing the AGFL calls xfs_alloc_ag_vextent() to prepare the AGFL for the allocation. This "double allocation" requirement is not really clear from the current xfs_alloc_fix_freelist() calls that are sprinkled through the allocation code. It's not helped that xfs_alloc_ag_vextent() can actually allocate from the AGFL itself, but there's special code to prevent AGFL prep allocations from allocating from the free list it's trying to prep. The naming is also not consistent: args->wasfromfl is true when we allocated _from_ the free list, but the indication that we are allocating _for_ the free list is via checking that (args->resv == XFS_AG_RESV_AGFL). So, lets make this "allocation required for allocation" situation clear by moving it all inside xfs_alloc_ag_vextent(). The freelist allocation is a specific XFS_ALLOCTYPE_THIS_AG allocation, which translated directly to xfs_alloc_ag_vextent_size() allocation. This enables us to replace __xfs_alloc_vextent_this_ag() with a call to xfs_alloc_ag_vextent(), and we drive the freelist fixing further into the per-ag allocation algorithm. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 65 +++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 2dec95f35562..011baace7e9d 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1140,22 +1140,38 @@ xfs_alloc_ag_vextent_small( * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. */ -STATIC int /* error */ +static int xfs_alloc_ag_vextent( - xfs_alloc_arg_t *args) /* argument structure for allocation */ + struct xfs_alloc_arg *args) { - int error=0; + struct xfs_mount *mp = args->mp; + int error = 0; ASSERT(args->minlen > 0); ASSERT(args->maxlen > 0); ASSERT(args->minlen <= args->maxlen); ASSERT(args->mod < args->prod); ASSERT(args->alignment > 0); + ASSERT(args->resv != XFS_AG_RESV_AGFL); + + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + args->wasfromfl = 0; /* * Branch to correct routine based on the type. */ - args->wasfromfl = 0; switch (args->type) { case XFS_ALLOCTYPE_THIS_AG: error = xfs_alloc_ag_vextent_size(args); @@ -1176,7 +1192,6 @@ xfs_alloc_ag_vextent( ASSERT(args->len >= args->minlen); ASSERT(args->len <= args->maxlen); - ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL); ASSERT(args->agbno % args->alignment == 0); /* if not file data, insert new block into the reverse map btree */ @@ -2721,7 +2736,7 @@ xfs_alloc_fix_freelist( targs.resv = XFS_AG_RESV_AGFL; /* Allocate as many blocks as possible at once. */ - error = xfs_alloc_ag_vextent(&targs); + error = xfs_alloc_ag_vextent_size(&targs); if (error) goto out_agflbp_relse; @@ -2735,6 +2750,18 @@ xfs_alloc_fix_freelist( break; goto out_agflbp_relse; } + + if (!xfs_rmap_should_skip_owner_update(&targs.oinfo)) { + error = xfs_rmap_alloc(tp, agbp, pag, + targs.agbno, targs.len, &targs.oinfo); + if (error) + goto out_agflbp_relse; + } + error = xfs_alloc_update_counters(tp, agbp, + -((long)(targs.len))); + if (error) + goto out_agflbp_relse; + /* * Put each allocated block on the list. */ @@ -3244,28 +3271,6 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ -static int -__xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) -{ - struct xfs_mount *mp = args->mp; - int error; - - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - return error; - } - if (!args->agbp) { - /* cannot allocate in this AG at all */ - trace_xfs_alloc_vextent_noagbp(args); - args->agbno = NULLAGBLOCK; - return 0; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - return xfs_alloc_ag_vextent(args); -} - static int xfs_alloc_vextent_this_ag( struct xfs_alloc_arg *args, @@ -3289,7 +3294,7 @@ xfs_alloc_vextent_this_ag( } args->pag = xfs_perag_get(mp, args->agno); - error = __xfs_alloc_vextent_this_ag(args); + error = xfs_alloc_ag_vextent(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); xfs_perag_put(args->pag); @@ -3329,7 +3334,7 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = __xfs_alloc_vextent_this_ag(args); + error = xfs_alloc_ag_vextent(args); if (error) { args->agbno = NULLAGBLOCK; break; From patchwork Wed Jan 18 22:44:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29524C54EBE for ; Wed, 18 Jan 2023 22:48:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229831AbjARWsT (ORCPT ); Wed, 18 Jan 2023 17:48:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230123AbjARWsF (ORCPT ); Wed, 18 Jan 2023 17:48:05 -0500 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC9B066CE4 for ; Wed, 18 Jan 2023 14:47:59 -0800 (PST) Received: by mail-pl1-x62a.google.com with SMTP id 20so588474plo.3 for ; Wed, 18 Jan 2023 14:47:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=U5lSoNDSufXES4ZweSR6MIDcWWZJSXhL3QQLhW+rlNU=; b=GKtZ/GcSS8ns42fCYWRdThc7r93hCNuN21utkfqGuo8QsKkzsCZ33nEGV1syiphcRT cFn2m4p2P98P8yeinOOY02DThAs6MGBYRqs9uU85gypfqEyFzSGS81Cf6ca7bD/rC+eE fYufrX6GQJTwPqMKsZJykmfu/zkUfPveF0BgQGSJyffsl5a8Rtei5hsbhwW2mVBRmLn7 Qelgm8FctXHi+ZHvBftyRtDdH81RTLm03+OQ7EoFPBR6aPsECyv+x+k5ADxlYAaqMdew NXx4arXg5TuSBRxmw7PsMahsx/SDrRjdt1XMN4XJZGt/0ZY9AYvfPLDsVtQRhpTxC/bF IBFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=U5lSoNDSufXES4ZweSR6MIDcWWZJSXhL3QQLhW+rlNU=; b=Iqge1HbT6HAOKzRBKXSFimEAOWQYDX8TWhNagvs72UZOjUnwZErY9bKkDaGjpnIJIF SwzokaLpZAprdBwz/fxPMleTYyV2gPv/9SVMqSKGQXJRkTkk/Ik9eTLdhINSB+idyJZg CzxwAQ0YlxhjQz3Qbj8bFfYaTA78MJXYUck46tXsWytGkcTFnTnjq/jEKG2N0351zqrQ VI3F62iSDRWLJO0pPvC91F2Q95wKHqDR588NVPTek2jbOk+fdGh/k58hxf445AwznTRS 24JCvYGwQKBEjNsrHMvkGy0YNqH4l+rFPIaWs3Hve96KqBvfoeh3z757TsrMB7WfWraE gjqw== X-Gm-Message-State: AFqh2kr/B4O5wI5FGPL6egeNxvdJXA532kPYmJQMf9RnUkx7wOCdzj9b kJeqkxB/z+ojsY0zduAXdAg/9RE0IwyGSTiV X-Google-Smtp-Source: AMrXdXsMXvfolV7nWvgXDCpP9WwE80uXXOA2o0/MGfAPSkbRMrxw0prNpO94LoF3fKtyOOJGNCwNmw== X-Received: by 2002:a17:90a:f307:b0:229:dcf4:4316 with SMTP id ca7-20020a17090af30700b00229dcf44316mr1386557pjb.42.1674082079272; Wed, 18 Jan 2023 14:47:59 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id a7-20020a17090a70c700b00228e56d375asm1809393pjm.33.2023.01.18.14.47.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:58 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXT-9l for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FDx-0z for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 18/42] xfs: use xfs_alloc_vextent_this_ag() where appropriate Date: Thu, 19 Jan 2023 09:44:41 +1100 Message-Id: <20230118224505.1964941-19-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_this_ag(). Drive the per-ag grabbing out to the callers, too, so that callers with active references don't need to do new lookups just for an allocation in a context that already has a perag reference. The only remaining caller that does single AG allocation through xfs_alloc_vextent() is xfs_bmap_btalloc() with XFS_ALLOCTYPE_NEAR_BNO. That is going to need more untangling before it can be converted cleanly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 3 +- fs/xfs/libxfs/xfs_alloc.c | 26 ++++++++------- fs/xfs/libxfs/xfs_alloc.h | 6 ++++ fs/xfs/libxfs/xfs_bmap.c | 52 +++++++++++++++++------------- fs/xfs/libxfs/xfs_bmap_btree.c | 22 ++++++------- fs/xfs/libxfs/xfs_ialloc.c | 9 ++++-- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 +- fs/xfs/libxfs/xfs_refcount_btree.c | 3 +- fs/xfs/scrub/repair.c | 3 +- 9 files changed, 74 insertions(+), 53 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index a3bdcde95845..053d77a283f7 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -887,6 +887,7 @@ xfs_ag_shrink_space( struct xfs_alloc_arg args = { .tp = *tpp, .mp = mp, + .pag = pag, .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, @@ -938,7 +939,7 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 011baace7e9d..28b79facf2e3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2723,7 +2723,6 @@ xfs_alloc_fix_freelist( targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = 1; - targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; error = xfs_alloc_read_agfl(pag, tp, &agflbp); if (error) @@ -3271,14 +3270,17 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ -static int +int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args, - xfs_agnumber_t minimum_agno) + struct xfs_alloc_arg *args) { struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; int error; + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + error = xfs_alloc_vextent_check_args(args); if (error) { if (error == -ENOSPC) @@ -3293,11 +3295,8 @@ xfs_alloc_vextent_this_ag( return 0; } - args->pag = xfs_perag_get(mp, args->agno); error = xfs_alloc_ag_vextent(args); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - xfs_perag_put(args->pag); return error; } @@ -3480,6 +3479,7 @@ xfs_alloc_vextent( struct xfs_alloc_arg *args) { xfs_agnumber_t minimum_agno = 0; + int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; @@ -3488,17 +3488,21 @@ xfs_alloc_vextent( case XFS_ALLOCTYPE_THIS_AG: case XFS_ALLOCTYPE_NEAR_BNO: case XFS_ALLOCTYPE_THIS_BNO: - return xfs_alloc_vextent_this_ag(args, minimum_agno); + args->pag = xfs_perag_get(args->mp, + XFS_FSB_TO_AGNO(args->mp, args->fsbno)); + error = xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); + break; case XFS_ALLOCTYPE_START_BNO: return xfs_alloc_vextent_start_ag(args, minimum_agno); case XFS_ALLOCTYPE_FIRST_AG: return xfs_alloc_vextent_first_ag(args, minimum_agno); default: + error = -EFSCORRUPTED; ASSERT(0); - /* NOTREACHED */ + break; } - /* Should never get here */ - return -EFSCORRUPTED; + return error; } /* Ensure that the freelist is at full capacity. */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 2c3f762dfb58..0a9ad6cd18e2 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -124,6 +124,12 @@ int /* error */ xfs_alloc_vextent( xfs_alloc_arg_t *args); /* allocation argument structure */ +/* + * Allocate an extent in the specific AG defined by args->fsbno. If there is no + * space in that AG, then the allocation will fail. + */ +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); + /* * Free an extent. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e5519abbfa0d..fec00cceeba7 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -789,6 +789,8 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; + args.total = total; + args.minlen = args.maxlen = args.prod = 1; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); /* * Allocate a block. We know we need only one, since the @@ -3506,8 +3508,7 @@ xfs_bmap_btalloc( xfs_extlen_t orig_length; xfs_extlen_t blen; xfs_extlen_t nextminlen = 0; - int isaligned; - int tryagain; + int isaligned = 0; int error; int stripe_align; @@ -3528,7 +3529,6 @@ xfs_bmap_btalloc( xfs_bmap_adjacent(ap); - tryagain = isaligned = 0; args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3576,9 +3576,9 @@ xfs_bmap_btalloc( * allocation with alignment turned on. */ atype = args.type; - tryagain = 1; args.type = XFS_ALLOCTYPE_THIS_BNO; args.alignment = 1; + /* * Compute the minlen+alignment for the * next case. Set slop so that the value @@ -3595,34 +3595,37 @@ xfs_bmap_btalloc( args.minlen - 1; else args.minalignslop = 0; + + args.pag = xfs_perag_get(mp, + XFS_FSB_TO_AGNO(mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); + if (error) + return error; + + if (args.fsbno != NULLFSBLOCK) + goto out_success; + /* + * Exact allocation failed. Now try with alignment + * turned on. + */ + args.pag = NULL; + args.type = atype; + args.fsbno = ap->blkno; + args.alignment = stripe_align; + args.minlen = nextminlen; + args.minalignslop = 0; + isaligned = 1; } } else { args.alignment = 1; args.minalignslop = 0; } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.resv = XFS_AG_RESV_NONE; - args.datatype = ap->datatype; error = xfs_alloc_vextent(&args); if (error) return error; - if (tryagain && args.fsbno == NULLFSBLOCK) { - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = stripe_align; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } if (isaligned && args.fsbno == NULLFSBLOCK) { /* * allocation failed, so turn off alignment and @@ -3650,8 +3653,13 @@ xfs_bmap_btalloc( return error; ap->tp->t_flags |= XFS_TRANS_LOWMODE; } + args.minleft = ap->minleft; + args.wasdel = ap->wasdel; + args.resv = XFS_AG_RESV_NONE; + args.datatype = ap->datatype; if (args.fsbno != NULLFSBLOCK) { +out_success: xfs_bmap_process_allocated_extent(ap, &args, orig_offset, orig_length); } else { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index afd9b2d962a3..d42c1a1da1fc 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -21,6 +21,7 @@ #include "xfs_quota.h" #include "xfs_trace.h" #include "xfs_rmap.h" +#include "xfs_ag.h" static struct kmem_cache *xfs_bmbt_cur_cache; @@ -200,14 +201,18 @@ xfs_bmbt_alloc_block( union xfs_btree_ptr *new, int *stat) { - xfs_alloc_arg_t args; /* block allocation args */ - int error; /* error return value */ + struct xfs_alloc_arg args; + int error; memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino, cur->bc_ino.whichfork); + args.minlen = args.maxlen = args.prod = 1; + args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; + if (!args.wasdel && args.tp->t_blk_res == 0) + return -ENOSPC; args.fsbno = be64_to_cpu(start->l); args.type = XFS_ALLOCTYPE_START_BNO; @@ -222,15 +227,9 @@ xfs_bmbt_alloc_block( args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, cur->bc_ino.whichfork); - args.minlen = args.maxlen = args.prod = 1; - args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; - if (!args.wasdel && args.tp->t_blk_res == 0) { - error = -ENOSPC; - goto error0; - } error = xfs_alloc_vextent(&args); if (error) - goto error0; + return error; if (args.fsbno == NULLFSBLOCK && args.minleft) { /* @@ -243,7 +242,7 @@ xfs_bmbt_alloc_block( args.type = XFS_ALLOCTYPE_START_BNO; error = xfs_alloc_vextent(&args); if (error) - goto error0; + return error; cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { @@ -262,9 +261,6 @@ xfs_bmbt_alloc_block( *stat = 1; return 0; - - error0: - return error; } STATIC int diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 50fef3f5af51..2f3e47cb9332 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -630,6 +630,7 @@ xfs_ialloc_ag_alloc( args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; args.oinfo = XFS_RMAP_OINFO_INODES; + args.pag = pag; #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -683,7 +684,8 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; /* @@ -731,7 +733,8 @@ xfs_ialloc_ag_alloc( * Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; } @@ -780,7 +783,7 @@ xfs_ialloc_ag_alloc( args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 3675a0d29310..fa6cd2502970 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -103,6 +103,7 @@ __xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.oinfo = XFS_RMAP_OINFO_INOBT; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno); args.minlen = 1; @@ -111,7 +112,7 @@ __xfs_inobt_alloc_block( args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index d20abf0390fc..a980fb18bde2 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -67,6 +67,7 @@ xfs_refcountbt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, xfs_refc_block(args.mp)); @@ -74,7 +75,7 @@ xfs_refcountbt_alloc_block( args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) goto out_error; trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno, diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index d0b1644efb89..5f4b50aac4bb 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -326,6 +326,7 @@ xrep_alloc_ag_block( args.tp = sc->tp; args.mp = sc->mp; + args.pag = sc->sa.pag; args.oinfo = *oinfo; args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; @@ -334,7 +335,7 @@ xrep_alloc_ag_block( args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; if (args.fsbno == NULLFSBLOCK) From patchwork Wed Jan 18 22:44:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107154 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CFECC38147 for ; Wed, 18 Jan 2023 22:48:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229819AbjARWsV (ORCPT ); Wed, 18 Jan 2023 17:48:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229904AbjARWsI (ORCPT ); Wed, 18 Jan 2023 17:48:08 -0500 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 799AB65EC4 for ; Wed, 18 Jan 2023 14:48:03 -0800 (PST) Received: by mail-pl1-x635.google.com with SMTP id jm10so533704plb.13 for ; Wed, 18 Jan 2023 14:48:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=xMwtjsJ3M4jO+zvHt6Gsp8jS41/1bE6R2T515GkbIY0=; b=Q6fr73oRi9rYOqSc9w28NKWTEtzPR1NBtq4YRnWNJ2BQlxfxYzJcUpsAEpB6qzhIQg ZRUJkBHVu3aGtUPSqNUY05gODYp4L5bKgZJK2ODwQIso7QnQbz0pS2XKQX5UJMknExyO f5t3cg2QwWiV0Q8YJ5hGr59fddkvfKrsTdWLHvvoJLEtq+GrE9O74fsHDKlN1gWrjO7j MizQnTr8o0XKBd3NZsEOtz0w4hP/xnL/rTuigjXKlAf3PEtXRWDOoVEGmcrj6Myhkd3f 9cvfqsPqseZ4scoVcsJF/RcYTAfDTERa2076EUB32f55q///UOL5o6XOvPUqBgFrh9ce eMrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xMwtjsJ3M4jO+zvHt6Gsp8jS41/1bE6R2T515GkbIY0=; b=XNJja6ZZw8pFheqgjZu0Bcw7hRF+6pPLpuR6rl6ROKGl/fHxmHoAZBf5aDAjMp4z4Z sKjkeiBRRwdfPckzpQAKTXRUM6hUcLC6FvQN8ztiHQMPe8g4ONkAf6m2vwP06qBCS91Y +eqy+Db5hQcDZmIiBxwuM2WUQyeiXFXVbG6/HB/bwZP1dRP8YsKwXxOhLlCrTqqo8NSx d94YLDSeod+uesVzv9aMOPFX0ertK8Pi7L8GASBZ6E1exVPD3oeRXIlSKQbwMMJ8nKHY mhDDe/lxstLvEZ27mNR1BUFJXbFX+2YP2icLFkvMT5BauK9s3GKNKPj6zX8/IssaVtl5 jbvw== X-Gm-Message-State: AFqh2kqSTOsskd62MhOMpUQreEP04PbAniiW/XmmTYMf3VULdbtu49eP TywMVbyZ7xHjDw0JtP5qnwj8fXuGWuNwtITc X-Google-Smtp-Source: AMrXdXuKMEb+nlQew9llxtPv2Jf/S8eULIAOHyJbcnkQA0n5h44IFZK5D/Y7YD6v2GDiIHC7teHpQw== X-Received: by 2002:a17:90a:7406:b0:226:f950:6f6c with SMTP id a6-20020a17090a740600b00226f9506f6cmr9294846pjg.33.1674082082923; Wed, 18 Jan 2023 14:48:02 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id g10-20020a17090a3c8a00b0022908f1398dsm1799499pjc.32.2023.01.18.14.48.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:02 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXV-Ag for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FE2-14 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 19/42] xfs: factor xfs_bmap_btalloc() Date: Thu, 19 Jan 2023 09:44:42 +1100 Message-Id: <20230118224505.1964941-20-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There are several different contexts xfs_bmap_btalloc() handles, and large chunks of the code execute independent allocation contexts. Try to untangle this mess a bit. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 333 +++++++++++++++++++++++---------------- 1 file changed, 196 insertions(+), 137 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index fec00cceeba7..cdf3b551ef7b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3196,13 +3196,13 @@ xfs_bmap_select_minlen( } } -STATIC int +static int xfs_bmap_btalloc_select_lengths( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen) { - struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_mount *mp = args->mp; struct xfs_perag *pag; xfs_agnumber_t agno, startag; int notinit = 0; @@ -3216,7 +3216,7 @@ xfs_bmap_btalloc_select_lengths( } args->total = ap->total; - startag = XFS_FSB_TO_AGNO(mp, args->fsbno); + startag = XFS_FSB_TO_AGNO(mp, ap->blkno); if (startag == NULLAGNUMBER) startag = 0; @@ -3258,7 +3258,7 @@ xfs_bmap_btalloc_filestreams( args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; - start_agno = XFS_FSB_TO_AGNO(mp, args->fsbno); + start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno); if (start_agno == NULLAGNUMBER) start_agno = 0; @@ -3496,170 +3496,229 @@ xfs_bmap_exact_minlen_extent_alloc( #endif -STATIC int -xfs_bmap_btalloc( - struct xfs_bmalloca *ap) +/* + * If we are not low on available data blocks and we are allocating at + * EOF, optimise allocation for contiguous file extension and/or stripe + * alignment of the new extent. + * + * NOTE: ap->aeof is only set if the allocation length is >= the + * stripe unit and the allocation offset is at the end of file. + */ +static int +xfs_bmap_btalloc_at_eof( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t blen, + int stripe_align) { - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_alloc_arg args = { .tp = ap->tp, .mp = mp }; - xfs_alloctype_t atype = 0; - xfs_agnumber_t ag; - xfs_fileoff_t orig_offset; - xfs_extlen_t orig_length; - xfs_extlen_t blen; - xfs_extlen_t nextminlen = 0; - int isaligned = 0; + struct xfs_mount *mp = args->mp; + xfs_alloctype_t atype; int error; - int stripe_align; - ASSERT(ap->length); - orig_offset = ap->offset; - orig_length = ap->length; + /* + * If there are already extents in the file, try an exact EOF block + * allocation to extend the file as a contiguous extent. If that fails, + * or it's the first allocation in a file, just try for a stripe aligned + * allocation. + */ + if (ap->offset) { + xfs_extlen_t nextminlen = 0; - stripe_align = xfs_bmap_compute_alignments(ap, &args); + atype = args->type; + args->type = XFS_ALLOCTYPE_THIS_BNO; + args->alignment = 1; + /* + * Compute the minlen+alignment for the next case. Set slop so + * that the value of minlen+alignment+slop doesn't go up between + * the calls. + */ + if (blen > stripe_align && blen <= args->maxlen) + nextminlen = blen - stripe_align; + else + nextminlen = args->minlen; + if (nextminlen + stripe_align > args->minlen + 1) + args->minalignslop = nextminlen + stripe_align - + args->minlen - 1; + else + args->minalignslop = 0; + + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); + error = xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); + if (error) + return error; + + if (args->fsbno != NULLFSBLOCK) + return 0; + /* + * Exact allocation failed. Reset to try an aligned allocation + * according to the original allocation specification. + */ + args->pag = NULL; + args->type = atype; + args->fsbno = ap->blkno; + args->alignment = stripe_align; + args->minlen = nextminlen; + args->minalignslop = 0; + } else { + args->alignment = stripe_align; + atype = args->type; + /* + * Adjust minlen to try and preserve alignment if we + * can't guarantee an aligned maxlen extent. + */ + if (blen > args->alignment && + blen <= args->maxlen + args->alignment) + args->minlen = blen - args->alignment; + args->minalignslop = 0; + } + + error = xfs_alloc_vextent(args); + if (error) + return error; + + if (args->fsbno != NULLFSBLOCK) + return 0; + + /* + * Allocation failed, so turn return the allocation args to their + * original non-aligned state so the caller can proceed on allocation + * failure as if this function was never called. + */ + args->type = atype; + args->fsbno = ap->blkno; + args->alignment = 1; + return 0; +} + +static int +xfs_bmap_btalloc_best_length( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + int stripe_align) +{ + struct xfs_mount *mp = args->mp; + xfs_extlen_t blen = 0; + int error; + + /* + * Determine the initial block number we will target for allocation. + */ if ((ap->datatype & XFS_ALLOC_USERDATA) && xfs_inode_is_filestream(ap->ip)) { - ag = xfs_filestream_lookup_ag(ap->ip); - ag = (ag != NULLAGNUMBER) ? ag : 0; - ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); + xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); + if (agno == NULLAGNUMBER) + agno = 0; + ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); } else { ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } - xfs_bmap_adjacent(ap); - - args.fsbno = ap->blkno; - args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; - - /* Trim the allocation back to the maximum an AG can fit. */ - args.maxlen = min(ap->length, mp->m_ag_max_usable); - blen = 0; + args->fsbno = ap->blkno; /* - * Search for an allocation group with a single extent large - * enough for the request. If one isn't found, then adjust - * the minimum allocation size to the largest space found. + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then adjust the minimum allocation + * size to the largest space found. */ if ((ap->datatype & XFS_ALLOC_USERDATA) && xfs_inode_is_filestream(ap->ip)) - error = xfs_bmap_btalloc_filestreams(ap, &args, &blen); + error = xfs_bmap_btalloc_filestreams(ap, args, &blen); else - error = xfs_bmap_btalloc_select_lengths(ap, &args, &blen); + error = xfs_bmap_btalloc_select_lengths(ap, args, &blen); if (error) return error; /* - * If we are not low on available data blocks, and the underlying - * logical volume manager is a stripe, and the file offset is zero then - * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof - * is only set if the allocation length is >= the stripe unit and the - * allocation offset is at the end of file. + * Don't attempt optimal EOF allocation if previous allocations barely + * succeeded due to being near ENOSPC. It is highly unlikely we'll get + * optimal or even aligned allocations in this case, so don't waste time + * trying. */ - if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) { - if (!ap->offset) { - args.alignment = stripe_align; - atype = args.type; - isaligned = 1; - /* - * Adjust minlen to try and preserve alignment if we - * can't guarantee an aligned maxlen extent. - */ - if (blen > args.alignment && - blen <= args.maxlen + args.alignment) - args.minlen = blen - args.alignment; - args.minalignslop = 0; - } else { - /* - * First try an exact bno allocation. - * If it fails then do a near or start bno - * allocation with alignment turned on. - */ - atype = args.type; - args.type = XFS_ALLOCTYPE_THIS_BNO; - args.alignment = 1; - - /* - * Compute the minlen+alignment for the - * next case. Set slop so that the value - * of minlen+alignment+slop doesn't go up - * between the calls. - */ - if (blen > stripe_align && blen <= args.maxlen) - nextminlen = blen - stripe_align; - else - nextminlen = args.minlen; - if (nextminlen + stripe_align > args.minlen + 1) - args.minalignslop = - nextminlen + stripe_align - - args.minlen - 1; - else - args.minalignslop = 0; - - args.pag = xfs_perag_get(mp, - XFS_FSB_TO_AGNO(mp, args.fsbno)); - error = xfs_alloc_vextent_this_ag(&args); - xfs_perag_put(args.pag); - if (error) - return error; - - if (args.fsbno != NULLFSBLOCK) - goto out_success; - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.pag = NULL; - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = stripe_align; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - } - } else { - args.alignment = 1; - args.minalignslop = 0; + if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { + error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align); + if (error) + return error; + if (args->fsbno != NULLFSBLOCK) + return 0; } - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent(args); if (error) return error; + if (args->fsbno != NULLFSBLOCK) + return 0; - if (isaligned && args.fsbno == NULLFSBLOCK) { - /* - * allocation failed, so turn off alignment and - * try again. - */ - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = 0; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK && - args.minlen > ap->minlen) { - args.minlen = ap->minlen; - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = ap->blkno; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - if (args.fsbno == NULLFSBLOCK) { - args.fsbno = 0; - args.type = XFS_ALLOCTYPE_FIRST_AG; - args.total = ap->minlen; - if ((error = xfs_alloc_vextent(&args))) + /* + * Try a locality first full filesystem minimum length allocation whilst + * still maintaining necessary total block reservation requirements. + */ + if (args->minlen > ap->minlen) { + args->minlen = ap->minlen; + args->type = XFS_ALLOCTYPE_START_BNO; + args->fsbno = ap->blkno; + error = xfs_alloc_vextent(args); + if (error) return error; - ap->tp->t_flags |= XFS_TRANS_LOWMODE; } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.resv = XFS_AG_RESV_NONE; - args.datatype = ap->datatype; + if (args->fsbno != NULLFSBLOCK) + return 0; + + /* + * We are now critically low on space, so this is a last resort + * allocation attempt: no reserve, no locality, blocking, minimum + * length, full filesystem free space scan. We also indicate to future + * allocations in this transaction that we are critically low on space + * so they don't waste time on allocation modes that are unlikely to + * succeed. + */ + args->fsbno = 0; + args->type = XFS_ALLOCTYPE_FIRST_AG; + args->total = ap->minlen; + error = xfs_alloc_vextent(args); + if (error) + return error; + ap->tp->t_flags |= XFS_TRANS_LOWMODE; + return 0; +} + +static int +xfs_bmap_btalloc( + struct xfs_bmalloca *ap) +{ + struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_alloc_arg args = { + .tp = ap->tp, + .mp = mp, + .fsbno = NULLFSBLOCK, + .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, + .minleft = ap->minleft, + .wasdel = ap->wasdel, + .resv = XFS_AG_RESV_NONE, + .datatype = ap->datatype, + .alignment = 1, + .minalignslop = 0, + }; + xfs_fileoff_t orig_offset; + xfs_extlen_t orig_length; + int error; + int stripe_align; + + ASSERT(ap->length); + orig_offset = ap->offset; + orig_length = ap->length; + + stripe_align = xfs_bmap_compute_alignments(ap, &args); + + /* Trim the allocation back to the maximum an AG can fit. */ + args.maxlen = min(ap->length, mp->m_ag_max_usable); + + error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align); + if (error) + return error; if (args.fsbno != NULLFSBLOCK) { -out_success: xfs_bmap_process_allocated_extent(ap, &args, orig_offset, orig_length); } else { From patchwork Wed Jan 18 22:44:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107152 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FCA1C32793 for ; Wed, 18 Jan 2023 22:48:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229741AbjARWsS (ORCPT ); Wed, 18 Jan 2023 17:48:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230119AbjARWsC (ORCPT ); Wed, 18 Jan 2023 17:48:02 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7408666CD6 for ; Wed, 18 Jan 2023 14:47:56 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id z1-20020a17090a66c100b00226f05b9595so102099pjl.0 for ; Wed, 18 Jan 2023 14:47:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=pElfy99eOEc0S2Pi7vIbPQFfCND9YbgO18hKOObwMIM=; b=hMrNR3JlHJL8MD5mo6rss2x5grCYrOvprU90bUBb08yPcxx1IERzVZqvLG+BwMZJyg 8X7xQdLY6W/5TAewSvGCL02ySJA4AyoK6t6TyxbtScDuaM58ERS7ZCvU3Rp7MO4O8N3R 7Uj2tnXUDVWgUPo6hpQqtNzEkWkgLIrBCHvk45kMC0HX9adI5GVMnjJYBeT0A2QO78WJ M19EuCQ0XyG/RDGmQSRXCznsy/UBvv7zjhpEFc7YCWROrt7VTCnAWeDhiqm5O7z8OkKN JvuRqMYNcpupKGsMEFn60jGwzrq68MUBwYklpbijj2VRkGbDcz0qR0aA8+bhly7bosiy d6Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pElfy99eOEc0S2Pi7vIbPQFfCND9YbgO18hKOObwMIM=; b=xsEgXIjNdclpon6J56M9C7kuXOZfyU2akt0i8R73+M/k+cSy6BDFHLsk7dD9i2Mi/y q0ZbT+yo89UD3hQL1LLEwxD08wNyitfo6WkX3CPwNr6hcIw1pgbiDut1MwcwBzhffBdq BcCeqQxo9RRuKmM8kfTTkZUUO7Z50KozSazbbxDCmxXvKykVmBo54Vd7KSRwxveUaWEd esyWcbG3DG0Un0VdzLcJETJkIuwL31lgMEd8QbS34895TaqPf7ElNntcyJsP7ZXes3yI PKyFDfXK7VnY/7SpbRlWwY6Ku/SKncdfuR0HrmTyIgiP99qBKK80pVdHZBFABFPcp6ms 34Xw== X-Gm-Message-State: AFqh2kroCinJJV3BIPi1hi3/JsfxnR3VvudPt50JcuzhEZB8opJOIUMG V5zF8F2rLYrt+r0nwZRoxyyPKokaN9fDg9U/ X-Google-Smtp-Source: AMrXdXs2MiyqAWdW5GoiXcYfVmiPykAwK6a2U1qr6+OaQQfLMUaLmtn3UEQz3gABDwBvYGaXSKHpmw== X-Received: by 2002:a17:90a:f297:b0:228:cb86:1f76 with SMTP id fs23-20020a17090af29700b00228cb861f76mr8898978pjb.21.1674082075921; Wed, 18 Jan 2023 14:47:55 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id t1-20020a63d241000000b004c974bb9a4esm7119267pgi.83.2023.01.18.14.47.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:55 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXY-Bd for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FE7-1A for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 20/42] xfs: use xfs_alloc_vextent_first_ag() where appropriate Date: Thu, 19 Jan 2023 09:44:43 +1100 Message-Id: <20230118224505.1964941-21-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_first_ag(). This gets rid of XFS_ALLOCTYPE_FIRST_AG as the type used within xfs_alloc_vextent_first_ag() during iteration is _THIS_AG. Hence we can remove the setting of args->type from all the callers of _first_ag() and remove the alloctype. While doing this, pass the allocation target fsb as a parameter rather than encoding it in args->fsbno. This starts the process of making args->fsbno an output only variable rather than input/output. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 35 +++++++++++++++++++---------------- fs/xfs/libxfs/xfs_alloc.h | 10 ++++++++-- fs/xfs/libxfs/xfs_bmap.c | 31 ++++++++++++++++--------------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 28b79facf2e3..186ce3aee9e0 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3183,7 +3183,8 @@ xfs_alloc_read_agf( */ static int xfs_alloc_vextent_check_args( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; xfs_agblock_t agsize; @@ -3201,13 +3202,13 @@ xfs_alloc_vextent_check_args( args->maxlen = agsize; if (args->alignment == 0) args->alignment = 1; - ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize); + ASSERT(XFS_FSB_TO_AGNO(mp, target) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, target) < agsize); ASSERT(args->minlen <= args->maxlen); ASSERT(args->minlen <= agsize); ASSERT(args->mod < args->prod); - if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount || - XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize || + if (XFS_FSB_TO_AGNO(mp, target) >= mp->m_sb.sb_agcount || + XFS_FSB_TO_AGBNO(mp, target) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; @@ -3281,7 +3282,7 @@ xfs_alloc_vextent_this_ag( if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - error = xfs_alloc_vextent_check_args(args); + error = xfs_alloc_vextent_check_args(args, args->fsbno); if (error) { if (error == -ENOSPC) return 0; @@ -3406,7 +3407,7 @@ xfs_alloc_vextent_start_ag( bool bump_rotor = false; int error; - error = xfs_alloc_vextent_check_args(args); + error = xfs_alloc_vextent_check_args(args, args->fsbno); if (error) { if (error == -ENOSPC) return 0; @@ -3444,25 +3445,29 @@ xfs_alloc_vextent_start_ag( * filesystem attempting blocking allocation. This does not wrap or try a second * pass, so will not recurse into AGs lower than indicated by fsbno. */ -static int -xfs_alloc_vextent_first_ag( +int + xfs_alloc_vextent_first_ag( struct xfs_alloc_arg *args, - xfs_agnumber_t minimum_agno) -{ + xfs_rfsblock_t target) + { struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; xfs_agnumber_t start_agno; int error; - error = xfs_alloc_vextent_check_args(args); + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; return error; } - start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, args->fsbno)); - + start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); args->type = XFS_ALLOCTYPE_THIS_AG; + args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, 0); xfs_alloc_vextent_set_fsbno(args, minimum_agno); @@ -3495,8 +3500,6 @@ xfs_alloc_vextent( break; case XFS_ALLOCTYPE_START_BNO: return xfs_alloc_vextent_start_ag(args, minimum_agno); - case XFS_ALLOCTYPE_FIRST_AG: - return xfs_alloc_vextent_first_ag(args, minimum_agno); default: error = -EFSCORRUPTED; ASSERT(0); diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 0a9ad6cd18e2..73697dd3ca55 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -19,7 +19,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); /* * Freespace allocation types. Argument to xfs_alloc_[v]extent. */ -#define XFS_ALLOCTYPE_FIRST_AG 0x02 /* ... start at ag 0 */ #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ #define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ @@ -29,7 +28,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_TYPES \ - { XFS_ALLOCTYPE_FIRST_AG, "FIRST_AG" }, \ { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ @@ -130,6 +128,14 @@ xfs_alloc_vextent( */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Iterate from the AG indicated from args->fsbno through to the end of the + * filesystem attempting blocking allocation. This is for use in last + * resort allocation attempts when everything else has failed. + */ +int xfs_alloc_vextent_first_ag(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Free an extent. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index cdf3b551ef7b..eb3dc8d5319b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3248,13 +3248,6 @@ xfs_bmap_btalloc_filestreams( int notinit = 0; int error; - if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { - args->type = XFS_ALLOCTYPE_FIRST_AG; - args->total = ap->minlen; - args->minlen = ap->minlen; - return 0; - } - args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; @@ -3462,9 +3455,7 @@ xfs_bmap_exact_minlen_extent_alloc( */ ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); - args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; - args.type = XFS_ALLOCTYPE_FIRST_AG; args.minlen = args.maxlen = ap->minlen; args.total = ap->total; @@ -3476,7 +3467,7 @@ xfs_bmap_exact_minlen_extent_alloc( args.resv = XFS_AG_RESV_NONE; args.datatype = ap->datatype; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_first_ag(&args, ap->blkno); if (error) return error; @@ -3623,10 +3614,21 @@ xfs_bmap_btalloc_best_length( * size to the largest space found. */ if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) + xfs_inode_is_filestream(ap->ip)) { + /* + * If there is very little free space before we start a + * filestreams allocation, we're almost guaranteed to fail to + * find an AG with enough contiguous free space to succeed, so + * just go straight to the low space algorithm. + */ + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + args->minlen = ap->minlen; + goto critically_low_space; + } error = xfs_bmap_btalloc_filestreams(ap, args, &blen); - else + } else { error = xfs_bmap_btalloc_select_lengths(ap, args, &blen); + } if (error) return error; @@ -3673,10 +3675,9 @@ xfs_bmap_btalloc_best_length( * so they don't waste time on allocation modes that are unlikely to * succeed. */ - args->fsbno = 0; - args->type = XFS_ALLOCTYPE_FIRST_AG; +critically_low_space: args->total = ap->minlen; - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_first_ag(args, 0); if (error) return error; ap->tp->t_flags |= XFS_TRANS_LOWMODE; From patchwork Wed Jan 18 22:44:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B42FC6379F for ; Wed, 18 Jan 2023 22:45:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229581AbjARWpX (ORCPT ); Wed, 18 Jan 2023 17:45:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43604 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229693AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6667460491 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: by mail-pl1-x644.google.com with SMTP id b17so560966pld.7 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=am6dRGIxBONTlNx8td89YADQ2kZ8jOcuNsD9gG75Rz8=; b=b79WuTIaViQsrn52rpyVA+AIMXxI3w2U7o8hFLCGuGmEspN1wm2P8OeOilsBZyXJ33 R4RSGMa0EW5VIm3ONB1HoFqF1L8wuRqFt5iNMKLFzckACS9UyioGBSlNzPMAnWSeqQ5s My9JT78zgfl6XnfiVfHHrGLhaBqzDXKLmyhyRXzjiTXFbW2aTTlXG9kjDZ1bEONMhvF+ XfhrPph7c3xwj4mv4FbcPVUQfbT5Ns6ki0HyQEaZ+jYucBEo0NrJ6LmSLkvwgp5GxzQH HJ1fBxvYJeXCTjdJp/i0+qyOj/xsp65Srq1DZyYr3EVFBEJx46ft8sIZ+DvrQ0HDbV4J xvmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=am6dRGIxBONTlNx8td89YADQ2kZ8jOcuNsD9gG75Rz8=; b=AtjPH3wDT2utttNN6FVc9WvmCh2j/w6L5W1YHdAD+xrvbwxLay9JVcl4z9tn0l5zHk zC55nqXsH6i7/spIWwRQXZtQoXAp+8+GI5N4Y9+B9ig7NEMDtbnoVtjWmHjfMciFj8VC shmbDwgkW14/6trye34+BLCmL3Jjf8zQoiHCIKUC7LHT3GfQIg8A0rEwOmRimbnfo15c L9ogNcS0WtSSlaAJPFGWyr5fsBuur1E1ULOGeW/rVwyUkOXQsW0YQsc5WDoamoHmZusp io6MKB2zzIUlcjYj/ODjF6Mv2SBtEo7Naf1rqPIsAfGZ4RMP0UAkD4npOB5Ikt5WOPF5 LKxw== X-Gm-Message-State: AFqh2kpF1JbPFIZYyDuYRkEcjbamD9uVKCissnfJ6Di1ZB9aioERQa9X 5I5/sus5JCV3DrTB409YfMkTuI+1tepLh5ct X-Google-Smtp-Source: AMrXdXv/GYnnQweD8JTEQ8XUapeEhzA4nRIIFQZ4iK9qp7vItlR3K6AnPMERUTv33KBCpT/9bk3i5Q== X-Received: by 2002:a17:902:7144:b0:194:9e86:ffee with SMTP id u4-20020a170902714400b001949e86ffeemr7392137plm.44.1674081914173; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id d8-20020a170903230800b001948107490csm8661518plh.19.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXc-CY for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEC-1G for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 21/42] xfs: use xfs_alloc_vextent_start_bno() where appropriate Date: Thu, 19 Jan 2023 09:44:44 +1100 Message-Id: <20230118224505.1964941-22-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Change obvious callers of single AG allocation to use xfs_alloc_vextent_start_bno(). Callers no long need to specify XFS_ALLOCTYPE_START_BNO, and so the type can be driven inward and removed. While doing this, also pass the allocation target fsb as a parameter rather than encoding it in args->fsbno. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 24 ++++++++++--------- fs/xfs/libxfs/xfs_alloc.h | 13 ++++++++-- fs/xfs/libxfs/xfs_bmap.c | 43 ++++++++++++++++++++-------------- fs/xfs/libxfs/xfs_bmap_btree.c | 9 ++----- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 186ce3aee9e0..294f80d596d9 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3189,7 +3189,6 @@ xfs_alloc_vextent_check_args( struct xfs_mount *mp = args->mp; xfs_agblock_t agsize; - args->otype = args->type; args->agbno = NULLAGBLOCK; /* @@ -3345,7 +3344,7 @@ xfs_alloc_vextent_iterate_ags( trace_xfs_alloc_vextent_loopfailed(args); if (args->agno == start_agno && - args->otype == XFS_ALLOCTYPE_START_BNO) + args->otype == XFS_ALLOCTYPE_NEAR_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; /* @@ -3373,7 +3372,7 @@ xfs_alloc_vextent_iterate_ags( } flags = 0; - if (args->otype == XFS_ALLOCTYPE_START_BNO) { + if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) { args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_NEAR_BNO; } @@ -3396,18 +3395,22 @@ xfs_alloc_vextent_iterate_ags( * otherwise will wrap back to the start AG and run a second blocking pass to * the end of the filesystem. */ -static int +int xfs_alloc_vextent_start_ag( struct xfs_alloc_arg *args, - xfs_agnumber_t minimum_agno) + xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; xfs_agnumber_t start_agno; xfs_agnumber_t rotorstep = xfs_rotorstep; bool bump_rotor = false; int error; - error = xfs_alloc_vextent_check_args(args, args->fsbno); + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; @@ -3416,14 +3419,15 @@ xfs_alloc_vextent_start_ag( if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) && xfs_is_inode32(mp)) { - args->fsbno = XFS_AGB_TO_FSB(mp, + target = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount), 0); bump_rotor = 1; } - start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, args->fsbno)); - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->type = XFS_ALLOCTYPE_NEAR_BNO; + args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, XFS_ALLOC_FLAG_TRYLOCK); @@ -3498,8 +3502,6 @@ xfs_alloc_vextent( error = xfs_alloc_vextent_this_ag(args); xfs_perag_put(args->pag); break; - case XFS_ALLOCTYPE_START_BNO: - return xfs_alloc_vextent_start_ag(args, minimum_agno); default: error = -EFSCORRUPTED; ASSERT(0); diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 73697dd3ca55..5487dff3d68a 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -20,7 +20,6 @@ unsigned int xfs_agfl_size(struct xfs_mount *mp); * Freespace allocation types. Argument to xfs_alloc_[v]extent. */ #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ -#define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ #define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ @@ -29,7 +28,6 @@ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_TYPES \ { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ - { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } @@ -128,6 +126,17 @@ xfs_alloc_vextent( */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Best effort full filesystem allocation scan. + * + * Locality aware allocation will be attempted in the initial AG, but on failure + * non-localised attempts will be made. The AGs are constrained by previous + * allocations in the current transaction. Two passes will be made - the first + * non-blocking, the second blocking. + */ +int xfs_alloc_vextent_start_ag(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Iterate from the AG indicated from args->fsbno through to the end of the * filesystem attempting blocking allocation. This is for use in last diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index eb3dc8d5319b..aefcdf2bfd57 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -646,12 +646,11 @@ xfs_bmap_extents_to_btree( args.mp = mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); - args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); args.minlen = args.maxlen = args.prod = 1; args.wasdel = wasdel; *logflagsp = 0; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, + XFS_INO_TO_FSB(mp, ip->i_ino)); if (error) goto out_root_realloc; @@ -792,15 +791,15 @@ xfs_bmap_local_to_extents( args.total = total; args.minlen = args.maxlen = args.prod = 1; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); + /* * Allocate a block. We know we need only one, since the * file currently fits in an inode. */ - args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); - args.type = XFS_ALLOCTYPE_START_BNO; args.total = total; args.minlen = args.maxlen = args.prod = 1; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, + XFS_INO_TO_FSB(args.mp, ip->i_ino)); if (error) goto done; @@ -3208,7 +3207,6 @@ xfs_bmap_btalloc_select_lengths( int notinit = 0; int error = 0; - args->type = XFS_ALLOCTYPE_START_BNO; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { args->total = ap->minlen; args->minlen = ap->minlen; @@ -3500,7 +3498,8 @@ xfs_bmap_btalloc_at_eof( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t blen, - int stripe_align) + int stripe_align, + bool ag_only) { struct xfs_mount *mp = args->mp; xfs_alloctype_t atype; @@ -3565,7 +3564,10 @@ xfs_bmap_btalloc_at_eof( args->minalignslop = 0; } - error = xfs_alloc_vextent(args); + if (ag_only) + error = xfs_alloc_vextent(args); + else + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; @@ -3591,13 +3593,17 @@ xfs_bmap_btalloc_best_length( { struct xfs_mount *mp = args->mp; xfs_extlen_t blen = 0; + bool is_filestream = false; int error; + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) + is_filestream = true; + /* * Determine the initial block number we will target for allocation. */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) { + if (is_filestream) { xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); if (agno == NULLAGNUMBER) agno = 0; @@ -3613,8 +3619,7 @@ xfs_bmap_btalloc_best_length( * the request. If one isn't found, then adjust the minimum allocation * size to the largest space found. */ - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) { + if (is_filestream) { /* * If there is very little free space before we start a * filestreams allocation, we're almost guaranteed to fail to @@ -3639,14 +3644,18 @@ xfs_bmap_btalloc_best_length( * trying. */ if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { - error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align); + error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, + is_filestream); if (error) return error; if (args->fsbno != NULLFSBLOCK) return 0; } - error = xfs_alloc_vextent(args); + if (is_filestream) + error = xfs_alloc_vextent(args); + else + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; if (args->fsbno != NULLFSBLOCK) @@ -3658,9 +3667,7 @@ xfs_bmap_btalloc_best_length( */ if (args->minlen > ap->minlen) { args->minlen = ap->minlen; - args->type = XFS_ALLOCTYPE_START_BNO; - args->fsbno = ap->blkno; - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) return error; } diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index d42c1a1da1fc..b8ad95050c9b 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -214,9 +214,6 @@ xfs_bmbt_alloc_block( if (!args.wasdel && args.tp->t_blk_res == 0) return -ENOSPC; - args.fsbno = be64_to_cpu(start->l); - args.type = XFS_ALLOCTYPE_START_BNO; - /* * If we are coming here from something like unwritten extent * conversion, there has been no data extent allocation already done, so @@ -227,7 +224,7 @@ xfs_bmbt_alloc_block( args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, cur->bc_ino.whichfork); - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, be64_to_cpu(start->l)); if (error) return error; @@ -237,10 +234,8 @@ xfs_bmbt_alloc_block( * a full btree split. Try again and if * successful activate the lowspace algorithm. */ - args.fsbno = 0; args.minleft = 0; - args.type = XFS_ALLOCTYPE_START_BNO; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_start_ag(&args, 0); if (error) return error; cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; From patchwork Wed Jan 18 22:44:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 102D5C46467 for ; Wed, 18 Jan 2023 22:48:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229780AbjARWsR (ORCPT ); Wed, 18 Jan 2023 17:48:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230121AbjARWsC (ORCPT ); Wed, 18 Jan 2023 17:48:02 -0500 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F7D66603D for ; Wed, 18 Jan 2023 14:47:53 -0800 (PST) Received: by mail-pl1-x62e.google.com with SMTP id 20so588253plo.3 for ; Wed, 18 Jan 2023 14:47:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ywVcLFRLHCjudPtvOIzM/bnfKbnu3wI5GJNOsA+GD9k=; b=ki04V/SNegOuRPRsHJHPwq9ZELvOMTkcjDke+8hii49jEvHybCyjNpc8FitnwkJgUf oXeN4AFxYnBA7klDjZorH3cdon+mjuTweEuDfnGTzGCdhpOQq29oX1Ong5DndP6Zqt2b JQ0XSm1vcaKvUewXvkddp2AW4nJu9TXTsuVd5HCN6ThznPcEY2cSRgUxKeVrJyaxIGsp nRDdYlXLO85s5CmL6D0W8VeJK1g6Pu+h6TxBsF7sTnGUohWB8Xf3wzkeWmob1mNIP0sW P75/rftmNuQoatN3gd++ZFBepC+/FPg0xmKn7jlNxBDoz1RoatGkUbgVVaBlAr2PT6pc AkRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ywVcLFRLHCjudPtvOIzM/bnfKbnu3wI5GJNOsA+GD9k=; b=6lxmM0hOUaQmNaG91soT13xcrkJTC2GRL6wkfxn90wkMrKSHKBGTP8Dnpg4GnY76gv WQVfU1HyC8vk+Id4sGVuSmjCMIsbWcJNEfv1sicmYqCUFsLFaQWz9Fl2QslHyfv6EK4c HAbR7+dr9lzxsLQV0qvBzN2yH586zsw7YndVM/1kxwZkdYwuEz28QD5+zW4c1UJLYYrG bVz+yP/XlnL56YLw/2n2dWFkTXj2dtuoeXI8fWzju8nuuAOoNF6Le0VXQE59brZUFOav 11aWNENAPgnZyxPCgfkxyAAh2+wziyeJgAu0nD2uThryN2gSqULQSSqtThFbfu7ypPWx BVEg== X-Gm-Message-State: AFqh2krLMdaI77m+14G1g/lZIz4kzX//REHWYoJ5szh+qNKqg5PzQH5c DdaRqBr2M3At5Nm5XAijzx7qcrDPzrdpS2P5 X-Google-Smtp-Source: AMrXdXtE/hgckTOB2K0QeULsFi/bwqgr90z/YpkODWNM6A13Af9VWdBcJIw++UyNOEYAGRxEMcEZrA== X-Received: by 2002:a17:902:8c94:b0:192:9d79:d3d6 with SMTP id t20-20020a1709028c9400b001929d79d3d6mr8933600plo.69.1674082072667; Wed, 18 Jan 2023 14:47:52 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id b6-20020a170902650600b00192d4ba98eesm23652111plk.167.2023.01.18.14.47.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:52 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXe-DX for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEH-1M for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 22/42] xfs: introduce xfs_alloc_vextent_near_bno() Date: Thu, 19 Jan 2023 09:44:45 +1100 Message-Id: <20230118224505.1964941-23-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The remaining callers of xfs_alloc_vextent() are all doing NEAR_BNO allocations. We can replace that function with a new xfs_alloc_vextent_near_bno() function that does this explicitly. We also multiplex NEAR_BNO allocations through xfs_alloc_vextent_this_ag via args->type. Replace all of these with direct calls to xfs_alloc_vextent_near_bno(), too. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 50 ++++++++++++++++++------------ fs/xfs/libxfs/xfs_alloc.h | 14 ++++----- fs/xfs/libxfs/xfs_bmap.c | 6 ++-- fs/xfs/libxfs/xfs_ialloc.c | 27 ++++++---------- fs/xfs/libxfs/xfs_ialloc_btree.c | 5 ++- fs/xfs/libxfs/xfs_refcount_btree.c | 7 ++--- 6 files changed, 55 insertions(+), 54 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 294f80d596d9..485a73eab9d9 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3479,35 +3479,47 @@ int } /* - * Allocate an extent (variable-size). - * Depending on the allocation type, we either look in a single allocation - * group or loop over the allocation groups to find the result. + * Allocate an extent as close to the target as possible. If there are not + * viable candidates in the AG, then fail the allocation. */ int -xfs_alloc_vextent( - struct xfs_alloc_arg *args) +xfs_alloc_vextent_near_bno( + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) { + struct xfs_mount *mp = args->mp; + bool need_pag = !args->pag; xfs_agnumber_t minimum_agno = 0; int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - switch (args->type) { - case XFS_ALLOCTYPE_THIS_AG: - case XFS_ALLOCTYPE_NEAR_BNO: - case XFS_ALLOCTYPE_THIS_BNO: - args->pag = xfs_perag_get(args->mp, - XFS_FSB_TO_AGNO(args->mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); - xfs_perag_put(args->pag); - break; - default: - error = -EFSCORRUPTED; - ASSERT(0); - break; + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; } - return error; + + args->agno = XFS_FSB_TO_AGNO(mp, target); + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + return 0; + } + + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->type = XFS_ALLOCTYPE_NEAR_BNO; + if (need_pag) + args->pag = xfs_perag_get(args->mp, args->agno); + error = xfs_alloc_ag_vextent(args); + if (need_pag) + xfs_perag_put(args->pag); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return 0; } /* Ensure that the freelist is at full capacity. */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 5487dff3d68a..f38a2f8e20fb 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -113,19 +113,19 @@ xfs_alloc_log_agf( struct xfs_buf *bp, /* buffer for a.g. freelist header */ uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ -/* - * Allocate an extent (variable-size). - */ -int /* error */ -xfs_alloc_vextent( - xfs_alloc_arg_t *args); /* allocation argument structure */ - /* * Allocate an extent in the specific AG defined by args->fsbno. If there is no * space in that AG, then the allocation will fail. */ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +/* + * Allocate an extent as close to the target as possible. If there are not + * viable candidates in the AG, then fail the allocation. + */ +int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index aefcdf2bfd57..4446b035eed5 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3246,7 +3246,6 @@ xfs_bmap_btalloc_filestreams( int notinit = 0; int error; - args->type = XFS_ALLOCTYPE_NEAR_BNO; args->total = ap->total; start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno); @@ -3565,7 +3564,7 @@ xfs_bmap_btalloc_at_eof( } if (ag_only) - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_near_bno(args, ap->blkno); else error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) @@ -3612,7 +3611,6 @@ xfs_bmap_btalloc_best_length( ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } xfs_bmap_adjacent(ap); - args->fsbno = ap->blkno; /* * Search for an allocation group with a single extent large enough for @@ -3653,7 +3651,7 @@ xfs_bmap_btalloc_best_length( } if (is_filestream) - error = xfs_alloc_vextent(args); + error = xfs_alloc_vextent_near_bno(args, ap->blkno); else error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 2f3e47cb9332..daa6f7055bba 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -717,23 +717,17 @@ xfs_ialloc_ag_alloc( isaligned = 1; } else args.alignment = igeo->cluster_align; - /* - * Need to figure out where to allocate the inode blocks. - * Ideally they should be spaced out through the a.g. - * For now, just allocate blocks up front. - */ - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); /* * Allocate a fixed-size extent of inodes. */ - args.type = XFS_ALLOCTYPE_NEAR_BNO; args.prod = 1; /* * Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); if (error) return error; } @@ -743,11 +737,11 @@ xfs_ialloc_ag_alloc( * alignment. */ if (isaligned && args.fsbno == NULLFSBLOCK) { - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); args.alignment = igeo->cluster_align; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); + if (error) return error; } @@ -759,9 +753,6 @@ xfs_ialloc_ag_alloc( igeo->ialloc_min_blks < igeo->ialloc_blks && args.fsbno == NULLFSBLOCK) { sparse_alloc: - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); args.alignment = args.mp->m_sb.sb_spino_align; args.prod = 1; @@ -783,7 +774,9 @@ xfs_ialloc_ag_alloc( args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + be32_to_cpu(agi->agi_root))); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index fa6cd2502970..9b28211d5a4c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -105,14 +105,13 @@ __xfs_inobt_alloc_block( args.mp = cur->bc_mp; args.pag = cur->bc_ag.pag; args.oinfo = XFS_RMAP_OINFO_INOBT; - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, sbno)); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index a980fb18bde2..f3b860970b26 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -68,14 +68,13 @@ xfs_refcountbt_alloc_block( args.tp = cur->bc_tp; args.mp = cur->bc_mp; args.pag = cur->bc_ag.pag; - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, - xfs_refc_block(args.mp)); args.oinfo = XFS_RMAP_OINFO_REFC; args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_near_bno(&args, + XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, + xfs_refc_block(args.mp))); if (error) goto out_error; trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno, From patchwork Wed Jan 18 22:44:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6969EC38159 for ; Wed, 18 Jan 2023 22:45:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229820AbjARWpa (ORCPT ); Wed, 18 Jan 2023 17:45:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229758AbjARWpQ (ORCPT ); Wed, 18 Jan 2023 17:45:16 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 036A663E31 for ; Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id q64so549130pjq.4 for ; Wed, 18 Jan 2023 14:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gYOQjTECmcadPuWz4I3IFUdQ7vHbzGKE7RshOXSTHuM=; b=Irf0+3NBtxWHJpl/OGm4P3R9LXQjGPUa2u+At6yddTJCjBVyYuN9jTQPlrjNbfe2h2 g/uOYOg3X4H6b6jrGVsgO2KEV5Nwqf7lhTFRrgZBvqNormr/UP1I+fyCSOEulj6TwVTM 3l3a60+vhLUOJR9DwLq0qoIC+tjUIgPPURRDIYEh8RYTHvxPr8aD+nMDcBOPj1hSI46I fhB0PknV4TI3nuM8yl1nBHMha6+Jg1qW/yaAFON9my2bQySPO9nTq8ul5DClm3u7MTVe gADFwwQj3S0O8l5vhFWQux8NUnFCV2FMmiy64ZmeSjvEV/qaMIajkfXYzPSLt7aZD/sl Z8DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gYOQjTECmcadPuWz4I3IFUdQ7vHbzGKE7RshOXSTHuM=; b=Ku5sOIWp/8BV7aNayCd2bLBPbRkeghVHHgwhk8wGxyr5gWhiWECoPMPNMDYnJbQIrA JGpthcw7uSNQKzRtzAp7n8wEOFzTN5cSM8cr0TFbSF8UjwOFrPVHqHcb2mqqc80wiEgb Lx/QjH7m0hOP9GeXouBmbsmaC/5DZh/V37r5MOgRtk7oIQydHPN0uErzHHiKoX2zceP2 EnM/89gl1KR8ASa0g25QPXsgL5Jw1qbp1TT+8oUXdEJ614qrpPJbuL0j9lJ7ZmEuLyqE SDAYoxxvaOlU031JJ6OdjAS4DVBiptp0XrsvKZ2pZQgBkU65jBP0a++wJ4rGMZISp4mR JqBQ== X-Gm-Message-State: AFqh2koX3xbyBbNAkCqriq/wQyGf64LRev4LfzhXACl7RczG4zQhmSN2 0zuXaYm+59cHHFJuhI2qUvybSnVn/tZWgtth X-Google-Smtp-Source: AMrXdXvD5lc7+BsWHV/pW6ZhN0gqF3jQFIaN5B1XUvi7YT7VcBZ7oEPSOAKW5LHFWGSOKFBghrAHkg== X-Received: by 2002:a17:902:7fc9:b0:194:84f2:c1ec with SMTP id t9-20020a1709027fc900b0019484f2c1ecmr9032672plb.21.1674081914540; Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id y23-20020a17090264d700b00192820d00d0sm23575065pli.120.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:14 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXh-ES for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEM-1R for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 23/42] xfs: introduce xfs_alloc_vextent_exact_bno() Date: Thu, 19 Jan 2023 09:44:46 +1100 Message-Id: <20230118224505.1964941-24-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Two of the callers to xfs_alloc_vextent_this_ag() actually want exact block number allocation, not anywhere-in-ag allocation. Split this out from _this_ag() as a first class citizen so no external extent allocation code needs to care about args->type anymore. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.c | 6 ++-- fs/xfs/libxfs/xfs_alloc.c | 65 ++++++++++++++++++++++++++++++++------ fs/xfs/libxfs/xfs_alloc.h | 13 ++++++-- fs/xfs/libxfs/xfs_bmap.c | 6 ++-- fs/xfs/libxfs/xfs_ialloc.c | 6 ++-- fs/xfs/scrub/repair.c | 4 +-- 6 files changed, 73 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 053d77a283f7..86696a1c6891 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -888,7 +888,6 @@ xfs_ag_shrink_space( .tp = *tpp, .mp = mp, .pag = pag, - .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, @@ -920,8 +919,6 @@ xfs_ag_shrink_space( if (delta >= aglen) return -EINVAL; - args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); - /* * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. @@ -939,7 +936,8 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta)); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 485a73eab9d9..b810a94aad70 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3272,28 +3272,34 @@ xfs_alloc_vextent_set_fsbno( */ int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_agnumber_t agno) { struct xfs_mount *mp = args->mp; xfs_agnumber_t minimum_agno = 0; + xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - error = xfs_alloc_vextent_check_args(args, args->fsbno); + if (minimum_agno > agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; + return 0; + } + + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } + args->agno = agno; + args->agbno = 0; + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_ag_vextent(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); @@ -3450,7 +3456,7 @@ xfs_alloc_vextent_start_ag( * pass, so will not recurse into AGs lower than indicated by fsbno. */ int - xfs_alloc_vextent_first_ag( +xfs_alloc_vextent_first_ag( struct xfs_alloc_arg *args, xfs_rfsblock_t target) { @@ -3472,12 +3478,51 @@ int start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); args->type = XFS_ALLOCTYPE_THIS_AG; args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, 0); xfs_alloc_vextent_set_fsbno(args, minimum_agno); return error; } +/* + * Allocate within a single AG only. + */ +int +xfs_alloc_vextent_exact_bno( + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; + int error; + + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, target); + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + return 0; + } + + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_BNO; + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return 0; +} + /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index f38a2f8e20fb..106b4deb1110 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -114,10 +114,10 @@ xfs_alloc_log_agf( uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ /* - * Allocate an extent in the specific AG defined by args->fsbno. If there is no - * space in that AG, then the allocation will fail. + * Allocate an extent anywhere in the specific AG given. If there is no + * space matching the requirements in that AG, then the allocation will fail. */ -int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); /* * Allocate an extent as close to the target as possible. If there are not @@ -126,6 +126,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, xfs_rfsblock_t target); +/* + * Allocate an extent exactly at the target given. If this is not possible + * then the allocation fails. + */ +int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4446b035eed5..c9902df16e25 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3514,7 +3514,6 @@ xfs_bmap_btalloc_at_eof( xfs_extlen_t nextminlen = 0; atype = args->type; - args->type = XFS_ALLOCTYPE_THIS_BNO; args->alignment = 1; /* @@ -3532,8 +3531,8 @@ xfs_bmap_btalloc_at_eof( else args->minalignslop = 0; - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); xfs_perag_put(args->pag); if (error) return error; @@ -3546,7 +3545,6 @@ xfs_bmap_btalloc_at_eof( */ args->pag = NULL; args->type = atype; - args->fsbno = ap->blkno; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index daa6f7055bba..d2525f0cc6cd 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc( goto sparse_alloc; if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); - args.type = XFS_ALLOCTYPE_THIS_BNO; args.prod = 1; /* @@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + args.agbno)); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 5f4b50aac4bb..1b71174ec0d6 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -328,14 +328,12 @@ xrep_alloc_ag_block( args.mp = sc->mp; args.pag = sc->sa.pag; args.oinfo = *oinfo; - args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_this_ag(&args, sc->sa.pag->pag_agno); if (error) return error; if (args.fsbno == NULLFSBLOCK) From patchwork Wed Jan 18 22:44:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8465C38159 for ; Wed, 18 Jan 2023 22:45:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229830AbjARWpd (ORCPT ); Wed, 18 Jan 2023 17:45:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43622 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229854AbjARWpS (ORCPT ); Wed, 18 Jan 2023 17:45:18 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B32EC5FD60 for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id 7-20020a17090a098700b002298931e366so67363pjo.2 for ; Wed, 18 Jan 2023 14:45:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=etaI0Gchj8lFe6SVq82O+3tRjxGxTPna0CWpt9psuR8=; b=Pfje9+2AsnhYqua03Ex8W3ngg/hRV/GI1PIRa9gkKHV2yLSOc+qpt3TkjIww4ocZK3 Pxyq+3Y6zgg2ZZTcUcePR6m7QAcJ2cKiJrmkQHM8TgRz3pT+ndzSXuSGaCbdvPD4mp4e ldl2XgaMuBAlCMhM6j47YneOFI7lAvD56ML0cYNaOTSMYMLRtMVbJ+SLb2v09yKBK56N yChJjLTWnL0NRJuLArYCL3p8DDswCfa2KcWx8ejgT8pXrYRKSEI4BV4GLJkXDtWssuv9 cz0rSBZzrBzoxBVxwzB6KNS1GGI2CJYjAGDPPDgGFB/URgD0d73FvTB0OthIOkmSWzR6 PeTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=etaI0Gchj8lFe6SVq82O+3tRjxGxTPna0CWpt9psuR8=; b=19mSvKJIavY25CtSFRHZlrLmfT1a67tz5+FyZNXmNhMFrSYqFRNJqBK/+5d+F6BYtF 0WOEYu7GCr83gg4dMQTJj7lV8pCJcG5guNfRumRHwX3NQJDANxbhxh1oJlvqaGp3vkmF Ob5+r8Zq7SXTJ0bRzBw5Sk8tJ93ceB9z3mresA18olLuAfWsLf5Nq6Q1zsoIBAR/dF8u 3xMErRYkwVQ0w11zZ9KbVHJmoFsh3XKnCV3dVYUSKk6upYhND6YWS5bGP2favXTuLRr/ oxKdIViKGDGp/EdtqHygm5zy8xHv3HEZiENP2cphPKmiAX1uDpBk8pXJYIflbqI2MxS6 I+5w== X-Gm-Message-State: AFqh2kr0LMtNTchWBwIP60yys4L4URB64gctYy6cpt6sVNWATRXzwvPC brp4hx8xLqs51Dgut5lnVbL0CjdjIitSC4WP X-Google-Smtp-Source: AMrXdXs9tGuLlV7qqqcl+9SxLKvZoz3gEJD80mNRiZDiOP5sK6lsFWSYdPNQ3xsA2yANJCA6GgXpFA== X-Received: by 2002:a17:902:c3cd:b0:194:623e:f401 with SMTP id j13-20020a170902c3cd00b00194623ef401mr9191092plj.8.1674081917095; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id q6-20020a170902dac600b0018544ad1e8esm2150724plx.238.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXl-FN for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FER-1X for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 24/42] xfs: introduce xfs_alloc_vextent_prepare() Date: Thu, 19 Jan 2023 09:44:47 +1100 Message-Id: <20230118224505.1964941-25-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that we have wrapper functions for each type of allocation we can ask for, we can start unravelling xfs_alloc_ag_vextent(). That is essentially just a prepare stage, the allocation multiplexer and a post-allocation accounting step is the allocation proceeded. The current xfs_alloc_vextent*() wrappers all have a prepare stage, the allocation operation and a post-allocation accounting step. We can consolidate this by moving the AG alloc prep code into the wrapper functions, the accounting code in the wrapper accounting functions, and cut out the multiplexer layer entirely. This patch consolidates the AG preparation stage. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 120 ++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index b810a94aad70..bfbbb7536310 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1144,31 +1144,8 @@ static int xfs_alloc_ag_vextent( struct xfs_alloc_arg *args) { - struct xfs_mount *mp = args->mp; int error = 0; - ASSERT(args->minlen > 0); - ASSERT(args->maxlen > 0); - ASSERT(args->minlen <= args->maxlen); - ASSERT(args->mod < args->prod); - ASSERT(args->alignment > 0); - ASSERT(args->resv != XFS_AG_RESV_AGFL); - - - error = xfs_alloc_fix_freelist(args, 0); - if (error) { - trace_xfs_alloc_vextent_nofix(args); - return error; - } - if (!args->agbp) { - /* cannot allocate in this AG at all */ - trace_xfs_alloc_vextent_noagbp(args); - args->agbno = NULLAGBLOCK; - return 0; - } - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); - args->wasfromfl = 0; - /* * Branch to correct routine based on the type. */ @@ -3201,11 +3178,18 @@ xfs_alloc_vextent_check_args( args->maxlen = agsize; if (args->alignment == 0) args->alignment = 1; + + ASSERT(args->minlen > 0); + ASSERT(args->maxlen > 0); + ASSERT(args->alignment > 0); + ASSERT(args->resv != XFS_AG_RESV_AGFL); + ASSERT(XFS_FSB_TO_AGNO(mp, target) < mp->m_sb.sb_agcount); ASSERT(XFS_FSB_TO_AGBNO(mp, target) < agsize); ASSERT(args->minlen <= args->maxlen); ASSERT(args->minlen <= agsize); ASSERT(args->mod < args->prod); + if (XFS_FSB_TO_AGNO(mp, target) >= mp->m_sb.sb_agcount || XFS_FSB_TO_AGBNO(mp, target) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || @@ -3217,6 +3201,41 @@ xfs_alloc_vextent_check_args( return 0; } +/* + * Prepare an AG for allocation. If the AG is not prepared to accept the + * allocation, return failure. + * + * XXX(dgc): The complexity of "need_pag" will go away as all caller paths are + * modified to hold their own perag references. + */ +static int +xfs_alloc_vextent_prepare_ag( + struct xfs_alloc_arg *args) +{ + bool need_pag = !args->pag; + int error; + + if (need_pag) + args->pag = xfs_perag_get(args->mp, args->agno); + + error = xfs_alloc_fix_freelist(args, 0); + if (error) { + trace_xfs_alloc_vextent_nofix(args); + if (need_pag) + xfs_perag_put(args->pag); + args->agbno = NULLAGBLOCK; + return error; + } + if (!args->agbp) { + /* cannot allocate in this AG at all */ + trace_xfs_alloc_vextent_noagbp(args); + args->agbno = NULLAGBLOCK; + return 0; + } + args->wasfromfl = 0; + return 0; +} + /* * Post-process allocation results to set the allocated block number correctly * for the caller. @@ -3268,7 +3287,8 @@ xfs_alloc_vextent_set_fsbno( } /* - * Allocate within a single AG only. + * Allocate within a single AG only. Caller is expected to hold a + * perag reference in args->pag. */ int xfs_alloc_vextent_this_ag( @@ -3301,7 +3321,10 @@ xfs_alloc_vextent_this_ag( args->fsbno = target; args->type = XFS_ALLOCTYPE_THIS_AG; - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_vextent_prepare_ag(args); + if (!error && args->agbp) + error = xfs_alloc_ag_vextent(args); + xfs_alloc_vextent_set_fsbno(args, minimum_agno); return error; } @@ -3339,13 +3362,19 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - error = xfs_alloc_ag_vextent(args); - if (error) { - args->agbno = NULLAGBLOCK; + args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + error = xfs_alloc_vextent_prepare_ag(args); + if (error) break; - } - if (args->agbp) + + if (args->agbp) { + /* + * Allocation is supposed to succeed now, so break out + * of the loop regardless of whether we succeed or not. + */ + error = xfs_alloc_ag_vextent(args); break; + } trace_xfs_alloc_vextent_loopfailed(args); @@ -3378,10 +3407,8 @@ xfs_alloc_vextent_iterate_ags( } flags = 0; - if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) { - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); + if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) args->type = XFS_ALLOCTYPE_NEAR_BNO; - } } xfs_perag_put(args->pag); args->pag = NULL; @@ -3485,7 +3512,8 @@ xfs_alloc_vextent_first_ag( } /* - * Allocate within a single AG only. + * Allocate at the exact block target or fail. Caller is expected to hold a + * perag reference in args->pag. */ int xfs_alloc_vextent_exact_bno( @@ -3515,9 +3543,10 @@ xfs_alloc_vextent_exact_bno( args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->fsbno = target; args->type = XFS_ALLOCTYPE_THIS_BNO; - error = xfs_alloc_ag_vextent(args); - if (error) - return error; + + error = xfs_alloc_vextent_prepare_ag(args); + if (!error && args->agbp) + error = xfs_alloc_ag_vextent(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); return 0; @@ -3526,6 +3555,8 @@ xfs_alloc_vextent_exact_bno( /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. + * + * Caller may or may not have a per-ag reference in args->pag. */ int xfs_alloc_vextent_near_bno( @@ -3550,21 +3581,22 @@ xfs_alloc_vextent_near_bno( args->agno = XFS_FSB_TO_AGNO(mp, target); if (minimum_agno > args->agno) { trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; return 0; } args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->type = XFS_ALLOCTYPE_NEAR_BNO; - if (need_pag) - args->pag = xfs_perag_get(args->mp, args->agno); - error = xfs_alloc_ag_vextent(args); + + error = xfs_alloc_vextent_prepare_ag(args); + if (!error && args->agbp) + error = xfs_alloc_ag_vextent(args); + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); if (need_pag) xfs_perag_put(args->pag); - if (error) - return error; - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - return 0; + return error; } /* Ensure that the freelist is at full capacity. */ From patchwork Wed Jan 18 22:44:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 522ECC38159 for ; Wed, 18 Jan 2023 22:45:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229463AbjARWpf (ORCPT ); Wed, 18 Jan 2023 17:45:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229877AbjARWpT (ORCPT ); Wed, 18 Jan 2023 17:45:19 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20B345F38D for ; Wed, 18 Jan 2023 14:45:19 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id u1-20020a17090a450100b0022936a63a21so3999529pjg.4 for ; Wed, 18 Jan 2023 14:45:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=rrTSlntKw9Lwv6sitBQVT6C1O2iE/xZ9M6S2+PSGUTc=; b=CV6o51V7pUcaBUILI1dO1teDNmEOVQ2ZvNzxq6qUHAymNAnpA7R0vXcUVDysf9cygV 18sbo3IvQ/eYHXzmJpseC9+d4Z6xpb9SLR3aJEMZN7Cc6bdWmYHQWMRw/z67yuLNipeF GQD+3k4EGg4fgMFFdROc6LzQDNlYRg8FrbOFzyx/8FpBluisXh1i6XQXeVoP8yREnz52 8cj0gJDr/pC/XRsBY6HOetLgNEdir2T7PY5r/X81ohjS8bOB4D/TeRbHVAj/LMpubbz+ zWeAMxzX/BooeHrj1z2ezhjHJcD9jL52Rp9KBTBR4wxUJoi81KbvQa7BFI18eNnW+/44 GRew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rrTSlntKw9Lwv6sitBQVT6C1O2iE/xZ9M6S2+PSGUTc=; b=qHvn4gXi7CVHDHUsRtbrJIxDUQxTZi/jnwkbF1I21q2E3m12NReDnQ4oZEgsf1ix1D 1s4Wb7ExFS24SxjLU5UitM141Bg7WRC8hBTeA1Nmkp7gbgl0QMc+/O6bzTw6rP9P9XUW 4ZSyDNpahsvSSpk9pgjOiInwE2vYgzIbJ62UcXZwE4XtEEuxtgpGpxsDU4qg1f8yHpvu 9xnzfDn2IgDGB4g7W5+q7jSZYfI8lJbngmINeBr19nmdPFYFhb/OgU8XZOz+OEX/yIhY 17yVUXAt7o0eeu8x/+dl9mPQI3Ze2zXFZ9+QXLeqm444wrJWH4wbE6us3PhRolTWX3rY wdAg== X-Gm-Message-State: AFqh2kqkaDusQkKOo/3I3MA9wE7YE9pPzRYFraJfPhPxfmmwGn491r6f ZHX1zJJ9ijDrikkxVbVmVLRjm9d+wDgPPVj5 X-Google-Smtp-Source: AMrXdXs2ViCIOOaQO+Lm5ZKs3moY5X5y/aJ7tC3JIbjgjnTWxzXlxdc1T9DbVzuz2KAWqddltKHMkw== X-Received: by 2002:a05:6a21:1013:b0:b6:b6a6:9753 with SMTP id nk19-20020a056a21101300b000b6b6a69753mr6781281pzb.8.1674081918584; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id u11-20020a6540cb000000b0046ff3634a78sm19589693pgp.71.2023.01.18.14.45.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXn-GF for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEW-1d for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 25/42] xfs: move allocation accounting to xfs_alloc_vextent_set_fsbno() Date: Thu, 19 Jan 2023 09:44:48 +1100 Message-Id: <20230118224505.1964941-26-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Move it from xfs_alloc_ag_vextent() so we can get rid of that layer. Rename xfs_alloc_vextent_set_fsbno() to xfs_alloc_vextent_finish() to indicate that it's function is finishing off the allocation that we've run now that it contains much more functionality. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 122 ++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index bfbbb7536310..ad2b91b230f6 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1163,36 +1163,6 @@ xfs_alloc_ag_vextent( ASSERT(0); /* NOTREACHED */ } - - if (error || args->agbno == NULLAGBLOCK) - return error; - - ASSERT(args->len >= args->minlen); - ASSERT(args->len <= args->maxlen); - ASSERT(args->agbno % args->alignment == 0); - - /* if not file data, insert new block into the reverse map btree */ - if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { - error = xfs_rmap_alloc(args->tp, args->agbp, args->pag, - args->agbno, args->len, &args->oinfo); - if (error) - return error; - } - - if (!args->wasfromfl) { - error = xfs_alloc_update_counters(args->tp, args->agbp, - -((long)(args->len))); - if (error) - return error; - - ASSERT(!xfs_extent_busy_search(args->mp, args->pag, - args->agbno, args->len)); - } - - xfs_ag_resv_alloc_extent(args->pag, args->resv, args); - - XFS_STATS_INC(args->mp, xs_allocx); - XFS_STATS_ADD(args->mp, xs_allocb, args->len); return error; } @@ -3237,18 +3207,21 @@ xfs_alloc_vextent_prepare_ag( } /* - * Post-process allocation results to set the allocated block number correctly - * for the caller. + * Post-process allocation results to account for the allocation if it succeed + * and set the allocated block number correctly for the caller. * - * XXX: xfs_alloc_vextent() should really be returning ENOSPC for ENOSPC, not + * XXX: we should really be returning ENOSPC for ENOSPC, not * hiding it behind a "successful" NULLFSBLOCK allocation. */ -static void -xfs_alloc_vextent_set_fsbno( +static int +xfs_alloc_vextent_finish( struct xfs_alloc_arg *args, - xfs_agnumber_t minimum_agno) + xfs_agnumber_t minimum_agno, + int alloc_error, + bool drop_perag) { struct xfs_mount *mp = args->mp; + int error = 0; /* * We can end up here with a locked AGF. If we failed, the caller is @@ -3271,19 +3244,54 @@ xfs_alloc_vextent_set_fsbno( args->agno > minimum_agno)) args->tp->t_highest_agno = args->agno; - /* Allocation failed with ENOSPC if NULLAGBLOCK was returned. */ - if (args->agbno == NULLAGBLOCK) { + /* + * If the allocation failed with an error or we had an ENOSPC result, + * preserve the returned error whilst also marking the allocation result + * as "no extent allocated". This ensures that callers that fail to + * capture the error will still treat it as a failed allocation. + */ + if (alloc_error || args->agbno == NULLAGBLOCK) { args->fsbno = NULLFSBLOCK; - return; + error = alloc_error; + goto out_drop_perag; } args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); -#ifdef DEBUG + ASSERT(args->len >= args->minlen); ASSERT(args->len <= args->maxlen); ASSERT(args->agbno % args->alignment == 0); XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); -#endif + + /* if not file data, insert new block into the reverse map btree */ + if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { + error = xfs_rmap_alloc(args->tp, args->agbp, args->pag, + args->agbno, args->len, &args->oinfo); + if (error) + goto out_drop_perag; + } + + if (!args->wasfromfl) { + error = xfs_alloc_update_counters(args->tp, args->agbp, + -((long)(args->len))); + if (error) + goto out_drop_perag; + + ASSERT(!xfs_extent_busy_search(mp, args->pag, args->agbno, + args->len)); + } + + xfs_ag_resv_alloc_extent(args->pag, args->resv, args); + + XFS_STATS_INC(mp, xs_allocx); + XFS_STATS_ADD(mp, xs_allocb, args->len); + +out_drop_perag: + if (drop_perag) { + xfs_perag_put(args->pag); + args->pag = NULL; + } + return error; } /* @@ -3325,8 +3333,7 @@ xfs_alloc_vextent_this_ag( if (!error && args->agbp) error = xfs_alloc_ag_vextent(args); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - return error; + return xfs_alloc_vextent_finish(args, minimum_agno, error, false); } /* @@ -3413,10 +3420,10 @@ xfs_alloc_vextent_iterate_ags( xfs_perag_put(args->pag); args->pag = NULL; } - if (args->pag) { - xfs_perag_put(args->pag); - args->pag = NULL; - } + /* + * The perag is left referenced in args for the caller to clean + * up after they've finished the allocation. + */ return error; } @@ -3473,8 +3480,7 @@ xfs_alloc_vextent_start_ag( (mp->m_sb.sb_agcount * rotorstep); } - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - return error; + return xfs_alloc_vextent_finish(args, minimum_agno, error, true); } /* @@ -3507,8 +3513,7 @@ xfs_alloc_vextent_first_ag( args->fsbno = target; error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, 0); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - return error; + return xfs_alloc_vextent_finish(args, minimum_agno, error, true); } /* @@ -3537,6 +3542,7 @@ xfs_alloc_vextent_exact_bno( args->agno = XFS_FSB_TO_AGNO(mp, target); if (minimum_agno > args->agno) { trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; return 0; } @@ -3548,8 +3554,7 @@ xfs_alloc_vextent_exact_bno( if (!error && args->agbp) error = xfs_alloc_ag_vextent(args); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - return 0; + return xfs_alloc_vextent_finish(args, minimum_agno, error, false); } /* @@ -3564,8 +3569,8 @@ xfs_alloc_vextent_near_bno( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - bool need_pag = !args->pag; xfs_agnumber_t minimum_agno = 0; + bool needs_perag = args->pag == NULL; int error; if (args->tp->t_highest_agno != NULLAGNUMBER) @@ -3585,6 +3590,9 @@ xfs_alloc_vextent_near_bno( return 0; } + if (needs_perag) + args->pag = xfs_perag_get(mp, args->agno); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); args->type = XFS_ALLOCTYPE_NEAR_BNO; @@ -3592,11 +3600,7 @@ xfs_alloc_vextent_near_bno( if (!error && args->agbp) error = xfs_alloc_ag_vextent(args); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - if (need_pag) - xfs_perag_put(args->pag); - - return error; + return xfs_alloc_vextent_finish(args, minimum_agno, error, needs_perag); } /* Ensure that the freelist is at full capacity. */ From patchwork Wed Jan 18 22:44:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107150 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 500F0C38147 for ; Wed, 18 Jan 2023 22:48:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229760AbjARWsR (ORCPT ); Wed, 18 Jan 2023 17:48:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230117AbjARWsC (ORCPT ); Wed, 18 Jan 2023 17:48:02 -0500 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B40CC656DC for ; Wed, 18 Jan 2023 14:47:49 -0800 (PST) Received: by mail-pj1-x1033.google.com with SMTP id y3-20020a17090a390300b00229add7bb36so55332pjb.4 for ; Wed, 18 Jan 2023 14:47:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=PFHNdEfZG3vF5DkjDeCV8HGj33I5PK7AxcZqcq5Z04Q=; b=hgJVm0NvZ7lSy3fmvx10xU6520usjruS9emhbZDSb97KK3azorlk1Yh9yCWOG/454S GSvtgCjjwU7mLTNtMtacXmDl2/NV0YjQ+Vs4RVMHORtDUu5TxKMOy8FO/3rD7MsXBvjR 91tkhlChaTU8nuDfmwgEyowu5cLQHs0JKdFgqxGihtYwJKgjhgXHYLiwXu3fBaA99tQK y/BATDDGLgSV4A9P3WDTI5CXToOZO+8ipVzfxcWL8kmahO4B4bZInhR/5WPVWhn+D0l5 TypYFRAu7fXlGPOZvaFcawXdJ1zPLCMe+JPjnIJFR0Jag99SPk3H4BCX3lVm2Dp3vfvY b0fA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PFHNdEfZG3vF5DkjDeCV8HGj33I5PK7AxcZqcq5Z04Q=; b=2Ctvogww6j/0bbMmZespOygTCJYaQ/IJJd3tvNUkE0b4hPezcmWgwmGoUljth8Vn7j PJd/fkW1J2y4t2exMvk+bE8EyKMg9blcemZafIy7uMUbcBgOspjY2COQpVC8F/quMPav oj3QWj51+yyvkT0zdJxL36qfHzHO/jj32NbNUB9bzvCZqYXtzfgfVBkNaB7aC9bPw31/ wNClPY5/bqFB/kLz1MlCH2a4TemmV9afIQLmz/7ckZKWZFA48PFLvktYYy5E13dYAPaW MmkYamkBCe7ztnceejSVqj8iO98u7hBVqOCu2X12g0wmDyyXuDefqOKaHmNWmg1Phxe4 /+iw== X-Gm-Message-State: AFqh2kp0PE2XUuCOgGEhASDQQ1lLJFWD2paCy4anzRja8gpTi4pLlFaJ bxMZ4HoqDNksUxXlJtqSidz0QODWRqOzzR6x X-Google-Smtp-Source: AMrXdXvvUuXGkHSXWgb6BRwOalA1I+81KDxQw6qS+TK0SncsmTBXLII6z9IeQ6Y4MNzKLxFGaHIx9Q== X-Received: by 2002:a17:902:d395:b0:194:5fc9:f579 with SMTP id e21-20020a170902d39500b001945fc9f579mr9005956pld.40.1674082069098; Wed, 18 Jan 2023 14:47:49 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id d5-20020a170903230500b001754fa42065sm10475749plh.143.2023.01.18.14.47.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:48 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXq-HG for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEb-1i for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 26/42] xfs: fold xfs_alloc_ag_vextent() into callers Date: Thu, 19 Jan 2023 09:44:49 +1100 Message-Id: <20230118224505.1964941-27-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner We don't need the multiplexing xfs_alloc_ag_vextent() provided anymore - we can just call the exact/near/size variants directly. This allows us to remove args->type completely and stop using args->fsbno as an input to the allocator algorithms. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 100 ++++++++++---------------------------- fs/xfs/libxfs/xfs_alloc.h | 17 ------- fs/xfs/libxfs/xfs_bmap.c | 10 +--- fs/xfs/xfs_trace.h | 8 +-- 4 files changed, 29 insertions(+), 106 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index ad2b91b230f6..4de9026d872f 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -36,10 +36,6 @@ struct workqueue_struct *xfs_alloc_wq; #define XFSA_FIXUP_BNO_OK 1 #define XFSA_FIXUP_CNT_OK 2 -STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); -STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); -STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); - /* * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in * the beginning of the block for a proper header with the location information @@ -772,8 +768,6 @@ xfs_alloc_cur_setup( int error; int i; - ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO); - acur->cur_len = args->maxlen; acur->rec_bno = 0; acur->rec_len = 0; @@ -887,7 +881,6 @@ xfs_alloc_cur_check( * We have an aligned record that satisfies minlen and beats or matches * the candidate extent size. Compare locality for near allocation mode. */ - ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); diff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, args->datatype, bnoa, lena, &bnew); @@ -1132,40 +1125,6 @@ xfs_alloc_ag_vextent_small( return error; } -/* - * Allocate a variable extent in the allocation group agno. - * Type and bno are used to determine where in the allocation group the - * extent will start. - * Extent's length (returned in *len) will be between minlen and maxlen, - * and of the form k * prod + mod unless there's nothing that large. - * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. - */ -static int -xfs_alloc_ag_vextent( - struct xfs_alloc_arg *args) -{ - int error = 0; - - /* - * Branch to correct routine based on the type. - */ - switch (args->type) { - case XFS_ALLOCTYPE_THIS_AG: - error = xfs_alloc_ag_vextent_size(args); - break; - case XFS_ALLOCTYPE_NEAR_BNO: - error = xfs_alloc_ag_vextent_near(args); - break; - case XFS_ALLOCTYPE_THIS_BNO: - error = xfs_alloc_ag_vextent_exact(args); - break; - default: - ASSERT(0); - /* NOTREACHED */ - } - return error; -} - /* * Allocate a variable extent at exactly agno/bno. * Extent's length (returned in *len) will be between minlen and maxlen, @@ -1351,7 +1310,6 @@ xfs_alloc_ag_vextent_locality( bool fbinc; ASSERT(acur->len == 0); - ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); *stat = 0; @@ -3137,6 +3095,7 @@ xfs_alloc_vextent_check_args( xfs_agblock_t agsize; args->agbno = NULLAGBLOCK; + args->fsbno = NULLFSBLOCK; /* * Just fix this up, for the case where the last a.g. is shorter @@ -3295,8 +3254,11 @@ xfs_alloc_vextent_finish( } /* - * Allocate within a single AG only. Caller is expected to hold a - * perag reference in args->pag. + * Allocate within a single AG only. This uses a best-fit length algorithm so if + * you need an exact sized allocation without locality constraints, this is the + * fastest way to do it. + * + * Caller is expected to hold a perag reference in args->pag. */ int xfs_alloc_vextent_this_ag( @@ -3305,7 +3267,6 @@ xfs_alloc_vextent_this_ag( { struct xfs_mount *mp = args->mp; xfs_agnumber_t minimum_agno = 0; - xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); int error; if (args->tp->t_highest_agno != NULLAGNUMBER) @@ -3317,7 +3278,7 @@ xfs_alloc_vextent_this_ag( return 0; } - error = xfs_alloc_vextent_check_args(args, target); + error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0)); if (error) { if (error == -ENOSPC) return 0; @@ -3326,12 +3287,10 @@ xfs_alloc_vextent_this_ag( args->agno = agno; args->agbno = 0; - args->fsbno = target; - args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_size(args); return xfs_alloc_vextent_finish(args, minimum_agno, error, false); } @@ -3355,6 +3314,7 @@ xfs_alloc_vextent_iterate_ags( struct xfs_alloc_arg *args, xfs_agnumber_t minimum_agno, xfs_agnumber_t start_agno, + xfs_agblock_t target_agbno, uint32_t flags) { struct xfs_mount *mp = args->mp; @@ -3369,7 +3329,6 @@ xfs_alloc_vextent_iterate_ags( args->agno = start_agno; for (;;) { args->pag = xfs_perag_get(mp, args->agno); - args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); error = xfs_alloc_vextent_prepare_ag(args); if (error) break; @@ -3379,16 +3338,18 @@ xfs_alloc_vextent_iterate_ags( * Allocation is supposed to succeed now, so break out * of the loop regardless of whether we succeed or not. */ - error = xfs_alloc_ag_vextent(args); + if (args->agno == start_agno && target_agbno) { + args->agbno = target_agbno; + error = xfs_alloc_ag_vextent_near(args); + } else { + args->agbno = 0; + error = xfs_alloc_ag_vextent_size(args); + } break; } trace_xfs_alloc_vextent_loopfailed(args); - if (args->agno == start_agno && - args->otype == XFS_ALLOCTYPE_NEAR_BNO) - args->type = XFS_ALLOCTYPE_THIS_AG; - /* * If we are try-locking, we can't deadlock on AGF locks so we * can wrap all the way back to the first AG. Otherwise, wrap @@ -3412,10 +3373,8 @@ xfs_alloc_vextent_iterate_ags( trace_xfs_alloc_vextent_allfailed(args); break; } - + args->agbno = target_agbno; flags = 0; - if (args->otype == XFS_ALLOCTYPE_NEAR_BNO) - args->type = XFS_ALLOCTYPE_NEAR_BNO; } xfs_perag_put(args->pag); args->pag = NULL; @@ -3464,13 +3423,11 @@ xfs_alloc_vextent_start_ag( mp->m_sb.sb_agcount), 0); bump_rotor = 1; } - start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); - args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->type = XFS_ALLOCTYPE_NEAR_BNO; - args->fsbno = target; + start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, - XFS_ALLOC_FLAG_TRYLOCK); + XFS_FSB_TO_AGBNO(mp, target), XFS_ALLOC_FLAG_TRYLOCK); + if (bump_rotor) { if (args->agno == start_agno) mp->m_agfrotor = (mp->m_agfrotor + 1) % @@ -3484,9 +3441,9 @@ xfs_alloc_vextent_start_ag( } /* - * Iterate from the agno indicated from args->fsbno through to the end of the + * Iterate from the agno indicated via @target through to the end of the * filesystem attempting blocking allocation. This does not wrap or try a second - * pass, so will not recurse into AGs lower than indicated by fsbno. + * pass, so will not recurse into AGs lower than indicated by the target. */ int xfs_alloc_vextent_first_ag( @@ -3509,10 +3466,8 @@ xfs_alloc_vextent_first_ag( } start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); - args->type = XFS_ALLOCTYPE_THIS_AG; - args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, - start_agno, 0); + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, + XFS_FSB_TO_AGBNO(mp, target), 0); return xfs_alloc_vextent_finish(args, minimum_agno, error, true); } @@ -3547,12 +3502,10 @@ xfs_alloc_vextent_exact_bno( } args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->fsbno = target; - args->type = XFS_ALLOCTYPE_THIS_BNO; error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_exact(args); return xfs_alloc_vextent_finish(args, minimum_agno, error, false); } @@ -3594,11 +3547,10 @@ xfs_alloc_vextent_near_bno( args->pag = xfs_perag_get(mp, args->agno); args->agbno = XFS_FSB_TO_AGBNO(mp, target); - args->type = XFS_ALLOCTYPE_NEAR_BNO; error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) - error = xfs_alloc_ag_vextent(args); + error = xfs_alloc_ag_vextent_near(args); return xfs_alloc_vextent_finish(args, minimum_agno, error, needs_perag); } diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 106b4deb1110..689419409e09 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -16,21 +16,6 @@ extern struct workqueue_struct *xfs_alloc_wq; unsigned int xfs_agfl_size(struct xfs_mount *mp); -/* - * Freespace allocation types. Argument to xfs_alloc_[v]extent. - */ -#define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ -#define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ -#define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ - -/* this should become an enum again when the tracing code is fixed */ -typedef unsigned int xfs_alloctype_t; - -#define XFS_ALLOC_TYPES \ - { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ - { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ - { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } - /* * Flags for xfs_alloc_fix_freelist. */ @@ -64,8 +49,6 @@ typedef struct xfs_alloc_arg { xfs_agblock_t min_agbno; /* set an agbno range for NEAR allocs */ xfs_agblock_t max_agbno; /* ... */ xfs_extlen_t len; /* output: actual size of extent */ - xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ - xfs_alloctype_t otype; /* original allocation type */ int datatype; /* mask defining data type treatment */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c9902df16e25..ba74aea034b0 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3501,7 +3501,6 @@ xfs_bmap_btalloc_at_eof( bool ag_only) { struct xfs_mount *mp = args->mp; - xfs_alloctype_t atype; int error; /* @@ -3513,14 +3512,12 @@ xfs_bmap_btalloc_at_eof( if (ap->offset) { xfs_extlen_t nextminlen = 0; - atype = args->type; - args->alignment = 1; - /* * Compute the minlen+alignment for the next case. Set slop so * that the value of minlen+alignment+slop doesn't go up between * the calls. */ + args->alignment = 1; if (blen > stripe_align && blen <= args->maxlen) nextminlen = blen - stripe_align; else @@ -3544,17 +3541,15 @@ xfs_bmap_btalloc_at_eof( * according to the original allocation specification. */ args->pag = NULL; - args->type = atype; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; } else { - args->alignment = stripe_align; - atype = args->type; /* * Adjust minlen to try and preserve alignment if we * can't guarantee an aligned maxlen extent. */ + args->alignment = stripe_align; if (blen > args->alignment && blen <= args->maxlen + args->alignment) args->minlen = blen - args->alignment; @@ -3576,7 +3571,6 @@ xfs_bmap_btalloc_at_eof( * original non-aligned state so the caller can proceed on allocation * failure as if this function was never called. */ - args->type = atype; args->fsbno = ap->blkno; args->alignment = 1; return 0; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index c921e9a5256d..3b25b10fccc1 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1799,8 +1799,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __field(xfs_extlen_t, alignment) __field(xfs_extlen_t, minalignslop) __field(xfs_extlen_t, len) - __field(short, type) - __field(short, otype) __field(char, wasdel) __field(char, wasfromfl) __field(int, resv) @@ -1820,8 +1818,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->alignment = args->alignment; __entry->minalignslop = args->minalignslop; __entry->len = args->len; - __entry->type = args->type; - __entry->otype = args->otype; __entry->wasdel = args->wasdel; __entry->wasfromfl = args->wasfromfl; __entry->resv = args->resv; @@ -1830,7 +1826,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, ), TP_printk("dev %d:%d agno 0x%x agbno 0x%x minlen %u maxlen %u mod %u " "prod %u minleft %u total %u alignment %u minalignslop %u " - "len %u type %s otype %s wasdel %d wasfromfl %d resv %d " + "len %u wasdel %d wasfromfl %d resv %d " "datatype 0x%x highest_agno 0x%x", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, @@ -1844,8 +1840,6 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->alignment, __entry->minalignslop, __entry->len, - __print_symbolic(__entry->type, XFS_ALLOC_TYPES), - __print_symbolic(__entry->otype, XFS_ALLOC_TYPES), __entry->wasdel, __entry->wasfromfl, __entry->resv, From patchwork Wed Jan 18 22:44:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F4EEC38147 for ; Wed, 18 Jan 2023 22:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229850AbjARWpe (ORCPT ); Wed, 18 Jan 2023 17:45:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229463AbjARWpT (ORCPT ); Wed, 18 Jan 2023 17:45:19 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B1A560491 for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id o7-20020a17090a0a0700b00226c9b82c3aso53650pjo.3 for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=P81BaZMttsxu9qBV+N8cR5TRwjRefLeeP4Kqf5YDWIQ=; b=zdJ+65g9/300ixAYDIoZNEgFZ1O6Mw3/S3LosLKcNoHQdVrE7oLa9Kss8XY8QGHAYl 0scBPfLiLeIHKQN24yH/wMdQx1ohCcPLorqVhaamoDTkZ1hnIxELJ73itrPQqYpD2U2m nYoH5MM6zvclDJj/LHpQZYPU0GCSgJgLR+nFbpobIu1Z0u4TZUOuJCXActcllQAJ9EA7 m0e+0K951xe8ADjEiNAAPel+FVAAgTS0F6pDaITrQ6pxjGI1vZB3p6Kkt+I0jbb77FmP 9rFaMDdstGMPB8bc1LFflZwJAvL8U+mveSEuSpUfc3qlpCSRhw/Rmfh8nDZyvy/NoEJZ zLnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P81BaZMttsxu9qBV+N8cR5TRwjRefLeeP4Kqf5YDWIQ=; b=qkOJBrX2CVTkjujClB2REEx7rvp8kSeQbVKUWdzhYdUmNcGFGRXFBx/QpvWm21TTK3 +59P7eVSaf9HF/t7aG+ALO3tnPwa8ArAacqS4yujltAVnD/IV13aOVDR0neIGUja/G+w lO22t1nezyu4nUKlGX8v2o0ih5XQxctJx2GD61Afbje5452Y6bClGu9ZRVKR1kZ/G81L 3lOIoYL9NGVPX7IvlBJtUyhVgRTmkKocv+ca5I0pZYyAPklw9/cid1XbbrIpEsxYSjeJ uLiss9bsnw+xeySBcv3ZfExYi9yqN9s2auFIb0FOxzW/u5sjLh0IP7+w30w8Svzrb0TJ ynBA== X-Gm-Message-State: AFqh2krcJqu9Vd7MYo/GND5apW8zJFOFWNO6PsdrdIBrsuj4a0ea54Wc 9bly6dhZ1njIu6szEommN5aBFzMoMf5u8rma X-Google-Smtp-Source: AMrXdXvfnPwUXxLsHVK46zqEPchJeJ7WKAMJ9PhgVGUOt2lPMaXFAn0hkC+LtN+aO9WdMuAKBd2+DQ== X-Received: by 2002:a17:90b:4f86:b0:229:307f:65e6 with SMTP id qe6-20020a17090b4f8600b00229307f65e6mr8990647pjb.48.1674081917595; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id u4-20020a17090a6a8400b0022717d8d835sm1797701pjj.16.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:15 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXu-IB for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEg-1p for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 27/42] xfs: move the minimum agno checks into xfs_alloc_vextent_check_args Date: Thu, 19 Jan 2023 09:44:50 +1100 Message-Id: <20230118224505.1964941-28-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner All of the allocation functions now extract the minimum allowed AG from the transaction and then use it in some way. The allocation functions that are restricted to a single AG all check if the AG requested can be allocated from and return an error if so. These all set args->agno appropriately. All the allocation functions that iterate AGs use it to calculate the scan start AG. args->agno is not set until the iterator starts walking AGs. Hence we can easily set up a conditional check against the minimum AG allowed in xfs_alloc_vextent_check_args() based on whether args->agno contains NULLAGNUMBER or not and move all the repeated setup code to xfs_alloc_vextent_check_args(), further simplifying the allocation functions. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 88 +++++++++++++++------------------------ 1 file changed, 33 insertions(+), 55 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 4de9026d872f..43a054002da3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3089,14 +3089,18 @@ xfs_alloc_read_agf( static int xfs_alloc_vextent_check_args( struct xfs_alloc_arg *args, - xfs_rfsblock_t target) + xfs_rfsblock_t target, + xfs_agnumber_t *minimum_agno) { struct xfs_mount *mp = args->mp; xfs_agblock_t agsize; - args->agbno = NULLAGBLOCK; args->fsbno = NULLFSBLOCK; + *minimum_agno = 0; + if (args->tp->t_highest_agno != NULLAGNUMBER) + *minimum_agno = args->tp->t_highest_agno; + /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure @@ -3123,11 +3127,16 @@ xfs_alloc_vextent_check_args( XFS_FSB_TO_AGBNO(mp, target) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || args->mod >= args->prod) { - args->fsbno = NULLFSBLOCK; trace_xfs_alloc_vextent_badargs(args); return -ENOSPC; } + + if (args->agno != NULLAGNUMBER && *minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + return -ENOSPC; + } return 0; + } /* @@ -3266,28 +3275,19 @@ xfs_alloc_vextent_this_ag( xfs_agnumber_t agno) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t minimum_agno = 0; + xfs_agnumber_t minimum_agno; int error; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; - - if (minimum_agno > agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } - - error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0)); + args->agno = agno; + args->agbno = 0; + error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0), + &minimum_agno); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = agno; - args->agbno = 0; - error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) error = xfs_alloc_ag_vextent_size(args); @@ -3400,16 +3400,15 @@ xfs_alloc_vextent_start_ag( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t minimum_agno = 0; + xfs_agnumber_t minimum_agno; xfs_agnumber_t start_agno; xfs_agnumber_t rotorstep = xfs_rotorstep; bool bump_rotor = false; int error; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; - - error = xfs_alloc_vextent_check_args(args, target); + args->agno = NULLAGNUMBER; + args->agbno = NULLAGBLOCK; + error = xfs_alloc_vextent_check_args(args, target, &minimum_agno); if (error) { if (error == -ENOSPC) return 0; @@ -3451,14 +3450,13 @@ xfs_alloc_vextent_first_ag( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t minimum_agno = 0; + xfs_agnumber_t minimum_agno; xfs_agnumber_t start_agno; int error; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; - - error = xfs_alloc_vextent_check_args(args, target); + args->agno = NULLAGNUMBER; + args->agbno = NULLAGBLOCK; + error = xfs_alloc_vextent_check_args(args, target, &minimum_agno); if (error) { if (error == -ENOSPC) return 0; @@ -3481,28 +3479,18 @@ xfs_alloc_vextent_exact_bno( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t minimum_agno = 0; + xfs_agnumber_t minimum_agno; int error; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; - - error = xfs_alloc_vextent_check_args(args, target); + args->agno = XFS_FSB_TO_AGNO(mp, target); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + error = xfs_alloc_vextent_check_args(args, target, &minimum_agno); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, target); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } - - args->agbno = XFS_FSB_TO_AGBNO(mp, target); - error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) error = xfs_alloc_ag_vextent_exact(args); @@ -3522,32 +3510,22 @@ xfs_alloc_vextent_near_bno( xfs_rfsblock_t target) { struct xfs_mount *mp = args->mp; - xfs_agnumber_t minimum_agno = 0; + xfs_agnumber_t minimum_agno; bool needs_perag = args->pag == NULL; int error; - if (args->tp->t_highest_agno != NULLAGNUMBER) - minimum_agno = args->tp->t_highest_agno; - - error = xfs_alloc_vextent_check_args(args, target); + args->agno = XFS_FSB_TO_AGNO(mp, target); + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + error = xfs_alloc_vextent_check_args(args, target, &minimum_agno); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, target); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } - if (needs_perag) args->pag = xfs_perag_get(mp, args->agno); - args->agbno = XFS_FSB_TO_AGBNO(mp, target); - error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) error = xfs_alloc_ag_vextent_near(args); From patchwork Wed Jan 18 22:44:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107149 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B7F9C38159 for ; Wed, 18 Jan 2023 22:48:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229507AbjARWsO (ORCPT ); Wed, 18 Jan 2023 17:48:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230079AbjARWr7 (ORCPT ); Wed, 18 Jan 2023 17:47:59 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F393654F8 for ; Wed, 18 Jan 2023 14:47:46 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id u1-20020a17090a450100b0022936a63a21so4004403pjg.4 for ; Wed, 18 Jan 2023 14:47:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=15eOzrsB+JxkdRA4BtFu4xZcL002FZiyOkGx7qF3I7M=; b=Ndo14pvY02JXIyrECFLQkPLFLrNvlopfHzz4Ma6gOqjaIOQiN/MqozW2Y7VR4bWtfv g3xePZZqawfmyAXInKI6G2QemBCqAfcMF9TZFcbaUSXXbUG6Wt/aqUqHqmRvQE2j0Ruv E1RFnhJzkOJO+UYRn+iiQXMqskB1/B4mrA3ml5/l1Zc0CwKHZ3r0kqkNsf055bfvLOy1 tIzbywcB0cX2H82qwn3aG3LTHQuRfhbH83nTBgTjVpw2zBGeg56zez32tKTTz2moBvNE zU0HATYg88LgFkx37XDavcPK4ZDlYtd0Kg6/trSrMlWgYeYXJ2zszbasty5fAUEbhodb UufQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=15eOzrsB+JxkdRA4BtFu4xZcL002FZiyOkGx7qF3I7M=; b=WNzTa8T3UyYpX7BZdZHYg7kEGn6J9IqITz+MHpcrEi0CTnbWlDJjPxs+k//1f9Mw7r Z7LKCsO9HHscfJlyHmRZvCdCNGhddmhDfT6bqk8EXUVDDlhFrSWBH8DFmXWPurTG91Vj 4JfBaQmS+R5iVaAuu+5l2zoAqgrAbqivlh9StryWjrPaT6xRoSmw8gQXlAe3RuLpOCmY Ta1LssS7Y48OlLQOIQcgNDeO4cT49eHNuAE0WA6nYxU9cb52gSKjoFciTNYST5IkAUvB KkKcQ9tijz/Bm7VLMhZmxkf30Qg75buMl4UovUakDKcYpFjhhSFS1kfIpKThcDDrBWjL HkyA== X-Gm-Message-State: AFqh2koLaZrP0+BqOlB8/1gqtpuop+SdYjUqcGRqNHg9GOVWyI9S6ZgA id+kMRtgzbcni1mWnR5Pby82IzDYbOcc91Ab X-Google-Smtp-Source: AMrXdXtLDydnr1b757d9OGm+02rS5YEvHhhTu1HTt07MEsvfoCmTWab6qqJfwm4bFzcmrOV0BFq2Ow== X-Received: by 2002:a05:6a20:a698:b0:a9:f163:3ecf with SMTP id ba24-20020a056a20a69800b000a9f1633ecfmr10483817pzb.50.1674082065826; Wed, 18 Jan 2023 14:47:45 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id 129-20020a630887000000b004777c56747csm19181116pgi.11.2023.01.18.14.47.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:45 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXw-J2 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEl-1u for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 28/42] xfs: convert xfs_alloc_vextent_iterate_ags() to use perag walker Date: Thu, 19 Jan 2023 09:44:51 +1100 Message-Id: <20230118224505.1964941-29-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that the AG iteration code in the core allocation code has been cleaned up, we can easily convert it to use a for_each_perag..() variant to use active references and skip AGs that it can't get active references on. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ag.h | 22 ++++++--- fs/xfs/libxfs/xfs_alloc.c | 98 ++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 8f43b91d4cf3..5e18536dfdce 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -253,6 +253,7 @@ xfs_perag_next_wrap( struct xfs_perag *pag, xfs_agnumber_t *agno, xfs_agnumber_t stop_agno, + xfs_agnumber_t restart_agno, xfs_agnumber_t wrap_agno) { struct xfs_mount *mp = pag->pag_mount; @@ -260,10 +261,11 @@ xfs_perag_next_wrap( *agno = pag->pag_agno + 1; xfs_perag_rele(pag); while (*agno != stop_agno) { - if (*agno >= wrap_agno) - *agno = 0; - if (*agno == stop_agno) - break; + if (*agno >= wrap_agno) { + if (restart_agno >= stop_agno) + break; + *agno = restart_agno; + } pag = xfs_perag_grab(mp, *agno); if (pag) @@ -274,14 +276,20 @@ xfs_perag_next_wrap( } /* - * Iterate all AGs from start_agno through wrap_agno, then 0 through + * Iterate all AGs from start_agno through wrap_agno, then restart_agno through * (start_agno - 1). */ -#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ +#define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \ for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \ (pag) != NULL; \ (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \ - (wrap_agno))) + (restart_agno), (wrap_agno))) +/* + * Iterate all AGs from start_agno through wrap_agno, then 0 through + * (start_agno - 1). + */ +#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \ + for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag)) /* * Iterate all AGs from start_agno through to the end of the filesystem, then 0 diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 43a054002da3..39f3e76efcab 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3156,6 +3156,7 @@ xfs_alloc_vextent_prepare_ag( if (need_pag) args->pag = xfs_perag_get(args->mp, args->agno); + args->agbp = NULL; error = xfs_alloc_fix_freelist(args, 0); if (error) { trace_xfs_alloc_vextent_nofix(args); @@ -3255,8 +3256,8 @@ xfs_alloc_vextent_finish( XFS_STATS_ADD(mp, xs_allocb, args->len); out_drop_perag: - if (drop_perag) { - xfs_perag_put(args->pag); + if (drop_perag && args->pag) { + xfs_perag_rele(args->pag); args->pag = NULL; } return error; @@ -3304,6 +3305,10 @@ xfs_alloc_vextent_this_ag( * we attempt to allocation in as there is no locality optimisation possible for * those allocations. * + * On return, args->pag may be left referenced if we finish before the "all + * failed" return point. The allocation finish still needs the perag, and + * so the caller will release it once they've finished the allocation. + * * When we wrap the AG iteration at the end of the filesystem, we have to be * careful not to wrap into AGs below ones we already have locked in the * transaction if we are doing a blocking iteration. This will result in an @@ -3318,72 +3323,59 @@ xfs_alloc_vextent_iterate_ags( uint32_t flags) { struct xfs_mount *mp = args->mp; + xfs_agnumber_t agno; int error = 0; - ASSERT(start_agno >= minimum_agno); +restart: + for_each_perag_wrap_range(mp, start_agno, minimum_agno, + mp->m_sb.sb_agcount, agno, args->pag) { + args->agno = agno; + trace_printk("sag %u minag %u agno %u pag %u, agbno %u, agcnt %u", + start_agno, minimum_agno, agno, args->pag->pag_agno, + target_agbno, mp->m_sb.sb_agcount); - /* - * Loop over allocation groups twice; first time with - * trylock set, second time without. - */ - args->agno = start_agno; - for (;;) { - args->pag = xfs_perag_get(mp, args->agno); error = xfs_alloc_vextent_prepare_ag(args); if (error) break; - - if (args->agbp) { - /* - * Allocation is supposed to succeed now, so break out - * of the loop regardless of whether we succeed or not. - */ - if (args->agno == start_agno && target_agbno) { - args->agbno = target_agbno; - error = xfs_alloc_ag_vextent_near(args); - } else { - args->agbno = 0; - error = xfs_alloc_ag_vextent_size(args); - } - break; + if (!args->agbp) { + trace_xfs_alloc_vextent_loopfailed(args); + continue; } - trace_xfs_alloc_vextent_loopfailed(args); - /* - * If we are try-locking, we can't deadlock on AGF locks so we - * can wrap all the way back to the first AG. Otherwise, wrap - * back to the start AG so we can't deadlock and let the end of - * scan handler decide what to do next. + * Allocation is supposed to succeed now, so break out of the + * loop regardless of whether we succeed or not. */ - if (++(args->agno) == mp->m_sb.sb_agcount) { - if (flags & XFS_ALLOC_FLAG_TRYLOCK) - args->agno = 0; - else - args->agno = minimum_agno; - } - - /* - * Reached the starting a.g., must either be done - * or switch to non-trylock mode. - */ - if (args->agno == start_agno) { - if (flags == 0) { - args->agbno = NULLAGBLOCK; - trace_xfs_alloc_vextent_allfailed(args); - break; - } + if (args->agno == start_agno && target_agbno) { args->agbno = target_agbno; - flags = 0; + error = xfs_alloc_ag_vextent_near(args); + } else { + args->agbno = 0; + error = xfs_alloc_ag_vextent_size(args); } - xfs_perag_put(args->pag); + break; + } + if (error) { + xfs_perag_rele(args->pag); args->pag = NULL; + return error; } + if (args->agbp) + return 0; + /* - * The perag is left referenced in args for the caller to clean - * up after they've finished the allocation. + * We didn't find an AG we can alloation from. If we were given + * constraining flags by the caller, drop them and retry the allocation + * without any constraints being set. */ - return error; + if (flags) { + flags = 0; + goto restart; + } + + ASSERT(args->pag == NULL); + trace_xfs_alloc_vextent_allfailed(args); + return 0; } /* @@ -3524,7 +3516,7 @@ xfs_alloc_vextent_near_bno( } if (needs_perag) - args->pag = xfs_perag_get(mp, args->agno); + args->pag = xfs_perag_grab(mp, args->agno); error = xfs_alloc_vextent_prepare_ag(args); if (!error && args->agbp) From patchwork Wed Jan 18 22:44:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107148 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF531C46467 for ; Wed, 18 Jan 2023 22:48:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229589AbjARWsO (ORCPT ); Wed, 18 Jan 2023 17:48:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230103AbjARWr5 (ORCPT ); Wed, 18 Jan 2023 17:47:57 -0500 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD1844A1DD for ; Wed, 18 Jan 2023 14:47:42 -0800 (PST) Received: by mail-pf1-x42e.google.com with SMTP id 127so125694pfe.4 for ; Wed, 18 Jan 2023 14:47:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=V4wObburgrZWXG01Q0SWeB3FM1sC8fnj6ToorhiMEJU=; b=KLd84KfL5/2j377EHOMHF4SPCmsIh/zaU+wHF0ae1gncvpewu9nhOu9QEKpOe05PAe GBIqD2f1mx+mQG3V63Q4SsS7TXlOMCOHoTflUb6tH4LlHeYgpRl+yA9IqitDX3WfOQLb 0UH9ODt3nsa9s0xRcb105d+0+pPpFIBM3iKckTvYtCEJuS/IOr/ajNz1Q2mRB5inkE4j t/TUa+CkgtZBWxVRSd+i4nk1xu46gWjOcStbyyFbdvIDLTDaaf9QIK90ar4pEdtJ+vbi 6BWNReJXrkxCVkiQOvzK+vW+CaOzYgmdEuIKqhLjUIn/WNKvNyvTTPBlCg4xjd6WgkR8 GfCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=V4wObburgrZWXG01Q0SWeB3FM1sC8fnj6ToorhiMEJU=; b=gnlN067KDSI0fXmh3YToV3QrBCAelihQHy6HDhvLjuMSZ4WhC3eiFZycwC6dwDalNG ynCnnLJQZWDz9XVQp1XCeeTjExnQ6g93EQM2g5zmX18roUd+EiKY5BdcoTCM1bz3hmPa 3R0ghFPT4yYj4FldivitOd1UdF5p0cbjh7CZaoC85C3oRSaYlsgyhhroEzijz3TAuD6b ulgCfj8Dkk/MyEraJpq3VxcyZY+00iFt2vsgjvxzCiLN9HSGLd02mCloCcN34Lb70Awn VC/OUpt99MpfZ+jbhfDiGwxpxa753TglPLMBa+zQGoSXPOYcCLoy4rTHuJErBbfyaboH iS5A== X-Gm-Message-State: AFqh2krMv05MdHP/qMvDbdASGLPYkUTvfQ3eojJqz+UTkMRWvznrmpxW 5bJakVkgXzJTb37kXr1BMyPAtQLXKcDFTsSH X-Google-Smtp-Source: AMrXdXt1zkX1xFapJ3zeFz6aPhbDXwtFC7QWbQeRHjjkVkCVenUUNkzN3QKjVWm80MqYyc0FiNXPgg== X-Received: by 2002:a05:6a00:3390:b0:58c:6ba1:58dd with SMTP id cm16-20020a056a00339000b0058c6ba158ddmr9422895pfb.11.1674082062104; Wed, 18 Jan 2023 14:47:42 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id w4-20020aa79544000000b0058db5d4b391sm5647733pfq.19.2023.01.18.14.47.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:41 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iXz-Jx for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEq-20 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 29/42] xfs: convert trim to use for_each_perag_range Date: Thu, 19 Jan 2023 09:44:52 +1100 Message-Id: <20230118224505.1964941-30-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner To convert it to using active perag references and hence make it shrink safe. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_discard.c | 50 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index bfc829c07f03..afc4c78b9eed 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -21,23 +21,20 @@ STATIC int xfs_trim_extents( - struct xfs_mount *mp, - xfs_agnumber_t agno, + struct xfs_perag *pag, xfs_daddr_t start, xfs_daddr_t end, xfs_daddr_t minlen, uint64_t *blocks_trimmed) { + struct xfs_mount *mp = pag->pag_mount; struct block_device *bdev = mp->m_ddev_targp->bt_bdev; struct xfs_btree_cur *cur; struct xfs_buf *agbp; struct xfs_agf *agf; - struct xfs_perag *pag; int error; int i; - pag = xfs_perag_get(mp, agno); - /* * Force out the log. This means any transactions that might have freed * space before we take the AGF buffer lock are now on disk, and the @@ -47,7 +44,7 @@ xfs_trim_extents( error = xfs_alloc_read_agf(pag, NULL, 0, &agbp); if (error) - goto out_put_perag; + return error; agf = agbp->b_addr; cur = xfs_allocbt_init_cursor(mp, NULL, agbp, pag, XFS_BTNUM_CNT); @@ -71,10 +68,10 @@ xfs_trim_extents( error = xfs_alloc_get_rec(cur, &fbno, &flen, &i); if (error) - goto out_del_cursor; + break; if (XFS_IS_CORRUPT(mp, i != 1)) { error = -EFSCORRUPTED; - goto out_del_cursor; + break; } ASSERT(flen <= be32_to_cpu(agf->agf_longest)); @@ -83,15 +80,15 @@ xfs_trim_extents( * the format the range/len variables are supplied in by * userspace. */ - dbno = XFS_AGB_TO_DADDR(mp, agno, fbno); + dbno = XFS_AGB_TO_DADDR(mp, pag->pag_agno, fbno); dlen = XFS_FSB_TO_BB(mp, flen); /* * Too small? Give up. */ if (dlen < minlen) { - trace_xfs_discard_toosmall(mp, agno, fbno, flen); - goto out_del_cursor; + trace_xfs_discard_toosmall(mp, pag->pag_agno, fbno, flen); + break; } /* @@ -100,7 +97,7 @@ xfs_trim_extents( * down partially overlapping ranges for now. */ if (dbno + dlen < start || dbno > end) { - trace_xfs_discard_exclude(mp, agno, fbno, flen); + trace_xfs_discard_exclude(mp, pag->pag_agno, fbno, flen); goto next_extent; } @@ -109,32 +106,30 @@ xfs_trim_extents( * discard and try again the next time. */ if (xfs_extent_busy_search(mp, pag, fbno, flen)) { - trace_xfs_discard_busy(mp, agno, fbno, flen); + trace_xfs_discard_busy(mp, pag->pag_agno, fbno, flen); goto next_extent; } - trace_xfs_discard_extent(mp, agno, fbno, flen); + trace_xfs_discard_extent(mp, pag->pag_agno, fbno, flen); error = blkdev_issue_discard(bdev, dbno, dlen, GFP_NOFS); if (error) - goto out_del_cursor; + break; *blocks_trimmed += flen; next_extent: error = xfs_btree_decrement(cur, 0, &i); if (error) - goto out_del_cursor; + break; if (fatal_signal_pending(current)) { error = -ERESTARTSYS; - goto out_del_cursor; + break; } } out_del_cursor: xfs_btree_del_cursor(cur, error); xfs_buf_relse(agbp); -out_put_perag: - xfs_perag_put(pag); return error; } @@ -152,11 +147,12 @@ xfs_ioc_trim( struct xfs_mount *mp, struct fstrim_range __user *urange) { + struct xfs_perag *pag; unsigned int granularity = bdev_discard_granularity(mp->m_ddev_targp->bt_bdev); struct fstrim_range range; xfs_daddr_t start, end, minlen; - xfs_agnumber_t start_agno, end_agno, agno; + xfs_agnumber_t agno; uint64_t blocks_trimmed = 0; int error, last_error = 0; @@ -193,18 +189,18 @@ xfs_ioc_trim( end = start + BTOBBT(range.len) - 1; if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1) - end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1; - - start_agno = xfs_daddr_to_agno(mp, start); - end_agno = xfs_daddr_to_agno(mp, end); + end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1; - for (agno = start_agno; agno <= end_agno; agno++) { - error = xfs_trim_extents(mp, agno, start, end, minlen, + agno = xfs_daddr_to_agno(mp, start); + for_each_perag_range(mp, agno, xfs_daddr_to_agno(mp, end), pag) { + error = xfs_trim_extents(pag, start, end, minlen, &blocks_trimmed); if (error) { last_error = error; - if (error == -ERESTARTSYS) + if (error == -ERESTARTSYS) { + xfs_perag_rele(pag); break; + } } } From patchwork Wed Jan 18 22:44:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107147 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FDE5C38147 for ; Wed, 18 Jan 2023 22:48:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229609AbjARWsN (ORCPT ); Wed, 18 Jan 2023 17:48:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230095AbjARWr4 (ORCPT ); Wed, 18 Jan 2023 17:47:56 -0500 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B38F66CD1 for ; Wed, 18 Jan 2023 14:47:40 -0800 (PST) Received: by mail-pg1-x52e.google.com with SMTP id g68so85438pgc.11 for ; Wed, 18 Jan 2023 14:47:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=oTV2m8LVZXzVgCdOKGIm8DM9aCk7NltTbgw3MjhF0rc=; b=wavsYH5nuYh7brk+KntZDmU3nkQx0vPKZRC8E0jRmIRbbSicMlYmYdY0V5pRO5Oi6o Mt1Ph0f/ZjH+HH7BSmhYt2MOvaTyWokxF/EHFXeS/ZZWayirk+qzHpCo382Z4pHw8q8e PO5Yybk+4Jl2GM+J8h9PNJz0tHmupTMbrLQuHNaaGfdpwraaP9pC4c2sgWMiXBhCGi4A KLXXNe2jxlryBwCczWokXkXC3i7q/8m5QxkMTs6ZSu6S2b9dumoSKzjaN0jnCWHHorma Pb49UiHle9fQhNOF1qTFgoG/uZ5m6F+Xen8/sAs9T8Rlg6i9t0gZsuap89gklmIg40Lx YV8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oTV2m8LVZXzVgCdOKGIm8DM9aCk7NltTbgw3MjhF0rc=; b=3FTmL3lOyjB7kpxuM8IvtHUCRz7gyuV6CFziiQTXAKrY2hqrjnvUYbhUQ9b9Fvth2Q BHauCwa8cT4rjcWHfbLg8HXPLDHAf8ebBl2RtUXVom/Ra7ItkFTsZPdcVpmPXa/FXuul yJlmAabIlfE6yUY7hQwShMVu6KELG3ulqOJ7AhF52xgUKEv1o2z2tyeOnseIods+RCYW 0GbSnCbJm94ubBUbYDM83DVqVqb3PyKiBVqqYaEgHJcpMnh0OsEyg/pWIvgyx6W7iWRV roXKUfC+k74zue2v7J5W4wBlqDP0W5cMgB3mpw2iEOu4WjMwKY/N+8r4JDVZY5SOyj6Z g0FQ== X-Gm-Message-State: AFqh2koV1w/q2K0Yx3xOkpjV03O9L3CwVGufyIiFwez4npYX/vp22qYk JqQ2jirXyP5O/g9MclsfJS+JI1sN80UcH7KZ X-Google-Smtp-Source: AMrXdXtQST9GPCgCPppjh4lt9Bcis5H7BgXmR0qsFsrxQC9Q9d7CUkZmrkYZGhnbePNCLKcn4fOAGA== X-Received: by 2002:a05:6a00:180d:b0:58d:c694:9a9e with SMTP id y13-20020a056a00180d00b0058dc6949a9emr10994160pfa.18.1674082059170; Wed, 18 Jan 2023 14:47:39 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id z5-20020aa79f85000000b0058bbdaaa5e4sm8164696pfr.162.2023.01.18.14.47.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:38 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iY3-Ku for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FEv-25 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 30/42] xfs: factor out filestreams from xfs_bmap_btalloc_nullfb Date: Thu, 19 Jan 2023 09:44:53 +1100 Message-Id: <20230118224505.1964941-31-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner There's many if (filestreams) {} else {} branches in this function. Split it out into a filestreams specific function so that we can then work directly on cleaning up the filestreams code without impacting the rest of the allocation algorithms. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 167 ++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 71 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ba74aea034b0..7ae08b44e4d8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3234,8 +3234,8 @@ xfs_bmap_btalloc_select_lengths( return 0; } -STATIC int -xfs_bmap_btalloc_filestreams( +static int +xfs_bmap_btalloc_filestreams_select_lengths( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen) @@ -3576,54 +3576,109 @@ xfs_bmap_btalloc_at_eof( return 0; } +/* + * We have failed multiple allocation attempts so now are in a low space + * allocation situation. Try a locality first full filesystem minimum length + * allocation whilst still maintaining necessary total block reservation + * requirements. + * + * If that fails, we are now critically low on space, so perform a last resort + * allocation attempt: no reserve, no locality, blocking, minimum length, full + * filesystem free space scan. We also indicate to future allocations in this + * transaction that we are critically low on space so they don't waste time on + * allocation modes that are unlikely to succeed. + */ static int -xfs_bmap_btalloc_best_length( +xfs_bmap_btalloc_low_space( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args) +{ + int error; + + if (args->minlen > ap->minlen) { + args->minlen = ap->minlen; + error = xfs_alloc_vextent_start_ag(args, ap->blkno); + if (error || args->fsbno != NULLFSBLOCK) + return error; + } + + /* Last ditch attempt before failure is declared. */ + args->total = ap->minlen; + error = xfs_alloc_vextent_first_ag(args, 0); + if (error) + return error; + ap->tp->t_flags |= XFS_TRANS_LOWMODE; + return 0; +} + +static int +xfs_bmap_btalloc_filestreams( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, int stripe_align) { - struct xfs_mount *mp = args->mp; + xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); xfs_extlen_t blen = 0; - bool is_filestream = false; int error; - if ((ap->datatype & XFS_ALLOC_USERDATA) && - xfs_inode_is_filestream(ap->ip)) - is_filestream = true; + /* Determine the initial block number we will target for allocation. */ + if (agno == NULLAGNUMBER) + agno = 0; + ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); + xfs_bmap_adjacent(ap); /* - * Determine the initial block number we will target for allocation. + * If there is very little free space before we start a + * filestreams allocation, we're almost guaranteed to fail to + * find an AG with enough contiguous free space to succeed, so + * just go straight to the low space algorithm. */ - if (is_filestream) { - xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); - if (agno == NULLAGNUMBER) - agno = 0; - ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); - } else { - ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + args->minlen = ap->minlen; + return xfs_bmap_btalloc_low_space(ap, args); } - xfs_bmap_adjacent(ap); /* * Search for an allocation group with a single extent large enough for * the request. If one isn't found, then adjust the minimum allocation * size to the largest space found. */ - if (is_filestream) { - /* - * If there is very little free space before we start a - * filestreams allocation, we're almost guaranteed to fail to - * find an AG with enough contiguous free space to succeed, so - * just go straight to the low space algorithm. - */ - if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { - args->minlen = ap->minlen; - goto critically_low_space; - } - error = xfs_bmap_btalloc_filestreams(ap, args, &blen); - } else { - error = xfs_bmap_btalloc_select_lengths(ap, args, &blen); + error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen); + if (error) + return error; + + if (ap->aeof) { + error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, + true); + if (error || args->fsbno != NULLFSBLOCK) + return error; } + + error = xfs_alloc_vextent_near_bno(args, ap->blkno); + if (error || args->fsbno != NULLFSBLOCK) + return error; + + return xfs_bmap_btalloc_low_space(ap, args); +} + +static int +xfs_bmap_btalloc_best_length( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + int stripe_align) +{ + xfs_extlen_t blen = 0; + int error; + + ap->blkno = XFS_INO_TO_FSB(args->mp, ap->ip->i_ino); + xfs_bmap_adjacent(ap); + + /* + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then adjust the minimum allocation + * size to the largest space found. + */ + error = xfs_bmap_btalloc_select_lengths(ap, args, &blen); if (error) return error; @@ -3635,50 +3690,16 @@ xfs_bmap_btalloc_best_length( */ if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, - is_filestream); - if (error) + false); + if (error || args->fsbno != NULLFSBLOCK) return error; - if (args->fsbno != NULLFSBLOCK) - return 0; } - if (is_filestream) - error = xfs_alloc_vextent_near_bno(args, ap->blkno); - else - error = xfs_alloc_vextent_start_ag(args, ap->blkno); - if (error) + error = xfs_alloc_vextent_start_ag(args, ap->blkno); + if (error || args->fsbno != NULLFSBLOCK) return error; - if (args->fsbno != NULLFSBLOCK) - return 0; - - /* - * Try a locality first full filesystem minimum length allocation whilst - * still maintaining necessary total block reservation requirements. - */ - if (args->minlen > ap->minlen) { - args->minlen = ap->minlen; - error = xfs_alloc_vextent_start_ag(args, ap->blkno); - if (error) - return error; - } - if (args->fsbno != NULLFSBLOCK) - return 0; - /* - * We are now critically low on space, so this is a last resort - * allocation attempt: no reserve, no locality, blocking, minimum - * length, full filesystem free space scan. We also indicate to future - * allocations in this transaction that we are critically low on space - * so they don't waste time on allocation modes that are unlikely to - * succeed. - */ -critically_low_space: - args->total = ap->minlen; - error = xfs_alloc_vextent_first_ag(args, 0); - if (error) - return error; - ap->tp->t_flags |= XFS_TRANS_LOWMODE; - return 0; + return xfs_bmap_btalloc_low_space(ap, args); } static int @@ -3712,7 +3733,11 @@ xfs_bmap_btalloc( /* Trim the allocation back to the maximum an AG can fit. */ args.maxlen = min(ap->length, mp->m_ag_max_usable); - error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align); + if ((ap->datatype & XFS_ALLOC_USERDATA) && + xfs_inode_is_filestream(ap->ip)) + error = xfs_bmap_btalloc_filestreams(ap, &args, stripe_align); + else + error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align); if (error) return error; From patchwork Wed Jan 18 22:44:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7717C32793 for ; Wed, 18 Jan 2023 22:48:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229469AbjARWsL (ORCPT ); Wed, 18 Jan 2023 17:48:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230035AbjARWrx (ORCPT ); Wed, 18 Jan 2023 17:47:53 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4E2B66CD8 for ; Wed, 18 Jan 2023 14:47:37 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id x2-20020a17090a46c200b002295ca9855aso4026807pjg.2 for ; Wed, 18 Jan 2023 14:47:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=zJpmWxutomaetKGVWIq9UhyMnsLIAD4UZ0Z9oHuCJ3s=; b=haS4XP9toNYBbnDLYRtGc6MjZm4oyLL0uM0RVEmpW46QAUj2wqiaYzcKrFgFh4i4wy lEZ/LSyCpW1XvO4s41Fy/Jg4TTY3/5VTzme9jDQ5SKjsUMdw7piagdLcga0mB5/ntEml Osf+UnC29FU+cbCb1C/8w1ht/ofoRAgSJ3qFjYDrCDRKJwuGCAdt6N8Nj5oXKn02e7bV ME/PQqNpXoQ1Zqw0Ntl5UpxsV3zza0itp3+m56XYbzTq3rO3Yxq47kxwW6nH9NsNJ/yu DEk1GsjLkQZKzc8tkf7jS+6BTottEvfQyDhDkiSsxq9JSnBkk1seRgt9l170uTdXp4vl Kmuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zJpmWxutomaetKGVWIq9UhyMnsLIAD4UZ0Z9oHuCJ3s=; b=J3OAVMEaT5jxUbcSMfbu9wNRnkq9HxcWZkmo4TFKY9+Iw/fCwL6/o5YVBSbRKEz/lJ VSiR9iSKArMGjYXktY6VQkXV7vxcsg6PFTa7pXEs3FuTPyUwDKjKBl41N5bE4rB6LEAl /Imxdr5l4YKQEXIncorsUwHLz8ByYhoSRH/9wIIjJIoemjNSER7zNFe2mcg0z7rCVeLM 5nSzEXDletYymof9Fo7ZZBFGYqa+kPN/5ksebulCjCDiRryTMcxy7Sag+xW4vTLduCf8 KZqjnR3FkCYQgVV6m3B2cTL5dBXaWtk7RT0KvMQfiY0cOyTXzggsmwBFzNTluNIBDwLc +6yQ== X-Gm-Message-State: AFqh2ko0+W0LdFPeKkF55Ou8HCM54wdoIhlQxTXGGb4lh6oM+j0aa4qJ PvHwhdYc6soC/WW0WQJZJooZUWnN1cT0+YlB X-Google-Smtp-Source: AMrXdXs34Gsn2QQl2+TBSkaIkyPatmjWmM2KP0yx04Gi772F4eq4e4gMfF0plSvrf7/y7tV5B2g4LQ== X-Received: by 2002:a17:902:8d83:b0:193:39bd:df97 with SMTP id v3-20020a1709028d8300b0019339bddf97mr9211100plo.14.1674082055642; Wed, 18 Jan 2023 14:47:35 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id p17-20020a170902c71100b001947b539140sm9201161plp.23.2023.01.18.14.47.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:35 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iY6-Lq for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FF0-2B for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 31/42] xfs: get rid of notinit from xfs_bmap_longest_free_extent Date: Thu, 19 Jan 2023 09:44:54 +1100 Message-Id: <20230118224505.1964941-32-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner It is only set if reading the AGF gets a EAGAIN error. Just return the EAGAIN error and handle that error in the callers. This means we can remove the not_init parameter from xfs_bmap_select_minlen(), too, because the use of not_init there is pessimistic. If we can't read the agf, it won't increase blen. The only time we actually care whether we checked all the AGFs for contiguous free space is when the best length is less than the minimum allocation length. If not_init is set, then we ignore blen and set the minimum alloc length to the absolute minimum, not the best length we know already is present. However, if blen is less than the minimum we're going to ignore it anyway, regardless of whether we scanned all the AGFs or not. Hence not_init can go away, because we only use if blen is good from the scanned AGs otherwise we ignore it altogether and use minlen. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 84 +++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 7ae08b44e4d8..58790951be3e 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3139,8 +3139,7 @@ static int xfs_bmap_longest_free_extent( struct xfs_perag *pag, struct xfs_trans *tp, - xfs_extlen_t *blen, - int *notinit) + xfs_extlen_t *blen) { xfs_extlen_t longest; int error = 0; @@ -3148,14 +3147,8 @@ xfs_bmap_longest_free_extent( if (!xfs_perag_initialised_agf(pag)) { error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); - if (error) { - /* Couldn't lock the AGF, so skip this AG. */ - if (error == -EAGAIN) { - *notinit = 1; - error = 0; - } + if (error) return error; - } } longest = xfs_alloc_longest_free_extent(pag, @@ -3167,32 +3160,28 @@ xfs_bmap_longest_free_extent( return 0; } -static void +static xfs_extlen_t xfs_bmap_select_minlen( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, - xfs_extlen_t *blen, - int notinit) + xfs_extlen_t blen) { - if (notinit || *blen < ap->minlen) { - /* - * Since we did a BUF_TRYLOCK above, it is possible that - * there is space for this request. - */ - args->minlen = ap->minlen; - } else if (*blen < args->maxlen) { - /* - * If the best seen length is less than the request length, - * use the best as the minimum. - */ - args->minlen = *blen; - } else { - /* - * Otherwise we've seen an extent as big as maxlen, use that - * as the minimum. - */ - args->minlen = args->maxlen; - } + + /* + * Since we used XFS_ALLOC_FLAG_TRYLOCK in _longest_free_extent(), it is + * possible that there is enough contiguous free space for this request. + */ + if (blen < ap->minlen) + return ap->minlen; + + /* + * If the best seen length is less than the request length, + * use the best as the minimum, otherwise we've got the maxlen we + * were asked for. + */ + if (blen < args->maxlen) + return blen; + return args->maxlen; } static int @@ -3204,7 +3193,6 @@ xfs_bmap_btalloc_select_lengths( struct xfs_mount *mp = args->mp; struct xfs_perag *pag; xfs_agnumber_t agno, startag; - int notinit = 0; int error = 0; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { @@ -3220,9 +3208,8 @@ xfs_bmap_btalloc_select_lengths( *blen = 0; for_each_perag_wrap(mp, startag, agno, pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen, - ¬init); - if (error) + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + if (error && error != -EAGAIN) break; if (*blen >= args->maxlen) break; @@ -3230,7 +3217,7 @@ xfs_bmap_btalloc_select_lengths( if (pag) xfs_perag_rele(pag); - xfs_bmap_select_minlen(ap, args, blen, notinit); + args->minlen = xfs_bmap_select_minlen(ap, args, *blen); return 0; } @@ -3243,7 +3230,6 @@ xfs_bmap_btalloc_filestreams_select_lengths( struct xfs_mount *mp = ap->ip->i_mount; struct xfs_perag *pag; xfs_agnumber_t start_agno; - int notinit = 0; int error; args->total = ap->total; @@ -3254,11 +3240,13 @@ xfs_bmap_btalloc_filestreams_select_lengths( pag = xfs_perag_grab(mp, start_agno); if (pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen, - ¬init); + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); xfs_perag_rele(pag); - if (error) - return error; + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } } if (*blen < args->maxlen) { @@ -3274,18 +3262,18 @@ xfs_bmap_btalloc_filestreams_select_lengths( if (!pag) goto out_select; - error = xfs_bmap_longest_free_extent(pag, args->tp, - blen, ¬init); + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); xfs_perag_rele(pag); - if (error) - return error; - + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } start_agno = agno; - } out_select: - xfs_bmap_select_minlen(ap, args, blen, notinit); + args->minlen = xfs_bmap_select_minlen(ap, args, *blen); /* * Set the failure fallback case to look in the selected AG as stream From patchwork Wed Jan 18 22:44:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 705E3C32793 for ; Wed, 18 Jan 2023 22:48:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229883AbjARWsW (ORCPT ); Wed, 18 Jan 2023 17:48:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230146AbjARWsI (ORCPT ); Wed, 18 Jan 2023 17:48:08 -0500 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88D1464680 for ; Wed, 18 Jan 2023 14:48:06 -0800 (PST) Received: by mail-pg1-x531.google.com with SMTP id q9so107422pgq.5 for ; Wed, 18 Jan 2023 14:48:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=4q+6Xp9n+VfYC+pf1Rd0pktWwQnGPXSqSq2RV/ab2hw=; b=km8Yzgv74qlP2yJQ6875jC22hg2aCxTX4bdPUio3pKDXT4VeH4iMPzp18F8KOF+m/9 +Tn8bvjLLfi7b/9TF3DWzq8RwkK0KISZorOHQse6cYjDaxvBXmIV2SMb7Z8pyRE/VNUy h05p4bwBP37gVXmERFldn0PDhy9Oc1sm2Nr5ofG4l5uRj3SSUSNjDmNj3B/xSEfRsDJp bkKIIRih5Mz/FiymORulgz1HtLhLhn/q8USSXQn2vIHaZUnOz6etTmwKyUrgYZZxdC4C diYQpsCd+mHCorTcs9WBFLEF/4wJ30BNj/1RKSrywOz7RwEI6ZP8GqJN1qYeZ1FbXTZa QBAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4q+6Xp9n+VfYC+pf1Rd0pktWwQnGPXSqSq2RV/ab2hw=; b=7v7mC8XbMiv5hSrYYiM9saOI7RGK+YMwBtl9nZUHhZqx2PVEkD1qo/w8cwIKfXes87 o86r2AZ6mVzcGSaNKvpKnB1ZyFq20ff1qWCw9OsKWLMM04rT2UtHrosrfjI6Oiwb4gzE CzjQ0LnJZp3bCEkkHYn3U6gYdXOjVLRn3yGhQgaX5W2eflb+FmrJ6mKvse3s9VX2eAoB H+rvAGmjsb6MXEBfgVnsGiPzGTANABcbUuOpU++DMcLFRPguw5/NVX5a0Sr/YNBUcQwd wS8x04L7PboCy9OGYrYcpD6F85AS5HAMUjik4s4BXbaeY7T2Byesa5mC0wRozMmdxyEF AzGA== X-Gm-Message-State: AFqh2krQSycNsNjKqd3E8ShyP8jUhePdXqvc2n2XUQbq6KmmNCNKcRSJ dGWthvUNp/al3AtskZRkbQQ4Z0znvshcE9Ow X-Google-Smtp-Source: AMrXdXuk1S82eM9pzaV+wM3n+TOmPrxK6oqnFie3+WPhH2JGuEO7sOX5aM/4JTHh0OrbXX78EMjX6A== X-Received: by 2002:a05:6a00:340a:b0:58d:aae8:1c2 with SMTP id cn10-20020a056a00340a00b0058daae801c2mr10000603pfb.8.1674082086059; Wed, 18 Jan 2023 14:48:06 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id z188-20020a6265c5000000b0055f209690c0sm21824530pfb.50.2023.01.18.14.48.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:05 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iY8-Mj for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FF5-2H for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 32/42] xfs: use xfs_bmap_longest_free_extent() in filestreams Date: Thu, 19 Jan 2023 09:44:55 +1100 Message-Id: <20230118224505.1964941-33-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The code in xfs_bmap_longest_free_extent() is open coded in xfs_filestream_pick_ag(). Export xfs_bmap_longest_free_extent and call it from the filestreams code instead. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_bmap.h | 2 ++ fs/xfs/xfs_filestream.c | 22 ++++++++-------------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 58790951be3e..c6a617dada27 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3135,7 +3135,7 @@ xfs_bmap_adjacent( #undef ISVALID } -static int +int xfs_bmap_longest_free_extent( struct xfs_perag *pag, struct xfs_trans *tp, diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 0ffc0d998850..7bd619eb2f7d 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -168,6 +168,8 @@ static inline bool xfs_bmap_is_written_extent(struct xfs_bmbt_irec *irec) #define xfs_valid_startblock(ip, startblock) \ ((startblock) != 0 || XFS_IS_REALTIME_INODE(ip)) +int xfs_bmap_longest_free_extent(struct xfs_perag *pag, + struct xfs_trans *tp, xfs_extlen_t *blen); void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, xfs_filblks_t len); unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp); diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 7e8b25ab6c46..2eb702034d05 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -124,17 +124,14 @@ xfs_filestream_pick_ag( trace_xfs_filestream_scan(mp, ip->i_ino, ag); pag = xfs_perag_get(mp, ag); - - if (!xfs_perag_initialised_agf(pag)) { - err = xfs_alloc_read_agf(pag, NULL, trylock, NULL); - if (err) { - if (err != -EAGAIN) { - xfs_perag_put(pag); - return err; - } - /* Couldn't lock the AGF, skip this AG. */ - goto next_ag; - } + longest = 0; + err = xfs_bmap_longest_free_extent(pag, NULL, &longest); + if (err) { + xfs_perag_put(pag); + if (err != -EAGAIN) + return err; + /* Couldn't lock the AGF, skip this AG. */ + goto next_ag; } /* Keep track of the AG with the most free blocks. */ @@ -154,9 +151,6 @@ xfs_filestream_pick_ag( goto next_ag; } - longest = xfs_alloc_longest_free_extent(pag, - xfs_alloc_min_freelist(mp, pag), - xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE)); if (((minlen && longest >= minlen) || (!minlen && pag->pagf_freeblks >= minfree)) && (!xfs_perag_prefers_metadata(pag) || From patchwork Wed Jan 18 22:44:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107156 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 235AAC38159 for ; Wed, 18 Jan 2023 22:48:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229566AbjARWsZ (ORCPT ); Wed, 18 Jan 2023 17:48:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229968AbjARWsK (ORCPT ); Wed, 18 Jan 2023 17:48:10 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D05DE5356D for ; Wed, 18 Jan 2023 14:48:09 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id 200so114144pfx.7 for ; Wed, 18 Jan 2023 14:48:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=DaIQWtHzJTO5NL5ekzY8BPUXBPXgLjETt+hTeq+rKVs=; b=F0Cp4u6AFUP0qR3FhVmoJfShnGi+WeEZZxaGF9jO491rl6+vAjHs5juAzm9ulgzi5j wQPryMEkJQN8QMqfTAFJWLkGA3fRJ1+w+XN5ZDpI46tBmtBZA2z302sXdjWPyWyAwZmL lxaSqL7mhCQHsT3GXmoa1G1dAKcIDW0qcRVr1us9sB/OUvW2ztVxSHjGMVIduJjipsOX /deE38aqjnVQN+i+zr7ZyytGoog3sO25qEXS6fqP4DWWPwnrR/5HnmE67AcT5Gdu0IEn Is75CskctA1Ztsek+v1ftxb9g/23prVV0AHo61NM8o8KapdintsiEYb7hpliyklHen4B LZUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DaIQWtHzJTO5NL5ekzY8BPUXBPXgLjETt+hTeq+rKVs=; b=eD3YyZrJWuJqXZ5S1+yuLEyBQ3G5xxuUJ+bgqGE6KJkMKRueUVUpK5yDi5ouvLPhTb ZqYSob7uufd7PCcgJm1A52Y8vXQWh8tOmpLBHDnvLV8ogBruOC43/Aj2JLezcjuERlTf A/i64T5k2vskke9g8K8ROmAMpCo2aJluJQwczXjyuVDVgZqQ4owY14CJlctxzEfvKApT 0A7UsryAQke4l83nWpj2G+D42Gk4vYo5WNRwOIjv34t6XyP+CAiEwWrOMB/6bd7awitA la7J2jQ0705RDaK8e1/a7L2WkygGOfsA5NPq5tqUchpQQyVVcalXKiJUtCCQHz/m3NVD eTLg== X-Gm-Message-State: AFqh2kqZHk+ZlzsbnaU2k16lxGeVmq0YZWltT++wV6vlso/1iLQqjdr7 k01PHBsW6vdn8rtWm4jRtJ1rfLEdRd6nQhcu X-Google-Smtp-Source: AMrXdXu3FcDo+Kbqe+7vsaCKl/aPnRwZo3sxuoa0BJMbcMy1tVx34OdxMvvL57diMHRMBAHLnk9Fug== X-Received: by 2002:aa7:880b:0:b0:58d:abd5:504a with SMTP id c11-20020aa7880b000000b0058dabd5504amr8344434pfo.31.1674082089190; Wed, 18 Jan 2023 14:48:09 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id a1-20020aa795a1000000b0058119caa82csm10009310pfk.205.2023.01.18.14.48.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:08 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYC-Nf for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFA-2M for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 33/42] xfs: move xfs_bmap_btalloc_filestreams() to xfs_filestreams.c Date: Thu, 19 Jan 2023 09:44:56 +1100 Message-Id: <20230118224505.1964941-34-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner xfs_bmap_btalloc_filestreams() calls two filestreams functions to select the AG to allocate from. Both those functions end up in the same selection function that iterates all AGs multiple times. Worst case, xfs_bmap_btalloc_filestreams() can iterate all AGs 4 times just to select the initial AG to allocate in. Move the AG selection to fs/xfs/xfs_filestreams.c as a single interface so that the inefficient AG interation is contained entirely within the filestreams code. This will allow the implementation to be simplified and made more efficient in future patches. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 94 +++++------------------------------- fs/xfs/libxfs/xfs_bmap.h | 3 ++ fs/xfs/xfs_filestream.c | 100 ++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_filestream.h | 5 +- 4 files changed, 115 insertions(+), 87 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c6a617dada27..098b46f3f3e3 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3221,68 +3221,6 @@ xfs_bmap_btalloc_select_lengths( return 0; } -static int -xfs_bmap_btalloc_filestreams_select_lengths( - struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t *blen) -{ - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_perag *pag; - xfs_agnumber_t start_agno; - int error; - - args->total = ap->total; - - start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno); - if (start_agno == NULLAGNUMBER) - start_agno = 0; - - pag = xfs_perag_grab(mp, start_agno); - if (pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - return error; - *blen = 0; - } - } - - if (*blen < args->maxlen) { - xfs_agnumber_t agno = start_agno; - - error = xfs_filestream_new_ag(ap, &agno); - if (error) - return error; - if (agno == NULLAGNUMBER) - goto out_select; - - pag = xfs_perag_grab(mp, agno); - if (!pag) - goto out_select; - - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - return error; - *blen = 0; - } - start_agno = agno; - } - -out_select: - args->minlen = xfs_bmap_select_minlen(ap, args, *blen); - - /* - * Set the failure fallback case to look in the selected AG as stream - * may have moved. - */ - ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0); - return 0; -} - /* Update all inode and quota accounting for the allocation we just did. */ static void xfs_bmap_btalloc_accounting( @@ -3576,7 +3514,7 @@ xfs_bmap_btalloc_at_eof( * transaction that we are critically low on space so they don't waste time on * allocation modes that are unlikely to succeed. */ -static int +int xfs_bmap_btalloc_low_space( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args) @@ -3605,36 +3543,25 @@ xfs_bmap_btalloc_filestreams( struct xfs_alloc_arg *args, int stripe_align) { - xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); xfs_extlen_t blen = 0; int error; - /* Determine the initial block number we will target for allocation. */ - if (agno == NULLAGNUMBER) - agno = 0; - ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); - xfs_bmap_adjacent(ap); + + error = xfs_filestream_select_ag(ap, args, &blen); + if (error) + return error; /* - * If there is very little free space before we start a - * filestreams allocation, we're almost guaranteed to fail to - * find an AG with enough contiguous free space to succeed, so - * just go straight to the low space algorithm. + * If we are in low space mode, then optimal allocation will fail so + * prepare for minimal allocation and jump to the low space algorithm + * immediately. */ if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { args->minlen = ap->minlen; - return xfs_bmap_btalloc_low_space(ap, args); + goto out_low_space; } - /* - * Search for an allocation group with a single extent large enough for - * the request. If one isn't found, then adjust the minimum allocation - * size to the largest space found. - */ - error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen); - if (error) - return error; - + args->minlen = xfs_bmap_select_minlen(ap, args, blen); if (ap->aeof) { error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, true); @@ -3646,6 +3573,7 @@ xfs_bmap_btalloc_filestreams( if (error || args->fsbno != NULLFSBLOCK) return error; +out_low_space: return xfs_bmap_btalloc_low_space(ap, args); } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 7bd619eb2f7d..94d9285eeba1 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -12,6 +12,7 @@ struct xfs_ifork; struct xfs_inode; struct xfs_mount; struct xfs_trans; +struct xfs_alloc_arg; /* * Argument structure for xfs_bmap_alloc. @@ -224,6 +225,8 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp, struct xfs_bmbt_irec *new, int *logflagsp); xfs_extlen_t xfs_bmapi_minleft(struct xfs_trans *tp, struct xfs_inode *ip, int fork); +int xfs_bmap_btalloc_low_space(struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args); enum xfs_bmap_intent_type { XFS_BMAP_MAP = 1, diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 2eb702034d05..a641404aa9a6 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -12,6 +12,7 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_bmap.h" +#include "xfs_bmap_util.h" #include "xfs_alloc.h" #include "xfs_mru_cache.h" #include "xfs_trace.h" @@ -263,7 +264,7 @@ xfs_filestream_get_parent( * * Returns NULLAGNUMBER in case of an error. */ -xfs_agnumber_t +static xfs_agnumber_t xfs_filestream_lookup_ag( struct xfs_inode *ip) { @@ -312,7 +313,7 @@ xfs_filestream_lookup_ag( * This is called when the allocator can't find a suitable extent in the * current AG, and we have to move the stream into a new AG with more space. */ -int +static int xfs_filestream_new_ag( struct xfs_bmalloca *ap, xfs_agnumber_t *agp) @@ -358,6 +359,101 @@ xfs_filestream_new_ag( return err; } +static int +xfs_filestreams_select_lengths( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t *blen) +{ + struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_perag *pag; + xfs_agnumber_t start_agno; + int error; + + args->total = ap->total; + + start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno); + if (start_agno == NULLAGNUMBER) + start_agno = 0; + + pag = xfs_perag_grab(mp, start_agno); + if (pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + xfs_perag_rele(pag); + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } + } + + if (*blen < args->maxlen) { + xfs_agnumber_t agno = start_agno; + + error = xfs_filestream_new_ag(ap, &agno); + if (error) + return error; + if (agno == NULLAGNUMBER) + goto out_select; + + pag = xfs_perag_grab(mp, agno); + if (!pag) + goto out_select; + + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + xfs_perag_rele(pag); + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } + start_agno = agno; + } + +out_select: + /* + * Set the failure fallback case to look in the selected AG as stream + * may have moved. + */ + ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0); + return 0; +} + +/* + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then the largest available free extent is + * returned as the best length possible. + */ +int +xfs_filestream_select_ag( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_extlen_t *blen) +{ + xfs_agnumber_t start_agno = xfs_filestream_lookup_ag(ap->ip); + + /* Determine the initial block number we will target for allocation. */ + if (start_agno == NULLAGNUMBER) + start_agno = 0; + ap->blkno = XFS_AGB_TO_FSB(args->mp, start_agno, 0); + xfs_bmap_adjacent(ap); + + /* + * If there is very little free space before we start a filestreams + * allocation, we're almost guaranteed to fail to find a better AG with + * larger free space available so we don't even try. + */ + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) + return 0; + + /* + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then adjust the minimum allocation + * size to the largest space found. + */ + return xfs_filestreams_select_lengths(ap, args, blen); +} + void xfs_filestream_deassociate( struct xfs_inode *ip) diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h index 403226ebb80b..df9f7553e106 100644 --- a/fs/xfs/xfs_filestream.h +++ b/fs/xfs/xfs_filestream.h @@ -9,13 +9,14 @@ struct xfs_mount; struct xfs_inode; struct xfs_bmalloca; +struct xfs_alloc_arg; int xfs_filestream_mount(struct xfs_mount *mp); void xfs_filestream_unmount(struct xfs_mount *mp); void xfs_filestream_deassociate(struct xfs_inode *ip); -xfs_agnumber_t xfs_filestream_lookup_ag(struct xfs_inode *ip); -int xfs_filestream_new_ag(struct xfs_bmalloca *ap, xfs_agnumber_t *agp); int xfs_filestream_peek_ag(struct xfs_mount *mp, xfs_agnumber_t agno); +int xfs_filestream_select_ag(struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, xfs_extlen_t *blen); static inline int xfs_inode_is_filestream( From patchwork Wed Jan 18 22:44:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6D0CC46467 for ; Wed, 18 Jan 2023 22:48:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229926AbjARWs0 (ORCPT ); Wed, 18 Jan 2023 17:48:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229786AbjARWsN (ORCPT ); Wed, 18 Jan 2023 17:48:13 -0500 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E355E63E28 for ; Wed, 18 Jan 2023 14:48:12 -0800 (PST) Received: by mail-pj1-x1036.google.com with SMTP id s13-20020a17090a6e4d00b0022900843652so4038065pjm.1 for ; Wed, 18 Jan 2023 14:48:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=jshD/9c7V6ANEfyMPGcv0GQviC/f5uQ0vJVfnkiQWRY=; b=54qOFW9hp++GmNfkvsC0HisOObL8PRFVr9E+oZoLIZcFVIU4jgQh0wN8Sg8ehuY+Ot jDyfHiJwG/Jk5qTseGLn55vDyqUPqZxfN0QzcstuJFQxSPR8HY46NhjL4bkRiyZtIHQB E13aHIJp7dVSFuHSW3F8MFO8G2XBqK6ySJr4EFtC97PuruLoufuuwYNwvRRrm0JuxTZT mklDZ6AeoMb4e3MvLw47zay9XPDTajY0EoOjF6DxtgMCro76cvSUhUkRDx0zGYbd4NRB GoyEYA09RYtgoFRSRrVrODs5QsOa8uC/Q1IvR45bN2pb8AmNz498MlIijGrpCMx7vrBM iQSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jshD/9c7V6ANEfyMPGcv0GQviC/f5uQ0vJVfnkiQWRY=; b=01I+te0AN2bQiksSIDOHuyqoQX4U2F6h29m+Dlr6/59m2orXvlMR/HCFadlLxFAR2r Dap/sVNXSWQEa0GNWkMY00Yu7ylMG2WOftADZN9h0C/WeKDi6NW0Po7z8XJJvMt2Qdwe S7FMfx0QCeZoLk1e4k1XF3nkBr/oKmuK4P1fEK4EB3qAz4Y4LXJwJIhTHOo3rlCkdyb5 5kUhnMzuVaRV/P3U3SCWq2e5dsQzANxQaNMLUaiJj8I13c3mR7jQJDOXfq4H9TLSL2YE MnjxymqZ0oScOMu23xWzBhxnQP3degva/xHfv9hq8BHkc0i9tuotsRhNR9aUUaF0iGqV p69A== X-Gm-Message-State: AFqh2krwbpmmkJXT12Y+yZ3oOv/n3bN3W0+YQb/EdwtHUq3NU62vBABw EPfA5R6jyy2lMjulbaLRtCy/2K47hob8kDvQ X-Google-Smtp-Source: AMrXdXujiMGBHygf+k28wJrIbAuQ46FQ1IxLUbmllIgmoVf+H9Buman6XwLwNx8Rf8ztxH1WUXFIMA== X-Received: by 2002:a17:902:720a:b0:193:25b6:71bc with SMTP id ba10-20020a170902720a00b0019325b671bcmr9702127plb.25.1674082092362; Wed, 18 Jan 2023 14:48:12 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id v13-20020a170902f0cd00b0019324fbec59sm6294135pla.41.2023.01.18.14.48.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:11 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYF-Ob for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFF-2S for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 34/42] xfs: merge filestream AG lookup into xfs_filestream_select_ag() Date: Thu, 19 Jan 2023 09:44:57 +1100 Message-Id: <20230118224505.1964941-35-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner The lookup currently either returns the cached filestream AG or it calls xfs_filestreams_select_lengths() to looks up a new AG. This has verify the AG that is selected, so we end up doing "select a new AG loop in a couple of places when only one really is needed. Merge the initial lookup functionality with the length selection so that we only need to do a single pick loop on lookup or verification failure. This undoes a lot of the factoring that enabled the selection to be moved over to the filestreams code. It makes xfs_filestream_select_ag() an awful messier, but it has to be made worse before it can get better in future patches... Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 184 +++++++++++++++------------------------- 1 file changed, 70 insertions(+), 114 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index a641404aa9a6..23044dab2001 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -258,55 +258,6 @@ xfs_filestream_get_parent( return dir ? XFS_I(dir) : NULL; } -/* - * Find the right allocation group for a file, either by finding an - * existing file stream or creating a new one. - * - * Returns NULLAGNUMBER in case of an error. - */ -static xfs_agnumber_t -xfs_filestream_lookup_ag( - struct xfs_inode *ip) -{ - struct xfs_mount *mp = ip->i_mount; - struct xfs_inode *pip = NULL; - xfs_agnumber_t startag, ag = NULLAGNUMBER; - struct xfs_mru_cache_elem *mru; - - ASSERT(S_ISREG(VFS_I(ip)->i_mode)); - - pip = xfs_filestream_get_parent(ip); - if (!pip) - return NULLAGNUMBER; - - mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); - if (mru) { - ag = container_of(mru, struct xfs_fstrm_item, mru)->ag; - xfs_mru_cache_done(mp->m_filestream); - - trace_xfs_filestream_lookup(mp, ip->i_ino, ag); - goto out; - } - - /* - * Set the starting AG using the rotor for inode32, otherwise - * use the directory inode's AG. - */ - if (xfs_is_inode32(mp)) { - xfs_agnumber_t rotorstep = xfs_rotorstep; - startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount; - mp->m_agfrotor = (mp->m_agfrotor + 1) % - (mp->m_sb.sb_agcount * rotorstep); - } else - startag = XFS_INO_TO_AGNO(mp, pip->i_ino); - - if (xfs_filestream_pick_ag(pip, startag, &ag, 0, 0)) - ag = NULLAGNUMBER; -out: - xfs_irele(pip); - return ag; -} - /* * Pick a new allocation group for the current file and its file stream. * @@ -359,83 +310,70 @@ xfs_filestream_new_ag( return err; } -static int -xfs_filestreams_select_lengths( +/* + * Search for an allocation group with a single extent large enough for + * the request. If one isn't found, then the largest available free extent is + * returned as the best length possible. + */ +int +xfs_filestream_select_ag( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; struct xfs_perag *pag; - xfs_agnumber_t start_agno; + struct xfs_inode *pip = NULL; + xfs_agnumber_t agno = NULLAGNUMBER; + struct xfs_mru_cache_elem *mru; int error; args->total = ap->total; + *blen = 0; - start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno); - if (start_agno == NULLAGNUMBER) - start_agno = 0; - - pag = xfs_perag_grab(mp, start_agno); - if (pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - return error; - *blen = 0; - } + pip = xfs_filestream_get_parent(ap->ip); + if (!pip) { + agno = 0; + goto new_ag; } - if (*blen < args->maxlen) { - xfs_agnumber_t agno = start_agno; + mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); + if (mru) { + agno = container_of(mru, struct xfs_fstrm_item, mru)->ag; + xfs_mru_cache_done(mp->m_filestream); - error = xfs_filestream_new_ag(ap, &agno); - if (error) - return error; - if (agno == NULLAGNUMBER) - goto out_select; + trace_xfs_filestream_lookup(mp, ap->ip->i_ino, agno); + xfs_irele(pip); - pag = xfs_perag_grab(mp, agno); - if (!pag) - goto out_select; + ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); + xfs_bmap_adjacent(ap); - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - return error; - *blen = 0; + pag = xfs_perag_grab(mp, agno); + if (pag) { + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + xfs_perag_rele(pag); + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } } - start_agno = agno; + if (*blen >= args->maxlen) + goto out_select; + } else if (xfs_is_inode32(mp)) { + xfs_agnumber_t rotorstep = xfs_rotorstep; + agno = (mp->m_agfrotor / rotorstep) % + mp->m_sb.sb_agcount; + mp->m_agfrotor = (mp->m_agfrotor + 1) % + (mp->m_sb.sb_agcount * rotorstep); + xfs_irele(pip); + } else { + agno = XFS_INO_TO_AGNO(mp, pip->i_ino); + xfs_irele(pip); } -out_select: - /* - * Set the failure fallback case to look in the selected AG as stream - * may have moved. - */ - ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0); - return 0; -} - -/* - * Search for an allocation group with a single extent large enough for - * the request. If one isn't found, then the largest available free extent is - * returned as the best length possible. - */ -int -xfs_filestream_select_ag( - struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t *blen) -{ - xfs_agnumber_t start_agno = xfs_filestream_lookup_ag(ap->ip); - - /* Determine the initial block number we will target for allocation. */ - if (start_agno == NULLAGNUMBER) - start_agno = 0; - ap->blkno = XFS_AGB_TO_FSB(args->mp, start_agno, 0); +new_ag: + ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); xfs_bmap_adjacent(ap); /* @@ -446,14 +384,32 @@ xfs_filestream_select_ag( if (ap->tp->t_flags & XFS_TRANS_LOWMODE) return 0; - /* - * Search for an allocation group with a single extent large enough for - * the request. If one isn't found, then adjust the minimum allocation - * size to the largest space found. - */ - return xfs_filestreams_select_lengths(ap, args, blen); + error = xfs_filestream_new_ag(ap, &agno); + if (error) + return error; + if (agno == NULLAGNUMBER) { + agno = 0; + goto out_select; + } + + pag = xfs_perag_grab(mp, agno); + if (!pag) + goto out_select; + + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + xfs_perag_rele(pag); + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } + +out_select: + ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); + return 0; } + void xfs_filestream_deassociate( struct xfs_inode *ip) From patchwork Wed Jan 18 22:44:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91607C32793 for ; Wed, 18 Jan 2023 22:45:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229847AbjARWpf (ORCPT ); Wed, 18 Jan 2023 17:45:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229872AbjARWpT (ORCPT ); Wed, 18 Jan 2023 17:45:19 -0500 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6C2461D4A for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: by mail-pj1-x102e.google.com with SMTP id o7-20020a17090a0a0700b00226c9b82c3aso53659pjo.3 for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Hyb8kFqnYO+7TbGRi2aAzXLcH3t+q4Rx2pDf7LxCmw8=; b=as7scDEOGEym7EiyON7KXQ+uo6zlFI2VXRtoEnSgPNxpCkwESICoXgBgaTnRx0MWw1 hKwvOKjK717+B/ErOeyspCxG7ZfC8k6hz40Yl2LctKubY9UdFDmntfACNvqxdShMUlKm oCrGFf2ntpTX4kQYcgFEtq3YTqGK10u+eb6cFCNWG7OaLVkA/rn57rkLHGlhl7goPW0s nzPvpuA5NjvK1Cs6bnY4C+ut5mLHiPuqhBZnn1bycQSrxt0aHV3pvP8eI+3sRz5Zt3KV h1E0BTdh2yUztZcsZD7AF6MPBOT6tuAGCg8AXazEJOKRIcX25I0sigDc1NHW+8HKw2fT 0M2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Hyb8kFqnYO+7TbGRi2aAzXLcH3t+q4Rx2pDf7LxCmw8=; b=eoSu1nY6teli/JxQPpqUWogvp6bS2hLmQCDiIrWRcW+V56pkcXTlyXifXrj2Kx1CFf z9nk7Vrzi6izqpvStoLXBhGl3qImutFYJxsqv2cV/zaiInfJEThx4E1T+OslNVXNLPye C6MIf7SH2P+f1c8sImMKBdwsO3fEhHtvPGO20GEhMvEH3z3lYP8pU2Tz7MNC6a89xH2M 3kw7N/J2uBHgfTkYFFHWjsZ/8HG+nerw+aXDXk72stAP9/RcNWSZoITMfcR5vX4X6XH/ 0rqT5LKSDswWfQMSzT7MEC3rRRuWRlJUHmCDFVGUIwrmrHIEw8CTKYV9M2sEzBFlzLt5 P1dg== X-Gm-Message-State: AFqh2kqG6bDdUiXKCPKer2La7c//os0mQE7Q3XwnX37PixGViMOYRHmd PFrhzNRgZFKSPJ+kYFQxhkuPc4d/r9sbiu7/ X-Google-Smtp-Source: AMrXdXvKiiEsP6vv8HBDsmxTBUTjy6HSMAx1JFk+or7sxROrSzjnMvdx37RY4nTibQzKGSlJfsLuJg== X-Received: by 2002:a05:6a20:441:b0:b8:9f05:5216 with SMTP id b1-20020a056a20044100b000b89f055216mr7891065pzb.57.1674081918291; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id g15-20020a63200f000000b004d1d89ec63fsm48396pgg.6.2023.01.18.14.45.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYH-PX for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFK-2Y for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 35/42] xfs: merge new filestream AG selection into xfs_filestream_select_ag() Date: Thu, 19 Jan 2023 09:44:58 +1100 Message-Id: <20230118224505.1964941-36-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner This is largely a wrapper around xfs_filestream_pick_ag() that repeats a lot of the lookups that we just merged back into xfs_filestream_select_ag() from the lookup code. Merge the xfs_filestream_new_ag() code back into _select_ag() to get rid of all the unnecessary logic. Indeed, this makes it obvious that if we have no parent inode, the filestreams allocator always selects AG 0 regardless of whether it is fit for purpose or not. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 112 ++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 72 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 23044dab2001..713766729dcf 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -98,16 +98,18 @@ xfs_fstrm_free_func( static int xfs_filestream_pick_ag( struct xfs_inode *ip, - xfs_agnumber_t startag, xfs_agnumber_t *agp, int flags, - xfs_extlen_t minlen) + xfs_extlen_t *longest) { struct xfs_mount *mp = ip->i_mount; struct xfs_fstrm_item *item; struct xfs_perag *pag; - xfs_extlen_t longest, free = 0, minfree, maxfree = 0; - xfs_agnumber_t ag, max_ag = NULLAGNUMBER; + xfs_extlen_t minlen = *longest; + xfs_extlen_t free = 0, minfree, maxfree = 0; + xfs_agnumber_t startag = *agp; + xfs_agnumber_t ag = startag; + xfs_agnumber_t max_ag = NULLAGNUMBER; int err, trylock, nscan; ASSERT(S_ISDIR(VFS_I(ip)->i_mode)); @@ -115,7 +117,6 @@ xfs_filestream_pick_ag( /* 2% of an AG's blocks must be free for it to be chosen. */ minfree = mp->m_sb.sb_agblocks / 50; - ag = startag; *agp = NULLAGNUMBER; /* For the first pass, don't sleep trying to init the per-AG. */ @@ -125,8 +126,8 @@ xfs_filestream_pick_ag( trace_xfs_filestream_scan(mp, ip->i_ino, ag); pag = xfs_perag_get(mp, ag); - longest = 0; - err = xfs_bmap_longest_free_extent(pag, NULL, &longest); + *longest = 0; + err = xfs_bmap_longest_free_extent(pag, NULL, longest); if (err) { xfs_perag_put(pag); if (err != -EAGAIN) @@ -152,7 +153,7 @@ xfs_filestream_pick_ag( goto next_ag; } - if (((minlen && longest >= minlen) || + if (((minlen && *longest >= minlen) || (!minlen && pag->pagf_freeblks >= minfree)) && (!xfs_perag_prefers_metadata(pag) || !(flags & XFS_PICK_USERDATA) || @@ -258,58 +259,6 @@ xfs_filestream_get_parent( return dir ? XFS_I(dir) : NULL; } -/* - * Pick a new allocation group for the current file and its file stream. - * - * This is called when the allocator can't find a suitable extent in the - * current AG, and we have to move the stream into a new AG with more space. - */ -static int -xfs_filestream_new_ag( - struct xfs_bmalloca *ap, - xfs_agnumber_t *agp) -{ - struct xfs_inode *ip = ap->ip, *pip; - struct xfs_mount *mp = ip->i_mount; - xfs_extlen_t minlen = ap->length; - xfs_agnumber_t startag = 0; - int flags = 0; - int err = 0; - struct xfs_mru_cache_elem *mru; - - *agp = NULLAGNUMBER; - - pip = xfs_filestream_get_parent(ip); - if (!pip) - goto exit; - - mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); - if (mru) { - struct xfs_fstrm_item *item = - container_of(mru, struct xfs_fstrm_item, mru); - startag = (item->ag + 1) % mp->m_sb.sb_agcount; - } - - if (ap->datatype & XFS_ALLOC_USERDATA) - flags |= XFS_PICK_USERDATA; - if (ap->tp->t_flags & XFS_TRANS_LOWMODE) - flags |= XFS_PICK_LOWSPACE; - - err = xfs_filestream_pick_ag(pip, startag, agp, flags, minlen); - - /* - * Only free the item here so we skip over the old AG earlier. - */ - if (mru) - xfs_fstrm_free_func(mp, mru); - - xfs_irele(pip); -exit: - if (*agp == NULLAGNUMBER) - *agp = 0; - return err; -} - /* * Search for an allocation group with a single extent large enough for * the request. If one isn't found, then the largest available free extent is @@ -326,6 +275,7 @@ xfs_filestream_select_ag( struct xfs_inode *pip = NULL; xfs_agnumber_t agno = NULLAGNUMBER; struct xfs_mru_cache_elem *mru; + int flags = 0; int error; args->total = ap->total; @@ -334,13 +284,14 @@ xfs_filestream_select_ag( pip = xfs_filestream_get_parent(ap->ip); if (!pip) { agno = 0; - goto new_ag; + goto out_select; } mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); if (mru) { agno = container_of(mru, struct xfs_fstrm_item, mru)->ag; xfs_mru_cache_done(mp->m_filestream); + mru = NULL; trace_xfs_filestream_lookup(mp, ap->ip->i_ino, agno); xfs_irele(pip); @@ -354,7 +305,7 @@ xfs_filestream_select_ag( xfs_perag_rele(pag); if (error) { if (error != -EAGAIN) - return error; + goto out_error; *blen = 0; } } @@ -366,13 +317,18 @@ xfs_filestream_select_ag( mp->m_sb.sb_agcount; mp->m_agfrotor = (mp->m_agfrotor + 1) % (mp->m_sb.sb_agcount * rotorstep); - xfs_irele(pip); } else { agno = XFS_INO_TO_AGNO(mp, pip->i_ino); - xfs_irele(pip); } -new_ag: + /* Changing parent AG association now, so remove the existing one. */ + mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); + if (mru) { + struct xfs_fstrm_item *item = + container_of(mru, struct xfs_fstrm_item, mru); + agno = (item->ag + 1) % mp->m_sb.sb_agcount; + xfs_fstrm_free_func(mp, mru); + } ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); xfs_bmap_adjacent(ap); @@ -382,33 +338,45 @@ xfs_filestream_select_ag( * larger free space available so we don't even try. */ if (ap->tp->t_flags & XFS_TRANS_LOWMODE) - return 0; + goto out_select; + + if (ap->datatype & XFS_ALLOC_USERDATA) + flags |= XFS_PICK_USERDATA; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) + flags |= XFS_PICK_LOWSPACE; - error = xfs_filestream_new_ag(ap, &agno); + *blen = ap->length; + error = xfs_filestream_pick_ag(pip, &agno, flags, blen); if (error) - return error; + goto out_error; if (agno == NULLAGNUMBER) { agno = 0; - goto out_select; + goto out_irele; } pag = xfs_perag_grab(mp, agno); if (!pag) - goto out_select; + goto out_irele; error = xfs_bmap_longest_free_extent(pag, args->tp, blen); xfs_perag_rele(pag); if (error) { if (error != -EAGAIN) - return error; + goto out_error; *blen = 0; } +out_irele: + xfs_irele(pip); out_select: ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); return 0; -} +out_error: + xfs_irele(pip); + return error; + +} void xfs_filestream_deassociate( From patchwork Wed Jan 18 22:44:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107145 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D8EEC32793 for ; Wed, 18 Jan 2023 22:48:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229686AbjARWsJ (ORCPT ); Wed, 18 Jan 2023 17:48:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229968AbjARWrt (ORCPT ); Wed, 18 Jan 2023 17:47:49 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 943F566025 for ; Wed, 18 Jan 2023 14:47:34 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id g68so85267pgc.11 for ; Wed, 18 Jan 2023 14:47:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=mcHcjqAtQ/8ITHolGO2Jkc+y/Vqb1PaZfvTWg60uLE8=; b=Ueg4T3/nJcAaTg1v5DXf4a9HPa+S+HFsKvoW+KJMpDOuTOa3OJ1cVweHOtseGENhl2 /2gvLTvAtBqvMHpzA2h/M9yhy3PB7MfdAI3bs7lto/Y4CqeR04fWZUUawHJhvmeIU0/O CcKFmtm6/HVN4fAuLbQPRVN8wvGOysySYwABB0VOTs0EC0XyzXDQmqHoxvYm9YiQ1pGL ExZSQPzCIia9uoxDC65EFbs2VFg6uKI1rjR8uRe5YBi1HyojXsVIW+O5XnA46Uz6G/OX uGguayzLdikaUYOJYaCVJZIJJja40SjtuLB/Z5E13y/ySbrnCjnv3GvbZvq6h0ATvTLj xjlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mcHcjqAtQ/8ITHolGO2Jkc+y/Vqb1PaZfvTWg60uLE8=; b=vvnTqZba2YHem1OPGDvu4d+HNMSw3pVM5P3EKh8g8Vg0I0+g7YCP7+KoBUMcRBNX2y mN/bTC+ixUCkTYQD3gTrFEjDUT+zPELbDv8n1D7V/k9mHDfLv7iaRYZV++UTySBC3z5T F2pptfgFzbyCgwBS4L1O8f3wcaAgxnu1kyTtw3DnDC2NnmtXdLoRMNTcM/CRVEu0DVrh +vqywViDK/IxR5GB1dcb7b8BkegYCUWiPS33vd4v0Fs3oMhSe9AYB/jTDL9fS1F67RNa 43bA27zqWbz94A5R/pQQtaKXgnA4I+BA94/13LjyoubB1kI4PgGL2Q2EcfI72O5J+HLU WIIA== X-Gm-Message-State: AFqh2kquRetDPP3eox7LvM+strL9A/CkudlF5LQZKLPlgdQKu3FUQYwq EnZ/NKYrIftCho+g0iosOIxUQOMQ1Bdm4mGb X-Google-Smtp-Source: AMrXdXtRMcPC/VJXfD9MceMvK/adSVThbQ9611qm0RREz73PZ1moe0TX4IHGlQUxSSIBEEYBKhrFHA== X-Received: by 2002:a05:6a00:a27:b0:566:900d:a1de with SMTP id p39-20020a056a000a2700b00566900da1demr11229855pfh.26.1674082052475; Wed, 18 Jan 2023 14:47:32 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id r15-20020aa79ecf000000b0056c2e497b02sm7328397pfq.173.2023.01.18.14.47.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:47:32 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYK-QS for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFP-2e for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 36/42] xfs: remove xfs_filestream_select_ag() longest extent check Date: Thu, 19 Jan 2023 09:44:59 +1100 Message-Id: <20230118224505.1964941-37-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Picking a new AG checks the longest free extent in the AG is valid, so there's no need to repeat the check in xfs_filestream_select_ag(). Remove it. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 713766729dcf..95e28aae35ab 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -276,7 +276,7 @@ xfs_filestream_select_ag( xfs_agnumber_t agno = NULLAGNUMBER; struct xfs_mru_cache_elem *mru; int flags = 0; - int error; + int error = 0; args->total = ap->total; *blen = 0; @@ -351,27 +351,11 @@ xfs_filestream_select_ag( goto out_error; if (agno == NULLAGNUMBER) { agno = 0; - goto out_irele; - } - - pag = xfs_perag_grab(mp, agno); - if (!pag) - goto out_irele; - - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - goto out_error; *blen = 0; } -out_irele: - xfs_irele(pip); out_select: ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); - return 0; - out_error: xfs_irele(pip); return error; From patchwork Wed Jan 18 22:45:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107144 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5239CC54EBE for ; Wed, 18 Jan 2023 22:45:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229854AbjARWpg (ORCPT ); Wed, 18 Jan 2023 17:45:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229878AbjARWpU (ORCPT ); Wed, 18 Jan 2023 17:45:20 -0500 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78DAC63E1F for ; Wed, 18 Jan 2023 14:45:19 -0800 (PST) Received: by mail-pl1-x636.google.com with SMTP id b17so561156pld.7 for ; Wed, 18 Jan 2023 14:45:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=jtQZpfvSmD/zQfrDfzr1/CpU1KRAS48UBEUHRo0ebaU=; b=VuYj/7vQk8iflTI0v7wZAxJfc+3vWz1BBX08Ldph2JlSAEnbbqZko0SoMCZybh+WJB AbF9Wv1qtZmP+6cR4OO2twTsTYaftHInhpb8HoRieW1uqB/9FR7N0HJFQ4Ay4phRKhnw TKmN/qTdUpz1gfIkF4ljqS2oIXoOFrkqdrKOGj0wwNtXrxeb2VEzkVgeiZfP17ZVX8VZ FCgD7BKlPtEdA1vUGkaPdZQ0spRd+jVHw7eH9QyI1pCT3GIQHWVuYPp0s+BR0pNS7HoU ePrBphdp9yottQJ58zHTbc6Ga+PR3rJ/3x1nCivDO9yPxsHZ7bF7a7XMvcx+1vrURseR poZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jtQZpfvSmD/zQfrDfzr1/CpU1KRAS48UBEUHRo0ebaU=; b=RvyK08cBTrFszmZGu8m6bg1u9mmsVXg+xCVCES7Mb3Adzkj8/x9yfPyBVALjYJd/EV u0QpP8pm2rKyp+d05OEM81bnSHRLQz1g1wx4DgPRZiiuuXH+VXAnu16Esysqc1436POV yhTL/X1RAboY2VjNQMuM5cl1rQ1fa9uerB/JICJliuy+v3aicJ3GKcPdLboSbb9KZSSP VEBH9sqNIhxUdr4Pti+Q2ePcJvYyefvocoPqr5Sfus/7LwdkmoHuF+T/HyFTSEYdaHVG B6YDbvGhatzcHKOy8+2RxyhB88/9NYNNvxMNsRmFfIr5UNd8LvfsQi+XZDuSPWMFx9FB fXLQ== X-Gm-Message-State: AFqh2kqgbJtC8CCzPymLuyXC2hMdPqj2oiadfDgpaxqdj63S9C45qifq m7mFx7DUr225dVaM3hFbsW1jDKFUcmUGfyRE X-Google-Smtp-Source: AMrXdXtJWumIRJRp8olnrI+OY8Kf2nMC9KaCeQNJ5ZKYGHwerqzNeZbQ/QIxu05Ra+L7QqIXm/RN0g== X-Received: by 2002:a17:90a:3e46:b0:229:180a:a18c with SMTP id t6-20020a17090a3e4600b00229180aa18cmr8822966pjm.38.1674081918925; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id x11-20020a17090aa38b00b00226eadf094dsm1828559pjp.30.2023.01.18.14.45.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYO-RN for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFU-2k for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 37/42] xfs: factor out MRU hit case in xfs_filestream_select_ag Date: Thu, 19 Jan 2023 09:45:00 +1100 Message-Id: <20230118224505.1964941-38-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Because it now stands out like a sore thumb. Factoring out this case starts the process of simplifying xfs_filestream_select_ag() again. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 133 +++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 95e28aae35ab..147296a1079e 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -259,10 +259,85 @@ xfs_filestream_get_parent( return dir ? XFS_I(dir) : NULL; } +/* + * Lookup the mru cache for an existing association. If one exists and we can + * use it, return with the agno and blen indicating that the allocation will + * proceed with that association. + * + * If we have no association, or we cannot use the current one and have to + * destroy it, return with blen = 0 and agno pointing at the next agno to try. + */ +int +xfs_filestream_select_ag_mru( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + struct xfs_inode *pip, + xfs_agnumber_t *agno, + xfs_extlen_t *blen) +{ + struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_perag *pag; + struct xfs_mru_cache_elem *mru; + int error; + + mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); + if (!mru) + goto out_default_agno; + + *agno = container_of(mru, struct xfs_fstrm_item, mru)->ag; + xfs_mru_cache_done(mp->m_filestream); + + trace_xfs_filestream_lookup(mp, ap->ip->i_ino, *agno); + + ap->blkno = XFS_AGB_TO_FSB(args->mp, *agno, 0); + xfs_bmap_adjacent(ap); + + pag = xfs_perag_grab(mp, *agno); + if (!pag) + goto out_default_agno; + + error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + xfs_perag_rele(pag); + if (error) { + if (error != -EAGAIN) + return error; + *blen = 0; + } + + /* + * We are done if there's still enough contiguous free space to succeed. + */ + if (*blen >= args->maxlen) + return 0; + + /* Changing parent AG association now, so remove the existing one. */ + mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); + if (mru) { + struct xfs_fstrm_item *item = + container_of(mru, struct xfs_fstrm_item, mru); + *agno = (item->ag + 1) % mp->m_sb.sb_agcount; + xfs_fstrm_free_func(mp, mru); + return 0; + } + +out_default_agno: + if (xfs_is_inode32(mp)) { + xfs_agnumber_t rotorstep = xfs_rotorstep; + *agno = (mp->m_agfrotor / rotorstep) % + mp->m_sb.sb_agcount; + mp->m_agfrotor = (mp->m_agfrotor + 1) % + (mp->m_sb.sb_agcount * rotorstep); + return 0; + } + *agno = XFS_INO_TO_AGNO(mp, pip->i_ino); + return 0; + +} + /* * Search for an allocation group with a single extent large enough for - * the request. If one isn't found, then the largest available free extent is - * returned as the best length possible. + * the request. If one isn't found, then adjust the minimum allocation + * size to the largest space found. */ int xfs_filestream_select_ag( @@ -271,12 +346,10 @@ xfs_filestream_select_ag( xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_perag *pag; struct xfs_inode *pip = NULL; - xfs_agnumber_t agno = NULLAGNUMBER; - struct xfs_mru_cache_elem *mru; + xfs_agnumber_t agno; int flags = 0; - int error = 0; + int error; args->total = ap->total; *blen = 0; @@ -287,48 +360,10 @@ xfs_filestream_select_ag( goto out_select; } - mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); - if (mru) { - agno = container_of(mru, struct xfs_fstrm_item, mru)->ag; - xfs_mru_cache_done(mp->m_filestream); - mru = NULL; - - trace_xfs_filestream_lookup(mp, ap->ip->i_ino, agno); - xfs_irele(pip); - - ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); - xfs_bmap_adjacent(ap); - - pag = xfs_perag_grab(mp, agno); - if (pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); - if (error) { - if (error != -EAGAIN) - goto out_error; - *blen = 0; - } - } - if (*blen >= args->maxlen) - goto out_select; - } else if (xfs_is_inode32(mp)) { - xfs_agnumber_t rotorstep = xfs_rotorstep; - agno = (mp->m_agfrotor / rotorstep) % - mp->m_sb.sb_agcount; - mp->m_agfrotor = (mp->m_agfrotor + 1) % - (mp->m_sb.sb_agcount * rotorstep); - } else { - agno = XFS_INO_TO_AGNO(mp, pip->i_ino); - } + error = xfs_filestream_select_ag_mru(ap, args, pip, &agno, blen); + if (error || *blen >= args->maxlen) + goto out_rele; - /* Changing parent AG association now, so remove the existing one. */ - mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); - if (mru) { - struct xfs_fstrm_item *item = - container_of(mru, struct xfs_fstrm_item, mru); - agno = (item->ag + 1) % mp->m_sb.sb_agcount; - xfs_fstrm_free_func(mp, mru); - } ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); xfs_bmap_adjacent(ap); @@ -347,8 +382,6 @@ xfs_filestream_select_ag( *blen = ap->length; error = xfs_filestream_pick_ag(pip, &agno, flags, blen); - if (error) - goto out_error; if (agno == NULLAGNUMBER) { agno = 0; *blen = 0; @@ -356,7 +389,7 @@ xfs_filestream_select_ag( out_select: ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); -out_error: +out_rele: xfs_irele(pip); return error; From patchwork Wed Jan 18 22:45:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7878EC6379F for ; Wed, 18 Jan 2023 22:48:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229656AbjARWs2 (ORCPT ); Wed, 18 Jan 2023 17:48:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229709AbjARWsQ (ORCPT ); Wed, 18 Jan 2023 17:48:16 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3262D4CE40 for ; Wed, 18 Jan 2023 14:48:16 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id i65so157190pfc.0 for ; Wed, 18 Jan 2023 14:48:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=4MxGyrhzueH+GZD55kMB+bnwd+X72Zf+Opr0UX/i4ng=; b=tJJ033buIiOhGy1JV2jMGWJosWvvr+1hh5LXnjtRUqgT1X27+MNjMCwqpJEPrqQcmY 9ozf2TaARw5h6GDPOxrHthRCQmxlNZpI1zjm76gpUqrryCHwWUAgrAIUNiEjCq7B4oWU Ldgvc5SrKItUZjNC4izBtIEA9lRv2wrx8QTmAksu+oKPWP09DwGK5EVTccH+Tif4YKf2 HGozP4MeWIy/oj9N5Sg0UGfuXvZYVlxfX9eIeOYBeA2X44s10aVyRNd+xifu/1Y3gE8m oo2uODwHWPaqOMVohXXmkHVxPCz964rKKpQI7/iLSIRhXVOfr6yRYCgGlZ1iQ3NvpWt2 OqPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4MxGyrhzueH+GZD55kMB+bnwd+X72Zf+Opr0UX/i4ng=; b=1QrQs9KLijv+g/5CkgNha3glJKw8SJhtSz5LwvKEugSksJ9l4lfS/XhTMetWIzhbvr vFZutTBzaAUk3nW3IODiasrRWr1Y5n6lDRVSQ5kJ4IldXAbneWr20FLD4WJO3F2iISY3 HBcOTa6/OKnphcAhC8VdH58cyaEOR8be3U9DcJMMAdfs2eBhqw2Bhhz2BzjMkkG//pWD o1KGEbvXUGhAxOd+OPQJ2NCU+p+X7G+7mNWWCX/0p+E6Sk7VNGKX5n/WOAlqVYZHWOLM W6c8/f6qbUcGohyNg64y2zW4PjP6BCx1Bj2Y/Wj3Lcrnq5B7Cw/YAgoEUSYpdxnhKogS NEzQ== X-Gm-Message-State: AFqh2koyzRz6+9g12xGS6a2fO2WeoYY37u76NzVDt0E77STPcbibdKsA PA1ynqsje6r8bRWlMjp2rz90S0SwjXlVZWXP X-Google-Smtp-Source: AMrXdXtUPCWolxe+ilb5jtRRqGRHaWimlCOai+ya3ZqS6XwpK/TsiXvZaWm6r0FZDPZDH8SrE/EQ0A== X-Received: by 2002:a05:6a00:278d:b0:56b:f51d:820a with SMTP id bd13-20020a056a00278d00b0056bf51d820amr9141422pfb.7.1674082095652; Wed, 18 Jan 2023 14:48:15 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id w67-20020a628246000000b005892ea4f092sm18465643pfd.95.2023.01.18.14.48.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:15 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYQ-SF for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFZ-2p for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 38/42] xfs: track an active perag reference in filestreams Date: Thu, 19 Jan 2023 09:45:01 +1100 Message-Id: <20230118224505.1964941-39-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Rather than just track the agno of the reference, track a referenced perag pointer instead. This will allow active filestreams to prevent AGs from going away until the filestreams have been torn down. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 100 +++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 147296a1079e..c92429272ff7 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -23,7 +23,7 @@ struct xfs_fstrm_item { struct xfs_mru_cache_elem mru; - xfs_agnumber_t ag; /* AG in use for this directory */ + struct xfs_perag *pag; /* AG in use for this directory */ }; enum xfs_fstrm_alloc { @@ -50,43 +50,18 @@ xfs_filestream_peek_ag( return ret; } -static int -xfs_filestream_get_ag( - xfs_mount_t *mp, - xfs_agnumber_t agno) -{ - struct xfs_perag *pag; - int ret; - - pag = xfs_perag_get(mp, agno); - ret = atomic_inc_return(&pag->pagf_fstrms); - xfs_perag_put(pag); - return ret; -} - -static void -xfs_filestream_put_ag( - xfs_mount_t *mp, - xfs_agnumber_t agno) -{ - struct xfs_perag *pag; - - pag = xfs_perag_get(mp, agno); - atomic_dec(&pag->pagf_fstrms); - xfs_perag_put(pag); -} - static void xfs_fstrm_free_func( void *data, struct xfs_mru_cache_elem *mru) { - struct xfs_mount *mp = data; struct xfs_fstrm_item *item = container_of(mru, struct xfs_fstrm_item, mru); + struct xfs_perag *pag = item->pag; - xfs_filestream_put_ag(mp, item->ag); - trace_xfs_filestream_free(mp, mru->key, item->ag); + trace_xfs_filestream_free(pag->pag_mount, mru->key, pag->pag_agno); + atomic_dec(&pag->pagf_fstrms); + xfs_perag_rele(pag); kmem_free(item); } @@ -105,11 +80,11 @@ xfs_filestream_pick_ag( struct xfs_mount *mp = ip->i_mount; struct xfs_fstrm_item *item; struct xfs_perag *pag; + struct xfs_perag *max_pag = NULL; xfs_extlen_t minlen = *longest; xfs_extlen_t free = 0, minfree, maxfree = 0; xfs_agnumber_t startag = *agp; xfs_agnumber_t ag = startag; - xfs_agnumber_t max_ag = NULLAGNUMBER; int err, trylock, nscan; ASSERT(S_ISDIR(VFS_I(ip)->i_mode)); @@ -125,13 +100,16 @@ xfs_filestream_pick_ag( for (nscan = 0; 1; nscan++) { trace_xfs_filestream_scan(mp, ip->i_ino, ag); - pag = xfs_perag_get(mp, ag); + err = 0; + pag = xfs_perag_grab(mp, ag); + if (!pag) + goto next_ag; *longest = 0; err = xfs_bmap_longest_free_extent(pag, NULL, longest); if (err) { - xfs_perag_put(pag); + xfs_perag_rele(pag); if (err != -EAGAIN) - return err; + break; /* Couldn't lock the AGF, skip this AG. */ goto next_ag; } @@ -139,7 +117,10 @@ xfs_filestream_pick_ag( /* Keep track of the AG with the most free blocks. */ if (pag->pagf_freeblks > maxfree) { maxfree = pag->pagf_freeblks; - max_ag = ag; + if (max_pag) + xfs_perag_rele(max_pag); + atomic_inc(&pag->pag_active_ref); + max_pag = pag; } /* @@ -148,8 +129,9 @@ xfs_filestream_pick_ag( * loop, and it guards against two filestreams being established * in the same AG as each other. */ - if (xfs_filestream_get_ag(mp, ag) > 1) { - xfs_filestream_put_ag(mp, ag); + if (atomic_inc_return(&pag->pagf_fstrms) > 1) { + atomic_dec(&pag->pagf_fstrms); + xfs_perag_rele(pag); goto next_ag; } @@ -161,15 +143,12 @@ xfs_filestream_pick_ag( /* Break out, retaining the reference on the AG. */ free = pag->pagf_freeblks; - xfs_perag_put(pag); - *agp = ag; break; } /* Drop the reference on this AG, it's not usable. */ - xfs_filestream_put_ag(mp, ag); + atomic_dec(&pag->pagf_fstrms); next_ag: - xfs_perag_put(pag); /* Move to the next AG, wrapping to AG 0 if necessary. */ if (++ag >= mp->m_sb.sb_agcount) ag = 0; @@ -194,10 +173,10 @@ xfs_filestream_pick_ag( * Take the AG with the most free space, regardless of whether * it's already in use by another filestream. */ - if (max_ag != NULLAGNUMBER) { - xfs_filestream_get_ag(mp, max_ag); + if (max_pag) { + pag = max_pag; + atomic_inc(&pag->pagf_fstrms); free = maxfree; - *agp = max_ag; break; } @@ -207,17 +186,26 @@ xfs_filestream_pick_ag( return 0; } - trace_xfs_filestream_pick(ip, *agp, free, nscan); + trace_xfs_filestream_pick(ip, pag ? pag->pag_agno : NULLAGNUMBER, + free, nscan); - if (*agp == NULLAGNUMBER) + if (max_pag) + xfs_perag_rele(max_pag); + + if (err) + return err; + + if (!pag) { + *agp = NULLAGNUMBER; return 0; + } err = -ENOMEM; item = kmem_alloc(sizeof(*item), KM_MAYFAIL); if (!item) goto out_put_ag; - item->ag = *agp; + item->pag = pag; err = xfs_mru_cache_insert(mp->m_filestream, ip->i_ino, &item->mru); if (err) { @@ -226,12 +214,14 @@ xfs_filestream_pick_ag( goto out_free_item; } + *agp = pag->pag_agno; return 0; out_free_item: kmem_free(item); out_put_ag: - xfs_filestream_put_ag(mp, *agp); + atomic_dec(&pag->pagf_fstrms); + xfs_perag_rele(pag); return err; } @@ -284,20 +274,15 @@ xfs_filestream_select_ag_mru( if (!mru) goto out_default_agno; - *agno = container_of(mru, struct xfs_fstrm_item, mru)->ag; + pag = container_of(mru, struct xfs_fstrm_item, mru)->pag; xfs_mru_cache_done(mp->m_filestream); - trace_xfs_filestream_lookup(mp, ap->ip->i_ino, *agno); + trace_xfs_filestream_lookup(mp, ap->ip->i_ino, pag->pag_agno); - ap->blkno = XFS_AGB_TO_FSB(args->mp, *agno, 0); + ap->blkno = XFS_AGB_TO_FSB(args->mp, pag->pag_agno, 0); xfs_bmap_adjacent(ap); - pag = xfs_perag_grab(mp, *agno); - if (!pag) - goto out_default_agno; - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - xfs_perag_rele(pag); if (error) { if (error != -EAGAIN) return error; @@ -307,6 +292,7 @@ xfs_filestream_select_ag_mru( /* * We are done if there's still enough contiguous free space to succeed. */ + *agno = pag->pag_agno; if (*blen >= args->maxlen) return 0; @@ -315,7 +301,7 @@ xfs_filestream_select_ag_mru( if (mru) { struct xfs_fstrm_item *item = container_of(mru, struct xfs_fstrm_item, mru); - *agno = (item->ag + 1) % mp->m_sb.sb_agcount; + *agno = (item->pag->pag_agno + 1) % mp->m_sb.sb_agcount; xfs_fstrm_free_func(mp, mru); return 0; } From patchwork Wed Jan 18 22:45:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107158 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA8DCC32793 for ; Wed, 18 Jan 2023 22:48:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229723AbjARWs1 (ORCPT ); Wed, 18 Jan 2023 17:48:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229670AbjARWsT (ORCPT ); Wed, 18 Jan 2023 17:48:19 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5804663E33 for ; Wed, 18 Jan 2023 14:48:19 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id v10-20020a17090abb8a00b00229c517a6eeso3998855pjr.5 for ; Wed, 18 Jan 2023 14:48:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=YG+zdlmm5lAWh9En7pnzqioreUYArbEXxAUwZRDcMWA=; b=G214PVaWPqGTgDrvtTJpXglwV4HbrCkUDr4obxZ8L8cuy2sxkhc5xwIGq6YSWZ8MyO yZScpz4FMxGsSp8e+hp0XCItk1UFaI8LfCdBhpyIE2GgOkaTLQE5aW6HW8G3J2Q1y3PW /CdLAo4MNsyc+JBqF9tOpAlk4eeYgHE4kgh4kJL8VGlGw5+XgqB3cyc1er/xyo7mxJiR ScktfBleKNnjUlnjI+FRtXy0Dd49wXePhzFGgNSP5cNRW/RodJRccAcIzQ+WimuJcklR PeyN+6BAXHiQ7rVJh9/Ms2ffbat+WQj5Tco7c/fjHn1JETtmBlCBHvIXZ1UImDk0Vv5D EJIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YG+zdlmm5lAWh9En7pnzqioreUYArbEXxAUwZRDcMWA=; b=HeIUuY/PYthdcc/QMNEaIZuKSZ4/5y5yEjbQPtEVbsA5tiq/QRvbydYDorE+I/PLbr 5EqvrVMZjoe8DmA6+gb4G4erSmANd3L/FZ7XfFzGggB9Ws3HuSr/jHLvtEdevLJlR0JD Em5a5WF38GTHEMs/i7FoiG4qbvJ9rOxCsKV/mcLbPvMd6FUM+1Cy4mGYzaCCe848VPiu XGyUEPGgJruEoRzClMf2bawWg5ag0NB726wjCcUddG9xFUMPi4o2BUsJyfDiKHPxZYY6 3iGTwSQQbuoBMmsIRnlQI1lFqKK780tzCk9GAtmaoKnwJ2tTTzHbMjB7yMQ3D9HUBemq CA0Q== X-Gm-Message-State: AFqh2kpmpw8px1qTEdAbNbhUXwaqMvwKSy7/ABoU6PpWgGt4g+o9Ablp UAQ9uaj/opSixyzYaxBpzrP+m7p5T1C/4fVJ X-Google-Smtp-Source: AMrXdXsB4fNzCZy5WBWckfkU50Mh78VVeGFtU+Yx95vSysGcC3GTEGs8b0A2ktTjzasH7FCkKSp07Q== X-Received: by 2002:a17:90a:1305:b0:229:369f:fc89 with SMTP id h5-20020a17090a130500b00229369ffc89mr8549492pja.35.1674082098864; Wed, 18 Jan 2023 14:48:18 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id dw13-20020a17090b094d00b00226f49eca92sm1856952pjb.28.2023.01.18.14.48.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:18 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYT-TC for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFe-2v for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 39/42] xfs: use for_each_perag_wrap in xfs_filestream_pick_ag Date: Thu, 19 Jan 2023 09:45:02 +1100 Message-Id: <20230118224505.1964941-40-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner xfs_filestream_pick_ag() is now ready to rework to use for_each_perag_wrap() for iterating the perags during the AG selection scan. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 101 ++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 60 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index c92429272ff7..71fa44485a2f 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -83,9 +83,9 @@ xfs_filestream_pick_ag( struct xfs_perag *max_pag = NULL; xfs_extlen_t minlen = *longest; xfs_extlen_t free = 0, minfree, maxfree = 0; - xfs_agnumber_t startag = *agp; - xfs_agnumber_t ag = startag; - int err, trylock, nscan; + xfs_agnumber_t start_agno = *agp; + xfs_agnumber_t agno; + int err, trylock; ASSERT(S_ISDIR(VFS_I(ip)->i_mode)); @@ -97,13 +97,9 @@ xfs_filestream_pick_ag( /* For the first pass, don't sleep trying to init the per-AG. */ trylock = XFS_ALLOC_FLAG_TRYLOCK; - for (nscan = 0; 1; nscan++) { - trace_xfs_filestream_scan(mp, ip->i_ino, ag); - - err = 0; - pag = xfs_perag_grab(mp, ag); - if (!pag) - goto next_ag; +restart: + for_each_perag_wrap(mp, start_agno, agno, pag) { + trace_xfs_filestream_scan(mp, ip->i_ino, agno); *longest = 0; err = xfs_bmap_longest_free_extent(pag, NULL, longest); if (err) { @@ -111,6 +107,7 @@ xfs_filestream_pick_ag( if (err != -EAGAIN) break; /* Couldn't lock the AGF, skip this AG. */ + err = 0; goto next_ag; } @@ -129,77 +126,61 @@ xfs_filestream_pick_ag( * loop, and it guards against two filestreams being established * in the same AG as each other. */ - if (atomic_inc_return(&pag->pagf_fstrms) > 1) { - atomic_dec(&pag->pagf_fstrms); - xfs_perag_rele(pag); - goto next_ag; - } - - if (((minlen && *longest >= minlen) || - (!minlen && pag->pagf_freeblks >= minfree)) && - (!xfs_perag_prefers_metadata(pag) || - !(flags & XFS_PICK_USERDATA) || - (flags & XFS_PICK_LOWSPACE))) { - - /* Break out, retaining the reference on the AG. */ - free = pag->pagf_freeblks; - break; + if (atomic_inc_return(&pag->pagf_fstrms) <= 1) { + if (((minlen && *longest >= minlen) || + (!minlen && pag->pagf_freeblks >= minfree)) && + (!xfs_perag_prefers_metadata(pag) || + !(flags & XFS_PICK_USERDATA) || + (flags & XFS_PICK_LOWSPACE))) { + /* Break out, retaining the reference on the AG. */ + free = pag->pagf_freeblks; + break; + } } /* Drop the reference on this AG, it's not usable. */ atomic_dec(&pag->pagf_fstrms); -next_ag: - /* Move to the next AG, wrapping to AG 0 if necessary. */ - if (++ag >= mp->m_sb.sb_agcount) - ag = 0; + } - /* If a full pass of the AGs hasn't been done yet, continue. */ - if (ag != startag) - continue; + if (err) { + xfs_perag_rele(pag); + if (max_pag) + xfs_perag_rele(max_pag); + return err; + } + if (!pag) { /* Allow sleeping in xfs_alloc_read_agf() on the 2nd pass. */ - if (trylock != 0) { + if (trylock) { trylock = 0; - continue; + goto restart; } /* Finally, if lowspace wasn't set, set it for the 3rd pass. */ if (!(flags & XFS_PICK_LOWSPACE)) { flags |= XFS_PICK_LOWSPACE; - continue; + goto restart; } /* - * Take the AG with the most free space, regardless of whether - * it's already in use by another filestream. + * No unassociated AGs are available, so select the AG with the + * most free space, regardless of whether it's already in use by + * another filestream. It none suit, return NULLAGNUMBER. */ - if (max_pag) { - pag = max_pag; - atomic_inc(&pag->pagf_fstrms); - free = maxfree; - break; + if (!max_pag) { + *agp = NULLAGNUMBER; + trace_xfs_filestream_pick(ip, *agp, free, 0); + return 0; } - - /* take AG 0 if none matched */ - trace_xfs_filestream_pick(ip, *agp, free, nscan); - *agp = 0; - return 0; - } - - trace_xfs_filestream_pick(ip, pag ? pag->pag_agno : NULLAGNUMBER, - free, nscan); - - if (max_pag) + pag = max_pag; + free = maxfree; + atomic_inc(&pag->pagf_fstrms); + } else if (max_pag) { xfs_perag_rele(max_pag); - - if (err) - return err; - - if (!pag) { - *agp = NULLAGNUMBER; - return 0; } + trace_xfs_filestream_pick(ip, pag->pag_agno, free, 0); + err = -ENOMEM; item = kmem_alloc(sizeof(*item), KM_MAYFAIL); if (!item) From patchwork Wed Jan 18 22:45:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107140 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FA68C46467 for ; Wed, 18 Jan 2023 22:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229774AbjARWpd (ORCPT ); Wed, 18 Jan 2023 17:45:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229863AbjARWpT (ORCPT ); Wed, 18 Jan 2023 17:45:19 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C91B60499 for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id v10-20020a17090abb8a00b00229c517a6eeso3992813pjr.5 for ; Wed, 18 Jan 2023 14:45:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qKuAMvXfEBORE+u/OsZZ6eeRG6KY8kuRyA4fB77aCEc=; b=CDg5KRlfSPpd9I/N7oGoc+MrJiA4BoAxJyNhLKYMgB6s7BeWWt9Ao2fjNBx9Xngb9+ KOJe7xt7exVsJ2efsua6DjJJLLouZ5It5Z2pY/I+0htigBtEprOXfb0i8FhE8/6DZP99 ty5+uGTlBNQUYH1oMV6LQbyBNa3p/fJHekWE1PN5/5cWQ2KMxgL4AN4VZzR3LOUrWXzx 2dNGniOtTCv5tln1OsVoxd03+Hhl0oQHk8VBIT9jYHFvBodJ+mIvmLDNuy9ytixXLuvq dKUWlNHBs2JD280KEkqANJwOo3UNhHcfgnsUaW1p0V/M1NfUFKIUjwsWaacLeidlUjLK hWyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qKuAMvXfEBORE+u/OsZZ6eeRG6KY8kuRyA4fB77aCEc=; b=j0ZDq4nGlxHavLlJjAJ3DLr03gZu8leb9RWRm9Q0JbpZiQ28bYkvq/zjDKb9y2C9OJ THnioC4qpYpRBrwOLIFfVdVtndMbczAURglDZk047HvUq0vKwE8zH1syNYmscUt49kZg hCubu2H6xorNJUTVtvissHRLRaaWB2ywJUl9Due6aOGrL78bmDs6gGs8YRcrTmkVveM3 XuUTdOBjK8TwdILbUBbuKNsAmqzfc6k7tUcbD/Xiq8j9+NKfCTSWcHB59SAABN/kwWWd q4HscvMxCZKc+zyieoMVH6RaycB//564c+PzOY4HjnHgFKtnFle2Ss51TP5wbQpzSKjd 33bw== X-Gm-Message-State: AFqh2krgMPiHAHg7afngY1aS9ueSMrSFhW3JbUxFhrW0340YIEiYcKZp 1XPygEy4zT3R0PiuwtMjs9hCfBCBLPOYB6t7 X-Google-Smtp-Source: AMrXdXvD7stD/cvKJYd/yEBVOGGZkKb9B3l+ZVd7L/p1SLTSMTi/q+3wmBYiSCKHeP02Nwqr2XioPg== X-Received: by 2002:a05:6a20:6b91:b0:ac:21c3:2fb7 with SMTP id bu17-20020a056a206b9100b000ac21c32fb7mr26228812pzb.6.1674081917983; Wed, 18 Jan 2023 14:45:17 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id q9-20020a170902bd8900b001910b21fe90sm879892pls.210.2023.01.18.14.45.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:45:16 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYX-UB for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFj-31 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 40/42] xfs: pass perag to filestreams tracing Date: Thu, 19 Jan 2023 09:45:03 +1100 Message-Id: <20230118224505.1964941-41-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Pass perags instead of raw ag numbers, avoiding the need for the special peek function for the tracing code. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 29 +++++------------------------ fs/xfs/xfs_filestream.h | 1 - fs/xfs/xfs_trace.h | 37 ++++++++++++++++++++----------------- 3 files changed, 25 insertions(+), 42 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 71fa44485a2f..81aebe3e09ba 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -31,25 +31,6 @@ enum xfs_fstrm_alloc { XFS_PICK_LOWSPACE = 2, }; -/* - * Allocation group filestream associations are tracked with per-ag atomic - * counters. These counters allow xfs_filestream_pick_ag() to tell whether a - * particular AG already has active filestreams associated with it. - */ -int -xfs_filestream_peek_ag( - xfs_mount_t *mp, - xfs_agnumber_t agno) -{ - struct xfs_perag *pag; - int ret; - - pag = xfs_perag_get(mp, agno); - ret = atomic_read(&pag->pagf_fstrms); - xfs_perag_put(pag); - return ret; -} - static void xfs_fstrm_free_func( void *data, @@ -59,7 +40,7 @@ xfs_fstrm_free_func( container_of(mru, struct xfs_fstrm_item, mru); struct xfs_perag *pag = item->pag; - trace_xfs_filestream_free(pag->pag_mount, mru->key, pag->pag_agno); + trace_xfs_filestream_free(pag, mru->key); atomic_dec(&pag->pagf_fstrms); xfs_perag_rele(pag); @@ -99,7 +80,7 @@ xfs_filestream_pick_ag( restart: for_each_perag_wrap(mp, start_agno, agno, pag) { - trace_xfs_filestream_scan(mp, ip->i_ino, agno); + trace_xfs_filestream_scan(pag, ip->i_ino); *longest = 0; err = xfs_bmap_longest_free_extent(pag, NULL, longest); if (err) { @@ -169,7 +150,7 @@ xfs_filestream_pick_ag( */ if (!max_pag) { *agp = NULLAGNUMBER; - trace_xfs_filestream_pick(ip, *agp, free, 0); + trace_xfs_filestream_pick(ip, NULL, free); return 0; } pag = max_pag; @@ -179,7 +160,7 @@ xfs_filestream_pick_ag( xfs_perag_rele(max_pag); } - trace_xfs_filestream_pick(ip, pag->pag_agno, free, 0); + trace_xfs_filestream_pick(ip, pag, free); err = -ENOMEM; item = kmem_alloc(sizeof(*item), KM_MAYFAIL); @@ -258,7 +239,7 @@ xfs_filestream_select_ag_mru( pag = container_of(mru, struct xfs_fstrm_item, mru)->pag; xfs_mru_cache_done(mp->m_filestream); - trace_xfs_filestream_lookup(mp, ap->ip->i_ino, pag->pag_agno); + trace_xfs_filestream_lookup(pag, ap->ip->i_ino); ap->blkno = XFS_AGB_TO_FSB(args->mp, pag->pag_agno, 0); xfs_bmap_adjacent(ap); diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h index df9f7553e106..84149ed0e340 100644 --- a/fs/xfs/xfs_filestream.h +++ b/fs/xfs/xfs_filestream.h @@ -14,7 +14,6 @@ struct xfs_alloc_arg; int xfs_filestream_mount(struct xfs_mount *mp); void xfs_filestream_unmount(struct xfs_mount *mp); void xfs_filestream_deassociate(struct xfs_inode *ip); -int xfs_filestream_peek_ag(struct xfs_mount *mp, xfs_agnumber_t agno); int xfs_filestream_select_ag(struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 3b25b10fccc1..b5f7d225d5b4 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -74,6 +74,7 @@ struct xfs_inobt_rec_incore; union xfs_btree_ptr; struct xfs_dqtrx; struct xfs_icwalk; +struct xfs_perag; #define XFS_ATTR_FILTER_FLAGS \ { XFS_ATTR_ROOT, "ROOT" }, \ @@ -638,8 +639,8 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release); DEFINE_BUF_ITEM_EVENT(xfs_trans_binval); DECLARE_EVENT_CLASS(xfs_filestream_class, - TP_PROTO(struct xfs_mount *mp, xfs_ino_t ino, xfs_agnumber_t agno), - TP_ARGS(mp, ino, agno), + TP_PROTO(struct xfs_perag *pag, xfs_ino_t ino), + TP_ARGS(pag, ino), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) @@ -647,10 +648,10 @@ DECLARE_EVENT_CLASS(xfs_filestream_class, __field(int, streams) ), TP_fast_assign( - __entry->dev = mp->m_super->s_dev; + __entry->dev = pag->pag_mount->m_super->s_dev; __entry->ino = ino; - __entry->agno = agno; - __entry->streams = xfs_filestream_peek_ag(mp, agno); + __entry->agno = pag->pag_agno; + __entry->streams = atomic_read(&pag->pagf_fstrms); ), TP_printk("dev %d:%d ino 0x%llx agno 0x%x streams %d", MAJOR(__entry->dev), MINOR(__entry->dev), @@ -660,39 +661,41 @@ DECLARE_EVENT_CLASS(xfs_filestream_class, ) #define DEFINE_FILESTREAM_EVENT(name) \ DEFINE_EVENT(xfs_filestream_class, name, \ - TP_PROTO(struct xfs_mount *mp, xfs_ino_t ino, xfs_agnumber_t agno), \ - TP_ARGS(mp, ino, agno)) + TP_PROTO(struct xfs_perag *pag, xfs_ino_t ino), \ + TP_ARGS(pag, ino)) DEFINE_FILESTREAM_EVENT(xfs_filestream_free); DEFINE_FILESTREAM_EVENT(xfs_filestream_lookup); DEFINE_FILESTREAM_EVENT(xfs_filestream_scan); TRACE_EVENT(xfs_filestream_pick, - TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno, - xfs_extlen_t free, int nscan), - TP_ARGS(ip, agno, free, nscan), + TP_PROTO(struct xfs_inode *ip, struct xfs_perag *pag, + xfs_extlen_t free), + TP_ARGS(ip, pag, free), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) __field(xfs_agnumber_t, agno) __field(int, streams) __field(xfs_extlen_t, free) - __field(int, nscan) ), TP_fast_assign( __entry->dev = VFS_I(ip)->i_sb->s_dev; __entry->ino = ip->i_ino; - __entry->agno = agno; - __entry->streams = xfs_filestream_peek_ag(ip->i_mount, agno); + if (pag) { + __entry->agno = pag->pag_agno; + __entry->streams = atomic_read(&pag->pagf_fstrms); + } else { + __entry->agno = NULLAGNUMBER; + __entry->streams = 0; + } __entry->free = free; - __entry->nscan = nscan; ), - TP_printk("dev %d:%d ino 0x%llx agno 0x%x streams %d free %d nscan %d", + TP_printk("dev %d:%d ino 0x%llx agno 0x%x streams %d free %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, __entry->agno, __entry->streams, - __entry->free, - __entry->nscan) + __entry->free) ); DECLARE_EVENT_CLASS(xfs_lock_class, From patchwork Wed Jan 18 22:45:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107160 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8476C38147 for ; Wed, 18 Jan 2023 22:48:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229709AbjARWs3 (ORCPT ); Wed, 18 Jan 2023 17:48:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229900AbjARWsY (ORCPT ); Wed, 18 Jan 2023 17:48:24 -0500 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F11F15399A for ; Wed, 18 Jan 2023 14:48:22 -0800 (PST) Received: by mail-pl1-x631.google.com with SMTP id k13so632508plg.0 for ; Wed, 18 Jan 2023 14:48:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ezIOhhBHSVSN11A4M+HFNIDRMu+m9Sh8NwY5jIIUTmA=; b=gXYbCe3/vIfs2Skxdmzzy9QnTRwDkrZtSHCwpFKBg+atYe32mt5YFqUTNHYCdTLOGq 4+r06Tm3OQP/oAvJ7En+RB1PKT/UZ0PtRo8IxNHq6uxXaFiOvSuGJf+7/SNobqjOEgQp HLVwb+tprGokbiQzA+SsNysu/PwufUuvkjB/WT1pGRuFsObB9R82ZZvV+HnjKwcIw6+C UUa1oSTxBsQr0CfIoo6OfV2PhPWuLDpjwzTZNORxPnAyUGveCy8OkSKB1lUSpp8t3WSY LsR1VXX7eymWbeFJ4/g+7R0aD078aRBGz1LeUaSWw3qcRximIqn61qvtEtok4qmRoOuV zaug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ezIOhhBHSVSN11A4M+HFNIDRMu+m9Sh8NwY5jIIUTmA=; b=ax+ABJECvEWRY7dpath4EOuO73yJV6Mg4sKiQwG5lfoKXImb/msOfD9TmkEHzq0IFK ystJhZ43AAQ0aklMs07JhR3a2hI9ysDHEL78xOh3ucBYMOp3lK4BPyLwqhPY1K7UbkMC JvQZpJN0fo76LXU8dKFBsObfNnwPqHkJaTMDKGG3peYwVHCQIp73Esxudk5AwNOYdqGu KzPtH8aElVHBEeW8UF7xw+hyJqHFhKRjnxKLCkrdKvQEFEF1yu/VRAs/7hSddu6EFSMK 5mNymEnb7RgwYrOKIjYb6fFdvxCr1BDktgnoCn+TvTpEfv296iPMFJSzU/shnMj4e2VH ETgQ== X-Gm-Message-State: AFqh2kpzcTYFBCM5FZgFk656TQlRUqrKjgiO+04lR+sBVKuDVwmSrpPt 5AxHq20OtPmWb6mC0Iu43zCN8Qzn4L634Fo1 X-Google-Smtp-Source: AMrXdXsvMt0My6J3/jPQm+qM1jTd+Dejy4IBN939TbX9+YiBn4KFObTCFryonnP+BHvQcRMK+l4FhA== X-Received: by 2002:a05:6a21:3946:b0:b8:8153:50fc with SMTP id ac6-20020a056a21394600b000b8815350fcmr9033620pzc.41.1674082102379; Wed, 18 Jan 2023 14:48:22 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id q25-20020a631f59000000b004cffa8c0227sm2149163pgm.23.2023.01.18.14.48.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:21 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYZ-V1 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFo-37 for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 41/42] xfs: return a referenced perag from filestreams allocator Date: Thu, 19 Jan 2023 09:45:04 +1100 Message-Id: <20230118224505.1964941-42-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that the filestreams AG selection tracks active perags, we need to return an active perag to the core allocator code. This is because the file allocation the filestreams code will run are AG specific allocations and so need to pin the AG until the allocations complete. We cannot rely on the filestreams item reference to do this - the filestreams association can be torn down at any time, hence we need to have a separate reference for the allocation process to pin the AG after it has been selected. This means there is some perag juggling in allocation failure fallback paths as they will do all AG scans in the case the AG specific allocation fails. Hence we need to track the perag reference that the filestream allocator returned to make sure we don't leak it on repeated allocation failure. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 38 +++++++++++----- fs/xfs/xfs_filestream.c | 93 ++++++++++++++++++++++++---------------- 2 files changed, 84 insertions(+), 47 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 098b46f3f3e3..7f56002b545d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3427,6 +3427,7 @@ xfs_bmap_btalloc_at_eof( bool ag_only) { struct xfs_mount *mp = args->mp; + struct xfs_perag *caller_pag = args->pag; int error; /* @@ -3454,9 +3455,11 @@ xfs_bmap_btalloc_at_eof( else args->minalignslop = 0; - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + if (!caller_pag) + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); error = xfs_alloc_vextent_exact_bno(args, ap->blkno); - xfs_perag_put(args->pag); + if (!caller_pag) + xfs_perag_put(args->pag); if (error) return error; @@ -3482,10 +3485,13 @@ xfs_bmap_btalloc_at_eof( args->minalignslop = 0; } - if (ag_only) + if (ag_only) { error = xfs_alloc_vextent_near_bno(args, ap->blkno); - else + } else { + args->pag = NULL; error = xfs_alloc_vextent_start_ag(args, ap->blkno); + args->pag = caller_pag; + } if (error) return error; @@ -3544,12 +3550,13 @@ xfs_bmap_btalloc_filestreams( int stripe_align) { xfs_extlen_t blen = 0; - int error; + int error = 0; error = xfs_filestream_select_ag(ap, args, &blen); if (error) return error; + ASSERT(args->pag); /* * If we are in low space mode, then optimal allocation will fail so @@ -3558,22 +3565,31 @@ xfs_bmap_btalloc_filestreams( */ if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { args->minlen = ap->minlen; + ASSERT(args->fsbno == NULLFSBLOCK); goto out_low_space; } args->minlen = xfs_bmap_select_minlen(ap, args, blen); - if (ap->aeof) { + if (ap->aeof) error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, true); - if (error || args->fsbno != NULLFSBLOCK) - return error; - } - error = xfs_alloc_vextent_near_bno(args, ap->blkno); + if (!error && args->fsbno == NULLFSBLOCK) + error = xfs_alloc_vextent_near_bno(args, ap->blkno); + +out_low_space: + /* + * We are now done with the perag reference for the filestreams + * association provided by xfs_filestream_select_ag(). Release it now as + * we've either succeeded, had a fatal error or we are out of space and + * need to do a full filesystem scan for free space which will take it's + * own references. + */ + xfs_perag_rele(args->pag); + args->pag = NULL; if (error || args->fsbno != NULLFSBLOCK) return error; -out_low_space: return xfs_bmap_btalloc_low_space(ap, args); } diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 81aebe3e09ba..523a3b8b5754 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -53,8 +53,9 @@ xfs_fstrm_free_func( */ static int xfs_filestream_pick_ag( + struct xfs_alloc_arg *args, struct xfs_inode *ip, - xfs_agnumber_t *agp, + xfs_agnumber_t start_agno, int flags, xfs_extlen_t *longest) { @@ -64,7 +65,6 @@ xfs_filestream_pick_ag( struct xfs_perag *max_pag = NULL; xfs_extlen_t minlen = *longest; xfs_extlen_t free = 0, minfree, maxfree = 0; - xfs_agnumber_t start_agno = *agp; xfs_agnumber_t agno; int err, trylock; @@ -73,8 +73,6 @@ xfs_filestream_pick_ag( /* 2% of an AG's blocks must be free for it to be chosen. */ minfree = mp->m_sb.sb_agblocks / 50; - *agp = NULLAGNUMBER; - /* For the first pass, don't sleep trying to init the per-AG. */ trylock = XFS_ALLOC_FLAG_TRYLOCK; @@ -89,7 +87,7 @@ xfs_filestream_pick_ag( break; /* Couldn't lock the AGF, skip this AG. */ err = 0; - goto next_ag; + continue; } /* Keep track of the AG with the most free blocks. */ @@ -146,16 +144,19 @@ xfs_filestream_pick_ag( /* * No unassociated AGs are available, so select the AG with the * most free space, regardless of whether it's already in use by - * another filestream. It none suit, return NULLAGNUMBER. + * another filestream. It none suit, just use whatever AG we can + * grab. */ if (!max_pag) { - *agp = NULLAGNUMBER; - trace_xfs_filestream_pick(ip, NULL, free); - return 0; + for_each_perag_wrap(mp, start_agno, agno, pag) + break; + atomic_inc(&pag->pagf_fstrms); + *longest = 0; + } else { + pag = max_pag; + free = maxfree; + atomic_inc(&pag->pagf_fstrms); } - pag = max_pag; - free = maxfree; - atomic_inc(&pag->pagf_fstrms); } else if (max_pag) { xfs_perag_rele(max_pag); } @@ -167,16 +168,29 @@ xfs_filestream_pick_ag( if (!item) goto out_put_ag; + + /* + * We are going to use this perag now, so take another ref to it for the + * allocation context returned to the caller. If we raced to create and + * insert the filestreams item into the MRU (-EEXIST), then we still + * keep this reference but free the item reference we gained above. On + * any other failure, we have to drop both. + */ + atomic_inc(&pag->pag_active_ref); item->pag = pag; + args->pag = pag; err = xfs_mru_cache_insert(mp->m_filestream, ip->i_ino, &item->mru); if (err) { - if (err == -EEXIST) + if (err == -EEXIST) { err = 0; + } else { + xfs_perag_rele(args->pag); + args->pag = NULL; + } goto out_free_item; } - *agp = pag->pag_agno; return 0; out_free_item: @@ -236,7 +250,14 @@ xfs_filestream_select_ag_mru( if (!mru) goto out_default_agno; + /* + * Grab the pag and take an extra active reference for the caller whilst + * the mru item cannot go away. This means we'll pin the perag with + * the reference we get here even if the filestreams association is torn + * down immediately after we mark the lookup as done. + */ pag = container_of(mru, struct xfs_fstrm_item, mru)->pag; + atomic_inc(&pag->pag_active_ref); xfs_mru_cache_done(mp->m_filestream); trace_xfs_filestream_lookup(pag, ap->ip->i_ino); @@ -246,6 +267,8 @@ xfs_filestream_select_ag_mru( error = xfs_bmap_longest_free_extent(pag, args->tp, blen); if (error) { + /* We aren't going to use this perag */ + xfs_perag_rele(pag); if (error != -EAGAIN) return error; *blen = 0; @@ -253,12 +276,18 @@ xfs_filestream_select_ag_mru( /* * We are done if there's still enough contiguous free space to succeed. + * If there is very little free space before we start a filestreams + * allocation, we're almost guaranteed to fail to find a better AG with + * larger free space available so we don't even try. */ *agno = pag->pag_agno; - if (*blen >= args->maxlen) + if (*blen >= args->maxlen || (ap->tp->t_flags & XFS_TRANS_LOWMODE)) { + args->pag = pag; return 0; + } /* Changing parent AG association now, so remove the existing one. */ + xfs_perag_rele(pag); mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); if (mru) { struct xfs_fstrm_item *item = @@ -297,46 +326,38 @@ xfs_filestream_select_ag( struct xfs_inode *pip = NULL; xfs_agnumber_t agno; int flags = 0; - int error; + int error = 0; args->total = ap->total; *blen = 0; pip = xfs_filestream_get_parent(ap->ip); if (!pip) { - agno = 0; - goto out_select; + ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); + return 0; } error = xfs_filestream_select_ag_mru(ap, args, pip, &agno, blen); - if (error || *blen >= args->maxlen) + if (error) goto out_rele; - - ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); - xfs_bmap_adjacent(ap); - - /* - * If there is very little free space before we start a filestreams - * allocation, we're almost guaranteed to fail to find a better AG with - * larger free space available so we don't even try. - */ + if (*blen >= args->maxlen) + goto out_select; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) goto out_select; + ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); + xfs_bmap_adjacent(ap); + *blen = ap->length; if (ap->datatype & XFS_ALLOC_USERDATA) flags |= XFS_PICK_USERDATA; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) flags |= XFS_PICK_LOWSPACE; - *blen = ap->length; - error = xfs_filestream_pick_ag(pip, &agno, flags, blen); - if (agno == NULLAGNUMBER) { - agno = 0; - *blen = 0; - } - + error = xfs_filestream_pick_ag(args, pip, agno, flags, blen); + if (error) + goto out_rele; out_select: - ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); + ap->blkno = XFS_AGB_TO_FSB(mp, args->pag->pag_agno, 0); out_rele: xfs_irele(pip); return error; From patchwork Wed Jan 18 22:45:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13107161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EB35C38159 for ; Wed, 18 Jan 2023 22:48:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229523AbjARWs3 (ORCPT ); Wed, 18 Jan 2023 17:48:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229695AbjARWs1 (ORCPT ); Wed, 18 Jan 2023 17:48:27 -0500 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 515CA5356D for ; Wed, 18 Jan 2023 14:48:26 -0800 (PST) Received: by mail-pj1-x1033.google.com with SMTP id y3-20020a17090a390300b00229add7bb36so56468pjb.4 for ; Wed, 18 Jan 2023 14:48:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=oLtq/pkkHxJ61NS55A+sOQQ4qC0oC9hGVcJnVKTyry8=; b=QsxOjoGIofcFSljZafd0I7w+uZC781lgsRJ1VwIXudd1IKhFTpU6dbi/qGo6smUIHj GCZcw0fx9P86LzvCMxYWoLCB5P3piDahvMFGRZNjf/mZ1rLB9J59D13ltP39iLhxE64w KZmQWlh6s4Po8tYoz36yB1CqeCDfuKtOfFigX6gXV1Cwkf447pdJTeGKM31gsCGQxnhF bRD0SQpxEn682WOaHRkFCgxSdRL6r1LRiTkP1p9Rj6duZTmz2CfRDuZxErIlraGsPkOg LvoJ6e3T5YFWeiYsfW7T6Ua2cbd72x8v4yTrjIBh267RpWTeBoZMtz9ZvSWCcjsF738/ i6LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oLtq/pkkHxJ61NS55A+sOQQ4qC0oC9hGVcJnVKTyry8=; b=W92FnBdTecfKiHuvpviBIipbIdTwUBi69QYcuvQt6S/BQ1JNuXXtbytU31UX0C7p7o a81VTkR09pB03zvrssdDUvbtz3JokUT1CgFX00gFUjeh3avNoWfiAIza75bIkl+xT5TW WBjqsBLMLw9dZS7ZMeUPJ3jBbbqN5myGxIhudweRaFG3NMPCNIC3jdRqmcbnxZQVDKhT kOu/OcMAENKVIM3izowCNHF85fgzP0JHbWWxbBd2avb7Kzw6+l4iPoRGfsDQISsSAunb T1q7fA3caBk1KlZfCl8oXehEiSA9s3eOrd5XuOYMtxjqAda69YQYLoGjKlktsSCWjZTJ Aqsg== X-Gm-Message-State: AFqh2kpNZFzDdTtBc9u527XkO+RfJZUMSgptTf6LASvB3B+tlEfzVo4S ZqBSExYpgjqeBlfn/raKY1EJDrv3qpWPPp+7 X-Google-Smtp-Source: AMrXdXsfAkc0TLum429J6qSKfNv8wkihUmp8WiIjIXp4D8M8AF0dRbxfSGw/maHK03czAoRa+jPJag== X-Received: by 2002:a17:902:834c:b0:194:bea4:57d2 with SMTP id z12-20020a170902834c00b00194bea457d2mr2892718pln.46.1674082105656; Wed, 18 Jan 2023 14:48:25 -0800 (PST) Received: from dread.disaster.area (pa49-186-146-207.pa.vic.optusnet.com.au. [49.186.146.207]) by smtp.gmail.com with ESMTPSA id u2-20020a1709026e0200b001948d2ef5b4sm7222652plk.75.2023.01.18.14.48.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 14:48:25 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1pIHB9-004iYc-Vy for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:12 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.96) (envelope-from ) id 1pIHB9-008FFt-3C for linux-xfs@vger.kernel.org; Thu, 19 Jan 2023 09:45:11 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 42/42] xfs: refactor the filestreams allocator pick functions Date: Thu, 19 Jan 2023 09:45:05 +1100 Message-Id: <20230118224505.1964941-43-david@fromorbit.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230118224505.1964941-1-david@fromorbit.com> References: <20230118224505.1964941-1-david@fromorbit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Now that the filestreams allocator is largely rewritten, restructure the main entry point and pick function to seperate out the different operations cleanly. The MRU lookup function should not handle the start AG selection on MRU lookup failure, and nor should the pick function handle building the association that is inserted into the MRU. This leaves the filestreams allocator fairly clean and easy to understand, returning to the caller with an active perag reference and a target block to allocate at. Signed-off-by: Dave Chinner --- fs/xfs/xfs_filestream.c | 247 +++++++++++++++++++++------------------- fs/xfs/xfs_trace.h | 9 +- 2 files changed, 132 insertions(+), 124 deletions(-) diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 523a3b8b5754..0a1d316ebdba 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -48,19 +48,19 @@ xfs_fstrm_free_func( } /* - * Scan the AGs starting at startag looking for an AG that isn't in use and has - * at least minlen blocks free. + * Scan the AGs starting at start_agno looking for an AG that isn't in use and + * has at least minlen blocks free. If no AG is found to match the allocation + * requirements, pick the AG with the most free space in it. */ static int xfs_filestream_pick_ag( struct xfs_alloc_arg *args, - struct xfs_inode *ip, + xfs_ino_t pino, xfs_agnumber_t start_agno, int flags, xfs_extlen_t *longest) { - struct xfs_mount *mp = ip->i_mount; - struct xfs_fstrm_item *item; + struct xfs_mount *mp = args->mp; struct xfs_perag *pag; struct xfs_perag *max_pag = NULL; xfs_extlen_t minlen = *longest; @@ -68,8 +68,6 @@ xfs_filestream_pick_ag( xfs_agnumber_t agno; int err, trylock; - ASSERT(S_ISDIR(VFS_I(ip)->i_mode)); - /* 2% of an AG's blocks must be free for it to be chosen. */ minfree = mp->m_sb.sb_agblocks / 50; @@ -78,7 +76,7 @@ xfs_filestream_pick_ag( restart: for_each_perag_wrap(mp, start_agno, agno, pag) { - trace_xfs_filestream_scan(pag, ip->i_ino); + trace_xfs_filestream_scan(pag, pino); *longest = 0; err = xfs_bmap_longest_free_extent(pag, NULL, longest); if (err) { @@ -148,9 +146,9 @@ xfs_filestream_pick_ag( * grab. */ if (!max_pag) { - for_each_perag_wrap(mp, start_agno, agno, pag) + for_each_perag_wrap(args->mp, 0, start_agno, args->pag) break; - atomic_inc(&pag->pagf_fstrms); + atomic_inc(&args->pag->pagf_fstrms); *longest = 0; } else { pag = max_pag; @@ -161,44 +159,10 @@ xfs_filestream_pick_ag( xfs_perag_rele(max_pag); } - trace_xfs_filestream_pick(ip, pag, free); - - err = -ENOMEM; - item = kmem_alloc(sizeof(*item), KM_MAYFAIL); - if (!item) - goto out_put_ag; - - - /* - * We are going to use this perag now, so take another ref to it for the - * allocation context returned to the caller. If we raced to create and - * insert the filestreams item into the MRU (-EEXIST), then we still - * keep this reference but free the item reference we gained above. On - * any other failure, we have to drop both. - */ - atomic_inc(&pag->pag_active_ref); - item->pag = pag; + trace_xfs_filestream_pick(pag, pino, free); args->pag = pag; - - err = xfs_mru_cache_insert(mp->m_filestream, ip->i_ino, &item->mru); - if (err) { - if (err == -EEXIST) { - err = 0; - } else { - xfs_perag_rele(args->pag); - args->pag = NULL; - } - goto out_free_item; - } - return 0; -out_free_item: - kmem_free(item); -out_put_ag: - atomic_dec(&pag->pagf_fstrms); - xfs_perag_rele(pag); - return err; } static struct xfs_inode * @@ -227,29 +191,29 @@ xfs_filestream_get_parent( /* * Lookup the mru cache for an existing association. If one exists and we can - * use it, return with the agno and blen indicating that the allocation will - * proceed with that association. + * use it, return with an active perag reference indicating that the allocation + * will proceed with that association. * * If we have no association, or we cannot use the current one and have to - * destroy it, return with blen = 0 and agno pointing at the next agno to try. + * destroy it, return with longest = 0 to tell the caller to create a new + * association. */ -int -xfs_filestream_select_ag_mru( +static int +xfs_filestream_lookup_association( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, - struct xfs_inode *pip, - xfs_agnumber_t *agno, - xfs_extlen_t *blen) + xfs_ino_t pino, + xfs_extlen_t *longest) { - struct xfs_mount *mp = ap->ip->i_mount; + struct xfs_mount *mp = args->mp; struct xfs_perag *pag; struct xfs_mru_cache_elem *mru; - int error; + int error = 0; - mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino); + *longest = 0; + mru = xfs_mru_cache_lookup(mp->m_filestream, pino); if (!mru) - goto out_default_agno; - + return 0; /* * Grab the pag and take an extra active reference for the caller whilst * the mru item cannot go away. This means we'll pin the perag with @@ -265,103 +229,148 @@ xfs_filestream_select_ag_mru( ap->blkno = XFS_AGB_TO_FSB(args->mp, pag->pag_agno, 0); xfs_bmap_adjacent(ap); - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); - if (error) { - /* We aren't going to use this perag */ - xfs_perag_rele(pag); - if (error != -EAGAIN) - return error; - *blen = 0; - } - /* - * We are done if there's still enough contiguous free space to succeed. * If there is very little free space before we start a filestreams - * allocation, we're almost guaranteed to fail to find a better AG with - * larger free space available so we don't even try. + * allocation, we're almost guaranteed to fail to find a large enough + * free space available so just use the cached AG. */ - *agno = pag->pag_agno; - if (*blen >= args->maxlen || (ap->tp->t_flags & XFS_TRANS_LOWMODE)) { - args->pag = pag; - return 0; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + *longest = 1; + goto out_done; } + error = xfs_bmap_longest_free_extent(pag, args->tp, longest); + if (error == -EAGAIN) + error = 0; + if (error || *longest < args->maxlen) { + /* We aren't going to use this perag */ + *longest = 0; + xfs_perag_rele(pag); + return error; + } + +out_done: + args->pag = pag; + return 0; +} + +static int +xfs_filestream_create_association( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + xfs_ino_t pino, + xfs_extlen_t *longest) +{ + struct xfs_mount *mp = args->mp; + struct xfs_mru_cache_elem *mru; + struct xfs_fstrm_item *item; + xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, pino); + int flags = 0; + int error; + /* Changing parent AG association now, so remove the existing one. */ - xfs_perag_rele(pag); - mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino); + mru = xfs_mru_cache_remove(mp->m_filestream, pino); if (mru) { struct xfs_fstrm_item *item = container_of(mru, struct xfs_fstrm_item, mru); - *agno = (item->pag->pag_agno + 1) % mp->m_sb.sb_agcount; - xfs_fstrm_free_func(mp, mru); - return 0; - } -out_default_agno: - if (xfs_is_inode32(mp)) { + agno = (item->pag->pag_agno + 1) % mp->m_sb.sb_agcount; + xfs_fstrm_free_func(mp, mru); + } else if (xfs_is_inode32(mp)) { xfs_agnumber_t rotorstep = xfs_rotorstep; - *agno = (mp->m_agfrotor / rotorstep) % - mp->m_sb.sb_agcount; + + agno = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount; mp->m_agfrotor = (mp->m_agfrotor + 1) % (mp->m_sb.sb_agcount * rotorstep); - return 0; } - *agno = XFS_INO_TO_AGNO(mp, pip->i_ino); + + ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); + xfs_bmap_adjacent(ap); + + if (ap->datatype & XFS_ALLOC_USERDATA) + flags |= XFS_PICK_USERDATA; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) + flags |= XFS_PICK_LOWSPACE; + + *longest = ap->length; + error = xfs_filestream_pick_ag(args, pino, agno, flags, longest); + if (error) + return error; + + /* + * We are going to use this perag now, so create an assoication for it. + * xfs_filestream_pick_ag() has already bumped the perag fstrms counter + * for us, so all we need to do here is take another active reference to + * the perag for the cached association. + * + * If we fail to store the association, we need to drop the fstrms + * counter as well as drop the perag reference we take here for the + * item. We do not need to return an error for this failure - as long as + * we return a referenced AG, the allocation can still go ahead just + * fine. + */ + item = kmem_alloc(sizeof(*item), KM_MAYFAIL); + if (!item) + goto out_put_fstrms; + + atomic_inc(&args->pag->pag_active_ref); + item->pag = args->pag; + error = xfs_mru_cache_insert(mp->m_filestream, pino, &item->mru); + if (error) + goto out_free_item; return 0; +out_free_item: + xfs_perag_rele(item->pag); + kmem_free(item); +out_put_fstrms: + atomic_dec(&args->pag->pagf_fstrms); + return 0; } /* * Search for an allocation group with a single extent large enough for - * the request. If one isn't found, then adjust the minimum allocation - * size to the largest space found. + * the request. First we look for an existing association and use that if it + * is found. Otherwise, we create a new association by selecting an AG that fits + * the allocation criteria. + * + * We return with a referenced perag in args->pag to indicate which AG we are + * allocating into or an error with no references held. */ int xfs_filestream_select_ag( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, - xfs_extlen_t *blen) + xfs_extlen_t *longest) { - struct xfs_mount *mp = ap->ip->i_mount; - struct xfs_inode *pip = NULL; - xfs_agnumber_t agno; - int flags = 0; + struct xfs_mount *mp = args->mp; + struct xfs_inode *pip; + xfs_ino_t ino = 0; int error = 0; + *longest = 0; args->total = ap->total; - *blen = 0; - pip = xfs_filestream_get_parent(ap->ip); - if (!pip) { - ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); - return 0; + if (pip) { + ino = pip->i_ino; + error = xfs_filestream_lookup_association(ap, args, ino, + longest); + xfs_irele(pip); + if (error) + return error; + if (*longest >= args->maxlen) + goto out_select; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) + goto out_select; } - error = xfs_filestream_select_ag_mru(ap, args, pip, &agno, blen); + error = xfs_filestream_create_association(ap, args, ino, longest); if (error) - goto out_rele; - if (*blen >= args->maxlen) - goto out_select; - if (ap->tp->t_flags & XFS_TRANS_LOWMODE) - goto out_select; - - ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0); - xfs_bmap_adjacent(ap); - *blen = ap->length; - if (ap->datatype & XFS_ALLOC_USERDATA) - flags |= XFS_PICK_USERDATA; - if (ap->tp->t_flags & XFS_TRANS_LOWMODE) - flags |= XFS_PICK_LOWSPACE; + return error; - error = xfs_filestream_pick_ag(args, pip, agno, flags, blen); - if (error) - goto out_rele; out_select: ap->blkno = XFS_AGB_TO_FSB(mp, args->pag->pag_agno, 0); -out_rele: - xfs_irele(pip); - return error; - + return 0; } void diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index b5f7d225d5b4..1d3569c0d2fe 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -668,9 +668,8 @@ DEFINE_FILESTREAM_EVENT(xfs_filestream_lookup); DEFINE_FILESTREAM_EVENT(xfs_filestream_scan); TRACE_EVENT(xfs_filestream_pick, - TP_PROTO(struct xfs_inode *ip, struct xfs_perag *pag, - xfs_extlen_t free), - TP_ARGS(ip, pag, free), + TP_PROTO(struct xfs_perag *pag, xfs_ino_t ino, xfs_extlen_t free), + TP_ARGS(pag, ino, free), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) @@ -679,8 +678,8 @@ TRACE_EVENT(xfs_filestream_pick, __field(xfs_extlen_t, free) ), TP_fast_assign( - __entry->dev = VFS_I(ip)->i_sb->s_dev; - __entry->ino = ip->i_ino; + __entry->dev = pag->pag_mount->m_super->s_dev; + __entry->ino = ino; if (pag) { __entry->agno = pag->pag_agno; __entry->streams = atomic_read(&pag->pagf_fstrms);