From patchwork Fri Aug 23 00:14:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774414 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B1B14688 for ; Fri, 23 Aug 2024 00:14:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372095; cv=none; b=gunGmVBBAvLSxHjX37urBK5mPXxvUntVYRxE3iBAUNS+RuMt++ZhPQtsRoNxqcPgdEaSi49jl5/3WrF6hZWN+9rwo9MR6VlpNnYC7JaPa235MiSJBWV8JLMHIy2mjDimbK+TtI59obsy9yTJMTU0LPQVdWMv5lIr3mUnQ0KBEWg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372095; c=relaxed/simple; bh=JbF7w8/OyCN4RPnonSFZraZk9qjmU9jy6fCnYPU9aMQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eIOAbLG+AeuCZDERGWmyHKdzyT3Ii3IZicyEj+D2sBlXOEKxI2GzkegrY77QMPyjMuJaoWxuwwJOSp7PPdlIOsfzO5oySPkcgC0uvYy3Lsxk6cR5rSOMtS4bLyNS4UzAPW/9iz+JRST/2oazE9fIkzYNU3ycFBtiyieBGsoOMvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tPUiZVsl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tPUiZVsl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 764B9C32782; Fri, 23 Aug 2024 00:14:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372095; bh=JbF7w8/OyCN4RPnonSFZraZk9qjmU9jy6fCnYPU9aMQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=tPUiZVsl3aPNkDMdUgTYlzjsI3JC/paq1D3RaksUutjCDWn2e2rBqZK3h6VztTtb+ yiiFulmePLliBqzsW1MCRLCB0m6ruvqkpVLpPQ2UqHPqhbpjVbhzJnJKESofLAI7e3 AIGjvvG1PMGAbq/Lm3V009hR0trhuOWlvDl3zy5vmOfsfKoaOkRKqAJhasGDjfpJ0t W4bUVtEnsUYXqKyoLVD788jLNEVRgV8kKBGtdRX5Gxt1AD0f5Aa6RqS1+89r4lRZM6 7Se5M6nC6lMy8PGCtdi97vddSCqpunhQIObyGtnkvJqyKiESIJqL+CzGlYzPbgVUY7 d/Ga+2AKj6Ttg== Date: Thu, 22 Aug 2024 17:14:55 -0700 Subject: [PATCH 01/24] xfs: clean up the ISVALID macro in xfs_bmap_adjacent From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087261.59588.1337508214006211237.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Turn the ISVALID macro defined and used inside in xfs_bmap_adjacent that relies on implict context into a proper inline function. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 55 +++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 314fc7d55659a..3a8796f165d6d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3115,6 +3115,23 @@ xfs_bmap_extsize_align( return 0; } +static inline bool +xfs_bmap_adjacent_valid( + struct xfs_bmalloca *ap, + xfs_fsblock_t x, + xfs_fsblock_t y) +{ + struct xfs_mount *mp = ap->ip->i_mount; + + if (XFS_IS_REALTIME_INODE(ap->ip) && + (ap->datatype & XFS_ALLOC_USERDATA)) + return x < mp->m_sb.sb_rblocks; + + return XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && + XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && + XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks; +} + #define XFS_ALLOC_GAP_UNITS 4 /* returns true if ap->blkno was modified */ @@ -3122,36 +3139,25 @@ bool xfs_bmap_adjacent( struct xfs_bmalloca *ap) /* bmap alloc argument struct */ { - xfs_fsblock_t adjust; /* adjustment to block numbers */ - xfs_mount_t *mp; /* mount point structure */ - int rt; /* true if inode is realtime */ + xfs_fsblock_t adjust; /* adjustment to block numbers */ -#define ISVALID(x,y) \ - (rt ? \ - (x) < mp->m_sb.sb_rblocks : \ - XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ - XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ - XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) - - mp = ap->ip->i_mount; - rt = XFS_IS_REALTIME_INODE(ap->ip) && - (ap->datatype & XFS_ALLOC_USERDATA); /* * If allocating at eof, and there's a previous real block, * try to use its last block as our starting point. */ if (ap->eof && ap->prev.br_startoff != NULLFILEOFF && !isnullstartblock(ap->prev.br_startblock) && - ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount, - ap->prev.br_startblock)) { + xfs_bmap_adjacent_valid(ap, + ap->prev.br_startblock + ap->prev.br_blockcount, + ap->prev.br_startblock)) { ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount; /* * Adjust for the gap between prevp and us. */ adjust = ap->offset - (ap->prev.br_startoff + ap->prev.br_blockcount); - if (adjust && - ISVALID(ap->blkno + adjust, ap->prev.br_startblock)) + if (adjust && xfs_bmap_adjacent_valid(ap, ap->blkno + adjust, + ap->prev.br_startblock)) ap->blkno += adjust; return true; } @@ -3174,7 +3180,8 @@ xfs_bmap_adjacent( !isnullstartblock(ap->prev.br_startblock) && (prevbno = ap->prev.br_startblock + ap->prev.br_blockcount) && - ISVALID(prevbno, ap->prev.br_startblock)) { + xfs_bmap_adjacent_valid(ap, prevbno, + ap->prev.br_startblock)) { /* * Calculate gap to end of previous block. */ @@ -3190,8 +3197,8 @@ xfs_bmap_adjacent( * number, then just use the end of the previous block. */ if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length && - ISVALID(prevbno + prevdiff, - ap->prev.br_startblock)) + xfs_bmap_adjacent_valid(ap, prevbno + prevdiff, + ap->prev.br_startblock)) prevbno += adjust; else prevdiff += adjust; @@ -3223,9 +3230,11 @@ xfs_bmap_adjacent( * offset by our length. */ if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length && - ISVALID(gotbno - gotdiff, gotbno)) + xfs_bmap_adjacent_valid(ap, gotbno - gotdiff, + gotbno)) gotbno -= adjust; - else if (ISVALID(gotbno - ap->length, gotbno)) { + else if (xfs_bmap_adjacent_valid(ap, gotbno - ap->length, + gotbno)) { gotbno -= ap->length; gotdiff += adjust - ap->length; } else @@ -3253,7 +3262,7 @@ xfs_bmap_adjacent( return true; } } -#undef ISVALID + return false; } From patchwork Fri Aug 23 00:15:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774415 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E98F3C36 for ; Fri, 23 Aug 2024 00:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372111; cv=none; b=C+wMk8TIVJaMcuJc8Gx4Oj9KMBhrxtYH9HyBgLp9ja2HmeHNH0O3DoEvy3yCNeFVwfVFrqbRjKqu+eNr+L99ROyfNcQ/S+fn9DxdKVBsA19qarsulWi8zdTdIGWLCpO6InHPxuT4K9NtlDFRwoxPjdp/BS1WgYkSQ4CtnoHNLbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372111; c=relaxed/simple; bh=0r5KbjMoN50bbZqPU7uuimt3YP9bqe9hH7T890jwL1U=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J1dsVt4S32ERNn/LglECnHAKD49Sbvy23m8zglbsVGE6eobMWrQeAlddVw/ZN7r7BRkgeBwt1AWynb+US72QJaVb72BG7kQ2GX7YrCnynHWPY12NtJmdophBCECj545A9QIUavt3ssNn5c9Ru9+SsIkBh33RBK041d1DwgHk/aM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i9J60lGy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="i9J60lGy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 20DD1C32782; Fri, 23 Aug 2024 00:15:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372111; bh=0r5KbjMoN50bbZqPU7uuimt3YP9bqe9hH7T890jwL1U=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=i9J60lGyzBbDi59p5Rm9xdS/ZtqkzZD7An8cY9UNdqG3dEtmnbKM5Tsde+4VvTSbn jjYTsh9uP6ehgqIZvgXJymxFKW1gPuFi0e/QBQ9gKPDkUpExC/xVu1/nRK6tl1pIkS F0h4tMzGiW5qJXSMhryAQNuiaadHLqk1k0T73RSl1Spcq78EQnq7WVZ+iazTOzWM5t 9ZFR3pDsufx7b3w2KQzZHWtHFttoR5l1mVb+RpW6F1jf50pJMR5GBfL6+Y8lrjFKy5 WhXGd1L1UALnSzn2Qrlq1BU/7Rf804U3qRY7un9d0aR2qup9zCQaA+VEg4czWQyHog ZpWuyQQlrZNlg== Date: Thu, 22 Aug 2024 17:15:10 -0700 Subject: [PATCH 02/24] xfs: factor out a xfs_rtallocate helper From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087277.59588.1424560489617257464.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Split out a helper from xfs_rtallocate that performs the actual allocation. This keeps the scope of the xfs_rtalloc_args structure contained, and prepares for rtgroups support. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 81 +++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 4e7db8d4c0827..861a82471b5d0 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1269,6 +1269,51 @@ xfs_rtalloc_align_minmax( *raminlen = newminlen; } +static int +xfs_rtallocate( + struct xfs_trans *tp, + xfs_rtxnum_t start, + xfs_rtxlen_t minlen, + xfs_rtxlen_t maxlen, + xfs_rtxlen_t prod, + bool wasdel, + xfs_rtblock_t *bno, + xfs_extlen_t *blen) +{ + struct xfs_rtalloc_args args = { + .mp = tp->t_mountp, + .tp = tp, + }; + xfs_rtxnum_t rtx; + xfs_rtxlen_t len = 0; + int error; + + if (start) { + error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen, + &len, prod, &rtx); + } else { + error = xfs_rtallocate_extent_size(&args, minlen, maxlen, &len, + prod, &rtx); + } + + if (error) + goto out_release; + + error = xfs_rtallocate_range(&args, rtx, len); + if (error) + goto out_release; + + xfs_trans_mod_sb(tp, wasdel ? + XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, + -(long)len); + *bno = xfs_rtx_to_rtb(args.mp, rtx); + *blen = xfs_rtxlen_to_extlen(args.mp, len); + +out_release: + xfs_rtbuf_cache_relse(&args); + return error; +} + int xfs_bmap_rtalloc( struct xfs_bmalloca *ap) @@ -1276,7 +1321,6 @@ xfs_bmap_rtalloc( struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; xfs_rtxnum_t start; /* allocation hint rtextent no */ - xfs_rtxnum_t rtx; /* actually allocated rtextent no */ xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t mod = 0; /* product factor for allocators */ xfs_rtxlen_t ralen = 0; /* realtime allocation length */ @@ -1286,10 +1330,6 @@ xfs_bmap_rtalloc( xfs_rtxlen_t raminlen; bool rtlocked = false; bool ignore_locality = false; - struct xfs_rtalloc_args args = { - .mp = mp, - .tp = ap->tp, - }; int error; align = xfs_get_extsz_hint(ap->ip); @@ -1363,19 +1403,9 @@ xfs_bmap_rtalloc( xfs_rtalloc_align_minmax(&raminlen, &ralen, &prod); } - if (start) { - error = xfs_rtallocate_extent_near(&args, start, raminlen, - ralen, &ralen, prod, &rtx); - } else { - error = xfs_rtallocate_extent_size(&args, raminlen, - ralen, &ralen, prod, &rtx); - } - - if (error) { - xfs_rtbuf_cache_relse(&args); - if (error != -ENOSPC) - return error; - + error = xfs_rtallocate(ap->tp, start, raminlen, ralen, prod, ap->wasdel, + &ap->blkno, &ap->length); + if (error == -ENOSPC) { if (align > mp->m_sb.sb_rextsize) { /* * We previously enlarged the request length to try to @@ -1403,20 +1433,9 @@ xfs_bmap_rtalloc( ap->length = 0; return 0; } - - error = xfs_rtallocate_range(&args, rtx, ralen); if (error) - goto out_release; + return error; - xfs_trans_mod_sb(ap->tp, ap->wasdel ? - XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, - -(long)ralen); - - ap->blkno = xfs_rtx_to_rtb(mp, rtx); - ap->length = xfs_rtxlen_to_extlen(mp, ralen); xfs_bmap_alloc_account(ap); - -out_release: - xfs_rtbuf_cache_relse(&args); - return error; + return 0; } From patchwork Fri Aug 23 00:15:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774416 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E08C823A6 for ; Fri, 23 Aug 2024 00:15:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372127; cv=none; b=DM/8aBC+1iMTfG/4OYyrvJdpu+QZlgVWzW4l5IivaBUDXfxtOkYVQAduZafySn9kd/0KkVVTPtPKJmY0WcFL7nQIsVngAtxfXAT7KTkP3jWwH9ecvDUpH3+JetyEp5w3l/TbsPZWtBH0q+AwlbsuiRHXmw3CFoF/XoAO+TCMs/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372127; c=relaxed/simple; bh=2UfE5ccd+bJCJ4lIVqkQAC7na7/4gpuiHYMB2kSC524=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h4HVr3kitVG2aUNJh1nYQpWMCBEpWVlX9G7rx3doleIrXbvYDw6Lk7qdLqPjl5hdoHV7oDoUQr2ok0VSE4MQfk/8U/UwXgVWnbieBXwa2cp5WOYFgJ/PN0VqP+dL7EFrGkRK9XP87mpGKv4goLbKuyN2KnvNOD9VUua7avJnwtI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i4lF5O1w; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="i4lF5O1w" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B8BD9C32782; Fri, 23 Aug 2024 00:15:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372126; bh=2UfE5ccd+bJCJ4lIVqkQAC7na7/4gpuiHYMB2kSC524=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=i4lF5O1wasbxhcsetfD2Dw2G/iNjr28PnBIofQKLxIfptUyYWvNxrKphSP1cLdHdn ccLSVunl0qjdksBjYePOX5URMR4yrl58WjGcQo7iCmxw0PUaBf5JVvogki6XkRHWqg tXbQ6l/aOBXKkyCakQLCsPNnMmam/E6lFy1xq+IGjGM36I2e7PT7VJBok7ns9DhBuu RIeITPclkAvbf+lTE5MHI335MqIsXj6jdsRuuO7v4z7SbH7GCyIhluiBsNY1iasTGr v/0qleAfXx1n50c99n7q71sFSVu6EhidJgKjMvWkowpH8A50wXYFGKC1JUXFSF3AXv cM6DmIbUDBx6w== Date: Thu, 22 Aug 2024 17:15:26 -0700 Subject: [PATCH 03/24] xfs: rework the rtalloc fallback handling From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087294.59588.10330585198208756592.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig xfs_rtallocate currently has two fallbacks, when an allocation fails: 1) drop the requested extent size alignment, if any, and retry 2) ignore the locality hint Oddly enough it does those in order, as trying a different location is more in line with what the user asked for, and does it in a very unstructured way. Lift the fallback to try to allocate without the locality hint into xfs_rtallocate to both perform them in a more sensible order and to clean up the code. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 69 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 861a82471b5d0..f39f05397201a 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1277,6 +1277,8 @@ xfs_rtallocate( xfs_rtxlen_t maxlen, xfs_rtxlen_t prod, bool wasdel, + bool initial_user_data, + bool *rtlocked, xfs_rtblock_t *bno, xfs_extlen_t *blen) { @@ -1286,12 +1288,38 @@ xfs_rtallocate( }; xfs_rtxnum_t rtx; xfs_rtxlen_t len = 0; - int error; + int error = 0; + + /* + * Lock out modifications to both the RT bitmap and summary inodes. + */ + if (!*rtlocked) { + xfs_rtbitmap_lock(args.mp); + xfs_rtbitmap_trans_join(tp); + *rtlocked = true; + } + + /* + * For an allocation to an empty file at offset 0, pick an extent that + * will space things out in the rt area. + */ + if (!start && initial_user_data) + start = xfs_rtpick_extent(args.mp, tp, maxlen); if (start) { error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen, &len, prod, &rtx); - } else { + /* + * If we can't allocate near a specific rt extent, try again + * without locality criteria. + */ + if (error == -ENOSPC) { + xfs_rtbuf_cache_relse(&args); + error = 0; + } + } + + if (!error) { error = xfs_rtallocate_extent_size(&args, minlen, maxlen, &len, prod, &rtx); } @@ -1320,7 +1348,7 @@ xfs_bmap_rtalloc( { struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; - xfs_rtxnum_t start; /* allocation hint rtextent no */ + xfs_rtxnum_t start = 0; /* allocation hint rtextent no */ xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t mod = 0; /* product factor for allocators */ xfs_rtxlen_t ralen = 0; /* realtime allocation length */ @@ -1329,7 +1357,6 @@ xfs_bmap_rtalloc( xfs_extlen_t minlen = mp->m_sb.sb_rextsize; xfs_rtxlen_t raminlen; bool rtlocked = false; - bool ignore_locality = false; int error; align = xfs_get_extsz_hint(ap->ip); @@ -1367,28 +1394,8 @@ xfs_bmap_rtalloc( ASSERT(raminlen > 0); ASSERT(raminlen <= ralen); - /* - * Lock out modifications to both the RT bitmap and summary inodes - */ - if (!rtlocked) { - xfs_rtbitmap_lock(mp); - xfs_rtbitmap_trans_join(ap->tp); - rtlocked = true; - } - - if (ignore_locality) { - start = 0; - } else if (xfs_bmap_adjacent(ap)) { + if (xfs_bmap_adjacent(ap)) start = xfs_rtb_to_rtx(mp, ap->blkno); - } else if (ap->datatype & XFS_ALLOC_INITIAL_USER_DATA) { - /* - * If it's an allocation to an empty file at offset 0, pick an - * extent that will space things out in the rt area. - */ - start = xfs_rtpick_extent(mp, ap->tp, ralen); - } else { - start = 0; - } /* * Only bother calculating a real prod factor if offset & length are @@ -1404,7 +1411,8 @@ xfs_bmap_rtalloc( } error = xfs_rtallocate(ap->tp, start, raminlen, ralen, prod, ap->wasdel, - &ap->blkno, &ap->length); + ap->datatype & XFS_ALLOC_INITIAL_USER_DATA, &rtlocked, + &ap->blkno, &ap->length); if (error == -ENOSPC) { if (align > mp->m_sb.sb_rextsize) { /* @@ -1420,15 +1428,6 @@ xfs_bmap_rtalloc( goto retry; } - if (!ignore_locality && start != 0) { - /* - * If we can't allocate near a specific rt extent, try - * again without locality criteria. - */ - ignore_locality = true; - goto retry; - } - ap->blkno = NULLFSBLOCK; ap->length = 0; return 0; From patchwork Fri Aug 23 00:15:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774417 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EAF5BA46 for ; Fri, 23 Aug 2024 00:15:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372142; cv=none; b=Ybas4AKq2IPK+j+v3mOHgobauTVGHJhG6NYSqTT2RIsPXTKVG/v/T23F42IXt1r/l6FG8MLGqMcLwVsn3zjFXr0EGhO4MvB4fPfqH8gy+5oiGRao08q3aiVKsqpayp633krBUFN0AklcK+4AAKaC0Qm86xwiHXQGT4yMnrnepfo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372142; c=relaxed/simple; bh=Gweqe2aN+DAQAwGJx5MI6dQddJVJLULbkJil+45r5pA=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QIBhYvA30JSn1RQj34QE6DE2RDKmFzFCs1vnHHp3BR/9209GIGtza7/JWsq6E2lTqVH5ffMJtwaX7r1+abp2Zv1JH3kik6mkg8tJKwTEIjd3vY1Ggy46+I5Ethq5HIyC6NIny6PJdFhVYnylXO6FpP20oSm7MqxyATWnF1EHyC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pZa3eIiB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pZa3eIiB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6DC88C32782; Fri, 23 Aug 2024 00:15:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372142; bh=Gweqe2aN+DAQAwGJx5MI6dQddJVJLULbkJil+45r5pA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=pZa3eIiBCBNIhio/MB+ydZUNCnYguN1LX/ket1gCv79BbKvsBtJPvBXHOb3pyq+tV tYXeNr4gIg4nleVAcr8HW7bl2OWlnBe2LOckg3wp4KcjUNJ6KuGVszvMVFcR2JFytm i0JMDXBUmS3rDonROJSFxalC7lT1TH7xeFrpj4rZirfEX7/yMsL8ElgaPyETUk86LY oQiSOYNneYkzwTudF8oDpDiHWRB/vUF8vkgQKUhNFqlFhyCSed+9GNHdZH8S1R6zMh F9tapV2iNivznnhbwlYCwIpzxC7cFUfvBT7LaIslFwHn0pblNMJnFTU5Qo6bFxEoGA T4+xbQVOd8q0g== Date: Thu, 22 Aug 2024 17:15:41 -0700 Subject: [PATCH 04/24] xfs: factor out a xfs_rtallocate_align helper From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087312.59588.11806080366381184380.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Split the code to calculate the aligned allocation request from xfs_bmap_rtalloc into a separate self-contained helper. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 93 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index f39f05397201a..7f20bc412d074 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1342,30 +1342,33 @@ xfs_rtallocate( return error; } -int -xfs_bmap_rtalloc( - struct xfs_bmalloca *ap) +static int +xfs_rtallocate_align( + struct xfs_bmalloca *ap, + xfs_rtxlen_t *ralen, + xfs_rtxlen_t *raminlen, + xfs_rtxlen_t *prod, + bool *noalign) { struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; - xfs_rtxnum_t start = 0; /* allocation hint rtextent no */ - xfs_rtxlen_t prod = 0; /* product factor for allocators */ - xfs_extlen_t mod = 0; /* product factor for allocators */ - xfs_rtxlen_t ralen = 0; /* realtime allocation length */ - xfs_extlen_t align; /* minimum allocation alignment */ - xfs_extlen_t orig_length = ap->length; xfs_extlen_t minlen = mp->m_sb.sb_rextsize; - xfs_rtxlen_t raminlen; - bool rtlocked = false; + xfs_extlen_t align; /* minimum allocation alignment */ + xfs_extlen_t mod; /* product factor for allocators */ int error; - align = xfs_get_extsz_hint(ap->ip); - if (!align) - align = 1; -retry: - error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, - align, 1, ap->eof, 0, - ap->conv, &ap->offset, &ap->length); + if (*noalign) { + align = mp->m_sb.sb_rextsize; + } else { + align = xfs_get_extsz_hint(ap->ip); + if (!align) + align = 1; + if (align == mp->m_sb.sb_rextsize) + *noalign = true; + } + + error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 1, + ap->eof, 0, ap->conv, &ap->offset, &ap->length); if (error) return error; ASSERT(ap->length); @@ -1389,32 +1392,54 @@ xfs_bmap_rtalloc( * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ - ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); - raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); - ASSERT(raminlen > 0); - ASSERT(raminlen <= ralen); - - if (xfs_bmap_adjacent(ap)) - start = xfs_rtb_to_rtx(mp, ap->blkno); + *ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); + *raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); + ASSERT(*raminlen > 0); + ASSERT(*raminlen <= *ralen); /* * Only bother calculating a real prod factor if offset & length are * perfectly aligned, otherwise it will just get us in trouble. */ div_u64_rem(ap->offset, align, &mod); - if (mod || ap->length % align) { - prod = 1; - } else { - prod = xfs_extlen_to_rtxlen(mp, align); - if (prod > 1) - xfs_rtalloc_align_minmax(&raminlen, &ralen, &prod); - } + if (mod || ap->length % align) + *prod = 1; + else + *prod = xfs_extlen_to_rtxlen(mp, align); + + if (*prod > 1) + xfs_rtalloc_align_minmax(raminlen, ralen, prod); + return 0; +} + +int +xfs_bmap_rtalloc( + struct xfs_bmalloca *ap) +{ + struct xfs_mount *mp = ap->ip->i_mount; + xfs_fileoff_t orig_offset = ap->offset; + xfs_rtxnum_t start = 0; /* allocation hint rtextent no */ + xfs_rtxlen_t prod = 0; /* product factor for allocators */ + xfs_rtxlen_t ralen = 0; /* realtime allocation length */ + xfs_extlen_t orig_length = ap->length; + xfs_rtxlen_t raminlen; + bool rtlocked = false; + bool noalign = false; + int error; + +retry: + error = xfs_rtallocate_align(ap, &ralen, &raminlen, &prod, &noalign); + if (error) + return error; + + if (xfs_bmap_adjacent(ap)) + start = xfs_rtb_to_rtx(mp, ap->blkno); error = xfs_rtallocate(ap->tp, start, raminlen, ralen, prod, ap->wasdel, ap->datatype & XFS_ALLOC_INITIAL_USER_DATA, &rtlocked, &ap->blkno, &ap->length); if (error == -ENOSPC) { - if (align > mp->m_sb.sb_rextsize) { + if (!noalign) { /* * We previously enlarged the request length to try to * satisfy an extent size hint. The allocator didn't @@ -1424,7 +1449,7 @@ xfs_bmap_rtalloc( */ ap->offset = orig_offset; ap->length = orig_length; - minlen = align = mp->m_sb.sb_rextsize; + noalign = true; goto retry; } From patchwork Fri Aug 23 00:15:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774418 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C8DB4A02 for ; Fri, 23 Aug 2024 00:15:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372158; cv=none; b=KIGT5rqYk4bItUeZIOWPO026fARY26ZNoRibiMZQCV01TZ2CVh3VXw2cp0sK5AE47og8hjmkPy96AwzTrsic9qSAgaDkv7ogejGiEz30nQgGL8i/8LPLIGlspmUELCCM+sd8eSIj/WrdNCDhPdKRR5C7ySQzKTy3P51ocDzHIfI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372158; c=relaxed/simple; bh=Dm46UwKvKXTIXHdpZihW8yyTlFssf50cboLtFa1RD9Q=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FsSCU0XFtX+CVybtRTR4gVkxz/K1oW7ov7Jfx0/g7B/OC3O3SzZWlKxN5N6YAcd3Uc3Ik+k5HtBnFetZrTZSAPsH6OhHgR7R30Cqklqo0S/Yh1USItJHrP7lZXu46p76nVP5MfvILzDon6sRpV7DiZV94kh4ntx2c2nCb5ACnJA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RCn8M30L; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RCn8M30L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 110BBC32782; Fri, 23 Aug 2024 00:15:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372158; bh=Dm46UwKvKXTIXHdpZihW8yyTlFssf50cboLtFa1RD9Q=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=RCn8M30Liisj6hR+SN5GpX92gNjauZOsYwT4G+gbvxTjHATZx24IAYAQHdZ1MTp6V sokfXSPLdSPnv0fwildXrq1ctorF31umEi3kfQurJdjD8xPHOr6CNkUiJ9RM8F+EZ1 jqWRg962DyTpAAoGb2eXgK31pdk5++PS0qS0DKGOjbaYxyZ2hJGiBgg79pVFta1MP5 hF3pMsrtj9NFpjcJqhFwzJcFYqqzPhp85U3ugwIR0PqxQ0RfsZOrdJhAFDFB4ZIBVI QgTtpdG3wOr6xwl7WRmnH84Y6kh1Ft+aOPZAHA4EPlI3OAl2RTYjpOfREA0PN5HdP9 yRUA5xrLG2wUA== Date: Thu, 22 Aug 2024 17:15:57 -0700 Subject: [PATCH 05/24] xfs: make the rtalloc start hint a xfs_rtblock_t From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087329.59588.10885914516722982578.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig 0 is a valid start RT extent, and with pending changes it will become both more common and non-unique. Switch to pass a xfs_rtblock_t instead so that we can use NULLRTBLOCK to determine if a hint was set or not. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 7f20bc412d074..7854cd355311b 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1272,7 +1272,7 @@ xfs_rtalloc_align_minmax( static int xfs_rtallocate( struct xfs_trans *tp, - xfs_rtxnum_t start, + xfs_rtblock_t bno_hint, xfs_rtxlen_t minlen, xfs_rtxlen_t maxlen, xfs_rtxlen_t prod, @@ -1286,6 +1286,7 @@ xfs_rtallocate( .mp = tp->t_mountp, .tp = tp, }; + xfs_rtxnum_t start = 0; xfs_rtxnum_t rtx; xfs_rtxlen_t len = 0; int error = 0; @@ -1303,7 +1304,9 @@ xfs_rtallocate( * For an allocation to an empty file at offset 0, pick an extent that * will space things out in the rt area. */ - if (!start && initial_user_data) + if (bno_hint) + start = xfs_rtb_to_rtx(args.mp, bno_hint); + else if (initial_user_data) start = xfs_rtpick_extent(args.mp, tp, maxlen); if (start) { @@ -1416,15 +1419,16 @@ int xfs_bmap_rtalloc( struct xfs_bmalloca *ap) { - struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; - xfs_rtxnum_t start = 0; /* allocation hint rtextent no */ xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_rtxlen_t ralen = 0; /* realtime allocation length */ + xfs_rtblock_t bno_hint = NULLRTBLOCK; xfs_extlen_t orig_length = ap->length; xfs_rtxlen_t raminlen; bool rtlocked = false; bool noalign = false; + bool initial_user_data = + ap->datatype & XFS_ALLOC_INITIAL_USER_DATA; int error; retry: @@ -1433,10 +1437,10 @@ xfs_bmap_rtalloc( return error; if (xfs_bmap_adjacent(ap)) - start = xfs_rtb_to_rtx(mp, ap->blkno); + bno_hint = ap->blkno; - error = xfs_rtallocate(ap->tp, start, raminlen, ralen, prod, ap->wasdel, - ap->datatype & XFS_ALLOC_INITIAL_USER_DATA, &rtlocked, + error = xfs_rtallocate(ap->tp, bno_hint, raminlen, ralen, prod, + ap->wasdel, initial_user_data, &rtlocked, &ap->blkno, &ap->length); if (error == -ENOSPC) { if (!noalign) { From patchwork Fri Aug 23 00:16:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774419 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5751AD49 for ; Fri, 23 Aug 2024 00:16:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372173; cv=none; b=Fe+pUWoxthCFyBtitQlj83xgWYRR/2+z71WTE/1QhYyCLFNkdk5FKUvG8vrPSWOi2gFdTlOFXWRp/WZZ/OrKz8OSYdAP0cU7+Zj1s/OfDgiFqhF5f77hza35tpPRM6Fj9FnAlYrqha1ku28jkMKgCU2ksIgQHRdFBfYXVJwz+4Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372173; c=relaxed/simple; bh=GDcTW74R+eO2uTLKY0/lYmBr6EfW56QBA7mMFjRtfzU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BcjILwyoHiE0k2o8uOKADLD5CVJn46CHxTzCVdWHRaQddPuzasQDz/whwi2HlTd9jRz9GauOQBt3BpJWduBgICAMQZmz4jlrTvVDM3yccdV/LZ1oHu+1qqltXemC4QbnVGt4qKjbyoY+JA3aIOh07sc6JTpWBwxn9Wh8VhigGGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tTx+q1bk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tTx+q1bk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AED50C32782; Fri, 23 Aug 2024 00:16:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372173; bh=GDcTW74R+eO2uTLKY0/lYmBr6EfW56QBA7mMFjRtfzU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=tTx+q1bkgiHwHsCep/Kit0ur4EsJUkcyhufM1xzdiTiXkE8QPvLQXkUDSRxw/Wo61 rKrbxJsecYu/ftnp0jNT1x620io0CmFZFMJKxdB4yrsL0URsffsj0FXIHDDFYcYx8m ofDbRm+b3bZcG/YWLGs7wSasw+hLCeEBIwIfqXHaajL1KPnemPMYLWn71X374DnZnx ppBATw8O4saaJMbgSvtjd6rWyp1Gel0JshP8ZHTN8CGtnM9QRhWqGe0TzYEcwCnzgd vlohhujA/cbCvVZcXmzDAXlqJxAOk9xfWno67fUtO5n1CLSahjAZZVs0GbRJBd4K43 JDZG++U4YjMCQ== Date: Thu, 22 Aug 2024 17:16:13 -0700 Subject: [PATCH 06/24] xfs: add xchk_setup_nothing and xchk_nothing helpers From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087346.59588.5144524048217225071.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add common helpers for no-op scrubbing methods. Signed-off-by: Darrick J. Wong [hch: split from a larger patch] Signed-off-by: Christoph Hellwig Reviewed-by: Christoph Hellwig --- fs/xfs/scrub/common.h | 29 +++++++++-------------------- fs/xfs/scrub/scrub.h | 29 +++++++++-------------------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 96fe6ef5f4dc7..27e5bf8f7c60b 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -53,6 +53,11 @@ int xchk_checkpoint_log(struct xfs_mount *mp); bool xchk_should_check_xref(struct xfs_scrub *sc, int *error, struct xfs_btree_cur **curpp); +static inline int xchk_setup_nothing(struct xfs_scrub *sc) +{ + return -ENOENT; +} + /* Setup functions */ int xchk_setup_agheader(struct xfs_scrub *sc); int xchk_setup_fs(struct xfs_scrub *sc); @@ -73,16 +78,8 @@ int xchk_setup_metapath(struct xfs_scrub *sc); int xchk_setup_rtbitmap(struct xfs_scrub *sc); int xchk_setup_rtsummary(struct xfs_scrub *sc); #else -static inline int -xchk_setup_rtbitmap(struct xfs_scrub *sc) -{ - return -ENOENT; -} -static inline int -xchk_setup_rtsummary(struct xfs_scrub *sc) -{ - return -ENOENT; -} +# define xchk_setup_rtbitmap xchk_setup_nothing +# define xchk_setup_rtsummary xchk_setup_nothing #endif #ifdef CONFIG_XFS_QUOTA int xchk_ino_dqattach(struct xfs_scrub *sc); @@ -94,16 +91,8 @@ xchk_ino_dqattach(struct xfs_scrub *sc) { return 0; } -static inline int -xchk_setup_quota(struct xfs_scrub *sc) -{ - return -ENOENT; -} -static inline int -xchk_setup_quotacheck(struct xfs_scrub *sc) -{ - return -ENOENT; -} +# define xchk_setup_quota xchk_setup_nothing +# define xchk_setup_quotacheck xchk_setup_nothing #endif int xchk_setup_fscounters(struct xfs_scrub *sc); int xchk_setup_nlinks(struct xfs_scrub *sc); diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index ab143c7a531e8..c688ff4fc7fc4 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -232,6 +232,11 @@ xchk_should_terminate( return false; } +static inline int xchk_nothing(struct xfs_scrub *sc) +{ + return -ENOENT; +} + /* Metadata scrubbers */ int xchk_tester(struct xfs_scrub *sc); int xchk_superblock(struct xfs_scrub *sc); @@ -256,31 +261,15 @@ int xchk_metapath(struct xfs_scrub *sc); int xchk_rtbitmap(struct xfs_scrub *sc); int xchk_rtsummary(struct xfs_scrub *sc); #else -static inline int -xchk_rtbitmap(struct xfs_scrub *sc) -{ - return -ENOENT; -} -static inline int -xchk_rtsummary(struct xfs_scrub *sc) -{ - return -ENOENT; -} +# define xchk_rtbitmap xchk_nothing +# define xchk_rtsummary xchk_nothing #endif #ifdef CONFIG_XFS_QUOTA int xchk_quota(struct xfs_scrub *sc); int xchk_quotacheck(struct xfs_scrub *sc); #else -static inline int -xchk_quota(struct xfs_scrub *sc) -{ - return -ENOENT; -} -static inline int -xchk_quotacheck(struct xfs_scrub *sc) -{ - return -ENOENT; -} +# define xchk_quota xchk_nothing +# define xchk_quotacheck xchk_nothing #endif int xchk_fscounters(struct xfs_scrub *sc); int xchk_nlinks(struct xfs_scrub *sc); From patchwork Fri Aug 23 00:16:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774420 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83EFFB662 for ; Fri, 23 Aug 2024 00:16:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372189; cv=none; b=gGH7Hh8fXQl/+3FHcgS85CMjnGGekVDOrAHl3qbvDNnvdGDtQLaDmw8gVTngZ2U81fQHYBhFOHKCRzQxCK0bKaC3gkd3MbS+sB5N1fKzo1pvi0uZPrg2rtf+6Poj5RtPPjZJmRuLZFk4arMZVgsS48lARnQM5imCa8o+T5NAz48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372189; c=relaxed/simple; bh=CjoKqodlPqZh0BP2v2A2PbXkXVSDyNgI5r0LbN9nPBg=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CDwEOSwDeOQoEruO9o+tLBCYnQRKJ8MCp9nHMKWPC39FgxXFbQRSZ1pRQ2QXUmGO61YV6oqE+ZUw7epNVfL5w4cziVKLfFh81IgHWMoxkxCWbnxz9oMTiW8B5SKQQe3r3KK4zhGbhphFtrgcNguK3FUx6eeFs54t3atkhzblSHo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bJ28JFGP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bJ28JFGP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 62A9AC32782; Fri, 23 Aug 2024 00:16:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372189; bh=CjoKqodlPqZh0BP2v2A2PbXkXVSDyNgI5r0LbN9nPBg=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=bJ28JFGPqkAP+Zy9ESee6IkmEhOb+Uc+jyijaVA1XES82upv0Un6z/5SRAp5JCNlv 8a4P5I2MQv/dnsaNVtWMpUMPaHW6qYeXRE+XJLeC3hNhxC/lSfEhpZBsegYrvYw28c ef2C4SA1jb2LuJ125tXF21fLnqW+b/g6m3j445+6/3ZrzBI5PRwjhRey9QJYcqkOkI r+NyJnmgp9Q6awpca54maEzSCeovaAS+zsQKAFDpGqqTSWDxcjdUVpoZEbFTYzguZx lTZeXP9q7JIjeKZIkaW2DCLmp9XwX44h+wC/a1Bowp5LnBXJytfKR/NQGwm3qJm1w1 b9wTKwyus8GrQ== Date: Thu, 22 Aug 2024 17:16:28 -0700 Subject: [PATCH 07/24] xfs: remove xfs_{rtbitmap,rtsummary}_wordcount From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087363.59588.1958048546474059875.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig xfs_rtbitmap_wordcount and xfs_rtsummary_wordcount are currently unused, so remove them to simplify refactoring other rtbitmap helpers. They can be added back or simply open coded when actually needed. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtbitmap.c | 31 ------------------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 7 ------- 2 files changed, 38 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index c58eb75ef0fa0..76706e8bbc4ea 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1148,21 +1148,6 @@ xfs_rtbitmap_blockcount( return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); } -/* - * Compute the number of rtbitmap words needed to populate every block of a - * bitmap that is large enough to track the given number of rt extents. - */ -unsigned long long -xfs_rtbitmap_wordcount( - struct xfs_mount *mp, - xfs_rtbxlen_t rtextents) -{ - xfs_filblks_t blocks; - - blocks = xfs_rtbitmap_blockcount(mp, rtextents); - return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; -} - /* Compute the number of rtsummary blocks needed to track the given rt space. */ xfs_filblks_t xfs_rtsummary_blockcount( @@ -1176,22 +1161,6 @@ xfs_rtsummary_blockcount( return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); } -/* - * Compute the number of rtsummary info words needed to populate every block of - * a summary file that is large enough to track the given rt space. - */ -unsigned long long -xfs_rtsummary_wordcount( - struct xfs_mount *mp, - unsigned int rsumlevels, - xfs_extlen_t rbmblocks) -{ - xfs_filblks_t blocks; - - blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks); - return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; -} - /* Lock both realtime free space metadata inodes for a freespace update. */ void xfs_rtbitmap_lock( diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 0dbc9bb40668a..140513d1d6bcf 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -316,13 +316,8 @@ int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents); -unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, - xfs_rtbxlen_t rtextents); - xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, unsigned int rsumlevels, xfs_extlen_t rbmblocks); -unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, - unsigned int rsumlevels, xfs_extlen_t rbmblocks); int xfs_rtfile_initialize_blocks(struct xfs_inode *ip, xfs_fileoff_t offset_fsb, xfs_fileoff_t end_fsb, void *data); @@ -355,9 +350,7 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) /* shut up gcc */ return 0; } -# define xfs_rtbitmap_wordcount(mp, r) (0) # define xfs_rtsummary_blockcount(mp, l, b) (0) -# define xfs_rtsummary_wordcount(mp, l, b) (0) # define xfs_rtbitmap_lock(mp) do { } while (0) # define xfs_rtbitmap_trans_join(tp) do { } while (0) # define xfs_rtbitmap_unlock(mp) do { } while (0) From patchwork Fri Aug 23 00:16:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774423 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71806B653 for ; Fri, 23 Aug 2024 00:16:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372205; cv=none; b=D9auXHV762n5r54JOy5yP804eXzRDu1jQFuewB4Nb7wZn+SZAFy50jjzY1sgnko/g2scGgBKkJefFfKgvhbjNIMYUgkFMnbUAUf4W28NutEZpqepR/WN5pKPKRnfBdbAWr/Znm4Yb/rOyLrDNUNkrr9vgCYHKn60CJF/PTs1jBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372205; c=relaxed/simple; bh=ozA4EmSscf8tKuWueZ/FTlxMDe7YcyxIJ4VhbpEOcvQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XAkdUvAx401WtV0YeXk0gz6VjbZXLIb5fYulWHzMfEkvTjs/ndslKoXnDsNcsoqVdUTVRrbcqQRi29N1y5mGlAOmodppxSoKJ08mq4LugKH0/cHvQk3qk8EEs6gIA4DyzsCetFkdjWepeIGiaUItMlrFHA89E/o0grotaX2bHj4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pZOUj1Oq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pZOUj1Oq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 032FCC32782; Fri, 23 Aug 2024 00:16:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372205; bh=ozA4EmSscf8tKuWueZ/FTlxMDe7YcyxIJ4VhbpEOcvQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=pZOUj1OqvDjOBu5lw9eT0nvRzgQeX7KI39IHSb/bB/SYQGI9m4RjI+nXbWXjAHMuZ LBANA3Ki7DX/cAyv3kU0bALFTqxXMhrrJxbIpANNrWlvOyf8CQkl7qP27qLiXGK8hP +Q+f1IDGo3eR2hHAtM5WNzE7PSPpZFUFTHYil6UKpqKgUrzkCRIkk5XxDqOlNkEt4o HVvVoh2+LZM2nRusoovSg+7EY24GFZSEbEw2J+O7NSeCXWeRY67ZvPYtPMdrsn9fn5 8zZsqGsvmzgcIbyNJTfSioAok4mVGEQD/guTKH8631Oh6Giu2T+7j4WSuXnV1+dCxO 3z2Qi4NXtIAaQ== Date: Thu, 22 Aug 2024 17:16:44 -0700 Subject: [PATCH 08/24] xfs: replace m_rsumsize with m_rsumblocks From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087380.59588.7712029800357305412.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Track the RT summary file size in blocks, just like the RT bitmap file. While we have users of both units, blocks are used slightly more often and this matches the bitmap file for consistency. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtbitmap.c | 2 +- fs/xfs/libxfs/xfs_trans_resv.c | 2 +- fs/xfs/scrub/rtsummary.c | 11 +++++------ fs/xfs/scrub/rtsummary.h | 2 +- fs/xfs/scrub/rtsummary_repair.c | 12 +++++------- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_rtalloc.c | 13 +++++-------- 7 files changed, 19 insertions(+), 25 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 76706e8bbc4ea..27a4472402bac 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -162,7 +162,7 @@ xfs_rtsummary_read_buf( { struct xfs_mount *mp = args->mp; - if (XFS_IS_CORRUPT(mp, block >= XFS_B_TO_FSB(mp, mp->m_rsumsize))) { + if (XFS_IS_CORRUPT(mp, block >= mp->m_rsumblocks)) { xfs_rt_mark_sick(args->mp, XFS_SICK_RT_SUMMARY); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 45aaf169806aa..2e6d7bb3b5a2f 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -918,7 +918,7 @@ xfs_calc_growrtfree_reservation( return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + xfs_calc_inode_res(mp, 2) + xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) + - xfs_calc_buf_res(1, mp->m_rsumsize); + xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, mp->m_rsumblocks)); } /* diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 3fee603f52441..7c7366c98338b 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -63,7 +63,8 @@ xchk_setup_rtsummary( * us to avoid pinning kernel memory for this purpose. */ descr = xchk_xfile_descr(sc, "realtime summary file"); - error = xfile_create(descr, mp->m_rsumsize, &sc->xfile); + error = xfile_create(descr, XFS_FSB_TO_B(mp, mp->m_rsumblocks), + &sc->xfile); kfree(descr); if (error) return error; @@ -95,16 +96,14 @@ xchk_setup_rtsummary( * volume. Hence it is safe to compute and check the geometry values. */ if (mp->m_sb.sb_rblocks) { - xfs_filblks_t rsumblocks; int rextslog; rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); rextslog = xfs_compute_rextslog(rts->rextents); rts->rsumlevels = rextslog + 1; rts->rbmblocks = xfs_rtbitmap_blockcount(mp, rts->rextents); - rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, + rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, rts->rbmblocks); - rts->rsumsize = XFS_FSB_TO_B(mp, rsumblocks); } return 0; } @@ -316,7 +315,7 @@ xchk_rtsummary( } /* Is m_rsumsize correct? */ - if (mp->m_rsumsize != rts->rsumsize) { + if (mp->m_rsumblocks != rts->rsumblocks) { xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); goto out_rbm; } @@ -332,7 +331,7 @@ xchk_rtsummary( * growfsrt expands the summary file before updating sb_rextents, so * the file can be larger than rsumsize. */ - if (mp->m_rsumip->i_disk_size < rts->rsumsize) { + if (mp->m_rsumip->i_disk_size < XFS_FSB_TO_B(mp, rts->rsumblocks)) { xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); goto out_rbm; } diff --git a/fs/xfs/scrub/rtsummary.h b/fs/xfs/scrub/rtsummary.h index e1d50304d8d48..e44b04cb6e2d5 100644 --- a/fs/xfs/scrub/rtsummary.h +++ b/fs/xfs/scrub/rtsummary.h @@ -14,7 +14,7 @@ struct xchk_rtsummary { uint64_t rextents; uint64_t rbmblocks; - uint64_t rsumsize; + xfs_filblks_t rsumblocks; unsigned int rsumlevels; unsigned int resblks; diff --git a/fs/xfs/scrub/rtsummary_repair.c b/fs/xfs/scrub/rtsummary_repair.c index d9e971c4c79fb..7deeb948cb702 100644 --- a/fs/xfs/scrub/rtsummary_repair.c +++ b/fs/xfs/scrub/rtsummary_repair.c @@ -56,7 +56,7 @@ xrep_setup_rtsummary( * transaction (which we cannot drop because we cannot drop the * rtsummary ILOCK) and cannot ask for more reservation. */ - blocks = XFS_B_TO_FSB(mp, mp->m_rsumsize); + blocks = mp->m_rsumblocks; blocks += xfs_bmbt_calc_size(mp, blocks) * 2; if (blocks > UINT_MAX) return -EOPNOTSUPP; @@ -100,7 +100,6 @@ xrep_rtsummary( { struct xchk_rtsummary *rts = sc->buf; struct xfs_mount *mp = sc->mp; - xfs_filblks_t rsumblocks; int error; /* We require the rmapbt to rebuild anything. */ @@ -131,10 +130,9 @@ xrep_rtsummary( } /* Make sure we have space allocated for the entire summary file. */ - rsumblocks = XFS_B_TO_FSB(mp, rts->rsumsize); xfs_trans_ijoin(sc->tp, sc->ip, 0); xfs_trans_ijoin(sc->tp, sc->tempip, 0); - error = xrep_tempfile_prealloc(sc, 0, rsumblocks); + error = xrep_tempfile_prealloc(sc, 0, rts->rsumblocks); if (error) return error; @@ -143,11 +141,11 @@ xrep_rtsummary( return error; /* Copy the rtsummary file that we generated. */ - error = xrep_tempfile_copyin(sc, 0, rsumblocks, + error = xrep_tempfile_copyin(sc, 0, rts->rsumblocks, xrep_rtsummary_prep_buf, rts); if (error) return error; - error = xrep_tempfile_set_isize(sc, rts->rsumsize); + error = xrep_tempfile_set_isize(sc, XFS_FSB_TO_B(mp, rts->rsumblocks)); if (error) return error; @@ -168,7 +166,7 @@ xrep_rtsummary( memset(mp->m_rsum_cache, 0xFF, mp->m_sb.sb_rbmblocks); mp->m_rsumlevels = rts->rsumlevels; - mp->m_rsumsize = rts->rsumsize; + mp->m_rsumblocks = rts->rsumblocks; /* Free the old rtsummary blocks if they're not in use. */ return xrep_reap_ifork(sc, sc->tempip, XFS_DATA_FORK); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 6251ebced3062..9e883d2159fd9 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -148,7 +148,7 @@ typedef struct xfs_mount { int m_logbufs; /* number of log buffers */ int m_logbsize; /* size of each log buffer */ uint m_rsumlevels; /* rt summary levels */ - uint m_rsumsize; /* size of rt summary, bytes */ + xfs_filblks_t m_rsumblocks; /* size of rt summary, FSBs */ int m_fixedfsid[2]; /* unchanged for life of FS */ uint m_qflags; /* quota status flags */ uint64_t m_features; /* active filesystem features */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 7854cd355311b..46a920b192d19 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -736,9 +736,8 @@ xfs_growfs_rt_bmblock( nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; - nmp->m_rsumsize = XFS_FSB_TO_B(mp, - xfs_rtsummary_blockcount(mp, nmp->m_rsumlevels, - nmp->m_sb.sb_rbmblocks)); + nmp->m_rsumblocks = xfs_rtsummary_blockcount(mp, nmp->m_rsumlevels, + nmp->m_sb.sb_rbmblocks); /* * Recompute the growfsrt reservation from the new rsumsize, so that the @@ -768,7 +767,7 @@ xfs_growfs_rt_bmblock( * so that inode inactivation won't punch what it thinks are "posteof" * blocks. */ - rsumip->i_disk_size = nmp->m_rsumsize; + rsumip->i_disk_size = nmp->m_rsumblocks * nmp->m_sb.sb_blocksize; i_size_write(VFS_I(rsumip), rsumip->i_disk_size); xfs_trans_log_inode(args.tp, rsumip, XFS_ILOG_CORE); @@ -820,7 +819,7 @@ xfs_growfs_rt_bmblock( * Update the calculated values in the real mount structure. */ mp->m_rsumlevels = nmp->m_rsumlevels; - mp->m_rsumsize = nmp->m_rsumsize; + mp->m_rsumblocks = nmp->m_rsumblocks; xfs_mount_sb_set_rextsize(mp, &mp->m_sb); /* @@ -1024,7 +1023,6 @@ xfs_rtmount_init( struct xfs_buf *bp; /* buffer for last block of subvolume */ struct xfs_sb *sbp; /* filesystem superblock copy in mount */ xfs_daddr_t d; /* address of last block of subvolume */ - unsigned int rsumblocks; int error; sbp = &mp->m_sb; @@ -1036,9 +1034,8 @@ xfs_rtmount_init( return -ENODEV; } mp->m_rsumlevels = sbp->sb_rextslog + 1; - rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, + mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, mp->m_sb.sb_rbmblocks); - mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks); mp->m_rbmip = mp->m_rsumip = NULL; /* * Check that the realtime section is an ok size. From patchwork Fri Aug 23 00:17:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774424 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6DA9B653 for ; Fri, 23 Aug 2024 00:17:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372220; cv=none; b=jTwbl6DetbqKWBio41vrsTjKaHSYVYCXB0q9r5BOcfgN3qcVXT8uhtjF0uO4TTVjMe72nkh9/LqwbwBda4V/Uh/BdEt295Im+mHVAHL9QsWszdWvLOGsRWwOojeSV7VxlH5IjaEbCe6J/BBqdUyrosY4as1G+CNmLKvhft1L00s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372220; c=relaxed/simple; bh=lh4PLGHIBMu2AEkauptWL93Ks3QHDDPDP3i43Re1mzI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Lg4suA4KIzpDJrkNS9hgrHgkNEdEJ508e54g6w1QOrZPUS10ptaIdg2I7IgXByEeTtyHR+xShHX5ImY+Z66coj5bc7SarMgbf84rMAgKaYM9w8XhcYKnJTuG8HIlxfKEF7NNF82zaUoqp97BmYqp34KomvGeesQsOkmwoZx8Fs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jT1QbCkG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jT1QbCkG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9909FC32782; Fri, 23 Aug 2024 00:17:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372220; bh=lh4PLGHIBMu2AEkauptWL93Ks3QHDDPDP3i43Re1mzI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=jT1QbCkGiL85xt9KAvPCSC9BbwRtUBX2x9fcoIjoQ4L6V5csGbovp8aLJ0mHGppkr Z3ykBk/k1XVw6YHzc8+kI8CaHIfmEa1TY9jJ4rSnPHlbHLeySD5UzDwmBM7OmFwRQh tYmi9TB/KigFT0VkopGpS4huGB+lSRT6BKT+/tw7dDhuSvD9w5EI+/ZJnBoqW6On2t CzlRxSbcHt9qqFsIiXL1Y5ZptPKPyiAJbdfMvXJ8zTAuAHCQVPn+nIIB46Iu9k/Pi6 OOImmKnMm63w07BptEsnnimbbPXIhsTu57+91cSA1pBOxpoBF7qHFqOMTgdWqhyrpa AleEiZwzropVw== Date: Thu, 22 Aug 2024 17:17:00 -0700 Subject: [PATCH 09/24] xfs: rearrange xfs_fsmap.c a little bit From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087398.59588.6301556679404762421.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong The order of the functions in this file has gotten a little confusing over the years. Specifically, the two data device implementations (bnobt and rmapbt) could be adjacent in the source code instead of split in two by the logdev and rtdev fsmap implementations. We're about to add more functionality to this file, so rearrange things now. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_fsmap.c | 268 ++++++++++++++++++++++++++-------------------------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index e154466268757..615253406fde1 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -441,140 +441,6 @@ xfs_getfsmap_set_irec_flags( irec->rm_flags |= XFS_RMAP_UNWRITTEN; } -/* Execute a getfsmap query against the log device. */ -STATIC int -xfs_getfsmap_logdev( - struct xfs_trans *tp, - const struct xfs_fsmap *keys, - struct xfs_getfsmap_info *info) -{ - struct xfs_mount *mp = tp->t_mountp; - struct xfs_rmap_irec rmap; - xfs_daddr_t rec_daddr, len_daddr; - xfs_fsblock_t start_fsb, end_fsb; - uint64_t eofs; - - eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); - if (keys[0].fmr_physical >= eofs) - return 0; - start_fsb = XFS_BB_TO_FSBT(mp, - keys[0].fmr_physical + keys[0].fmr_length); - end_fsb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); - - /* Adjust the low key if we are continuing from where we left off. */ - if (keys[0].fmr_length > 0) - info->low_daddr = XFS_FSB_TO_BB(mp, start_fsb); - - trace_xfs_fsmap_low_key_linear(mp, info->dev, start_fsb); - trace_xfs_fsmap_high_key_linear(mp, info->dev, end_fsb); - - if (start_fsb > 0) - return 0; - - /* Fabricate an rmap entry for the external log device. */ - rmap.rm_startblock = 0; - rmap.rm_blockcount = mp->m_sb.sb_logblocks; - rmap.rm_owner = XFS_RMAP_OWN_LOG; - rmap.rm_offset = 0; - rmap.rm_flags = 0; - - rec_daddr = XFS_FSB_TO_BB(mp, rmap.rm_startblock); - len_daddr = XFS_FSB_TO_BB(mp, rmap.rm_blockcount); - return xfs_getfsmap_helper(tp, info, &rmap, rec_daddr, len_daddr); -} - -#ifdef CONFIG_XFS_RT -/* Transform a rtbitmap "record" into a fsmap */ -STATIC int -xfs_getfsmap_rtdev_rtbitmap_helper( - struct xfs_mount *mp, - struct xfs_trans *tp, - const struct xfs_rtalloc_rec *rec, - void *priv) -{ - struct xfs_getfsmap_info *info = priv; - struct xfs_rmap_irec irec; - xfs_rtblock_t rtbno; - xfs_daddr_t rec_daddr, len_daddr; - - rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); - rec_daddr = XFS_FSB_TO_BB(mp, rtbno); - irec.rm_startblock = rtbno; - - rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); - len_daddr = XFS_FSB_TO_BB(mp, rtbno); - irec.rm_blockcount = rtbno; - - irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ - irec.rm_offset = 0; - irec.rm_flags = 0; - - return xfs_getfsmap_helper(tp, info, &irec, rec_daddr, len_daddr); -} - -/* Execute a getfsmap query against the realtime device rtbitmap. */ -STATIC int -xfs_getfsmap_rtdev_rtbitmap( - struct xfs_trans *tp, - const struct xfs_fsmap *keys, - struct xfs_getfsmap_info *info) -{ - - struct xfs_rtalloc_rec ahigh = { 0 }; - struct xfs_mount *mp = tp->t_mountp; - xfs_rtblock_t start_rtb; - xfs_rtblock_t end_rtb; - xfs_rtxnum_t high; - uint64_t eofs; - int error; - - eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); - if (keys[0].fmr_physical >= eofs) - return 0; - start_rtb = XFS_BB_TO_FSBT(mp, - keys[0].fmr_physical + keys[0].fmr_length); - end_rtb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); - - info->missing_owner = XFS_FMR_OWN_UNKNOWN; - - /* Adjust the low key if we are continuing from where we left off. */ - if (keys[0].fmr_length > 0) { - info->low_daddr = XFS_FSB_TO_BB(mp, start_rtb); - if (info->low_daddr >= eofs) - return 0; - } - - trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb); - trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb); - - xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); - - /* - * Set up query parameters to return free rtextents covering the range - * we want. - */ - high = xfs_rtb_to_rtxup(mp, end_rtb); - error = xfs_rtalloc_query_range(mp, tp, xfs_rtb_to_rtx(mp, start_rtb), - high, xfs_getfsmap_rtdev_rtbitmap_helper, info); - if (error) - goto err; - - /* - * Report any gaps at the end of the rtbitmap by simulating a null - * rmap starting at the block after the end of the query range. - */ - info->last = true; - ahigh.ar_startext = min(mp->m_sb.sb_rextents, high); - - error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, tp, &ahigh, info); - if (error) - goto err; -err: - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); - return error; -} -#endif /* CONFIG_XFS_RT */ - static inline bool rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r) { @@ -799,6 +665,140 @@ xfs_getfsmap_datadev_bnobt( xfs_getfsmap_datadev_bnobt_query, &akeys[0]); } +/* Execute a getfsmap query against the log device. */ +STATIC int +xfs_getfsmap_logdev( + struct xfs_trans *tp, + const struct xfs_fsmap *keys, + struct xfs_getfsmap_info *info) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_rmap_irec rmap; + xfs_daddr_t rec_daddr, len_daddr; + xfs_fsblock_t start_fsb, end_fsb; + uint64_t eofs; + + eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + if (keys[0].fmr_physical >= eofs) + return 0; + start_fsb = XFS_BB_TO_FSBT(mp, + keys[0].fmr_physical + keys[0].fmr_length); + end_fsb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); + + /* Adjust the low key if we are continuing from where we left off. */ + if (keys[0].fmr_length > 0) + info->low_daddr = XFS_FSB_TO_BB(mp, start_fsb); + + trace_xfs_fsmap_low_key_linear(mp, info->dev, start_fsb); + trace_xfs_fsmap_high_key_linear(mp, info->dev, end_fsb); + + if (start_fsb > 0) + return 0; + + /* Fabricate an rmap entry for the external log device. */ + rmap.rm_startblock = 0; + rmap.rm_blockcount = mp->m_sb.sb_logblocks; + rmap.rm_owner = XFS_RMAP_OWN_LOG; + rmap.rm_offset = 0; + rmap.rm_flags = 0; + + rec_daddr = XFS_FSB_TO_BB(mp, rmap.rm_startblock); + len_daddr = XFS_FSB_TO_BB(mp, rmap.rm_blockcount); + return xfs_getfsmap_helper(tp, info, &rmap, rec_daddr, len_daddr); +} + +#ifdef CONFIG_XFS_RT +/* Transform a rtbitmap "record" into a fsmap */ +STATIC int +xfs_getfsmap_rtdev_rtbitmap_helper( + struct xfs_mount *mp, + struct xfs_trans *tp, + const struct xfs_rtalloc_rec *rec, + void *priv) +{ + struct xfs_getfsmap_info *info = priv; + struct xfs_rmap_irec irec; + xfs_rtblock_t rtbno; + xfs_daddr_t rec_daddr, len_daddr; + + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); + rec_daddr = XFS_FSB_TO_BB(mp, rtbno); + irec.rm_startblock = rtbno; + + rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); + len_daddr = XFS_FSB_TO_BB(mp, rtbno); + irec.rm_blockcount = rtbno; + + irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ + irec.rm_offset = 0; + irec.rm_flags = 0; + + return xfs_getfsmap_helper(tp, info, &irec, rec_daddr, len_daddr); +} + +/* Execute a getfsmap query against the realtime device rtbitmap. */ +STATIC int +xfs_getfsmap_rtdev_rtbitmap( + struct xfs_trans *tp, + const struct xfs_fsmap *keys, + struct xfs_getfsmap_info *info) +{ + + struct xfs_rtalloc_rec ahigh = { 0 }; + struct xfs_mount *mp = tp->t_mountp; + xfs_rtblock_t start_rtb; + xfs_rtblock_t end_rtb; + xfs_rtxnum_t high; + uint64_t eofs; + int error; + + eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); + if (keys[0].fmr_physical >= eofs) + return 0; + start_rtb = XFS_BB_TO_FSBT(mp, + keys[0].fmr_physical + keys[0].fmr_length); + end_rtb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); + + info->missing_owner = XFS_FMR_OWN_UNKNOWN; + + /* Adjust the low key if we are continuing from where we left off. */ + if (keys[0].fmr_length > 0) { + info->low_daddr = XFS_FSB_TO_BB(mp, start_rtb); + if (info->low_daddr >= eofs) + return 0; + } + + trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb); + trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb); + + xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); + + /* + * Set up query parameters to return free rtextents covering the range + * we want. + */ + high = xfs_rtb_to_rtxup(mp, end_rtb); + error = xfs_rtalloc_query_range(mp, tp, xfs_rtb_to_rtx(mp, start_rtb), + high, xfs_getfsmap_rtdev_rtbitmap_helper, info); + if (error) + goto err; + + /* + * Report any gaps at the end of the rtbitmap by simulating a null + * rmap starting at the block after the end of the query range. + */ + info->last = true; + ahigh.ar_startext = min(mp->m_sb.sb_rextents, high); + + error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, tp, &ahigh, info); + if (error) + goto err; +err: + xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); + return error; +} +#endif /* CONFIG_XFS_RT */ + /* Do we recognize the device? */ STATIC bool xfs_getfsmap_is_valid_device( From patchwork Fri Aug 23 00:17:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774425 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E114B653 for ; Fri, 23 Aug 2024 00:17:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372236; cv=none; b=KZijqsHLZesHo+bJdbNfjyZ+xjd7FGxamVmDYYFXG31It4odPpXYmMTQYp9o2R04oSh/EbcvefEG+kKGw7/CujJOslf4L/rfWc9tTGrvPanpuWX68yzVtGCsBrjijHFDmX3IG6rQFXvs0KZfKGz06UVhbu8K0wZe78wJaW2z0Gw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372236; c=relaxed/simple; bh=W/y3KxVD8ILShj7mNzn100m/2uBdtfqtMKl9cG+WcSo=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tsnQACuEGiCy9MS0O8/UHA9ipn2oDbOkk1huwUbXJDsTrkQ6Z1q9aDBAk+OJWN1QhXoF2KyVW0adSGSye6QO8jxGzw8q+yCKgi3gfXC8vC0mP8SaHV6IHRU/xrhjyRusv5dKRD6zuNgL53S4TaYWxtoouED2sLMvMAhrPG2KuBg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=igVu4el5; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="igVu4el5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 393A4C32782; Fri, 23 Aug 2024 00:17:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372236; bh=W/y3KxVD8ILShj7mNzn100m/2uBdtfqtMKl9cG+WcSo=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=igVu4el5pl4+rnfr7SbOWlT8b+h+pnEf9cB1ckUTnlJFY7sNQUw/jkkoLPvL6XOMw xa3eUTcWDzjtGXciqqOGR/SBIIrUjrvvQe7MHViFPuluBkBaG8AhB8owE8gigWCJu1 IBBFgkTeH4t29THiqC25w1hYGzlXoaWwsqmokF7a0lT47yFNLQMlSyMEBLLGYZiYBq NWTK4a7OT43M4hztqCTjT04L2kcXXrOy7bEF/x+XB0zcr07M6Gf62rk9nwVnVnCWVZ BBYdrII4R2XEGuxRL48wTZeBiU87MXY8ancV7t9zd3LWPwBl0fTLapwgql4gSbYe9W 2TS+8XymstA+A== Date: Thu, 22 Aug 2024 17:17:15 -0700 Subject: [PATCH 10/24] xfs: move xfs_ioc_getfsmap out of xfs_ioctl.c From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087416.59588.14421297568216399851.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Move this function out of xfs_ioctl.c to reduce the clutter in there, and make the entire getfsmap implementation self-contained in a single file. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_fsmap.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_fsmap.h | 6 +- fs/xfs/xfs_ioctl.c | 130 -------------------------------------------------- 3 files changed, 134 insertions(+), 136 deletions(-) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 615253406fde1..ae18ab86e608b 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -44,7 +44,7 @@ xfs_fsmap_from_internal( } /* Convert an fsmap to an xfs_fsmap. */ -void +static void xfs_fsmap_to_internal( struct xfs_fsmap *dest, struct fsmap *src) @@ -889,7 +889,7 @@ xfs_getfsmap_check_keys( * xfs_getfsmap_info.low/high -- per-AG low/high keys computed from * dkeys; used to query the metadata. */ -int +STATIC int xfs_getfsmap( struct xfs_mount *mp, struct xfs_fsmap_head *head, @@ -1019,3 +1019,133 @@ xfs_getfsmap( head->fmh_oflags = FMH_OF_DEV_T; return error; } + +int +xfs_ioc_getfsmap( + struct xfs_inode *ip, + struct fsmap_head __user *arg) +{ + struct xfs_fsmap_head xhead = {0}; + struct fsmap_head head; + struct fsmap *recs; + unsigned int count; + __u32 last_flags = 0; + bool done = false; + int error; + + if (copy_from_user(&head, arg, sizeof(struct fsmap_head))) + return -EFAULT; + if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) || + memchr_inv(head.fmh_keys[0].fmr_reserved, 0, + sizeof(head.fmh_keys[0].fmr_reserved)) || + memchr_inv(head.fmh_keys[1].fmr_reserved, 0, + sizeof(head.fmh_keys[1].fmr_reserved))) + return -EINVAL; + + /* + * Use an internal memory buffer so that we don't have to copy fsmap + * data to userspace while holding locks. Start by trying to allocate + * up to 128k for the buffer, but fall back to a single page if needed. + */ + count = min_t(unsigned int, head.fmh_count, + 131072 / sizeof(struct fsmap)); + recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); + if (!recs) { + count = min_t(unsigned int, head.fmh_count, + PAGE_SIZE / sizeof(struct fsmap)); + recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); + if (!recs) + return -ENOMEM; + } + + xhead.fmh_iflags = head.fmh_iflags; + xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]); + xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]); + + trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); + trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]); + + head.fmh_entries = 0; + do { + struct fsmap __user *user_recs; + struct fsmap *last_rec; + + user_recs = &arg->fmh_recs[head.fmh_entries]; + xhead.fmh_entries = 0; + xhead.fmh_count = min_t(unsigned int, count, + head.fmh_count - head.fmh_entries); + + /* Run query, record how many entries we got. */ + error = xfs_getfsmap(ip->i_mount, &xhead, recs); + switch (error) { + case 0: + /* + * There are no more records in the result set. Copy + * whatever we got to userspace and break out. + */ + done = true; + break; + case -ECANCELED: + /* + * The internal memory buffer is full. Copy whatever + * records we got to userspace and go again if we have + * not yet filled the userspace buffer. + */ + error = 0; + break; + default: + goto out_free; + } + head.fmh_entries += xhead.fmh_entries; + head.fmh_oflags = xhead.fmh_oflags; + + /* + * If the caller wanted a record count or there aren't any + * new records to return, we're done. + */ + if (head.fmh_count == 0 || xhead.fmh_entries == 0) + break; + + /* Copy all the records we got out to userspace. */ + if (copy_to_user(user_recs, recs, + xhead.fmh_entries * sizeof(struct fsmap))) { + error = -EFAULT; + goto out_free; + } + + /* Remember the last record flags we copied to userspace. */ + last_rec = &recs[xhead.fmh_entries - 1]; + last_flags = last_rec->fmr_flags; + + /* Set up the low key for the next iteration. */ + xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec); + trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); + } while (!done && head.fmh_entries < head.fmh_count); + + /* + * If there are no more records in the query result set and we're not + * in counting mode, mark the last record returned with the LAST flag. + */ + if (done && head.fmh_count > 0 && head.fmh_entries > 0) { + struct fsmap __user *user_rec; + + last_flags |= FMR_OF_LAST; + user_rec = &arg->fmh_recs[head.fmh_entries - 1]; + + if (copy_to_user(&user_rec->fmr_flags, &last_flags, + sizeof(last_flags))) { + error = -EFAULT; + goto out_free; + } + } + + /* copy back header */ + if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) { + error = -EFAULT; + goto out_free; + } + +out_free: + kvfree(recs); + return error; +} diff --git a/fs/xfs/xfs_fsmap.h b/fs/xfs/xfs_fsmap.h index a0775788e7b13..a0bcc38486a56 100644 --- a/fs/xfs/xfs_fsmap.h +++ b/fs/xfs/xfs_fsmap.h @@ -7,6 +7,7 @@ #define __XFS_FSMAP_H__ struct fsmap; +struct fsmap_head; /* internal fsmap representation */ struct xfs_fsmap { @@ -27,9 +28,6 @@ struct xfs_fsmap_head { struct xfs_fsmap fmh_keys[2]; /* low and high keys */ }; -void xfs_fsmap_to_internal(struct xfs_fsmap *dest, struct fsmap *src); - -int xfs_getfsmap(struct xfs_mount *mp, struct xfs_fsmap_head *head, - struct fsmap *out_recs); +int xfs_ioc_getfsmap(struct xfs_inode *ip, struct fsmap_head __user *arg); #endif /* __XFS_FSMAP_H__ */ diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index b53af3e674912..461780ffb8fc0 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -883,136 +883,6 @@ xfs_ioc_getbmap( return error; } -STATIC int -xfs_ioc_getfsmap( - struct xfs_inode *ip, - struct fsmap_head __user *arg) -{ - struct xfs_fsmap_head xhead = {0}; - struct fsmap_head head; - struct fsmap *recs; - unsigned int count; - __u32 last_flags = 0; - bool done = false; - int error; - - if (copy_from_user(&head, arg, sizeof(struct fsmap_head))) - return -EFAULT; - if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) || - memchr_inv(head.fmh_keys[0].fmr_reserved, 0, - sizeof(head.fmh_keys[0].fmr_reserved)) || - memchr_inv(head.fmh_keys[1].fmr_reserved, 0, - sizeof(head.fmh_keys[1].fmr_reserved))) - return -EINVAL; - - /* - * Use an internal memory buffer so that we don't have to copy fsmap - * data to userspace while holding locks. Start by trying to allocate - * up to 128k for the buffer, but fall back to a single page if needed. - */ - count = min_t(unsigned int, head.fmh_count, - 131072 / sizeof(struct fsmap)); - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); - if (!recs) { - count = min_t(unsigned int, head.fmh_count, - PAGE_SIZE / sizeof(struct fsmap)); - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); - if (!recs) - return -ENOMEM; - } - - xhead.fmh_iflags = head.fmh_iflags; - xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]); - xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]); - - trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); - trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]); - - head.fmh_entries = 0; - do { - struct fsmap __user *user_recs; - struct fsmap *last_rec; - - user_recs = &arg->fmh_recs[head.fmh_entries]; - xhead.fmh_entries = 0; - xhead.fmh_count = min_t(unsigned int, count, - head.fmh_count - head.fmh_entries); - - /* Run query, record how many entries we got. */ - error = xfs_getfsmap(ip->i_mount, &xhead, recs); - switch (error) { - case 0: - /* - * There are no more records in the result set. Copy - * whatever we got to userspace and break out. - */ - done = true; - break; - case -ECANCELED: - /* - * The internal memory buffer is full. Copy whatever - * records we got to userspace and go again if we have - * not yet filled the userspace buffer. - */ - error = 0; - break; - default: - goto out_free; - } - head.fmh_entries += xhead.fmh_entries; - head.fmh_oflags = xhead.fmh_oflags; - - /* - * If the caller wanted a record count or there aren't any - * new records to return, we're done. - */ - if (head.fmh_count == 0 || xhead.fmh_entries == 0) - break; - - /* Copy all the records we got out to userspace. */ - if (copy_to_user(user_recs, recs, - xhead.fmh_entries * sizeof(struct fsmap))) { - error = -EFAULT; - goto out_free; - } - - /* Remember the last record flags we copied to userspace. */ - last_rec = &recs[xhead.fmh_entries - 1]; - last_flags = last_rec->fmr_flags; - - /* Set up the low key for the next iteration. */ - xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec); - trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); - } while (!done && head.fmh_entries < head.fmh_count); - - /* - * If there are no more records in the query result set and we're not - * in counting mode, mark the last record returned with the LAST flag. - */ - if (done && head.fmh_count > 0 && head.fmh_entries > 0) { - struct fsmap __user *user_rec; - - last_flags |= FMR_OF_LAST; - user_rec = &arg->fmh_recs[head.fmh_entries - 1]; - - if (copy_to_user(&user_rec->fmr_flags, &last_flags, - sizeof(last_flags))) { - error = -EFAULT; - goto out_free; - } - } - - /* copy back header */ - if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) { - error = -EFAULT; - goto out_free; - } - -out_free: - kvfree(recs); - return error; -} - int xfs_ioc_swapext( xfs_swapext_t *sxp) From patchwork Fri Aug 23 00:17:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774426 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0453BB662 for ; Fri, 23 Aug 2024 00:17:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372252; cv=none; b=fF6bJoibKu+2KpU+eeXQ2ThCPEu7mAx4YGgYR4VBpWUF7yGK37jqc8dpIhK/5cbRr4xkTDpCEwh/64skryH58YzPFeALN+ZlCHwzB4Ipb7wOIf5aWZj21Fhoze3PUc145NMgTsAQv40wRTSg1tdipDVCWG0s3iIWflGqd93gPzE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372252; c=relaxed/simple; bh=RqvG4LmK9nt4MgF+sJ20jWImH27wAlk/2q5nhCinZGM=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WeGGGlAS9FdGjpg8cFILkdmPB6xMJCyZYr4FlQOQShMlPB8flpgsS7N6b3cnTMxxindXUY2Nl3YWxZemZQ0d52jAgQszQCaqv+bRmTc41xsDf+1hTVVrOCYJSsvpIkWF2AC9+QESYukEuaiyeGqer35kJKSiDP7ocejLj6+uGRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DH3Y0ia3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DH3Y0ia3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D41AEC32782; Fri, 23 Aug 2024 00:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372251; bh=RqvG4LmK9nt4MgF+sJ20jWImH27wAlk/2q5nhCinZGM=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=DH3Y0ia3H7J2eMhR/P19upHUvsVrfYKr07yxA5QgIcUvNw2XXXQWkjXHucpC5eRGA 26yETvPFoqz6HSuuKPq4zKwwfcwTdQanzKcEkusTzIjiYEGWkbuAfOGBxx1amTcyIy CallgmmfW2jwQ0K4ARG99nFWuk4mzVpLgHOT6S56VmK9JGFoJa9/Wd0Yv9qU5G/QuB hnn2idh42YPQmovazV7xcGF9Z5pxZ6s6rloQXeAdcM2Xh0Fl3UkeuZYxjhK83P1Grz n/KtSqCD+uRdzVWytwsWMfrq9o/cKdSi2XMGWmkoBUgVKbDWiuqcdJ4eGOPHUIRN9+ 1SDv3tuue8c9A== Date: Thu, 22 Aug 2024 17:17:31 -0700 Subject: [PATCH 11/24] xfs: create incore realtime group structures From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087433.59588.10419191726395528458.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create an incore object that will contain information about a realtime allocation group. This will eventually enable us to shard the realtime section in a similar manner to how we shard the data section, but for now just a single object for the entire RT subvolume is created. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_format.h | 3 + fs/xfs/libxfs/xfs_rtgroup.c | 196 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 212 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_sb.c | 7 + fs/xfs/libxfs/xfs_types.h | 4 + fs/xfs/xfs_log_recover.c | 20 ++++ fs/xfs/xfs_mount.c | 16 +++ fs/xfs/xfs_mount.h | 14 +++ fs/xfs/xfs_rtalloc.c | 6 + fs/xfs/xfs_super.c | 1 fs/xfs/xfs_trace.c | 1 fs/xfs/xfs_trace.h | 38 ++++++++ 13 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 fs/xfs/libxfs/xfs_rtgroup.c create mode 100644 fs/xfs/libxfs/xfs_rtgroup.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 4d8ca08cdd0ec..388b5cef48ca5 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -60,6 +60,7 @@ xfs-y += $(addprefix libxfs/, \ # xfs_rtbitmap is shared with libxfs xfs-$(CONFIG_XFS_RT) += $(addprefix libxfs/, \ xfs_rtbitmap.o \ + xfs_rtgroup.o \ ) # highlevel code diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 16a7bc02aa5f5..fa5cfc8265d92 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -176,6 +176,9 @@ typedef struct xfs_sb { xfs_ino_t sb_metadirino; /* metadata directory tree root */ + xfs_rgnumber_t sb_rgcount; /* number of realtime groups */ + xfs_rtxlen_t sb_rgextents; /* size of a realtime group in rtx */ + /* must be padded to 64 bit alignment */ } xfs_sb_t; diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c new file mode 100644 index 0000000000000..2bad1ecb811eb --- /dev/null +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_rmap_btree.h" +#include "xfs_alloc.h" +#include "xfs_ialloc.h" +#include "xfs_rmap.h" +#include "xfs_ag.h" +#include "xfs_ag_resv.h" +#include "xfs_health.h" +#include "xfs_error.h" +#include "xfs_bmap.h" +#include "xfs_defer.h" +#include "xfs_log_format.h" +#include "xfs_trans.h" +#include "xfs_trace.h" +#include "xfs_inode.h" +#include "xfs_icache.h" +#include "xfs_rtgroup.h" +#include "xfs_rtbitmap.h" + +/* + * Passive reference counting access wrappers to the rtgroup structures. If + * the rtgroup structure is to be freed, the freeing code is responsible for + * cleaning up objects with passive references before freeing the structure. + */ +struct xfs_rtgroup * +xfs_rtgroup_get( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + struct xfs_rtgroup *rtg; + + rcu_read_lock(); + rtg = xa_load(&mp->m_rtgroups, rgno); + if (rtg) { + trace_xfs_rtgroup_get(rtg, _RET_IP_); + ASSERT(atomic_read(&rtg->rtg_ref) >= 0); + atomic_inc(&rtg->rtg_ref); + } + rcu_read_unlock(); + return rtg; +} + +/* Get a passive reference to the given rtgroup. */ +struct xfs_rtgroup * +xfs_rtgroup_hold( + struct xfs_rtgroup *rtg) +{ + ASSERT(atomic_read(&rtg->rtg_ref) > 0 || + atomic_read(&rtg->rtg_active_ref) > 0); + + trace_xfs_rtgroup_hold(rtg, _RET_IP_); + atomic_inc(&rtg->rtg_ref); + return rtg; +} + +void +xfs_rtgroup_put( + struct xfs_rtgroup *rtg) +{ + trace_xfs_rtgroup_put(rtg, _RET_IP_); + ASSERT(atomic_read(&rtg->rtg_ref) > 0); + atomic_dec(&rtg->rtg_ref); +} + +/* + * Active references for rtgroup structures. This is for short term access to + * the rtgroup structures for walking trees or accessing state. If an rtgroup + * is being shrunk or is offline, then this will fail to find that group and + * return NULL instead. + */ +struct xfs_rtgroup * +xfs_rtgroup_grab( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_rtgroup *rtg; + + rcu_read_lock(); + rtg = xa_load(&mp->m_rtgroups, agno); + if (rtg) { + trace_xfs_rtgroup_grab(rtg, _RET_IP_); + if (!atomic_inc_not_zero(&rtg->rtg_active_ref)) + rtg = NULL; + } + rcu_read_unlock(); + return rtg; +} + +void +xfs_rtgroup_rele( + struct xfs_rtgroup *rtg) +{ + trace_xfs_rtgroup_rele(rtg, _RET_IP_); + if (atomic_dec_and_test(&rtg->rtg_active_ref)) + wake_up(&rtg->rtg_active_wq); +} + +int +xfs_rtgroup_alloc( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + struct xfs_rtgroup *rtg; + int error; + + rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL); + if (!rtg) + return -ENOMEM; + rtg->rtg_rgno = rgno; + rtg->rtg_mount = mp; + + error = xa_insert(&mp->m_rtgroups, rgno, rtg, GFP_KERNEL); + if (error) { + WARN_ON_ONCE(error == -EBUSY); + goto out_free_rtg; + } + +#ifdef __KERNEL__ + /* Place kernel structure only init below this point. */ + spin_lock_init(&rtg->rtg_state_lock); + init_waitqueue_head(&rtg->rtg_active_wq); +#endif /* __KERNEL__ */ + + /* Active ref owned by mount indicates rtgroup is online. */ + atomic_set(&rtg->rtg_active_ref, 1); + return 0; + +out_free_rtg: + kfree(rtg); + return error; +} + +void +xfs_rtgroup_free( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + struct xfs_rtgroup *rtg; + + rtg = xa_erase(&mp->m_rtgroups, rgno); + if (!rtg) /* can happen when growfs fails */ + return; + + XFS_IS_CORRUPT(mp, atomic_read(&rtg->rtg_ref) != 0); + + /* drop the mount's active reference */ + xfs_rtgroup_rele(rtg); + XFS_IS_CORRUPT(mp, atomic_read(&rtg->rtg_active_ref) != 0); + + kfree_rcu_mightsleep(rtg); +} + +/* + * Free up the rtgroup resources associated with the mount structure. + */ +void +xfs_free_rtgroups( + struct xfs_mount *mp, + xfs_rgnumber_t rgcount) +{ + xfs_rgnumber_t rgno; + + for (rgno = 0; rgno < rgcount; rgno++) + xfs_rtgroup_free(mp, rgno); +} + +/* Compute the number of rt extents in this realtime group. */ +xfs_rtxnum_t +xfs_rtgroup_extents( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + xfs_rgnumber_t rgcount = mp->m_sb.sb_rgcount; + + ASSERT(rgno < rgcount); + if (rgno == rgcount - 1) + return mp->m_sb.sb_rextents - + ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents); + + ASSERT(xfs_has_rtgroups(mp)); + return mp->m_sb.sb_rgextents; +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h new file mode 100644 index 0000000000000..2c09ecfc50328 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#ifndef __LIBXFS_RTGROUP_H +#define __LIBXFS_RTGROUP_H 1 + +struct xfs_mount; +struct xfs_trans; + +/* + * Realtime group incore structure, similar to the per-AG structure. + */ +struct xfs_rtgroup { + struct xfs_mount *rtg_mount; + xfs_rgnumber_t rtg_rgno; + atomic_t rtg_ref; /* passive reference count */ + atomic_t rtg_active_ref; /* active reference count */ + wait_queue_head_t rtg_active_wq;/* woken active_ref falls to zero */ + + /* Number of blocks in this group */ + xfs_rtxnum_t rtg_extents; + +#ifdef __KERNEL__ + /* -- kernel only structures below this line -- */ + spinlock_t rtg_state_lock; +#endif /* __KERNEL__ */ +}; + +#ifdef CONFIG_XFS_RT +/* Passive rtgroup references */ +struct xfs_rtgroup *xfs_rtgroup_get(struct xfs_mount *mp, xfs_rgnumber_t rgno); +struct xfs_rtgroup *xfs_rtgroup_hold(struct xfs_rtgroup *rtg); +void xfs_rtgroup_put(struct xfs_rtgroup *rtg); + +/* Active rtgroup references */ +struct xfs_rtgroup *xfs_rtgroup_grab(struct xfs_mount *mp, xfs_rgnumber_t rgno); +void xfs_rtgroup_rele(struct xfs_rtgroup *rtg); + +int xfs_rtgroup_alloc(struct xfs_mount *mp, xfs_rgnumber_t rgno); +void xfs_rtgroup_free(struct xfs_mount *mp, xfs_rgnumber_t rgno); +void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t rgcount); +#else /* CONFIG_XFS_RT */ +static inline struct xfs_rtgroup *xfs_rtgroup_get(struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + return NULL; +} +static inline struct xfs_rtgroup *xfs_rtgroup_hold(struct xfs_rtgroup *rtg) +{ + ASSERT(rtg == NULL); + return NULL; +} +static inline void xfs_rtgroup_put(struct xfs_rtgroup *rtg) +{ +} +static inline int xfs_rtgroup_alloc( struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + return 0; +} +static inline void xfs_free_rtgroups(struct xfs_mount *mp, + xfs_rgnumber_t rgcount) +{ +} +#define xfs_rtgroup_grab xfs_rtgroup_get +#define xfs_rtgroup_rele xfs_rtgroup_put +#endif /* CONFIG_XFS_RT */ + +/* + * rt group iteration APIs + */ +static inline struct xfs_rtgroup * +xfs_rtgroup_next( + struct xfs_rtgroup *rtg, + xfs_rgnumber_t *rgno, + xfs_rgnumber_t end_rgno) +{ + struct xfs_mount *mp = rtg->rtg_mount; + + *rgno = rtg->rtg_rgno + 1; + xfs_rtgroup_rele(rtg); + if (*rgno > end_rgno) + return NULL; + return xfs_rtgroup_grab(mp, *rgno); +} + +#define for_each_rtgroup_range(mp, rgno, end_rgno, rtg) \ + for ((rtg) = xfs_rtgroup_grab((mp), (rgno)); \ + (rtg) != NULL; \ + (rtg) = xfs_rtgroup_next((rtg), &(rgno), (end_rgno))) + +#define for_each_rtgroup_from(mp, rgno, rtg) \ + for_each_rtgroup_range((mp), (rgno), (mp)->m_sb.sb_rgcount - 1, (rtg)) + + +#define for_each_rtgroup(mp, rgno, rtg) \ + (rgno) = 0; \ + for_each_rtgroup_from((mp), (rgno), (rtg)) + +static inline bool +xfs_verify_rgbno( + struct xfs_rtgroup *rtg, + xfs_rgblock_t rgbno) +{ + struct xfs_mount *mp = rtg->rtg_mount; + + if (rgbno >= rtg->rtg_extents * mp->m_sb.sb_rextsize) + return false; + if (xfs_has_rtsb(mp) && rtg->rtg_rgno == 0 && + rgbno < mp->m_sb.sb_rextsize) + return false; + return true; +} + +static inline bool +xfs_verify_rgbext( + struct xfs_rtgroup *rtg, + xfs_rgblock_t rgbno, + xfs_rgblock_t len) +{ + if (rgbno + len <= rgbno) + return false; + + if (!xfs_verify_rgbno(rtg, rgbno)) + return false; + + return xfs_verify_rgbno(rtg, rgbno + len - 1); +} + +static inline xfs_rtblock_t +xfs_rgno_start_rtb( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + if (mp->m_rgblklog >= 0) + return ((xfs_rtblock_t)rgno << mp->m_rgblklog); + return ((xfs_rtblock_t)rgno * mp->m_rgblocks); +} + +static inline xfs_rtblock_t +xfs_rgbno_to_rtb( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + xfs_rgblock_t rgbno) +{ + return xfs_rgno_start_rtb(mp, rgno) + rgbno; +} + +static inline xfs_rgnumber_t +xfs_rtb_to_rgno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + if (!xfs_has_rtgroups(mp)) + return 0; + + if (mp->m_rgblklog >= 0) + return rtbno >> mp->m_rgblklog; + + return div_u64(rtbno, mp->m_rgblocks); +} + +static inline uint64_t +__xfs_rtb_to_rgbno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + uint32_t rem; + + if (!xfs_has_rtgroups(mp)) + return rtbno; + + if (mp->m_rgblklog >= 0) + return rtbno & mp->m_rgblkmask; + + div_u64_rem(rtbno, mp->m_rgblocks, &rem); + return rem; +} + +static inline xfs_rgblock_t +xfs_rtb_to_rgbno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return __xfs_rtb_to_rgbno(mp, rtbno); +} + +static inline xfs_daddr_t +xfs_rtb_to_daddr( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return rtbno << mp->m_blkbb_log; +} + +static inline xfs_rtblock_t +xfs_daddr_to_rtb( + struct xfs_mount *mp, + xfs_daddr_t daddr) +{ + return daddr >> mp->m_blkbb_log; +} + +#ifdef CONFIG_XFS_RT +xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno); +#else +# define xfs_rtgroup_extents(mp, rgno) (0) +#endif /* CONFIG_XFS_RT */ + +#endif /* __LIBXFS_RTGROUP_H */ diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index b83ce29640511..f1cdffb2f3392 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -696,6 +696,9 @@ __xfs_sb_from_disk( to->sb_metadirino = be64_to_cpu(from->sb_metadirino); else to->sb_metadirino = NULLFSINO; + + to->sb_rgcount = 1; + to->sb_rgextents = 0; } void @@ -982,6 +985,10 @@ xfs_mount_sb_set_rextsize( { mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); + + mp->m_rgblocks = 0; + mp->m_rgblklog = 0; + mp->m_rgblkmask = 0; } /* diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index a8cd44d03ef64..1ce4b9eb16f47 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -9,10 +9,12 @@ typedef uint32_t prid_t; /* project ID */ typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */ +typedef uint32_t xfs_rgblock_t; /* blockno in realtime group */ typedef uint32_t xfs_agino_t; /* inode # within allocation grp */ typedef uint32_t xfs_extlen_t; /* extent length in blocks */ typedef uint32_t xfs_rtxlen_t; /* file extent length in rtextents */ typedef uint32_t xfs_agnumber_t; /* allocation group number */ +typedef uint32_t xfs_rgnumber_t; /* realtime group number */ typedef uint64_t xfs_extnum_t; /* # of extents in a file */ typedef uint32_t xfs_aextnum_t; /* # extents in an attribute fork */ typedef int64_t xfs_fsize_t; /* bytes in a file */ @@ -53,7 +55,9 @@ typedef void * xfs_failaddr_t; #define NULLFILEOFF ((xfs_fileoff_t)-1) #define NULLAGBLOCK ((xfs_agblock_t)-1) +#define NULLRGBLOCK ((xfs_rgblock_t)-1) #define NULLAGNUMBER ((xfs_agnumber_t)-1) +#define NULLRGNUMBER ((xfs_rgnumber_t)-1) #define NULLCOMMITLSN ((xfs_lsn_t)-1) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4423dd344239b..c627cde3bb1e0 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -28,6 +28,7 @@ #include "xfs_ag.h" #include "xfs_quota.h" #include "xfs_reflink.h" +#include "xfs_rtgroup.h" #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) @@ -3346,6 +3347,7 @@ xlog_do_recover( struct xfs_mount *mp = log->l_mp; struct xfs_buf *bp = mp->m_sb_bp; struct xfs_sb *sbp = &mp->m_sb; + xfs_rgnumber_t old_rgcount = sbp->sb_rgcount; int error; trace_xfs_log_recover(log, head_blk, tail_blk); @@ -3399,6 +3401,24 @@ xlog_do_recover( xfs_warn(mp, "Failed post-recovery per-ag init: %d", error); return error; } + + if (sbp->sb_rgcount < old_rgcount) { + xfs_warn(mp, "rgcount shrink not supported"); + return -EINVAL; + } + if (sbp->sb_rgcount > old_rgcount) { + xfs_rgnumber_t rgno; + + for (rgno = old_rgcount; rgno < sbp->sb_rgcount; rgno++) { + error = xfs_rtgroup_alloc(mp, rgno); + if (error) { + xfs_warn(mp, + "Failed post-recovery rtgroup init: %d", + error); + return error; + } + } + } mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); /* Normal transactions can now occur */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b0ea88acdb618..e1e849101cdd4 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -36,6 +36,7 @@ #include "xfs_ag.h" #include "xfs_rtbitmap.h" #include "xfs_metafile.h" +#include "xfs_rtgroup.h" #include "scrub/stats.h" static DEFINE_MUTEX(xfs_uuid_table_mutex); @@ -664,6 +665,7 @@ xfs_mountfs( struct xfs_ino_geometry *igeo = M_IGEO(mp); uint quotamount = 0; uint quotaflags = 0; + xfs_rgnumber_t rgno; int error = 0; xfs_sb_mount_common(mp, sbp); @@ -830,10 +832,18 @@ xfs_mountfs( goto out_free_dir; } + for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) { + error = xfs_rtgroup_alloc(mp, rgno); + if (error) { + xfs_warn(mp, "Failed rtgroup init: %d", error); + goto out_free_rtgroup; + } + } + if (XFS_IS_CORRUPT(mp, !sbp->sb_logblocks)) { xfs_warn(mp, "no log defined"); error = -EFSCORRUPTED; - goto out_free_perag; + goto out_free_rtgroup; } error = xfs_inodegc_register_shrinker(mp); @@ -1068,7 +1078,8 @@ xfs_mountfs( if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) xfs_buftarg_drain(mp->m_logdev_targp); xfs_buftarg_drain(mp->m_ddev_targp); - out_free_perag: + out_free_rtgroup: + xfs_free_rtgroups(mp, rgno); xfs_free_perag(mp); out_free_dir: xfs_da_unmount(mp); @@ -1152,6 +1163,7 @@ xfs_unmountfs( xfs_errortag_clearall(mp); #endif shrinker_free(mp->m_inodegc_shrinker); + xfs_free_rtgroups(mp, mp->m_sb.sb_rgcount); xfs_free_perag(mp); xfs_errortag_del(mp); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 9e883d2159fd9..f69da6802e8c1 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -121,6 +121,7 @@ typedef struct xfs_mount { uint8_t m_agno_log; /* log #ag's */ uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ int8_t m_rtxblklog; /* log2 of rextsize, if possible */ + int8_t m_rgblklog; /* log2 of rt group sz if possible */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwmask; /* blockwsize-1 */ @@ -149,12 +150,14 @@ typedef struct xfs_mount { int m_logbsize; /* size of each log buffer */ uint m_rsumlevels; /* rt summary levels */ xfs_filblks_t m_rsumblocks; /* size of rt summary, FSBs */ + uint32_t m_rgblocks; /* size of rtgroup in rtblocks */ int m_fixedfsid[2]; /* unchanged for life of FS */ uint m_qflags; /* quota status flags */ uint64_t m_features; /* active filesystem features */ uint64_t m_low_space[XFS_LOWSP_MAX]; uint64_t m_low_rtexts[XFS_LOWSP_MAX]; uint64_t m_rtxblkmask; /* rt extent block mask */ + uint64_t m_rgblkmask; /* rt group block mask */ struct xfs_ino_geometry m_ino_geo; /* inode geometry */ struct xfs_trans_resv m_resv; /* precomputed res values */ /* low free space thresholds */ @@ -209,6 +212,7 @@ typedef struct xfs_mount { */ atomic64_t m_allocbt_blks; + struct xarray m_rtgroups; /* per-rt group info */ struct radix_tree_root m_perag_tree; /* per-ag accounting info */ spinlock_t m_perag_lock; /* lock for m_perag_tree */ uint64_t m_resblks; /* total reserved blocks */ @@ -358,6 +362,16 @@ __XFS_HAS_FEAT(large_extent_counts, NREXT64) __XFS_HAS_FEAT(exchange_range, EXCHANGE_RANGE) __XFS_HAS_FEAT(metadir, METADIR) +static inline bool xfs_has_rtgroups(struct xfs_mount *mp) +{ + return false; +} + +static inline bool xfs_has_rtsb(struct xfs_mount *mp) +{ + return false; +} + /* * Some features are always on for v5 file systems, allow the compiler to * eliminiate dead code when building without v4 support. diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 46a920b192d19..59898117f817d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -27,6 +27,7 @@ #include "xfs_health.h" #include "xfs_da_format.h" #include "xfs_metafile.h" +#include "xfs_rtgroup.h" /* * Return whether there are any free extents in the size range given @@ -1136,6 +1137,8 @@ xfs_rtmount_inodes( { struct xfs_trans *tp; struct xfs_sb *sbp = &mp->m_sb; + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; int error; error = xfs_trans_alloc_empty(mp, &tp); @@ -1166,6 +1169,9 @@ xfs_rtmount_inodes( if (error) goto out_rele_summary; + for_each_rtgroup(mp, rgno, rtg) + rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg->rtg_rgno); + error = xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); if (error) goto out_rele_summary; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 34066b50585e8..cee64c1a7d650 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -2015,6 +2015,7 @@ static int xfs_init_fs_context( spin_lock_init(&mp->m_sb_lock); INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); spin_lock_init(&mp->m_perag_lock); + xa_init(&mp->m_rtgroups); mutex_init(&mp->m_growlock); INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker); INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); diff --git a/fs/xfs/xfs_trace.c b/fs/xfs/xfs_trace.c index c5f818cf40c29..f888d41e3283f 100644 --- a/fs/xfs/xfs_trace.c +++ b/fs/xfs/xfs_trace.c @@ -46,6 +46,7 @@ #include "xfs_refcount.h" #include "xfs_metafile.h" #include "xfs_metadir.h" +#include "xfs_rtgroup.h" /* * We include this last to have the helpers above available for the trace diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7f259891ebcaa..4401a7c6230df 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -94,6 +94,7 @@ struct xfs_extent_free_item; struct xfs_rmap_intent; struct xfs_refcount_intent; struct xfs_metadir_update; +struct xfs_rtgroup; #define XFS_ATTR_FILTER_FLAGS \ { XFS_ATTR_ROOT, "ROOT" }, \ @@ -220,6 +221,43 @@ 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); +#ifdef CONFIG_XFS_RT +DECLARE_EVENT_CLASS(xfs_rtgroup_class, + TP_PROTO(struct xfs_rtgroup *rtg, unsigned long caller_ip), + TP_ARGS(rtg, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_rgnumber_t, rgno) + __field(int, refcount) + __field(int, active_refcount) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = rtg->rtg_mount->m_super->s_dev; + __entry->rgno = rtg->rtg_rgno; + __entry->refcount = atomic_read(&rtg->rtg_ref); + __entry->active_refcount = atomic_read(&rtg->rtg_active_ref); + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d rgno 0x%x passive refs %d active refs %d caller %pS", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->rgno, + __entry->refcount, + __entry->active_refcount, + (char *)__entry->caller_ip) +); + +#define DEFINE_RTGROUP_REF_EVENT(name) \ +DEFINE_EVENT(xfs_rtgroup_class, name, \ + TP_PROTO(struct xfs_rtgroup *rtg, unsigned long caller_ip), \ + TP_ARGS(rtg, caller_ip)) +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_get); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_hold); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_put); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_grab); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_rele); +#endif /* CONFIG_XFS_RT */ + TRACE_EVENT(xfs_inodegc_worker, TP_PROTO(struct xfs_mount *mp, unsigned int shrinker_hits), TP_ARGS(mp, shrinker_hits), From patchwork Fri Aug 23 00:17:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774427 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1F8FB653 for ; Fri, 23 Aug 2024 00:17:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372267; cv=none; b=OfGNXBeVzUQrRjkP6pdwoGpqnj9rkTVKsxkSiLdfHGLz/yyh9P9pMCiTY4sqZkj7xBfqlVWY5zss7hHrQ6L4mcRzxUyz6VwojqG33Em+dJeKHCodK7TzTkPGEcVxZOIt05/+7za+hZMVkSUpZ+lkUjAV+fe+lSq2LdvobNo+99A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372267; c=relaxed/simple; bh=sB6tRoLmmWP0MZVCKWyGNlT8hqw3pXXpHcs4QrfsEl4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PvSUAUSXvKioYRNCBkoUNgGjJwKxgeTjJZTnn4UhdhuaLCKoVdzbNJMYfjmFxX/YIgydHyj+/Psbn7Si+3eYgO9ThC7y7cmQSFBSOLc9s4rFi229QbYzy++IkN7W8EgmgZHRBLPvyj7S6yrnilKc0Uo/cQfSb8yT4Mh3VbAutGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tkXsVsIJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tkXsVsIJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 804B9C32782; Fri, 23 Aug 2024 00:17:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372267; bh=sB6tRoLmmWP0MZVCKWyGNlT8hqw3pXXpHcs4QrfsEl4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=tkXsVsIJiRvPHMkf8jZC34ciSJEQk4vFCKG1sTH00q4T4NytuHTkKv0uBu5gK4g2X Al4HUSddDHSPvPE/0mWycbgvFdqBnYGFkb4rDiE29OE0x1cL2AIHzO59z2gJ74UNI5 pbxEQCoH8QluspjO9dibpNL7lUDBHutl/cO314uTFY2dhCV/yYmSpFBPSOrGbZ1aIW +nuwF3bg5y0eV2P9TWiYFGX17vHsay8AjaW/uHFEF/ggLVPxuX6kgjzS6TiLXjhTPB KcXBUBkkxaXDOZYHX9W6kWBOhQY2qLzdlHeIKp7uQUKh7te4pBqlr+GAVinvrZCXnh QyLP68VG51A5w== Date: Thu, 22 Aug 2024 17:17:47 -0700 Subject: [PATCH 12/24] xfs: define locking primitives for realtime groups From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087452.59588.12210244336745998210.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Define helper functions to lock all metadata inodes related to a realtime group. There's not much to look at now, but this will become important when we add per-rtgroup metadata files and online fsck code for them. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtgroup.c | 49 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 16 ++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 2bad1ecb811eb..51f04cad5227c 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -194,3 +194,52 @@ xfs_rtgroup_extents( ASSERT(xfs_has_rtgroups(mp)); return mp->m_sb.sb_rgextents; } + +/* Lock metadata inodes associated with this rt group. */ +void +xfs_rtgroup_lock( + struct xfs_rtgroup *rtg, + unsigned int rtglock_flags) +{ + ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); + ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || + !(rtglock_flags & XFS_RTGLOCK_BITMAP)); + + if (rtglock_flags & XFS_RTGLOCK_BITMAP) + xfs_rtbitmap_lock(rtg->rtg_mount); + else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) + xfs_rtbitmap_lock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP); +} + +/* Unlock metadata inodes associated with this rt group. */ +void +xfs_rtgroup_unlock( + struct xfs_rtgroup *rtg, + unsigned int rtglock_flags) +{ + ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); + ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || + !(rtglock_flags & XFS_RTGLOCK_BITMAP)); + + if (rtglock_flags & XFS_RTGLOCK_BITMAP) + xfs_rtbitmap_unlock(rtg->rtg_mount); + else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) + xfs_rtbitmap_unlock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP); +} + +/* + * Join realtime group metadata inodes to the transaction. The ILOCKs will be + * released on transaction commit. + */ +void +xfs_rtgroup_trans_join( + struct xfs_trans *tp, + struct xfs_rtgroup *rtg, + unsigned int rtglock_flags) +{ + ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); + ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)); + + if (rtglock_flags & XFS_RTGLOCK_BITMAP) + xfs_rtbitmap_trans_join(tp); +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index 2c09ecfc50328..d2eb2cd5775dd 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -205,8 +205,24 @@ xfs_daddr_to_rtb( #ifdef CONFIG_XFS_RT xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno); + +/* Lock the rt bitmap inode in exclusive mode */ +#define XFS_RTGLOCK_BITMAP (1U << 0) +/* Lock the rt bitmap inode in shared mode */ +#define XFS_RTGLOCK_BITMAP_SHARED (1U << 1) + +#define XFS_RTGLOCK_ALL_FLAGS (XFS_RTGLOCK_BITMAP | \ + XFS_RTGLOCK_BITMAP_SHARED) + +void xfs_rtgroup_lock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); +void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); +void xfs_rtgroup_trans_join(struct xfs_trans *tp, struct xfs_rtgroup *rtg, + unsigned int rtglock_flags); #else # define xfs_rtgroup_extents(mp, rgno) (0) +# define xfs_rtgroup_lock(rtg, gf) ((void)0) +# define xfs_rtgroup_unlock(rtg, gf) ((void)0) +# define xfs_rtgroup_trans_join(tp, rtg, gf) ((void)0) #endif /* CONFIG_XFS_RT */ #endif /* __LIBXFS_RTGROUP_H */ From patchwork Fri Aug 23 00:18:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774428 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A1D5AD59 for ; Fri, 23 Aug 2024 00:18:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372283; cv=none; b=SrodOC+JkWGCft4PtsbyDfTzj8TjPF6x/19Gzk0pIEco5kGj0QF6QdkiL0Juf1OizpreZCZzYnH9ZmP6P2Ez2Rr6vsqlKMr78AQCHNmh4BXyLbsTc9GvC4vIaTwDxa30Yt8TyZ7oiH9Qf2yVHtvLKNyVwtGoHqYH/SC8Bxhkqqo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372283; c=relaxed/simple; bh=5vtQ6hRvDM9ILOUM86lV+047aqRF9n2dX+arbHuMzQE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UdubtDqiQ0s1Tg7dF6D7wB7gABkgo0vf5aJI8lkUevWmG0OhhQc1BVbevSb1G5EELHNCUXgnA79YBtldMieFNlBngqY8vxwuYMfqAxayDRarf8i3uWPGN0hFAhaLqjEVksJhEcZ9jcfCFRIzDbQog7AgIh7mv61c9nEDZwE1kO4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=igg1ChLm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="igg1ChLm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24B92C4AF0E; Fri, 23 Aug 2024 00:18:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372283; bh=5vtQ6hRvDM9ILOUM86lV+047aqRF9n2dX+arbHuMzQE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=igg1ChLmybMIgPQYxmO+o5jCa5VMW7MVT76PjyB0UvSzrRjC8/vPjEPIfXtIyK7vj 1FcgpUYuwkaoxxIvfTxai+7r7fHGyphBab1ZqJ9OfW7IZ25ya99ekuiL+fJrpe+9IC Pq0UD+IFYmm8/D66DioXJEttwGo2ZzJmuIJRQXZsDW8SLwpT1r/TjUlZiBZAwsKd0A InP8dbOJA7mp1mFGNcgG+X7PMOzjFzo1aMHPyKJF1+jIl0FmgXyhHxX0ATxhe7X5/w zzTXLAvxsbmXIzbcWF8rLh+jNjQup1EGnzzVP3ZlMz3gGcLqFaKqZOs6RfbqunqTy/ 2hevEgBwg1lmQ== Date: Thu, 22 Aug 2024 17:18:02 -0700 Subject: [PATCH 13/24] xfs: add a lockdep class key for rtgroup inodes From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087470.59588.4171434021531099837.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add a dynamic lockdep class key for rtgroup inodes. This will enable lockdep to deduce inconsistencies in the rtgroup metadata ILOCK locking order. Each class can have 8 subclasses, and for now we will only have 2 inodes per group. This enables rtgroup order and inode order checks when nesting ILOCKs. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtgroup.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 51f04cad5227c..ae6d67c673b1a 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -243,3 +243,55 @@ xfs_rtgroup_trans_join( if (rtglock_flags & XFS_RTGLOCK_BITMAP) xfs_rtbitmap_trans_join(tp); } + +#ifdef CONFIG_PROVE_LOCKING +static struct lock_class_key xfs_rtginode_lock_class; + +static int +xfs_rtginode_ilock_cmp_fn( + const struct lockdep_map *m1, + const struct lockdep_map *m2) +{ + const struct xfs_inode *ip1 = + container_of(m1, struct xfs_inode, i_lock.dep_map); + const struct xfs_inode *ip2 = + container_of(m2, struct xfs_inode, i_lock.dep_map); + + if (ip1->i_projid < ip2->i_projid) + return -1; + if (ip1->i_projid > ip2->i_projid) + return 1; + return 0; +} + +static inline void +xfs_rtginode_ilock_print_fn( + const struct lockdep_map *m) +{ + const struct xfs_inode *ip = + container_of(m, struct xfs_inode, i_lock.dep_map); + + printk(KERN_CONT " rgno=%u", ip->i_projid); +} + +/* + * Most of the time each of the RTG inode locks are only taken one at a time. + * But when committing deferred ops, more than one of a kind can be taken. + * However, deferred rt ops will be committed in rgno order so there is no + * potential for deadlocks. The code here is needed to tell lockdep about this + * order. + */ +static inline void +xfs_rtginode_lockdep_setup( + struct xfs_inode *ip, + xfs_rgnumber_t rgno, + enum xfs_rtg_inodes type) +{ + lockdep_set_class_and_subclass(&ip->i_lock, &xfs_rtginode_lock_class, + type); + lock_set_cmp_fn(&ip->i_lock, xfs_rtginode_ilock_cmp_fn, + xfs_rtginode_ilock_print_fn); +} +#else +#define xfs_rtginode_lockdep_setup(ip, rgno, type) do { } while (0) +#endif /* CONFIG_PROVE_LOCKING */ From patchwork Fri Aug 23 00:18:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774429 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31D1A1CD06 for ; Fri, 23 Aug 2024 00:18:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372299; cv=none; b=h0ZKFB2hjNu0NA7BRp4PwRxDpO7Hz81w2YLjDyyMv7K2Murnz1ha6DkQfcNK+/FnsUDglqUIb6PJdlYeeBVmDsYCqZVyTOqYf28920WhP36d3vMS45FHdDRzlbVAC83huovTmuOr4wiCXFyJYhhU1uwNDfA1T4Bl4qcigm0Et04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372299; c=relaxed/simple; bh=inSqoDNQ8qIQIOISPh5/dpX9rtVpCDBqs9VM4Eh+pNM=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=anIYkWLNXX+tICmUJdlr7jVmZENsJ9BRH1I7lIbBkhI5HiphD0sDWHLbhkpjaZKR/QPXlTCQavrzbB8x3xmndiC7zFeoGQk10vRNa0tYIl737M9g7YZc4DU+tAa2phFbpAfajDrVSwKX9R8PxlxYAH2XV+TUtIrneT+MC+wPrXA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oMOt/by8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oMOt/by8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C01A7C4AF11; Fri, 23 Aug 2024 00:18:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372298; bh=inSqoDNQ8qIQIOISPh5/dpX9rtVpCDBqs9VM4Eh+pNM=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=oMOt/by8KrcOxSTSsILafGJl4A9O3B+2teluA0q+1QI3YT/4mhcxT3DM24Zrypmb3 3Jk6vbzWFGa1z9yd2twzIOsW7HTqOXEQMZ8SSuna2dhguoquaaxad1Us1jrpTCNlNB HJ5QwWtC45uEMs8O5u5FgM1hRjMdCp1diUVQzIjGQd7/SyTCKG4k7UwCl9Xn+UyotI BEO0b+KFRc+trV6Cxv0NQ6hI+aTiaixR4rZeA7YoyQEwZqT5ENDNhEoYyC9cegTE4n LVcpziQd8ddMNbXmYXUHNkQTf8kJV7Fs1noUUGUyXbmA7Ayp8bVErjJDyBYPkkF3Mj sQartB2ruUhYw== Date: Thu, 22 Aug 2024 17:18:18 -0700 Subject: [PATCH 14/24] xfs: support caching rtgroup metadata inodes From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087487.59588.6672080001636292983.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create the necessary per-rtgroup infrastructure that we need to load metadata inodes into memory. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtgroup.c | 182 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 28 +++++++ fs/xfs/xfs_mount.h | 1 fs/xfs/xfs_rtalloc.c | 48 +++++++++++ 4 files changed, 258 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index ae6d67c673b1a..50e4a56d749f0 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -30,6 +30,8 @@ #include "xfs_icache.h" #include "xfs_rtgroup.h" #include "xfs_rtbitmap.h" +#include "xfs_metafile.h" +#include "xfs_metadir.h" /* * Passive reference counting access wrappers to the rtgroup structures. If @@ -295,3 +297,183 @@ xfs_rtginode_lockdep_setup( #else #define xfs_rtginode_lockdep_setup(ip, rgno, type) do { } while (0) #endif /* CONFIG_PROVE_LOCKING */ + +struct xfs_rtginode_ops { + const char *name; /* short name */ + + enum xfs_metafile_type metafile_type; + + /* Does the fs have this feature? */ + bool (*enabled)(struct xfs_mount *mp); + + /* Create this rtgroup metadata inode and initialize it. */ + int (*create)(struct xfs_rtgroup *rtg, + struct xfs_inode *ip, + struct xfs_trans *tp, + bool init); +}; + +static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = { +}; + +/* Return the shortname of this rtgroup inode. */ +const char * +xfs_rtginode_name( + enum xfs_rtg_inodes type) +{ + return xfs_rtginode_ops[type].name; +} + +/* Should this rtgroup inode be present? */ +bool +xfs_rtginode_enabled( + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type) +{ + const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; + + if (!ops->enabled) + return true; + return ops->enabled(rtg->rtg_mount); +} + +/* Load and existing rtgroup inode into the rtgroup structure. */ +int +xfs_rtginode_load( + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type, + struct xfs_trans *tp) +{ + struct xfs_mount *mp = tp->t_mountp; + const char *path; + struct xfs_inode *ip; + const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; + int error; + + if (!xfs_rtginode_enabled(rtg, type)) + return 0; + + if (!mp->m_rtdirip) + return -EFSCORRUPTED; + + path = xfs_rtginode_path(rtg->rtg_rgno, type); + if (!path) + return -ENOMEM; + error = xfs_metadir_load(tp, mp->m_rtdirip, path, ops->metafile_type, + &ip); + kfree(path); + + if (error) + return error; + + if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && + ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) { + xfs_irele(ip); + return -EFSCORRUPTED; + } + + if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg->rtg_rgno)) { + xfs_irele(ip); + return -EFSCORRUPTED; + } + + xfs_rtginode_lockdep_setup(ip, rtg->rtg_rgno, type); + rtg->rtg_inodes[type] = ip; + return 0; +} + +/* Release an rtgroup metadata inode. */ +void +xfs_rtginode_irele( + struct xfs_inode **ipp) +{ + if (*ipp) + xfs_irele(*ipp); + *ipp = NULL; +} + +/* Add a metadata inode for a realtime rmap btree. */ +int +xfs_rtginode_create( + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type, + bool init) +{ + const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_metadir_update upd = { + .dp = mp->m_rtdirip, + .metafile_type = ops->metafile_type, + }; + int error; + + if (!xfs_rtginode_enabled(rtg, type)) + return 0; + + if (!mp->m_rtdirip) + return -EFSCORRUPTED; + + upd.path = xfs_rtginode_path(rtg->rtg_rgno, type); + if (!upd.path) + return -ENOMEM; + + error = xfs_metadir_start_create(&upd); + if (error) + goto out_path; + + error = xfs_metadir_create(&upd, S_IFREG); + if (error) + return error; + + xfs_rtginode_lockdep_setup(upd.ip, rtg->rtg_rgno, type); + + upd.ip->i_projid = rtg->rtg_rgno; + error = ops->create(rtg, upd.ip, upd.tp, init); + if (error) + goto out_cancel; + + error = xfs_metadir_commit(&upd); + if (error) + goto out_path; + + kfree(upd.path); + xfs_finish_inode_setup(upd.ip); + rtg->rtg_inodes[type] = upd.ip; + return 0; + +out_cancel: + xfs_metadir_cancel(&upd, error); + /* Have to finish setting up the inode to ensure it's deleted. */ + if (upd.ip) { + xfs_finish_inode_setup(upd.ip); + xfs_irele(upd.ip); + } +out_path: + kfree(upd.path); + return error; +} + +/* Create the parent directory for all rtgroup inodes and load it. */ +int +xfs_rtginode_mkdir_parent( + struct xfs_mount *mp) +{ + if (!mp->m_metadirip) + return -EFSCORRUPTED; + + return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip); +} + +/* Load the parent directory of all rtgroup inodes. */ +int +xfs_rtginode_load_parent( + struct xfs_trans *tp) +{ + struct xfs_mount *mp = tp->t_mountp; + + if (!mp->m_metadirip) + return -EFSCORRUPTED; + + return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups", + XFS_METAFILE_DIR, &mp->m_rtdirip); +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index d2eb2cd5775dd..b5c769211b4bb 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -9,6 +9,14 @@ struct xfs_mount; struct xfs_trans; +enum xfs_rtg_inodes { + XFS_RTGI_MAX, +}; + +#ifdef MAX_LOCKDEP_SUBCLASSES +static_assert(XFS_RTGI_MAX <= MAX_LOCKDEP_SUBCLASSES); +#endif + /* * Realtime group incore structure, similar to the per-AG structure. */ @@ -19,6 +27,9 @@ struct xfs_rtgroup { atomic_t rtg_active_ref; /* active reference count */ wait_queue_head_t rtg_active_wq;/* woken active_ref falls to zero */ + /* per-rtgroup metadata inodes */ + struct xfs_inode *rtg_inodes[1 /* hack */]; + /* Number of blocks in this group */ xfs_rtxnum_t rtg_extents; @@ -218,6 +229,23 @@ void xfs_rtgroup_lock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); void xfs_rtgroup_trans_join(struct xfs_trans *tp, struct xfs_rtgroup *rtg, unsigned int rtglock_flags); + +int xfs_rtginode_mkdir_parent(struct xfs_mount *mp); +int xfs_rtginode_load_parent(struct xfs_trans *tp); + +const char *xfs_rtginode_name(enum xfs_rtg_inodes type); +bool xfs_rtginode_enabled(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type); +int xfs_rtginode_load(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type, + struct xfs_trans *tp); +int xfs_rtginode_create(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type, + bool init); +void xfs_rtginode_irele(struct xfs_inode **ipp); + +static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno, + enum xfs_rtg_inodes type) +{ + return kasprintf(GFP_KERNEL, "%u.%s", rgno, xfs_rtginode_name(type)); +} #else # define xfs_rtgroup_extents(mp, rgno) (0) # define xfs_rtgroup_lock(rtg, gf) ((void)0) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f69da6802e8c1..73959c26075a5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -94,6 +94,7 @@ typedef struct xfs_mount { struct xfs_inode *m_rsumip; /* pointer to summary inode */ struct xfs_inode *m_rootip; /* pointer to root directory */ struct xfs_inode *m_metadirip; /* ptr to metadata directory */ + struct xfs_inode *m_rtdirip; /* ptr to realtime metadir */ struct xfs_quotainfo *m_quotainfo; /* disk quota information */ struct xfs_buftarg *m_ddev_targp; /* data device */ struct xfs_buftarg *m_logdev_targp;/* log device */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 59898117f817d..dcdb726ebe4a0 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -28,6 +28,7 @@ #include "xfs_da_format.h" #include "xfs_metafile.h" #include "xfs_rtgroup.h" +#include "xfs_error.h" /* * Return whether there are any free extents in the size range given @@ -652,6 +653,16 @@ xfs_rtallocate_extent_size( return -ENOSPC; } +static void +xfs_rtunmount_rtg( + struct xfs_rtgroup *rtg) +{ + int i; + + for (i = 0; i < XFS_RTGI_MAX; i++) + xfs_rtginode_irele(&rtg->rtg_inodes[i]); +} + static int xfs_alloc_rsum_cache( struct xfs_mount *mp, @@ -1127,6 +1138,18 @@ xfs_rtmount_iread_extents( return error; } +static void +xfs_rtgroup_unmount_inodes( + struct xfs_mount *mp) +{ + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; + + for_each_rtgroup(mp, rgno, rtg) + xfs_rtunmount_rtg(rtg); + xfs_rtginode_irele(&mp->m_rtdirip); +} + /* * Get the bitmap and summary inodes and the summary cache into the mount * structure at mount time. @@ -1139,6 +1162,7 @@ xfs_rtmount_inodes( struct xfs_sb *sbp = &mp->m_sb; struct xfs_rtgroup *rtg; xfs_rgnumber_t rgno; + unsigned int i; int error; error = xfs_trans_alloc_empty(mp, &tp); @@ -1169,15 +1193,34 @@ xfs_rtmount_inodes( if (error) goto out_rele_summary; - for_each_rtgroup(mp, rgno, rtg) + if (xfs_has_rtgroups(mp) && mp->m_sb.sb_rgcount > 0) { + error = xfs_rtginode_load_parent(tp); + if (error) + goto out_rele_rtdir; + } + + for_each_rtgroup(mp, rgno, rtg) { rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg->rtg_rgno); + for (i = 0; i < XFS_RTGI_MAX; i++) { + error = xfs_rtginode_load(rtg, i, tp); + if (error) { + xfs_rtgroup_rele(rtg); + goto out_rele_inodes; + } + } + } + error = xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); if (error) goto out_rele_summary; xfs_trans_cancel(tp); return 0; +out_rele_inodes: + xfs_rtgroup_unmount_inodes(mp); +out_rele_rtdir: + xfs_rtginode_irele(&mp->m_rtdirip); out_rele_summary: xfs_irele(mp->m_rsumip); out_rele_bitmap: @@ -1192,6 +1235,9 @@ xfs_rtunmount_inodes( struct xfs_mount *mp) { kvfree(mp->m_rsum_cache); + + xfs_rtgroup_unmount_inodes(mp); + xfs_rtginode_irele(&mp->m_rtdirip); if (mp->m_rbmip) xfs_irele(mp->m_rbmip); if (mp->m_rsumip) From patchwork Fri Aug 23 00:18:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774430 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E71341DA3D for ; Fri, 23 Aug 2024 00:18:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372315; cv=none; b=jnCTdPfyGZRQ7x61yktlGGWUAnImMRNpKQ1VYyRLmQcjtJJVf7qZ0nE8FwMNKMXC8TVrhxGSzT4gNcQTOPcPFqmT+k/DgGiDkKTuGirt4kq3lLJH0js6k3NXuswvI737Ik3hrladLRozb10pPqxGkv3lW38KCrT9NfAB0/Wi3uQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372315; c=relaxed/simple; bh=KBCOWGEAfiSxZTKJ76yBY1Au9OFD1BVFFCHXf+AK0hE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NyQvaXBuBoDIsn6/sG+IuDbmvWt6ySzrSUIei0OF5yee4pJIEj2yL1eIDo8EYvwu0RfR614oVrL0NOKINQij77ylvvtCRzXavDWVAgOaITd1Zwu2RyTS2MrlcAQtL8yZ7nbWZ/wzavUauFJwBd4ASabcfrhOGEO9su5WahCPeGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=shMxfBrl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="shMxfBrl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 696B4C32782; Fri, 23 Aug 2024 00:18:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372314; bh=KBCOWGEAfiSxZTKJ76yBY1Au9OFD1BVFFCHXf+AK0hE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=shMxfBrlWeNN90/RooFtKbPFVyrg6WqdNCjFX9TsBZtloxqKZjBvZC2otbDpRcQr5 CUNzlqj8YSJxgtUQRgK1XnYoJyecD3F2NPvuvlQ4HOo/ZZLngmzOvkSK3w4sEvI20J eC0BtO8DdJnGRmsqOsU71A0d8gXYxZAtRIdiq6upsE9EeQMPtYMeH9ux5WBweOJsvR IAnWlqQbWSil2Q1G6CLH6/LvsGC1UIWI0PQUj7E7QUd7tXtNMj6Rl8ZFpDqZj1QMdt 8pjyoNtgp3j/c5YdhcHZgbKA1WOgDSaG+/pcUpHegf18oBp2CKw6V7fOdeiLLnFiQL 6kNSXawQj9U7Q== Date: Thu, 22 Aug 2024 17:18:33 -0700 Subject: [PATCH 15/24] xfs: add rtgroup-based realtime scrubbing context management From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087504.59588.10025312195068387840.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create a pair of helpers to deal with setting up the necessary incore context to check metadata records against the realtime metadata. Right now this is limited to locking the realtime bitmap and summary inodes, but as we add rmap and reflink to the realtime device this will grow to include btree cursors. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/scrub/common.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/common.h | 30 +++++++++++++++++++ fs/xfs/scrub/scrub.c | 29 ++++++++++++++++++ fs/xfs/scrub/scrub.h | 13 ++++++++ 4 files changed, 150 insertions(+) diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 5245943496c8b..8d44f18787c42 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -34,6 +34,7 @@ #include "xfs_quota.h" #include "xfs_exchmaps.h" #include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" @@ -121,6 +122,17 @@ xchk_process_error( XFS_SCRUB_OFLAG_CORRUPT, __return_address); } +bool +xchk_process_rt_error( + struct xfs_scrub *sc, + xfs_rgnumber_t rgno, + xfs_rgblock_t rgbno, + int *error) +{ + return __xchk_process_error(sc, rgno, rgbno, error, + XFS_SCRUB_OFLAG_CORRUPT, __return_address); +} + bool xchk_xref_process_error( struct xfs_scrub *sc, @@ -684,6 +696,72 @@ xchk_ag_init( return 0; } +#ifdef CONFIG_XFS_RT +/* + * For scrubbing a realtime group, grab all the in-core resources we'll need to + * check the metadata, which means taking the ILOCK of the realtime group's + * metadata inodes. Callers must not join these inodes to the transaction with + * non-zero lockflags or concurrency problems will result. The @rtglock_flags + * argument takes XFS_RTGLOCK_* flags. + */ +int +xchk_rtgroup_init( + struct xfs_scrub *sc, + xfs_rgnumber_t rgno, + struct xchk_rt *sr) +{ + ASSERT(sr->rtg == NULL); + ASSERT(sr->rtlock_flags == 0); + + sr->rtg = xfs_rtgroup_get(sc->mp, rgno); + if (!sr->rtg) + return -ENOENT; + return 0; +} + +void +xchk_rtgroup_lock( + struct xchk_rt *sr, + unsigned int rtglock_flags) +{ + xfs_rtgroup_lock(sr->rtg, rtglock_flags); + sr->rtlock_flags = rtglock_flags; +} + +/* + * Unlock the realtime group. This must be done /after/ committing (or + * cancelling) the scrub transaction. + */ +static void +xchk_rtgroup_unlock( + struct xchk_rt *sr) +{ + ASSERT(sr->rtg != NULL); + + if (sr->rtlock_flags) { + xfs_rtgroup_unlock(sr->rtg, sr->rtlock_flags); + sr->rtlock_flags = 0; + } +} + +/* + * Unlock the realtime group and release its resources. This must be done + * /after/ committing (or cancelling) the scrub transaction. + */ +void +xchk_rtgroup_free( + struct xfs_scrub *sc, + struct xchk_rt *sr) +{ + ASSERT(sr->rtg != NULL); + + xchk_rtgroup_unlock(sr); + + xfs_rtgroup_put(sr->rtg); + sr->rtg = NULL; +} +#endif /* CONFIG_XFS_RT */ + /* Per-scrubber setup functions */ void diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 27e5bf8f7c60b..0d531770e83b0 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -12,6 +12,8 @@ void xchk_trans_cancel(struct xfs_scrub *sc); bool xchk_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); +bool xchk_process_rt_error(struct xfs_scrub *sc, xfs_rgnumber_t rgno, + xfs_rgblock_t rgbno, int *error); bool xchk_fblock_process_error(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error); @@ -118,6 +120,34 @@ xchk_ag_init_existing( return error == -ENOENT ? -EFSCORRUPTED : error; } +#ifdef CONFIG_XFS_RT + +/* All the locks we need to check an rtgroup. */ +#define XCHK_RTGLOCK_ALL (XFS_RTGLOCK_BITMAP) + +int xchk_rtgroup_init(struct xfs_scrub *sc, xfs_rgnumber_t rgno, + struct xchk_rt *sr); + +static inline int +xchk_rtgroup_init_existing( + struct xfs_scrub *sc, + xfs_rgnumber_t rgno, + struct xchk_rt *sr) +{ + int error = xchk_rtgroup_init(sc, rgno, sr); + + return error == -ENOENT ? -EFSCORRUPTED : error; +} + +void xchk_rtgroup_lock(struct xchk_rt *sr, unsigned int rtglock_flags); +void xchk_rtgroup_free(struct xfs_scrub *sc, struct xchk_rt *sr); +#else +# define xchk_rtgroup_init(sc, rgno, sr) (-EFSCORRUPTED) +# define xchk_rtgroup_init_existing(sc, rgno, sr) (-EFSCORRUPTED) +# define xchk_rtgroup_lock(sc, lockflags) do { } while (0) +# define xchk_rtgroup_free(sc, sr) do { } while (0) +#endif /* CONFIG_XFS_RT */ + int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa); void xchk_ag_btcur_free(struct xchk_ag *sa); diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 04a7a5944837d..9d9990d5c6c48 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -225,6 +225,8 @@ xchk_teardown( xfs_trans_cancel(sc->tp); sc->tp = NULL; } + if (sc->sr.rtg) + xchk_rtgroup_free(sc, &sc->sr); if (sc->ip) { if (sc->ilock_flags) xchk_iunlock(sc, sc->ilock_flags); @@ -498,6 +500,33 @@ xchk_validate_inputs( break; case ST_GENERIC: break; + case ST_RTGROUP: + if (sm->sm_ino || sm->sm_gen) + goto out; + if (xfs_has_rtgroups(mp)) { + /* + * On a rtgroups filesystem, there won't be an rtbitmap + * or rtsummary file for group 0 unless there's + * actually a realtime volume attached. However, older + * xfs_scrub always calls the rtbitmap/rtsummary + * scrubbers with sm_agno==0 so transform the error + * code to ENOENT. + */ + if (sm->sm_agno >= mp->m_sb.sb_rgcount) { + if (sm->sm_agno == 0) + error = -ENOENT; + goto out; + } + } else { + /* + * Prior to rtgroups, the rtbitmap/rtsummary scrubbers + * accepted sm_agno==0, so we still accept that for + * scrubbing pre-rtgroups filesystems. + */ + if (sm->sm_agno != 0) + goto out; + } + break; default: goto out; } diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index c688ff4fc7fc4..f73c6d0d90a11 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -74,6 +74,7 @@ enum xchk_type { ST_FS, /* per-FS metadata */ ST_INODE, /* per-inode metadata */ ST_GENERIC, /* determined by the scrubber */ + ST_RTGROUP, /* rtgroup metadata */ }; struct xchk_meta_ops { @@ -118,6 +119,15 @@ struct xchk_ag { struct xfs_btree_cur *refc_cur; }; +/* Inode lock state for the RT volume. */ +struct xchk_rt { + /* incore rtgroup, if applicable */ + struct xfs_rtgroup *rtg; + + /* XFS_RTGLOCK_* lock state if locked */ + unsigned int rtlock_flags; +}; + struct xfs_scrub { /* General scrub state. */ struct xfs_mount *mp; @@ -179,6 +189,9 @@ struct xfs_scrub { /* State tracking for single-AG operations. */ struct xchk_ag sa; + + /* State tracking for realtime operations. */ + struct xchk_rt sr; }; /* XCHK state flags grow up from zero, XREP state flags grown down from 2^31 */ From patchwork Fri Aug 23 00:18:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774431 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 442FB12B6C for ; Fri, 23 Aug 2024 00:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372330; cv=none; b=oRoklfGMZE0ZmoIGmSKzohb+owg8ECMkwVRBEBlWfn+duB2IngbUxVNr54FGCLQ0b9UHh1/DWmj7zx6fG1qOpo2ZGWMuBFHUKYCDwfeL6bVsW3Ff6WTHxyCuamFhqZqeJOxXxGd9CmA0b4RoNWXI0bmqR+jDMLaYNXnU/UQW1tQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372330; c=relaxed/simple; bh=vbuVrKIw7XIPoWd7csR7pd7P71aupyDs18eaNjhE9ww=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qXhPSnH3++ZYMVx5j2xllyfwJmUDPW9FKS0mwuIXc7ivMKMWRtACW+qd2oR+iaRKDs/As3Z+puFUkD0d74nNY9iiZF4wZZ48bsWQ2eK+MziVp4IgyI/RIjQ/+rKrASlQlnnFKyGE59Cb4+mN9sg8jjVGF2pN7tl9UngOcWer4NU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Wl379b8J; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Wl379b8J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 060A9C32782; Fri, 23 Aug 2024 00:18:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372330; bh=vbuVrKIw7XIPoWd7csR7pd7P71aupyDs18eaNjhE9ww=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Wl379b8JhScQUjY5y0NsYS72p67UbXz6BEPu02ANg1k+OoLjfgwbdIJOQIe346AlX NSWHioCXkg7tK/N0NETvJZDs37KgOcBkPE0wFsHoOPxjPWM5gdmCpUb3I5vq4lsPbl D5BRJx0TCZ6BLmaxt8AAfnyLM5hVRSIfBChMZS4IgkDn+qvAr3dOZorb9o4U/VnpSc q7xPLFMkfboC0zU6HzP7BBqvpgRBu+X8x92apUxhxP3Oda8nTCuOeCoxUqSRmrkQba Xyj+78clMvC54c1vVQTuoefhr6Zi92TJsU2ZcoG+a/yCxDR1USiStx1iNstZIGb9A/ FGrNm8gVQrPEg== Date: Thu, 22 Aug 2024 17:18:49 -0700 Subject: [PATCH 16/24] xfs: move RT bitmap and summary information to the rtgroup From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087522.59588.18128505844339338904.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Move the pointers to the RT bitmap and summary inodes as well as the summary cache to the rtgroups structure to prepare for having a separate bitmap and summary inodes for each rtgroup. Code using the inodes now needs to operate on a rtgroup. Where easily possible such code is converted to iterate over all rtgroups, else rtgroup 0 (the only one that can currently exist) is hardcoded. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 40 +++- fs/xfs/libxfs/xfs_rtbitmap.c | 174 ++++++++-------- fs/xfs/libxfs/xfs_rtbitmap.h | 68 +++--- fs/xfs/libxfs/xfs_rtgroup.c | 90 +++++++- fs/xfs/libxfs/xfs_rtgroup.h | 14 + fs/xfs/scrub/bmap.c | 13 + fs/xfs/scrub/fscounters.c | 26 +- fs/xfs/scrub/repair.c | 24 ++ fs/xfs/scrub/repair.h | 7 + fs/xfs/scrub/rtbitmap.c | 45 ++-- fs/xfs/scrub/rtsummary.c | 93 +++++---- fs/xfs/scrub/rtsummary_repair.c | 7 - fs/xfs/scrub/scrub.c | 4 fs/xfs/xfs_discard.c | 100 ++++++--- fs/xfs/xfs_fsmap.c | 143 ++++++++----- fs/xfs/xfs_mount.h | 10 - fs/xfs/xfs_qm.c | 27 ++- fs/xfs/xfs_rtalloc.c | 415 ++++++++++++++++++++++----------------- 18 files changed, 763 insertions(+), 537 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 3a8796f165d6d..a1ee8dc91d6ba 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5167,6 +5167,34 @@ xfs_bmap_del_extent_cow( ip->i_delayed_blks -= del->br_blockcount; } +static int +xfs_bmap_free_rtblocks( + struct xfs_trans *tp, + struct xfs_bmbt_irec *del) +{ + struct xfs_rtgroup *rtg; + int error; + + rtg = xfs_rtgroup_grab(tp->t_mountp, 0); + if (!rtg) + return -EIO; + + /* + * Ensure the bitmap and summary inodes are locked and joined to the + * transaction before modifying them. + */ + if (!(tp->t_flags & XFS_TRANS_RTBITMAP_LOCKED)) { + tp->t_flags |= XFS_TRANS_RTBITMAP_LOCKED; + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP); + xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_BITMAP); + } + + error = xfs_rtfree_blocks(tp, rtg, del->br_startblock, + del->br_blockcount); + xfs_rtgroup_rele(rtg); + return error; +} + /* * Called by xfs_bmapi to update file extent records and the btree * after removing space. @@ -5382,17 +5410,7 @@ xfs_bmap_del_extent_real( if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) { xfs_refcount_decrease_extent(tp, del); } else if (xfs_ifork_is_realtime(ip, whichfork)) { - /* - * Ensure the bitmap and summary inodes are locked - * and joined to the transaction before modifying them. - */ - if (!(tp->t_flags & XFS_TRANS_RTBITMAP_LOCKED)) { - tp->t_flags |= XFS_TRANS_RTBITMAP_LOCKED; - xfs_rtbitmap_lock(mp); - xfs_rtbitmap_trans_join(tp); - } - error = xfs_rtfree_blocks(tp, del->br_startblock, - del->br_blockcount); + error = xfs_bmap_free_rtblocks(tp, del); } else { unsigned int efi_flags = 0; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 27a4472402bac..41de2f071934f 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -90,12 +90,12 @@ xfs_rtbuf_get( if (issum) { cbpp = &args->sumbp; coffp = &args->sumoff; - ip = mp->m_rsumip; + ip = args->rtg->rtg_inodes[XFS_RTGI_SUMMARY]; type = XFS_BLFT_RTSUMMARY_BUF; } else { cbpp = &args->rbmbp; coffp = &args->rbmoff; - ip = mp->m_rbmip; + ip = args->rtg->rtg_inodes[XFS_RTGI_BITMAP]; type = XFS_BLFT_RTBITMAP_BUF; } @@ -503,6 +503,7 @@ xfs_rtmodify_summary( { struct xfs_mount *mp = args->mp; xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno); + uint8_t *rsum_cache = args->rtg->rtg_rsum_cache; unsigned int infoword; xfs_suminfo_t val; int error; @@ -514,11 +515,11 @@ xfs_rtmodify_summary( infoword = xfs_rtsumoffs_to_infoword(mp, so); val = xfs_suminfo_add(args, infoword, delta); - if (mp->m_rsum_cache) { - if (val == 0 && log + 1 == mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno] = log; - if (val != 0 && log >= mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno] = log + 1; + if (rsum_cache) { + if (val == 0 && log + 1 == rsum_cache[bbno]) + rsum_cache[bbno] = log; + if (val != 0 && log >= rsum_cache[bbno]) + rsum_cache[bbno] = log + 1; } xfs_trans_log_rtsummary(args, infoword); @@ -737,7 +738,7 @@ xfs_rtfree_range( /* * Find the next allocated block (end of allocated extent). */ - error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, + error = xfs_rtfind_forw(args, end, args->rtg->rtg_extents - 1, &postblock); if (error) return error; @@ -961,19 +962,22 @@ xfs_rtcheck_alloc_range( int xfs_rtfree_extent( struct xfs_trans *tp, /* transaction pointer */ + struct xfs_rtgroup *rtg, xfs_rtxnum_t start, /* starting rtext number to free */ xfs_rtxlen_t len) /* length of extent freed */ { struct xfs_mount *mp = tp->t_mountp; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; struct xfs_rtalloc_args args = { .mp = mp, .tp = tp, + .rtg = rtg, }; int error; struct timespec64 atime; - ASSERT(mp->m_rbmip->i_itemp != NULL); - xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL); + ASSERT(rbmip->i_itemp != NULL); + xfs_assert_ilocked(rbmip, XFS_ILOCK_EXCL); error = xfs_rtcheck_alloc_range(&args, start, len); if (error) @@ -996,13 +1000,13 @@ xfs_rtfree_extent( */ if (tp->t_frextents_delta + mp->m_sb.sb_frextents == mp->m_sb.sb_rextents) { - if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) - mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; + if (!(rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) + rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; - atime = inode_get_atime(VFS_I(mp->m_rbmip)); + atime = inode_get_atime(VFS_I(rbmip)); atime.tv_sec = 0; - inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime); - xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); + inode_set_atime_to_ts(VFS_I(rbmip), atime); + xfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); } error = 0; out: @@ -1018,6 +1022,7 @@ xfs_rtfree_extent( int xfs_rtfree_blocks( struct xfs_trans *tp, + struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno, xfs_filblks_t rtlen) { @@ -1038,21 +1043,23 @@ xfs_rtfree_blocks( return -EIO; } - return xfs_rtfree_extent(tp, xfs_rtb_to_rtx(mp, rtbno), - xfs_rtb_to_rtx(mp, rtlen)); + return xfs_rtfree_extent(tp, rtg, xfs_rtb_to_rtx(mp, rtbno), + xfs_extlen_to_rtxlen(mp, rtlen)); } /* Find all the free records within a given range. */ int xfs_rtalloc_query_range( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, xfs_rtxnum_t start, xfs_rtxnum_t end, xfs_rtalloc_query_range_fn fn, void *priv) { + struct xfs_mount *mp = rtg->rtg_mount; struct xfs_rtalloc_args args = { + .rtg = rtg, .mp = mp, .tp = tp, }; @@ -1060,10 +1067,10 @@ xfs_rtalloc_query_range( if (start > end) return -EINVAL; - if (start == end || start >= mp->m_sb.sb_rextents) + if (start == end || start >= rtg->rtg_extents) return 0; - end = min(end, mp->m_sb.sb_rextents - 1); + end = min(end, rtg->rtg_extents - 1); /* Iterate the bitmap, looking for discrepancies. */ while (start <= end) { @@ -1086,7 +1093,7 @@ xfs_rtalloc_query_range( rec.ar_startext = start; rec.ar_extcount = rtend - start + 1; - error = fn(mp, tp, &rec, priv); + error = fn(rtg, tp, &rec, priv); if (error) break; } @@ -1101,26 +1108,27 @@ xfs_rtalloc_query_range( /* Find all the free records. */ int xfs_rtalloc_query_all( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, xfs_rtalloc_query_range_fn fn, void *priv) { - return xfs_rtalloc_query_range(mp, tp, 0, mp->m_sb.sb_rextents - 1, fn, + return xfs_rtalloc_query_range(rtg, tp, 0, rtg->rtg_extents - 1, fn, priv); } /* Is the given extent all free? */ int xfs_rtalloc_extent_is_free( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free) { struct xfs_rtalloc_args args = { - .mp = mp, + .mp = rtg->rtg_mount, + .rtg = rtg, .tp = tp, }; xfs_rtxnum_t end; @@ -1161,65 +1169,6 @@ xfs_rtsummary_blockcount( return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); } -/* Lock both realtime free space metadata inodes for a freespace update. */ -void -xfs_rtbitmap_lock( - struct xfs_mount *mp) -{ - xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); - xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); -} - -/* - * Join both realtime free space metadata inodes to the transaction. The - * ILOCKs will be released on transaction commit. - */ -void -xfs_rtbitmap_trans_join( - struct xfs_trans *tp) -{ - xfs_trans_ijoin(tp, tp->t_mountp->m_rbmip, XFS_ILOCK_EXCL); - xfs_trans_ijoin(tp, tp->t_mountp->m_rsumip, XFS_ILOCK_EXCL); -} - -/* Unlock both realtime free space metadata inodes after a freespace update. */ -void -xfs_rtbitmap_unlock( - struct xfs_mount *mp) -{ - xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); - xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); -} - -/* - * Lock the realtime free space metadata inodes for a freespace scan. Callers - * must walk metadata blocks in order of increasing file offset. - */ -void -xfs_rtbitmap_lock_shared( - struct xfs_mount *mp, - unsigned int rbmlock_flags) -{ - if (rbmlock_flags & XFS_RBMLOCK_BITMAP) - xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); - - if (rbmlock_flags & XFS_RBMLOCK_SUMMARY) - xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM); -} - -/* Unlock the realtime free space metadata inodes after a freespace scan. */ -void -xfs_rtbitmap_unlock_shared( - struct xfs_mount *mp, - unsigned int rbmlock_flags) -{ - if (rbmlock_flags & XFS_RBMLOCK_SUMMARY) - xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM); - - if (rbmlock_flags & XFS_RBMLOCK_BITMAP) - xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); -} - static int xfs_rtfile_alloc_blocks( struct xfs_inode *ip, @@ -1260,21 +1209,25 @@ xfs_rtfile_alloc_blocks( /* Get a buffer for the block. */ static int xfs_rtfile_initialize_block( - struct xfs_inode *ip, + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type, xfs_fsblock_t fsbno, void *data) { - struct xfs_mount *mp = ip->i_mount; + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_inode *ip = rtg->rtg_inodes[type]; struct xfs_trans *tp; struct xfs_buf *bp; const size_t copylen = mp->m_blockwsize << XFS_WORDLOG; enum xfs_blft buf_type; int error; - if (ip == mp->m_rsumip) - buf_type = XFS_BLFT_RTSUMMARY_BUF; - else + if (type == XFS_RTGI_BITMAP) buf_type = XFS_BLFT_RTBITMAP_BUF; + else if (type == XFS_RTGI_SUMMARY) + buf_type = XFS_BLFT_RTSUMMARY_BUF; + else + return -EINVAL; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp); if (error) @@ -1306,12 +1259,13 @@ xfs_rtfile_initialize_block( */ int xfs_rtfile_initialize_blocks( - struct xfs_inode *ip, /* inode (bitmap/summary) */ + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb, /* offset to start from */ xfs_fileoff_t end_fsb, /* offset to allocate to */ void *data) /* data to fill the blocks */ { - struct xfs_mount *mp = ip->i_mount; + struct xfs_mount *mp = rtg->rtg_mount; const size_t copylen = mp->m_blockwsize << XFS_WORDLOG; while (offset_fsb < end_fsb) { @@ -1319,8 +1273,8 @@ xfs_rtfile_initialize_blocks( xfs_filblks_t i; int error; - error = xfs_rtfile_alloc_blocks(ip, offset_fsb, - end_fsb - offset_fsb, &map); + error = xfs_rtfile_alloc_blocks(rtg->rtg_inodes[type], + offset_fsb, end_fsb - offset_fsb, &map); if (error) return error; @@ -1330,7 +1284,7 @@ xfs_rtfile_initialize_blocks( * Do this one block per transaction, to keep it simple. */ for (i = 0; i < map.br_blockcount; i++) { - error = xfs_rtfile_initialize_block(ip, + error = xfs_rtfile_initialize_block(rtg, type, map.br_startblock + i, data); if (error) return error; @@ -1343,3 +1297,35 @@ xfs_rtfile_initialize_blocks( return 0; } + +int +xfs_rtbitmap_create( + struct xfs_rtgroup *rtg, + struct xfs_inode *ip, + struct xfs_trans *tp, + bool init) +{ + struct xfs_mount *mp = rtg->rtg_mount; + + ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; + if (init && !xfs_has_rtgroups(mp)) { + ip->i_diflags |= XFS_DIFLAG_NEWRTBM; + inode_set_atime(VFS_I(ip), 0, 0); + } + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + return 0; +} + +int +xfs_rtsummary_create( + struct xfs_rtgroup *rtg, + struct xfs_inode *ip, + struct xfs_trans *tp, + bool init) +{ + struct xfs_mount *mp = rtg->rtg_mount; + + ip->i_disk_size = mp->m_rsumblocks * mp->m_sb.sb_blocksize; + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + return 0; +} diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 140513d1d6bcf..e4994a3e461d3 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -6,7 +6,10 @@ #ifndef __XFS_RTBITMAP_H__ #define __XFS_RTBITMAP_H__ +#include "xfs_rtgroup.h" + struct xfs_rtalloc_args { + struct xfs_rtgroup *rtg; struct xfs_mount *mp; struct xfs_trans *tp; @@ -268,7 +271,7 @@ struct xfs_rtalloc_rec { }; typedef int (*xfs_rtalloc_query_range_fn)( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv); @@ -291,53 +294,41 @@ int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, xfs_fileoff_t bbno, int delta); int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, xfs_rtxlen_t len); -int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, +int xfs_rtalloc_query_range(struct xfs_rtgroup *rtg, struct xfs_trans *tp, xfs_rtxnum_t start, xfs_rtxnum_t end, xfs_rtalloc_query_range_fn fn, void *priv); -int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtalloc_query_range_fn fn, - void *priv); -int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxlen_t len, - bool *is_free); -/* - * Free an extent in the realtime subvolume. Length is expressed in - * realtime extents, as is the block number. - */ -int /* error */ -xfs_rtfree_extent( - struct xfs_trans *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number to free */ - xfs_rtxlen_t len); /* length of extent freed */ - +int xfs_rtalloc_query_all(struct xfs_rtgroup *rtg, struct xfs_trans *tp, + xfs_rtalloc_query_range_fn fn, void *priv); +int xfs_rtalloc_extent_is_free(struct xfs_rtgroup *rtg, struct xfs_trans *tp, + xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free); +int xfs_rtfree_extent(struct xfs_trans *tp, struct xfs_rtgroup *rtg, + xfs_rtxnum_t start, xfs_rtxlen_t len); /* Same as above, but in units of rt blocks. */ -int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, - xfs_filblks_t rtlen); +int xfs_rtfree_blocks(struct xfs_trans *tp, struct xfs_rtgroup *rtg, + xfs_fsblock_t rtbno, xfs_filblks_t rtlen); xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents); xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, unsigned int rsumlevels, xfs_extlen_t rbmblocks); -int xfs_rtfile_initialize_blocks(struct xfs_inode *ip, - xfs_fileoff_t offset_fsb, xfs_fileoff_t end_fsb, void *data); +int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb, + xfs_fileoff_t end_fsb, void *data); +int xfs_rtbitmap_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip, + struct xfs_trans *tp, bool init); +int xfs_rtsummary_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip, + struct xfs_trans *tp, bool init); -void xfs_rtbitmap_lock(struct xfs_mount *mp); -void xfs_rtbitmap_unlock(struct xfs_mount *mp); -void xfs_rtbitmap_trans_join(struct xfs_trans *tp); - -/* Lock the rt bitmap inode in shared mode */ -#define XFS_RBMLOCK_BITMAP (1U << 0) -/* Lock the rt summary inode in shared mode */ -#define XFS_RBMLOCK_SUMMARY (1U << 1) - -void xfs_rtbitmap_lock_shared(struct xfs_mount *mp, - unsigned int rbmlock_flags); -void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp, - unsigned int rbmlock_flags); #else /* CONFIG_XFS_RT */ # define xfs_rtfree_extent(t,b,l) (-ENOSYS) -# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) + +static inline int xfs_rtfree_blocks(struct xfs_trans *tp, + struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno, + xfs_filblks_t rtlen) +{ + return -ENOSYS; +} # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) # define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) @@ -351,11 +342,6 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) return 0; } # define xfs_rtsummary_blockcount(mp, l, b) (0) -# define xfs_rtbitmap_lock(mp) do { } while (0) -# define xfs_rtbitmap_trans_join(tp) do { } while (0) -# define xfs_rtbitmap_unlock(mp) do { } while (0) -# define xfs_rtbitmap_lock_shared(mp, lf) do { } while (0) -# define xfs_rtbitmap_unlock_shared(mp, lf) do { } while (0) #endif /* CONFIG_XFS_RT */ #endif /* __XFS_RTBITMAP_H__ */ diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 50e4a56d749f0..4618caf344efd 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -207,10 +207,16 @@ xfs_rtgroup_lock( ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || !(rtglock_flags & XFS_RTGLOCK_BITMAP)); - if (rtglock_flags & XFS_RTGLOCK_BITMAP) - xfs_rtbitmap_lock(rtg->rtg_mount); - else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) - xfs_rtbitmap_lock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP); + if (rtglock_flags & XFS_RTGLOCK_BITMAP) { + /* + * Lock both realtime free space metadata inodes for a freespace + * update. + */ + xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL); + xfs_ilock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL); + } else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) { + xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED); + } } /* Unlock metadata inodes associated with this rt group. */ @@ -223,10 +229,12 @@ xfs_rtgroup_unlock( ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || !(rtglock_flags & XFS_RTGLOCK_BITMAP)); - if (rtglock_flags & XFS_RTGLOCK_BITMAP) - xfs_rtbitmap_unlock(rtg->rtg_mount); - else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) - xfs_rtbitmap_unlock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP); + if (rtglock_flags & XFS_RTGLOCK_BITMAP) { + xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL); + xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL); + } else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) { + xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED); + } } /* @@ -242,8 +250,12 @@ xfs_rtgroup_trans_join( ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)); - if (rtglock_flags & XFS_RTGLOCK_BITMAP) - xfs_rtbitmap_trans_join(tp); + if (rtglock_flags & XFS_RTGLOCK_BITMAP) { + xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_BITMAP], + XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_SUMMARY], + XFS_ILOCK_EXCL); + } } #ifdef CONFIG_PROVE_LOCKING @@ -314,6 +326,16 @@ struct xfs_rtginode_ops { }; static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = { + [XFS_RTGI_BITMAP] = { + .name = "bitmap", + .metafile_type = XFS_METAFILE_RTBITMAP, + .create = xfs_rtbitmap_create, + }, + [XFS_RTGI_SUMMARY] = { + .name = "summary", + .metafile_type = XFS_METAFILE_RTSUMMARY, + .create = xfs_rtsummary_create, + }, }; /* Return the shortname of this rtgroup inode. */ @@ -324,6 +346,14 @@ xfs_rtginode_name( return xfs_rtginode_ops[type].name; } +/* Return the metafile type of this rtgroup inode. */ +enum xfs_metafile_type +xfs_rtginode_metafile_type( + enum xfs_rtg_inodes type) +{ + return xfs_rtginode_ops[type].metafile_type; +} + /* Should this rtgroup inode be present? */ bool xfs_rtginode_enabled( @@ -345,7 +375,6 @@ xfs_rtginode_load( struct xfs_trans *tp) { struct xfs_mount *mp = tp->t_mountp; - const char *path; struct xfs_inode *ip; const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; int error; @@ -353,15 +382,36 @@ xfs_rtginode_load( if (!xfs_rtginode_enabled(rtg, type)) return 0; - if (!mp->m_rtdirip) - return -EFSCORRUPTED; - - path = xfs_rtginode_path(rtg->rtg_rgno, type); - if (!path) - return -ENOMEM; - error = xfs_metadir_load(tp, mp->m_rtdirip, path, ops->metafile_type, - &ip); - kfree(path); + if (!xfs_has_rtgroups(mp)) { + xfs_ino_t ino; + + switch (type) { + case XFS_RTGI_BITMAP: + ino = mp->m_sb.sb_rbmino; + break; + case XFS_RTGI_SUMMARY: + ino = mp->m_sb.sb_rsumino; + break; + default: + /* None of the other types exist on !rtgroups */ + return 0; + } + + error = xfs_trans_metafile_iget(tp, ino, ops->metafile_type, + &ip); + } else { + const char *path; + + if (!mp->m_rtdirip) + return -EFSCORRUPTED; + + path = xfs_rtginode_path(rtg->rtg_rgno, type); + if (!path) + return -ENOMEM; + error = xfs_metadir_load(tp, mp->m_rtdirip, path, + ops->metafile_type, &ip); + kfree(path); + } if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index b5c769211b4bb..e622b24a0d75f 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -10,6 +10,9 @@ struct xfs_mount; struct xfs_trans; enum xfs_rtg_inodes { + XFS_RTGI_BITMAP, /* allocation bitmap */ + XFS_RTGI_SUMMARY, /* allocation summary */ + XFS_RTGI_MAX, }; @@ -28,11 +31,19 @@ struct xfs_rtgroup { wait_queue_head_t rtg_active_wq;/* woken active_ref falls to zero */ /* per-rtgroup metadata inodes */ - struct xfs_inode *rtg_inodes[1 /* hack */]; + struct xfs_inode *rtg_inodes[XFS_RTGI_MAX]; /* Number of blocks in this group */ xfs_rtxnum_t rtg_extents; + /* + * Optional cache of rt summary level per bitmap block with the + * invariant that rtg_rsum_cache[bbno] > the maximum i for which + * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i. + * Reads and writes are serialized by the rsumip inode lock. + */ + uint8_t *rtg_rsum_cache; + #ifdef __KERNEL__ /* -- kernel only structures below this line -- */ spinlock_t rtg_state_lock; @@ -234,6 +245,7 @@ int xfs_rtginode_mkdir_parent(struct xfs_mount *mp); int xfs_rtginode_load_parent(struct xfs_trans *tp); const char *xfs_rtginode_name(enum xfs_rtg_inodes type); +enum xfs_metafile_type xfs_rtginode_metafile_type(enum xfs_rtg_inodes type); bool xfs_rtginode_enabled(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type); int xfs_rtginode_load(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type, struct xfs_trans *tp); diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 5ab2ac53c9200..69dac1bd6a83e 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -19,6 +19,7 @@ #include "xfs_bmap_btree.h" #include "xfs_rmap.h" #include "xfs_rmap_btree.h" +#include "xfs_rtgroup.h" #include "xfs_health.h" #include "scrub/scrub.h" #include "scrub/common.h" @@ -314,8 +315,20 @@ xchk_bmap_rt_iextent_xref( struct xchk_bmap_info *info, struct xfs_bmbt_irec *irec) { + int error; + + error = xchk_rtgroup_init_existing(info->sc, + xfs_rtb_to_rgno(ip->i_mount, irec->br_startblock), + &info->sc->sr); + if (!xchk_fblock_process_error(info->sc, info->whichfork, + irec->br_startoff, &error)) + return; + + xchk_rtgroup_lock(&info->sc->sr, XCHK_RTGLOCK_ALL); xchk_xref_is_used_rt_space(info->sc, irec->br_startblock, irec->br_blockcount); + + xchk_rtgroup_free(info->sc, &info->sc->sr); } /* Cross-reference a single datadev extent record. */ diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 1d3e98346933e..5f6449fc85dc0 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -19,6 +19,7 @@ #include "xfs_rtbitmap.h" #include "xfs_inode.h" #include "xfs_icache.h" +#include "xfs_rtgroup.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" @@ -388,7 +389,7 @@ xchk_fscount_aggregate_agcounts( #ifdef CONFIG_XFS_RT STATIC int xchk_fscount_add_frextent( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) @@ -409,6 +410,8 @@ xchk_fscount_count_frextents( struct xchk_fscounters *fsc) { struct xfs_mount *mp = sc->mp; + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; int error; fsc->frextents = 0; @@ -416,19 +419,20 @@ xchk_fscount_count_frextents( if (!xfs_has_realtime(mp)) return 0; - xfs_rtbitmap_lock_shared(sc->mp, XFS_RBMLOCK_BITMAP); - error = xfs_rtalloc_query_all(sc->mp, sc->tp, - xchk_fscount_add_frextent, fsc); - if (error) { - xchk_set_incomplete(sc); - goto out_unlock; + for_each_rtgroup(mp, rgno, rtg) { + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + error = xfs_rtalloc_query_all(rtg, sc->tp, + xchk_fscount_add_frextent, fsc); + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + if (error) { + xchk_set_incomplete(sc); + xfs_rtgroup_rele(rtg); + return error; + } } fsc->frextents_delayed = percpu_counter_sum(&mp->m_delalloc_rtextents); - -out_unlock: - xfs_rtbitmap_unlock_shared(sc->mp, XFS_RBMLOCK_BITMAP); - return error; + return 0; } #else STATIC int diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 01c0e863775d4..cb01a9bdfd6db 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -21,6 +21,7 @@ #include "xfs_rmap.h" #include "xfs_rmap_btree.h" #include "xfs_refcount_btree.h" +#include "xfs_rtbitmap.h" #include "xfs_extent_busy.h" #include "xfs_ag.h" #include "xfs_ag_resv.h" @@ -953,6 +954,29 @@ xrep_ag_init( return 0; } +#ifdef CONFIG_XFS_RT +/* + * Given a reference to a rtgroup structure, lock rtgroup btree inodes and + * create btree cursors. Must only be called to repair a regular rt file. + */ +int +xrep_rtgroup_init( + struct xfs_scrub *sc, + struct xfs_rtgroup *rtg, + struct xchk_rt *sr, + unsigned int rtglock_flags) +{ + ASSERT(sr->rtg == NULL); + + xfs_rtgroup_lock(rtg, rtglock_flags); + sr->rtlock_flags = rtglock_flags; + + /* Grab our own passive reference from the caller's ref. */ + sr->rtg = xfs_rtgroup_hold(rtg); + return 0; +} +#endif /* CONFIG_XFS_RT */ + /* Reinitialize the per-AG block reservation for the AG we just fixed. */ int xrep_reset_perag_resv( diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 90f9cb3b5ad8b..4052185743910 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -8,6 +8,7 @@ #include "xfs_quota_defs.h" +struct xfs_rtgroup; struct xchk_stats_run; static inline int xrep_notsupported(struct xfs_scrub *sc) @@ -106,6 +107,12 @@ int xrep_setup_inode(struct xfs_scrub *sc, const struct xfs_imap *imap); void xrep_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); int xrep_ag_init(struct xfs_scrub *sc, struct xfs_perag *pag, struct xchk_ag *sa); +#ifdef CONFIG_XFS_RT +int xrep_rtgroup_init(struct xfs_scrub *sc, struct xfs_rtgroup *rtg, + struct xchk_rt *sr, unsigned int rtglock_flags); +#else +# define xrep_rtgroup_init(sc, rtg, sr, lockflags) (-ENOSYS) +#endif /* CONFIG_XFS_RT */ /* Metadata revalidators */ diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 46583517377ff..6551b4374b89f 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -35,6 +35,10 @@ xchk_setup_rtbitmap( return -ENOMEM; sc->buf = rtb; + error = xchk_rtgroup_init(sc, sc->sm->sm_agno, &sc->sr); + if (error) + return error; + if (xchk_could_repair(sc)) { error = xrep_setup_rtbitmap(sc, rtb); if (error) @@ -45,7 +49,8 @@ xchk_setup_rtbitmap( if (error) return error; - error = xchk_install_live_inode(sc, sc->mp->m_rbmip); + error = xchk_install_live_inode(sc, + sc->sr.rtg->rtg_inodes[XFS_RTGI_BITMAP]); if (error) return error; @@ -53,18 +58,18 @@ xchk_setup_rtbitmap( if (error) return error; - xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); - /* * Now that we've locked the rtbitmap, we can't race with growfsrt * trying to expand the bitmap or change the size of the rt volume. * Hence it is safe to compute and check the geometry values. */ + xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP); if (mp->m_sb.sb_rblocks) { rtb->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); rtb->rextslog = xfs_compute_rextslog(rtb->rextents); rtb->rbmblocks = xfs_rtbitmap_blockcount(mp, rtb->rextents); } + return 0; } @@ -73,11 +78,12 @@ xchk_setup_rtbitmap( /* Scrub a free extent record from the realtime bitmap. */ STATIC int xchk_rtbitmap_rec( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) { + struct xfs_mount *mp = rtg->rtg_mount; struct xfs_scrub *sc = priv; xfs_rtblock_t startblock; xfs_filblks_t blockcount; @@ -140,18 +146,20 @@ xchk_rtbitmap( struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; + struct xfs_rtgroup *rtg = sc->sr.rtg; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; struct xchk_rtbitmap *rtb = sc->buf; int error; /* Is sb_rextents correct? */ if (mp->m_sb.sb_rextents != rtb->rextents) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } /* Is sb_rextslog correct? */ if (mp->m_sb.sb_rextslog != rtb->rextslog) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } @@ -160,17 +168,17 @@ xchk_rtbitmap( * case can we exceed 4bn bitmap blocks since the super field is a u32. */ if (rtb->rbmblocks > U32_MAX) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } if (mp->m_sb.sb_rbmblocks != rtb->rbmblocks) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } /* The bitmap file length must be aligned to an fsblock. */ - if (mp->m_rbmip->i_disk_size & mp->m_blockmask) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + if (rbmip->i_disk_size & mp->m_blockmask) { + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } @@ -179,8 +187,8 @@ xchk_rtbitmap( * growfsrt expands the bitmap file before updating sb_rextents, so the * file can be larger than sb_rbmblocks. */ - if (mp->m_rbmip->i_disk_size < XFS_FSB_TO_B(mp, rtb->rbmblocks)) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); + if (rbmip->i_disk_size < XFS_FSB_TO_B(mp, rtb->rbmblocks)) { + xchk_ino_set_corrupt(sc, rbmip->i_ino); return 0; } @@ -193,7 +201,7 @@ xchk_rtbitmap( if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; - error = xfs_rtalloc_query_all(mp, sc->tp, xchk_rtbitmap_rec, sc); + error = xfs_rtalloc_query_all(rtg, sc->tp, xchk_rtbitmap_rec, sc); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) return error; @@ -207,6 +215,8 @@ xchk_xref_is_used_rt_space( xfs_rtblock_t rtbno, xfs_extlen_t len) { + struct xfs_rtgroup *rtg = sc->sr.rtg; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; xfs_rtxnum_t startext; xfs_rtxnum_t endext; bool is_free; @@ -217,13 +227,10 @@ xchk_xref_is_used_rt_space( startext = xfs_rtb_to_rtx(sc->mp, rtbno); endext = xfs_rtb_to_rtx(sc->mp, rtbno + len - 1); - xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); - error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, + error = xfs_rtalloc_extent_is_free(rtg, sc->tp, startext, endext - startext + 1, &is_free); if (!xchk_should_check_xref(sc, &error, NULL)) - goto out_unlock; + return; if (is_free) - xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino); -out_unlock: - xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); + xchk_ino_xref_set_corrupt(sc, rbmip->i_ino); } diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 7c7366c98338b..43d509422053c 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -18,6 +18,7 @@ #include "xfs_bmap.h" #include "xfs_sb.h" #include "xfs_exchmaps.h" +#include "xfs_rtgroup.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" @@ -46,12 +47,19 @@ xchk_setup_rtsummary( struct xchk_rtsummary *rts; int error; + if (xchk_need_intent_drain(sc)) + xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); + rts = kvzalloc(struct_size(rts, words, mp->m_blockwsize), XCHK_GFP_FLAGS); if (!rts) return -ENOMEM; sc->buf = rts; + error = xchk_rtgroup_init(sc, sc->sm->sm_agno, &sc->sr); + if (error) + return error; + if (xchk_could_repair(sc)) { error = xrep_setup_rtsummary(sc, rts); if (error) @@ -73,7 +81,8 @@ xchk_setup_rtsummary( if (error) return error; - error = xchk_install_live_inode(sc, mp->m_rsumip); + error = xchk_install_live_inode(sc, + sc->sr.rtg->rtg_inodes[XFS_RTGI_SUMMARY]); if (error) return error; @@ -81,20 +90,17 @@ xchk_setup_rtsummary( if (error) return error; - /* - * Locking order requires us to take the rtbitmap first. We must be - * careful to unlock it ourselves when we are done with the rtbitmap - * file since the scrub infrastructure won't do that for us. Only - * then we can lock the rtsummary inode. - */ - xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); - xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); - /* * Now that we've locked the rtbitmap and rtsummary, we can't race with * growfsrt trying to expand the summary or change the size of the rt * volume. Hence it is safe to compute and check the geometry values. + * + * Note that there is no strict requirement for an exclusive lock on the + * summary here, but to keep the locking APIs simple we lock both inodes + * exclusively here. If we ever start caring about running concurrent + * fsmap with scrub this could be changed. */ + xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP); if (mp->m_sb.sb_rblocks) { int rextslog; @@ -105,6 +111,7 @@ xchk_setup_rtsummary( rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, rts->rbmblocks); } + return 0; } @@ -155,11 +162,12 @@ xchk_rtsum_inc( /* Update the summary file to reflect the free extent that we've accumulated. */ STATIC int xchk_rtsum_record_free( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) { + struct xfs_mount *mp = rtg->rtg_mount; struct xfs_scrub *sc = priv; xfs_fileoff_t rbmoff; xfs_rtblock_t rtbno; @@ -182,7 +190,8 @@ xchk_rtsum_record_free( rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { - xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); + xchk_ino_xref_set_corrupt(sc, + rtg->rtg_inodes[XFS_RTGI_BITMAP]->i_ino); return -EFSCORRUPTED; } @@ -204,15 +213,16 @@ xchk_rtsum_compute( struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; + struct xfs_rtgroup *rtg = sc->sr.rtg; unsigned long long rtbmp_blocks; /* If the bitmap size doesn't match the computed size, bail. */ rtbmp_blocks = xfs_rtbitmap_blockcount(mp, mp->m_sb.sb_rextents); - if (XFS_FSB_TO_B(mp, rtbmp_blocks) != mp->m_rbmip->i_disk_size) + if (XFS_FSB_TO_B(mp, rtbmp_blocks) != + rtg->rtg_inodes[XFS_RTGI_BITMAP]->i_disk_size) return -EFSCORRUPTED; - return xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtsum_record_free, - sc); + return xfs_rtalloc_query_all(rtg, sc->tp, xchk_rtsum_record_free, sc); } /* Compare the rtsummary file against the one we computed. */ @@ -231,8 +241,9 @@ xchk_rtsum_compare( xfs_rtsumoff_t sumoff = 0; int error = 0; - rts->args.mp = sc->mp; + rts->args.mp = mp; rts->args.tp = sc->tp; + rts->args.rtg = sc->sr.rtg; /* Mappings may not cross or lie beyond EOF. */ endoff = XFS_B_TO_FSB(mp, ip->i_disk_size); @@ -299,31 +310,34 @@ xchk_rtsummary( struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; + struct xfs_rtgroup *rtg = sc->sr.rtg; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; + struct xfs_inode *rsumip = rtg->rtg_inodes[XFS_RTGI_SUMMARY]; struct xchk_rtsummary *rts = sc->buf; - int error = 0; + int error; /* Is sb_rextents correct? */ if (mp->m_sb.sb_rextents != rts->rextents) { - xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); - goto out_rbm; + xchk_ino_set_corrupt(sc, rbmip->i_ino); + return 0; } /* Is m_rsumlevels correct? */ if (mp->m_rsumlevels != rts->rsumlevels) { - xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); - goto out_rbm; + xchk_ino_set_corrupt(sc, rsumip->i_ino); + return 0; } /* Is m_rsumsize correct? */ if (mp->m_rsumblocks != rts->rsumblocks) { - xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); - goto out_rbm; + xchk_ino_set_corrupt(sc, rsumip->i_ino); + return 0; } /* The summary file length must be aligned to an fsblock. */ - if (mp->m_rsumip->i_disk_size & mp->m_blockmask) { - xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); - goto out_rbm; + if (rsumip->i_disk_size & mp->m_blockmask) { + xchk_ino_set_corrupt(sc, rsumip->i_ino); + return 0; } /* @@ -331,15 +345,15 @@ xchk_rtsummary( * growfsrt expands the summary file before updating sb_rextents, so * the file can be larger than rsumsize. */ - if (mp->m_rsumip->i_disk_size < XFS_FSB_TO_B(mp, rts->rsumblocks)) { - xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); - goto out_rbm; + if (rsumip->i_disk_size < XFS_FSB_TO_B(mp, rts->rsumblocks)) { + xchk_ino_set_corrupt(sc, rsumip->i_ino); + return 0; } /* Invoke the fork scrubber. */ error = xchk_metadata_inode_forks(sc); if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) - goto out_rbm; + return error; /* Construct the new summary file from the rtbitmap. */ error = xchk_rtsum_compute(sc); @@ -348,23 +362,12 @@ xchk_rtsummary( * EFSCORRUPTED means the rtbitmap is corrupt, which is an xref * error since we're checking the summary file. */ - xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); - error = 0; - goto out_rbm; + xchk_ino_set_corrupt(sc, rbmip->i_ino); + return 0; } if (error) - goto out_rbm; + return error; /* Does the computed summary file match the actual rtsummary file? */ - error = xchk_rtsum_compare(sc); - -out_rbm: - /* - * Unlock the rtbitmap since we're done with it. All other writers of - * the rt free space metadata grab the bitmap and summary ILOCKs in - * that order, so we're still protected against allocation activities - * even if we continue on to the repair function. - */ - xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); - return error; + return xchk_rtsum_compare(sc); } diff --git a/fs/xfs/scrub/rtsummary_repair.c b/fs/xfs/scrub/rtsummary_repair.c index 7deeb948cb702..1688380988007 100644 --- a/fs/xfs/scrub/rtsummary_repair.c +++ b/fs/xfs/scrub/rtsummary_repair.c @@ -76,8 +76,9 @@ xrep_rtsummary_prep_buf( union xfs_suminfo_raw *ondisk; int error; - rts->args.mp = sc->mp; + rts->args.mp = mp; rts->args.tp = sc->tp; + rts->args.rtg = sc->sr.rtg; rts->args.sumbp = bp; ondisk = xfs_rsumblock_infoptr(&rts->args, 0); rts->args.sumbp = NULL; @@ -162,8 +163,8 @@ xrep_rtsummary( return error; /* Reset incore state and blow out the summary cache. */ - if (mp->m_rsum_cache) - memset(mp->m_rsum_cache, 0xFF, mp->m_sb.sb_rbmblocks); + if (sc->sr.rtg->rtg_rsum_cache) + memset(sc->sr.rtg->rtg_rsum_cache, 0xFF, mp->m_sb.sb_rbmblocks); mp->m_rsumlevels = rts->rsumlevels; mp->m_rsumblocks = rts->rsumblocks; diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 9d9990d5c6c48..910825d4b61a2 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -384,13 +384,13 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .repair = xrep_parent, }, [XFS_SCRUB_TYPE_RTBITMAP] = { /* realtime bitmap */ - .type = ST_FS, + .type = ST_RTGROUP, .setup = xchk_setup_rtbitmap, .scrub = xchk_rtbitmap, .repair = xrep_rtbitmap, }, [XFS_SCRUB_TYPE_RTSUM] = { /* realtime summary */ - .type = ST_FS, + .type = ST_RTGROUP, .setup = xchk_setup_rtsummary, .scrub = xchk_rtsummary, .repair = xrep_rtsummary, diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index bf1e3f330018d..b2ef5ebe1f047 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -21,6 +21,7 @@ #include "xfs_ag.h" #include "xfs_health.h" #include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" /* * Notes on an efficient, low latency fstrim algorithm @@ -506,7 +507,7 @@ xfs_discard_rtdev_extents( static int xfs_trim_gather_rtextent( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) @@ -525,12 +526,12 @@ xfs_trim_gather_rtextent( return -ECANCELED; } - rbno = xfs_rtx_to_rtb(mp, rec->ar_startext); - rlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); + rbno = xfs_rtx_to_rtb(rtg->rtg_mount, rec->ar_startext); + rlen = xfs_rtx_to_rtb(rtg->rtg_mount, rec->ar_extcount); /* Ignore too small. */ if (rlen < tr->minlen_fsb) { - trace_xfs_discard_rttoosmall(mp, rbno, rlen); + trace_xfs_discard_rttoosmall(rtg->rtg_mount, rbno, rlen); return 0; } @@ -548,69 +549,49 @@ xfs_trim_gather_rtextent( } static int -xfs_trim_rtdev_extents( - struct xfs_mount *mp, - xfs_daddr_t start, - xfs_daddr_t end, +xfs_trim_rtg_extents( + struct xfs_rtgroup *rtg, + xfs_rtxnum_t low, + xfs_rtxnum_t high, xfs_daddr_t minlen) { + struct xfs_mount *mp = rtg->rtg_mount; struct xfs_trim_rtdev tr = { .minlen_fsb = XFS_BB_TO_FSB(mp, minlen), + .extent_list = LIST_HEAD_INIT(tr.extent_list), }; - xfs_rtxnum_t low, high; struct xfs_trans *tp; - xfs_daddr_t rtdev_daddr; int error; - INIT_LIST_HEAD(&tr.extent_list); - - /* Shift the start and end downwards to match the rt device. */ - rtdev_daddr = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); - if (start > rtdev_daddr) - start -= rtdev_daddr; - else - start = 0; - - if (end <= rtdev_daddr) - return 0; - end -= rtdev_daddr; - error = xfs_trans_alloc_empty(mp, &tp); if (error) return error; - end = min_t(xfs_daddr_t, end, - XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks) - 1); - - /* Convert the rt blocks to rt extents */ - low = xfs_rtb_to_rtxup(mp, XFS_BB_TO_FSB(mp, start)); - high = xfs_rtb_to_rtx(mp, XFS_BB_TO_FSBT(mp, end)); - /* * Walk the free ranges between low and high. The query_range function * trims the extents returned. */ do { tr.stop_rtx = low + (mp->m_sb.sb_blocksize * NBBY); - xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); - error = xfs_rtalloc_query_range(mp, tp, low, high, + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + error = xfs_rtalloc_query_range(rtg, tp, low, high, xfs_trim_gather_rtextent, &tr); if (error == -ECANCELED) error = 0; if (error) { - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); xfs_discard_free_rtdev_extents(&tr); break; } if (list_empty(&tr.extent_list)) { - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); break; } error = xfs_discard_rtdev_extents(mp, &tr); - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); if (error) break; @@ -620,6 +601,55 @@ xfs_trim_rtdev_extents( xfs_trans_cancel(tp); return error; } + +static int +xfs_trim_rtdev_extents( + struct xfs_mount *mp, + xfs_daddr_t start, + xfs_daddr_t end, + xfs_daddr_t minlen) +{ + xfs_rtblock_t start_rtbno, end_rtbno; + xfs_rtxnum_t start_rtx, end_rtx; + xfs_rgnumber_t rgno, end_rgno; + int last_error = 0, error; + struct xfs_rtgroup *rtg; + + /* Shift the start and end downwards to match the rt device. */ + start_rtbno = xfs_daddr_to_rtb(mp, start); + if (start_rtbno > mp->m_sb.sb_dblocks) + start_rtbno -= mp->m_sb.sb_dblocks; + else + start_rtbno = 0; + start_rtx = xfs_rtb_to_rtx(mp, start_rtbno); + rgno = xfs_rtb_to_rgno(mp, start_rtbno); + + end_rtbno = xfs_daddr_to_rtb(mp, end); + if (end_rtbno <= mp->m_sb.sb_dblocks) + return 0; + end_rtbno -= mp->m_sb.sb_dblocks; + end_rtx = xfs_rtb_to_rtx(mp, end_rtbno + mp->m_sb.sb_rextsize - 1); + end_rgno = xfs_rtb_to_rgno(mp, end_rtbno); + + for_each_rtgroup_range(mp, rgno, end_rgno, rtg) { + xfs_rtxnum_t rtg_end = rtg->rtg_extents; + + if (rgno == end_rgno) + rtg_end = min(rtg_end, end_rtx); + + error = xfs_trim_rtg_extents(rtg, start_rtx, rtg_end, minlen); + if (error) + last_error = error; + + if (xfs_trim_should_stop()) { + xfs_rtgroup_rele(rtg); + break; + } + start_rtx = 0; + } + + return last_error; +} #else # define xfs_trim_rtdev_extents(...) (-EOPNOTSUPP) #endif /* CONFIG_XFS_RT */ diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index ae18ab86e608b..0e0ec3f0574b1 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -159,6 +159,7 @@ struct xfs_getfsmap_info { struct fsmap *fsmap_recs; /* mapping records */ struct xfs_buf *agf_bp; /* AGF, for refcount queries */ struct xfs_perag *pag; /* AG info, if applicable */ + struct xfs_rtgroup *rtg; /* rtgroup, if applicable */ xfs_daddr_t next_daddr; /* next daddr we expect */ /* daddr of low fsmap key when we're using the rtbitmap */ xfs_daddr_t low_daddr; @@ -352,8 +353,14 @@ xfs_getfsmap_helper( if (info->head->fmh_entries >= info->head->fmh_count) return -ECANCELED; - trace_xfs_fsmap_mapping(mp, info->dev, - info->pag ? info->pag->pag_agno : NULLAGNUMBER, rec); + if (info->pag) + trace_xfs_fsmap_mapping(mp, info->dev, info->pag->pag_agno, + rec); + else if (info->rtg) + trace_xfs_fsmap_mapping(mp, info->dev, info->rtg->rtg_rgno, + rec); + else + trace_xfs_fsmap_mapping(mp, info->dev, NULLAGNUMBER, rec); fmr.fmr_device = info->dev; fmr.fmr_physical = rec_daddr; @@ -711,29 +718,26 @@ xfs_getfsmap_logdev( /* Transform a rtbitmap "record" into a fsmap */ STATIC int xfs_getfsmap_rtdev_rtbitmap_helper( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) { + struct xfs_mount *mp = rtg->rtg_mount; struct xfs_getfsmap_info *info = priv; - struct xfs_rmap_irec irec; - xfs_rtblock_t rtbno; - xfs_daddr_t rec_daddr, len_daddr; - - rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); - rec_daddr = XFS_FSB_TO_BB(mp, rtbno); - irec.rm_startblock = rtbno; - - rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); - len_daddr = XFS_FSB_TO_BB(mp, rtbno); - irec.rm_blockcount = rtbno; - - irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ - irec.rm_offset = 0; - irec.rm_flags = 0; - - return xfs_getfsmap_helper(tp, info, &irec, rec_daddr, len_daddr); + xfs_rtblock_t start_rtb = + xfs_rtx_to_rtb(mp, rec->ar_startext); + uint64_t rtbcount = + xfs_rtx_to_rtb(mp, rec->ar_extcount); + struct xfs_rmap_irec irec = { + .rm_startblock = start_rtb, + .rm_blockcount = rtbcount, + .rm_owner = XFS_RMAP_OWN_NULL, /* "free" */ + }; + + return xfs_getfsmap_helper(tp, info, &irec, + xfs_rtb_to_daddr(mp, start_rtb), + xfs_rtb_to_daddr(mp, rtbcount)); } /* Execute a getfsmap query against the realtime device rtbitmap. */ @@ -743,58 +747,82 @@ xfs_getfsmap_rtdev_rtbitmap( const struct xfs_fsmap *keys, struct xfs_getfsmap_info *info) { - - struct xfs_rtalloc_rec ahigh = { 0 }; struct xfs_mount *mp = tp->t_mountp; - xfs_rtblock_t start_rtb; - xfs_rtblock_t end_rtb; - xfs_rtxnum_t high; + xfs_rtblock_t start_rtbno, end_rtbno; + xfs_rtxnum_t start_rtx, end_rtx; + xfs_rgnumber_t rgno, end_rgno; + struct xfs_rtgroup *rtg; uint64_t eofs; int error; - eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); + eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); if (keys[0].fmr_physical >= eofs) return 0; - start_rtb = XFS_BB_TO_FSBT(mp, - keys[0].fmr_physical + keys[0].fmr_length); - end_rtb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); info->missing_owner = XFS_FMR_OWN_UNKNOWN; /* Adjust the low key if we are continuing from where we left off. */ + start_rtbno = xfs_daddr_to_rtb(mp, + keys[0].fmr_physical + keys[0].fmr_length); if (keys[0].fmr_length > 0) { - info->low_daddr = XFS_FSB_TO_BB(mp, start_rtb); + info->low_daddr = XFS_FSB_TO_BB(mp, start_rtbno); if (info->low_daddr >= eofs) return 0; } + start_rtx = xfs_rtb_to_rtx(mp, start_rtbno); + rgno = xfs_rtb_to_rgno(mp, start_rtbno); + trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtbno); + + end_rtbno = xfs_daddr_to_rtb(mp, min(eofs - 1, keys[1].fmr_physical)); + end_rgno = xfs_rtb_to_rgno(mp, end_rtbno); + trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtbno); + + end_rtx = -1ULL; + + for_each_rtgroup_range(mp, rgno, end_rgno, rtg) { + if (rgno == end_rgno) + end_rtx = xfs_rtb_to_rtx(mp, + end_rtbno + mp->m_sb.sb_rextsize - 1); + + info->rtg = rtg; + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + error = xfs_rtalloc_query_range(rtg, tp, start_rtx, end_rtx, + xfs_getfsmap_rtdev_rtbitmap_helper, info); + if (error) + break; + + /* + * Report any gaps at the end of the rtbitmap by simulating a + * zero-length free extent starting at the rtx after the end + * of the query range. + */ + if (rgno == end_rgno) { + struct xfs_rtalloc_rec ahigh = { + .ar_startext = min(end_rtx + 1, + rtg->rtg_extents), + }; + + info->last = true; + error = xfs_getfsmap_rtdev_rtbitmap_helper(rtg, tp, + &ahigh, info); + if (error) + break; + } + + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + info->rtg = NULL; + start_rtx = 0; + } + + if (info->rtg) { + xfs_rtgroup_unlock(info->rtg, XFS_RTGLOCK_BITMAP_SHARED); + xfs_rtgroup_rele(info->rtg); + info->rtg = NULL; + } else if (rtg) { + /* loop termination case */ + xfs_rtgroup_rele(rtg); + } - trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb); - trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb); - - xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); - - /* - * Set up query parameters to return free rtextents covering the range - * we want. - */ - high = xfs_rtb_to_rtxup(mp, end_rtb); - error = xfs_rtalloc_query_range(mp, tp, xfs_rtb_to_rtx(mp, start_rtb), - high, xfs_getfsmap_rtdev_rtbitmap_helper, info); - if (error) - goto err; - - /* - * Report any gaps at the end of the rtbitmap by simulating a null - * rmap starting at the block after the end of the query range. - */ - info->last = true; - ahigh.ar_startext = min(mp->m_sb.sb_rextents, high); - - error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, tp, &ahigh, info); - if (error) - goto err; -err: - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); return error; } #endif /* CONFIG_XFS_RT */ @@ -1004,6 +1032,7 @@ xfs_getfsmap( info.dev = handlers[i].dev; info.last = false; info.pag = NULL; + info.rtg = NULL; info.low_daddr = XFS_BUF_DADDR_NULL; info.low.rm_blockcount = 0; error = handlers[i].fn(tp, dkeys, &info); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 73959c26075a5..2518977150295 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -90,8 +90,6 @@ typedef struct xfs_mount { struct xfs_da_geometry *m_dir_geo; /* directory block geometry */ struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */ struct xlog *m_log; /* log specific stuff */ - struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ - struct xfs_inode *m_rsumip; /* pointer to summary inode */ struct xfs_inode *m_rootip; /* pointer to root directory */ struct xfs_inode *m_metadirip; /* ptr to metadata directory */ struct xfs_inode *m_rtdirip; /* ptr to realtime metadir */ @@ -100,14 +98,6 @@ typedef struct xfs_mount { struct xfs_buftarg *m_logdev_targp;/* log device */ struct xfs_buftarg *m_rtdev_targp; /* rt device */ void __percpu *m_inodegc; /* percpu inodegc structures */ - - /* - * Optional cache of rt summary level per bitmap block with the - * invariant that m_rsum_cache[bbno] > the maximum i for which - * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i. - * Reads and writes are serialized by the rsumip inode lock. - */ - uint8_t *m_rsum_cache; struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ struct workqueue_struct *m_buf_workqueue; struct workqueue_struct *m_unwritten_workqueue; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index b94d6f192e725..28b1420bac1dd 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -29,6 +29,7 @@ #include "xfs_health.h" #include "xfs_da_format.h" #include "xfs_metafile.h" +#include "xfs_rtgroup.h" /* * The global quota manager. There is only one of these for the entire @@ -210,6 +211,21 @@ xfs_qm_unmount( } } +static void +xfs_qm_unmount_rt( + struct xfs_mount *mp) +{ + struct xfs_rtgroup *rtg = xfs_rtgroup_grab(mp, 0); + + if (!rtg) + return; + if (rtg->rtg_inodes[XFS_RTGI_BITMAP]) + xfs_qm_dqdetach(rtg->rtg_inodes[XFS_RTGI_BITMAP]); + if (rtg->rtg_inodes[XFS_RTGI_SUMMARY]) + xfs_qm_dqdetach(rtg->rtg_inodes[XFS_RTGI_SUMMARY]); + xfs_rtgroup_rele(rtg); +} + /* * Called from the vfsops layer. */ @@ -223,10 +239,13 @@ xfs_qm_unmount_quotas( */ ASSERT(mp->m_rootip); xfs_qm_dqdetach(mp->m_rootip); - if (mp->m_rbmip) - xfs_qm_dqdetach(mp->m_rbmip); - if (mp->m_rsumip) - xfs_qm_dqdetach(mp->m_rsumip); + + /* + * For pre-RTG file systems, the RT inodes have quotas attached, + * detach them now. + */ + if (!xfs_has_rtgroups(mp)) + xfs_qm_unmount_rt(mp); /* * Release the quota inodes. diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index dcdb726ebe4a0..f63228b3dd9a2 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -42,14 +42,14 @@ xfs_rtany_summary( xfs_fileoff_t bbno, /* bitmap block number */ int *maxlog) /* out: max log2 extent size free */ { - struct xfs_mount *mp = args->mp; + uint8_t *rsum_cache = args->rtg->rtg_rsum_cache; int error; int log; /* loop counter, log2 of ext. size */ xfs_suminfo_t sum; /* summary data */ - /* There are no extents at levels >= m_rsum_cache[bbno]. */ - if (mp->m_rsum_cache) { - high = min(high, mp->m_rsum_cache[bbno] - 1); + /* There are no extents at levels >= rsum_cache[bbno]. */ + if (rsum_cache) { + high = min(high, rsum_cache[bbno] - 1); if (low > high) { *maxlog = -1; return 0; @@ -81,12 +81,11 @@ xfs_rtany_summary( *maxlog = -1; out: /* There were no extents at levels > log. */ - if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno] = log + 1; + if (rsum_cache && log + 1 < rsum_cache[bbno]) + rsum_cache[bbno] = log + 1; return 0; } - /* * Copy and transform the summary file, given the old and new * parameters in the mount structures. @@ -153,7 +152,7 @@ xfs_rtallocate_range( /* * Find the next allocated block (end of free extent). */ - error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, + error = xfs_rtfind_forw(args, end, args->rtg->rtg_extents - 1, &postblock); if (error) return error; @@ -215,14 +214,14 @@ xfs_rtalloc_align_len( */ static inline xfs_rtxlen_t xfs_rtallocate_clamp_len( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, xfs_rtxnum_t startrtx, xfs_rtxlen_t rtxlen, xfs_rtxlen_t prod) { xfs_rtxlen_t ret; - ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; + ret = min(rtg->rtg_extents, startrtx + rtxlen) - startrtx; return xfs_rtalloc_align_len(ret, prod); } @@ -257,10 +256,11 @@ xfs_rtallocate_extent_block( * Loop over all the extents starting in this bitmap block up to the * end of the rt volume, looking for one that's long enough. */ - end = min(mp->m_sb.sb_rextents, xfs_rbmblock_to_rtx(mp, bbno + 1)) - 1; + end = min(args->rtg->rtg_extents, xfs_rbmblock_to_rtx(mp, bbno + 1)) - + 1; for (i = xfs_rbmblock_to_rtx(mp, bbno); i <= end; i++) { /* Make sure we don't scan off the end of the rt volume. */ - scanlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); + scanlen = xfs_rtallocate_clamp_len(args->rtg, i, maxlen, prod); if (scanlen < minlen) break; @@ -345,7 +345,6 @@ xfs_rtallocate_extent_exact( xfs_rtxlen_t prod, /* extent product factor */ xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - struct xfs_mount *mp = args->mp; xfs_rtxnum_t next; /* next rtext to try (dummy) */ xfs_rtxlen_t alloclen; /* candidate length */ xfs_rtxlen_t scanlen; /* number of free rtx to look for */ @@ -356,7 +355,7 @@ xfs_rtallocate_extent_exact( ASSERT(maxlen % prod == 0); /* Make sure we don't run off the end of the rt volume. */ - scanlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); + scanlen = xfs_rtallocate_clamp_len(args->rtg, start, maxlen, prod); if (scanlen < minlen) return -ENOSPC; @@ -417,11 +416,10 @@ xfs_rtallocate_extent_near( ASSERT(maxlen % prod == 0); /* - * If the block number given is off the end, silently set it to - * the last block. + * If the block number given is off the end, silently set it to the last + * block. */ - if (start >= mp->m_sb.sb_rextents) - start = mp->m_sb.sb_rextents - 1; + start = min(start, args->rtg->rtg_extents - 1); /* * Try the exact allocation first. @@ -661,21 +659,22 @@ xfs_rtunmount_rtg( for (i = 0; i < XFS_RTGI_MAX; i++) xfs_rtginode_irele(&rtg->rtg_inodes[i]); + kvfree(rtg->rtg_rsum_cache); } static int xfs_alloc_rsum_cache( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, xfs_extlen_t rbmblocks) { /* * The rsum cache is initialized to the maximum value, which is * trivially an upper bound on the maximum level with any free extents. */ - mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); - if (!mp->m_rsum_cache) + rtg->rtg_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); + if (!rtg->rtg_rsum_cache) return -ENOMEM; - memset(mp->m_rsum_cache, -1, rbmblocks); + memset(rtg->rtg_rsum_cache, -1, rbmblocks); return 0; } @@ -712,19 +711,45 @@ xfs_growfs_rt_fixup_extsize( return error; } +/* Ensure that the rtgroup metadata inode is loaded, creating it if neeeded. */ +static int +xfs_rtginode_ensure( + struct xfs_rtgroup *rtg, + enum xfs_rtg_inodes type) +{ + struct xfs_trans *tp; + int error; + + if (rtg->rtg_inodes[type]) + return 0; + + error = xfs_trans_alloc_empty(rtg->rtg_mount, &tp); + if (error) + return error; + error = xfs_rtginode_load(rtg, type, tp); + xfs_trans_cancel(tp); + + if (error != -ENOENT) + return 0; + return xfs_rtginode_create(rtg, type, true); +} + static int xfs_growfs_rt_bmblock( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, xfs_rfsblock_t nrblocks, xfs_agblock_t rextsize, xfs_fileoff_t bmbno) { - struct xfs_inode *rbmip = mp->m_rbmip; - struct xfs_inode *rsumip = mp->m_rsumip; + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; + struct xfs_inode *rsumip = rtg->rtg_inodes[XFS_RTGI_SUMMARY]; struct xfs_rtalloc_args args = { .mp = mp, + .rtg = rtg, }; struct xfs_rtalloc_args nargs = { + .rtg = rtg, }; struct xfs_mount *nmp; xfs_rfsblock_t nrblocks_step; @@ -750,6 +775,7 @@ xfs_growfs_rt_bmblock( nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; nmp->m_rsumblocks = xfs_rtsummary_blockcount(mp, nmp->m_rsumlevels, nmp->m_sb.sb_rbmblocks); + rtg->rtg_extents = xfs_rtgroup_extents(nmp, rtg->rtg_rgno); /* * Recompute the growfsrt reservation from the new rsumsize, so that the @@ -762,8 +788,8 @@ xfs_growfs_rt_bmblock( goto out_free; nargs.tp = args.tp; - xfs_rtbitmap_lock(mp); - xfs_rtbitmap_trans_join(args.tp); + xfs_rtgroup_lock(args.rtg, XFS_RTGLOCK_BITMAP); + xfs_rtgroup_trans_join(args.tp, args.rtg, XFS_RTGLOCK_BITMAP); /* * Update the bitmap inode's size ondisk and incore. We need to update @@ -865,8 +891,9 @@ xfs_growfs_rt_bmblock( */ static xfs_fileoff_t xfs_last_rt_bmblock( - struct xfs_mount *mp) + struct xfs_rtgroup *rtg) { + struct xfs_mount *mp = rtg->rtg_mount; xfs_fileoff_t bmbno = mp->m_sb.sb_rbmblocks; /* Skip the current block if it is exactly full. */ @@ -875,6 +902,103 @@ xfs_last_rt_bmblock( return bmbno; } +/* + * Allocate space to the bitmap and summary files, as necessary. + */ +static int +xfs_growfs_rt_alloc_blocks( + struct xfs_rtgroup *rtg, + xfs_rfsblock_t nrblocks, + xfs_agblock_t rextsize, + xfs_extlen_t *nrbmblocks) +{ + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; + struct xfs_inode *rsumip = rtg->rtg_inodes[XFS_RTGI_SUMMARY]; + xfs_rtxnum_t nrextents = div_u64(nrblocks, rextsize); + xfs_extlen_t orbmblocks; + xfs_extlen_t orsumblocks; + xfs_extlen_t nrsumblocks; + int error; + + /* + * Get the old block counts for bitmap and summary inodes. + * These can't change since other growfs callers are locked out. + */ + orbmblocks = XFS_B_TO_FSB(mp, rbmip->i_disk_size); + orsumblocks = XFS_B_TO_FSB(mp, rsumip->i_disk_size); + + *nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); + nrsumblocks = xfs_rtsummary_blockcount(mp, + xfs_compute_rextslog(nrextents) + 1, *nrbmblocks); + + error = xfs_rtfile_initialize_blocks(rtg, XFS_RTGI_BITMAP, orbmblocks, + *nrbmblocks, NULL); + if (error) + return error; + return xfs_rtfile_initialize_blocks(rtg, XFS_RTGI_SUMMARY, orsumblocks, + nrsumblocks, NULL); +} + +static int +xfs_growfs_rtg( + struct xfs_mount *mp, + xfs_rfsblock_t nrblocks, + xfs_agblock_t rextsize) +{ + uint8_t *old_rsum_cache = NULL; + xfs_extlen_t bmblocks; + xfs_fileoff_t bmbno; + struct xfs_rtgroup *rtg; + unsigned int i; + int error; + + rtg = xfs_rtgroup_grab(mp, 0); + if (!rtg) + return -EINVAL; + + for (i = 0; i < XFS_RTGI_MAX; i++) { + error = xfs_rtginode_ensure(rtg, i); + if (error) + goto out_rele; + } + + error = xfs_growfs_rt_alloc_blocks(rtg, nrblocks, rextsize, &bmblocks); + if (error) + goto out_rele; + + if (bmblocks != rtg->rtg_mount->m_sb.sb_rbmblocks) { + old_rsum_cache = rtg->rtg_rsum_cache; + error = xfs_alloc_rsum_cache(rtg, bmblocks); + if (error) + goto out_rele; + } + + for (bmbno = xfs_last_rt_bmblock(rtg); bmbno < bmblocks; bmbno++) { + error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno); + if (error) + goto out_error; + } + + if (old_rsum_cache) + kvfree(old_rsum_cache); + xfs_rtgroup_rele(rtg); + return 0; + +out_error: + /* + * Reset rtg_extents to the old value if adding more blocks failed. + */ + rtg->rtg_extents = xfs_rtgroup_extents(rtg->rtg_mount, rtg->rtg_rgno); + if (old_rsum_cache) { + kvfree(rtg->rtg_rsum_cache); + rtg->rtg_rsum_cache = old_rsum_cache; + } +out_rele: + xfs_rtgroup_rele(rtg); + return error; +} + /* * Grow the realtime area of the filesystem. */ @@ -883,16 +1007,12 @@ xfs_growfs_rt( xfs_mount_t *mp, /* mount point for filesystem */ xfs_growfs_rt_t *in) /* growfs rt input struct */ { - xfs_fileoff_t bmbno; /* bitmap block number */ - struct xfs_buf *bp; /* temporary buffer */ - int error; /* error return value */ - xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ - xfs_rtxnum_t nrextents; /* new number of realtime extents */ - xfs_extlen_t nrsumblocks; /* new number of summary blocks */ - xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ - xfs_extlen_t rsumblocks; /* current number of rt summary blks */ - uint8_t *rsum_cache; /* old summary cache */ - xfs_agblock_t old_rextsize = mp->m_sb.sb_rextsize; + xfs_rtxnum_t nrextents; + xfs_extlen_t nrbmblocks; + xfs_extlen_t nrsumblocks; + struct xfs_buf *bp; + xfs_agblock_t old_rextsize = mp->m_sb.sb_rextsize; + int error; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -903,15 +1023,9 @@ xfs_growfs_rt( if (!mutex_trylock(&mp->m_growlock)) return -EWOULDBLOCK; - /* - * Mount should fail if the rt bitmap/summary files don't load, but - * we'll check anyway. - */ - error = -EINVAL; - if (!mp->m_rbmip || !mp->m_rsumip) - goto out_unlock; /* Shrink not supported. */ + error = -EINVAL; if (in->newblocks <= mp->m_sb.sb_rblocks) goto out_unlock; /* Can only change rt extent size when adding rt volume. */ @@ -945,10 +1059,9 @@ xfs_growfs_rt( * Calculate new parameters. These are the final values to be reached. */ nrextents = div_u64(in->newblocks, in->extsize); - if (nrextents == 0) { - error = -EINVAL; + error = -EINVAL; + if (nrextents == 0) goto out_unlock; - } nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); nrsumblocks = xfs_rtsummary_blockcount(mp, xfs_compute_rextslog(nrextents) + 1, nrbmblocks); @@ -958,68 +1071,22 @@ xfs_growfs_rt( * the log. This prevents us from getting a log overflow, * since we'll log basically the whole summary file at once. */ - if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1)) { - error = -EINVAL; + if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1)) goto out_unlock; - } - /* - * Get the old block counts for bitmap and summary inodes. - * These can't change since other growfs callers are locked out. - */ - rbmblocks = XFS_B_TO_FSB(mp, mp->m_rbmip->i_disk_size); - rsumblocks = XFS_B_TO_FSB(mp, mp->m_rsumip->i_disk_size); - /* - * Allocate space to the bitmap and summary files, as necessary. - */ - error = xfs_rtfile_initialize_blocks(mp->m_rbmip, rbmblocks, - nrbmblocks, NULL); + error = xfs_growfs_rtg(mp, in->newblocks, in->extsize); if (error) goto out_unlock; - error = xfs_rtfile_initialize_blocks(mp->m_rsumip, rsumblocks, - nrsumblocks, NULL); - if (error) - goto out_unlock; - - rsum_cache = mp->m_rsum_cache; - if (nrbmblocks != mp->m_sb.sb_rbmblocks) { - error = xfs_alloc_rsum_cache(mp, nrbmblocks); - if (error) - goto out_unlock; - } - - /* Initialize the free space bitmap one bitmap block at a time. */ - for (bmbno = xfs_last_rt_bmblock(mp); bmbno < nrbmblocks; bmbno++) { - error = xfs_growfs_rt_bmblock(mp, in->newblocks, in->extsize, - bmbno); - if (error) - goto out_free; - } if (old_rextsize != in->extsize) { error = xfs_growfs_rt_fixup_extsize(mp); if (error) - goto out_free; + goto out_unlock; } /* Update secondary superblocks now the physical grow has completed */ error = xfs_update_secondary_sbs(mp); -out_free: - /* - * If we had to allocate a new rsum_cache, we either need to free the - * old one (if we succeeded) or free the new one and restore the old one - * (if there was an error). - */ - if (rsum_cache != mp->m_rsum_cache) { - if (error) { - kvfree(mp->m_rsum_cache); - mp->m_rsum_cache = rsum_cache; - } else { - kvfree(rsum_cache); - } - } - out_unlock: mutex_unlock(&mp->m_growlock); return error; @@ -1048,7 +1115,7 @@ xfs_rtmount_init( mp->m_rsumlevels = sbp->sb_rextslog + 1; mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, mp->m_sb.sb_rbmblocks); - mp->m_rbmip = mp->m_rsumip = NULL; + /* * Check that the realtime section is an ok size. */ @@ -1072,7 +1139,7 @@ xfs_rtmount_init( static int xfs_rtalloc_count_frextent( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, struct xfs_trans *tp, const struct xfs_rtalloc_rec *rec, void *priv) @@ -1094,12 +1161,17 @@ xfs_rtalloc_reinit_frextents( uint64_t val = 0; int error; - xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); - error = xfs_rtalloc_query_all(mp, NULL, xfs_rtalloc_count_frextent, - &val); - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); - if (error) - return error; + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; + + for_each_rtgroup(mp, rgno, rtg) { + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + error = xfs_rtalloc_query_all(rtg, NULL, xfs_rtalloc_count_frextent, + &val); + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED); + if (error) + return error; + } spin_lock(&mp->m_sb_lock); mp->m_sb.sb_frextents = val; @@ -1138,16 +1210,30 @@ xfs_rtmount_iread_extents( return error; } -static void -xfs_rtgroup_unmount_inodes( - struct xfs_mount *mp) +static int +xfs_rtmount_rtg( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_rtgroup *rtg) { - struct xfs_rtgroup *rtg; - xfs_rgnumber_t rgno; + int error, i; - for_each_rtgroup(mp, rgno, rtg) - xfs_rtunmount_rtg(rtg); - xfs_rtginode_irele(&mp->m_rtdirip); + rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg->rtg_rgno); + + for (i = 0; i < XFS_RTGI_MAX; i++) { + error = xfs_rtginode_load(rtg, i, tp); + if (error) + return error; + + if (rtg->rtg_inodes[i]) { + error = xfs_rtmount_iread_extents(tp, + rtg->rtg_inodes[i], 0); + if (error) + return error; + } + } + + return xfs_alloc_rsum_cache(rtg, mp->m_sb.sb_rbmblocks); } /* @@ -1159,73 +1245,30 @@ xfs_rtmount_inodes( struct xfs_mount *mp) { struct xfs_trans *tp; - struct xfs_sb *sbp = &mp->m_sb; struct xfs_rtgroup *rtg; xfs_rgnumber_t rgno; - unsigned int i; int error; error = xfs_trans_alloc_empty(mp, &tp); if (error) return error; - error = xfs_trans_metafile_iget(tp, mp->m_sb.sb_rbmino, - XFS_METAFILE_RTBITMAP, &mp->m_rbmip); - if (xfs_metadata_is_sick(error)) - xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP); - if (error) - goto out_trans; - ASSERT(mp->m_rbmip != NULL); - - error = xfs_rtmount_iread_extents(tp, mp->m_rbmip, XFS_ILOCK_RTBITMAP); - if (error) - goto out_rele_bitmap; - - error = xfs_trans_metafile_iget(tp, mp->m_sb.sb_rsumino, - XFS_METAFILE_RTSUMMARY, &mp->m_rsumip); - if (xfs_metadata_is_sick(error)) - xfs_rt_mark_sick(mp, XFS_SICK_RT_SUMMARY); - if (error) - goto out_rele_bitmap; - ASSERT(mp->m_rsumip != NULL); - - error = xfs_rtmount_iread_extents(tp, mp->m_rsumip, XFS_ILOCK_RTSUM); - if (error) - goto out_rele_summary; - if (xfs_has_rtgroups(mp) && mp->m_sb.sb_rgcount > 0) { error = xfs_rtginode_load_parent(tp); if (error) - goto out_rele_rtdir; + goto out_cancel; } for_each_rtgroup(mp, rgno, rtg) { - rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg->rtg_rgno); - - for (i = 0; i < XFS_RTGI_MAX; i++) { - error = xfs_rtginode_load(rtg, i, tp); - if (error) { - xfs_rtgroup_rele(rtg); - goto out_rele_inodes; - } + error = xfs_rtmount_rtg(mp, tp, rtg); + if (error) { + xfs_rtgroup_rele(rtg); + xfs_rtunmount_inodes(mp); + break; } } - error = xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); - if (error) - goto out_rele_summary; - xfs_trans_cancel(tp); - return 0; - -out_rele_inodes: - xfs_rtgroup_unmount_inodes(mp); -out_rele_rtdir: - xfs_rtginode_irele(&mp->m_rtdirip); -out_rele_summary: - xfs_irele(mp->m_rsumip); -out_rele_bitmap: - xfs_irele(mp->m_rbmip); -out_trans: +out_cancel: xfs_trans_cancel(tp); return error; } @@ -1234,14 +1277,12 @@ void xfs_rtunmount_inodes( struct xfs_mount *mp) { - kvfree(mp->m_rsum_cache); + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; - xfs_rtgroup_unmount_inodes(mp); + for_each_rtgroup(mp, rgno, rtg) + xfs_rtunmount_rtg(rtg); xfs_rtginode_irele(&mp->m_rtdirip); - if (mp->m_rbmip) - xfs_irele(mp->m_rbmip); - if (mp->m_rsumip) - xfs_irele(mp->m_rsumip); } /* @@ -1253,28 +1294,29 @@ xfs_rtunmount_inodes( */ static xfs_rtxnum_t xfs_rtpick_extent( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ + struct xfs_rtgroup *rtg, + struct xfs_trans *tp, xfs_rtxlen_t len) /* allocation length (rtextents) */ { - xfs_rtxnum_t b; /* result rtext */ + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; + xfs_rtxnum_t b = 0; /* result rtext */ int log2; /* log of sequence number */ uint64_t resid; /* residual after log removed */ uint64_t seq; /* sequence number of file creation */ struct timespec64 ts; /* timespec in inode */ - xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL); + xfs_assert_ilocked(rbmip, XFS_ILOCK_EXCL); - ts = inode_get_atime(VFS_I(mp->m_rbmip)); - if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) { - mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; + ts = inode_get_atime(VFS_I(rbmip)); + if (!(rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) { + rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; seq = 0; } else { seq = ts.tv_sec; } - if ((log2 = xfs_highbit64(seq)) == -1) - b = 0; - else { + log2 = xfs_highbit64(seq); + if (log2 != -1) { resid = seq - (1ULL << log2); b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >> (log2 + 1); @@ -1284,8 +1326,8 @@ xfs_rtpick_extent( b = mp->m_sb.sb_rextents - len; } ts.tv_sec = seq + 1; - inode_set_atime_to_ts(VFS_I(mp->m_rbmip), ts); - xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); + inode_set_atime_to_ts(VFS_I(rbmip), ts); + xfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); return b; } @@ -1340,12 +1382,16 @@ xfs_rtallocate( xfs_rtxlen_t len = 0; int error = 0; + args.rtg = xfs_rtgroup_grab(args.mp, 0); + if (!args.rtg) + return -ENOSPC; + /* * Lock out modifications to both the RT bitmap and summary inodes. */ if (!*rtlocked) { - xfs_rtbitmap_lock(args.mp); - xfs_rtbitmap_trans_join(tp); + xfs_rtgroup_lock(args.rtg, XFS_RTGLOCK_BITMAP); + xfs_rtgroup_trans_join(tp, args.rtg, XFS_RTGLOCK_BITMAP); *rtlocked = true; } @@ -1356,7 +1402,7 @@ xfs_rtallocate( if (bno_hint) start = xfs_rtb_to_rtx(args.mp, bno_hint); else if (initial_user_data) - start = xfs_rtpick_extent(args.mp, tp, maxlen); + start = xfs_rtpick_extent(args.rtg, tp, maxlen); if (start) { error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen, @@ -1390,6 +1436,7 @@ xfs_rtallocate( *blen = xfs_rtxlen_to_extlen(args.mp, len); out_release: + xfs_rtgroup_rele(args.rtg); xfs_rtbuf_cache_relse(&args); return error; } From patchwork Fri Aug 23 00:19:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774432 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0796171A7 for ; Fri, 23 Aug 2024 00:19:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372345; cv=none; b=MTXYDM7/sXccftD30RIbmsm7hC3AyJfkgRaP80Tk28xgPtMMVPU734P9k1JGElqBGBBad8QP1AcJ/tPbIxo0DJQ6jCPaYji6EeJTYg/xoY7D8NaEHVecT+sAqQ4aBt4ggnVo3TrYkfJGfwOCxGxETqN0h4CjOPddLCALPV7/QbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372345; c=relaxed/simple; bh=Z3kNLW5brImQGqB2T/5tlM5sRNAxVBQ48Yl8M2k7368=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BvWa9RFm61CpEZDQfz8oo1cEH2ebezDgqv+MJBmAjjhXVFpaj3iK7paBzhqlrI3ICkKutINYpMm0ZNyBMapgH+P5FRm862xfUgGxI0inLp/HYz9ZBOfzjtSAuXov87nysSVEpNXlbCElCZ2vXB8IYBSbz9CvYOD5+uJFGEfskKE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LCFVYttM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LCFVYttM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A807AC32782; Fri, 23 Aug 2024 00:19:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372345; bh=Z3kNLW5brImQGqB2T/5tlM5sRNAxVBQ48Yl8M2k7368=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=LCFVYttMwsFJe+unHJ/jDPmJwqMwmNYfas/QHk+Qysq8aTRA1myGBqx9s1Zko8WXa CNIyW7eetDTQtkFoUfE5I4WmgdB3HV7EGb9T7m4djjljeAZzjkcuEq2x9bornMluYe LLCl+91vP2v2bGdVFeKjBjYrWabxLINjDoq3RREK08ppIiH+cI7Iq/mRH26LBkxLM9 /HC2vGExfRkToJkdJ0p5mvXjVWlsCdShVMDmt25KDAYeC20tBVOUWPnHekTit9cT00 legNTXyKoQSuL+yijTsaqsajn/wwUQAisoaAPUEsT9UPkCZygE7FXUjD5fBf/K2RO8 KDTARHSzAv7ew== Date: Thu, 22 Aug 2024 17:19:05 -0700 Subject: [PATCH 17/24] xfs: remove XFS_ILOCK_RT* From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087542.59588.13853236455832390956.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that we've centralized the realtime metadata locking routines, get rid of the ILOCK subclasses since we now use explicit lockdep classes. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_inode.c | 3 +-- fs/xfs/xfs_inode.h | 13 ++++--------- fs/xfs/xfs_rtalloc.c | 9 ++++----- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index fff3037e67574..4ae628fe7d877 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -342,8 +342,7 @@ xfs_lock_inumorder( { uint class = 0; - ASSERT(!(lock_mode & (XFS_ILOCK_PARENT | XFS_ILOCK_RTBITMAP | - XFS_ILOCK_RTSUM))); + ASSERT(!(lock_mode & XFS_ILOCK_PARENT)); ASSERT(xfs_lockdep_subclass_ok(subclass)); if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 54d995740b328..7c35511d0e471 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -443,9 +443,8 @@ static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip) * However, MAX_LOCKDEP_SUBCLASSES == 8, which means we are greatly * limited to the subclasses we can represent via nesting. We need at least * 5 inodes nest depth for the ILOCK through rename, and we also have to support - * XFS_ILOCK_PARENT, which gives 6 subclasses. Then we have XFS_ILOCK_RTBITMAP - * and XFS_ILOCK_RTSUM, which are another 2 unique subclasses, so that's all - * 8 subclasses supported by lockdep. + * XFS_ILOCK_PARENT, which gives 6 subclasses. That's 6 of the 8 subclasses + * supported by lockdep. * * This also means we have to number the sub-classes in the lowest bits of * the mask we keep, and we have to ensure we never exceed 3 bits of lockdep @@ -471,8 +470,8 @@ static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip) * ILOCK values * 0-4 subclass values * 5 PARENT subclass (not nestable) - * 6 RTBITMAP subclass (not nestable) - * 7 RTSUM subclass (not nestable) + * 6 unused + * 7 unused * */ #define XFS_IOLOCK_SHIFT 16 @@ -487,12 +486,8 @@ static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip) #define XFS_ILOCK_SHIFT 24 #define XFS_ILOCK_PARENT_VAL 5u #define XFS_ILOCK_MAX_SUBCLASS (XFS_ILOCK_PARENT_VAL - 1) -#define XFS_ILOCK_RTBITMAP_VAL 6u -#define XFS_ILOCK_RTSUM_VAL 7u #define XFS_ILOCK_DEP_MASK 0xff000000u #define XFS_ILOCK_PARENT (XFS_ILOCK_PARENT_VAL << XFS_ILOCK_SHIFT) -#define XFS_ILOCK_RTBITMAP (XFS_ILOCK_RTBITMAP_VAL << XFS_ILOCK_SHIFT) -#define XFS_ILOCK_RTSUM (XFS_ILOCK_RTSUM_VAL << XFS_ILOCK_SHIFT) #define XFS_LOCK_SUBCLASS_MASK (XFS_IOLOCK_DEP_MASK | \ XFS_MMAPLOCK_DEP_MASK | \ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index f63228b3dd9a2..2a694ad8ead2c 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1188,12 +1188,11 @@ xfs_rtalloc_reinit_frextents( static inline int xfs_rtmount_iread_extents( struct xfs_trans *tp, - struct xfs_inode *ip, - unsigned int lock_class) + struct xfs_inode *ip) { int error; - xfs_ilock(ip, XFS_ILOCK_EXCL | lock_class); + xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_iread_extents(tp, ip, XFS_DATA_FORK); if (error) @@ -1206,7 +1205,7 @@ xfs_rtmount_iread_extents( } out_unlock: - xfs_iunlock(ip, XFS_ILOCK_EXCL | lock_class); + xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } @@ -1227,7 +1226,7 @@ xfs_rtmount_rtg( if (rtg->rtg_inodes[i]) { error = xfs_rtmount_iread_extents(tp, - rtg->rtg_inodes[i], 0); + rtg->rtg_inodes[i]); if (error) return error; } From patchwork Fri Aug 23 00:19:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774433 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C82FF171A7 for ; Fri, 23 Aug 2024 00:19:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372361; cv=none; b=b0nroSDlGLCFmYpMxeVABgkSgOtPtYRj7sWgFEenGHm7Eqg26tQhjTT6JOEHCn401vRd0kzeCmuSiAqE6sR7Npsgu4JBepbARi70pqqxPAd2U2ZL7uB04/lmEtVOCjwcKhS7G6Ge8z/9NdPHSR24syvyBBimmBPxChJ4r8qUHbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372361; c=relaxed/simple; bh=vNTs4runLJBFVYw2QchsEk6/kHNxYCdZDs8RVkqEpuA=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hRcHaUsooIWFsqjqOuLmbt27dtZYWObF+GTuu77VRe1UFys0Pr7Q1f6zac5eqjpncx7vveM0D7i+RkFV5EG3PDPvQhi9ldA0ybc6H8e9V2CCQbrdenum+lVeWm4up+6meBmtRp+iqxPTw3bH/ZFQShuIkzRVfT3FfG20li7I4Eg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XgVohfeC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XgVohfeC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4FE79C32782; Fri, 23 Aug 2024 00:19:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372361; bh=vNTs4runLJBFVYw2QchsEk6/kHNxYCdZDs8RVkqEpuA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=XgVohfeCtl0KNddyZdo8DdxuTjI8y1qVvYvIJbZTmQw2qmxGZJw49FW73kDGn91wA 8lL9LSBRTMKZjImJqSMgsSdAHzCiYlAyUc1TsinCf7ofrEdrVUHm8gpFFCVrl27ao8 ui8rosmIiw5gy5IIlZLiCfZrhgYAtGpnxpdJ4WJhafM3HEullp6LIkQu4dpf1kfmuZ LBw9n3TnsLESfedA1IQ/+UFiD3mzKLJOBKcO5jrqQKVMDHNMePlf8LIEigPkM7KiyP 2LvHChtDgOfGggNX1FWZiumr24f9AbKp+NQQ4SaqjFYzyqYNemnA/pgvXsSTsYsMmh W/CefYkUO7suA== Date: Thu, 22 Aug 2024 17:19:20 -0700 Subject: [PATCH 18/24] xfs: calculate RT bitmap and summary blocks based on sb_rextents From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087559.59588.9823973927107871792.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Use the on-disk rextents to calculate the bitmap and summary blocks instead of the calculated one so that we can refactor the helpers for calculating them. As the RT bitmap and summary scrubbers already check that sb_rextents match the block count this does not change coverage of the scrubber. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/scrub/rtbitmap.c | 3 ++- fs/xfs/scrub/rtsummary.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 6551b4374b89f..4a3e9d0302b51 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -67,7 +67,8 @@ xchk_setup_rtbitmap( if (mp->m_sb.sb_rblocks) { rtb->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); rtb->rextslog = xfs_compute_rextslog(rtb->rextents); - rtb->rbmblocks = xfs_rtbitmap_blockcount(mp, rtb->rextents); + rtb->rbmblocks = xfs_rtbitmap_blockcount(mp, + mp->m_sb.sb_rextents); } return 0; diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 43d509422053c..a756fb2c4abf8 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -105,9 +105,10 @@ xchk_setup_rtsummary( int rextslog; rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); - rextslog = xfs_compute_rextslog(rts->rextents); + rextslog = xfs_compute_rextslog(mp->m_sb.sb_rextents); rts->rsumlevels = rextslog + 1; - rts->rbmblocks = xfs_rtbitmap_blockcount(mp, rts->rextents); + rts->rbmblocks = xfs_rtbitmap_blockcount(mp, + mp->m_sb.sb_rextents); rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, rts->rbmblocks); } From patchwork Fri Aug 23 00:19:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774434 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14790171A5 for ; Fri, 23 Aug 2024 00:19:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372377; cv=none; b=NyY52kOP+zJXU4CDi4CzFhITHDPf4kQ0MPxaUVXtzEUv+umyXBMIVRAcCQWzN+MGpf3qQJFJMTA8/HSs3ADj4MLC/GVOd0oMCVNHfaHFJA01PrG40w5Dh57xynAcegn3V4CARYtTOtT3/QkaQK90CiQi7bFiYTCQW1NfKClETfY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372377; c=relaxed/simple; bh=YAmBgkVlvNct18O0EZGpoKDvL9YusFpvfoPxlEAU9ko=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kI+zbbY/QdeN+Is8Oj7GPLBpAl8r/3ryxdOekRUnJwMZ7pE1gDExHXzizC0O/8GDbfdvLFHkVkxRkfjSP6k0e3SbXUzdJtU32NOF//O3Klh7miBMS4pzktBw+qDkeJQxurBz5+4caOxWB30MseM1v5IDOzAhHFJFG9MxyEkZMDA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aVcjqRhh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aVcjqRhh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E54D2C32782; Fri, 23 Aug 2024 00:19:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372377; bh=YAmBgkVlvNct18O0EZGpoKDvL9YusFpvfoPxlEAU9ko=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=aVcjqRhhxPUOlcXEDPkDQTbMxpAlZKPqwhTsPgMUK6zs9Q1cetdFG8D8qidpTH+QE JPgqyDUQVL3fC2zQZstfVX4Cxju/JZmWshds9I4sfrRkKdEgAnB6nj8qOlm1HTYTzM EcGHXHhWqAMy+lzVZLf5XJ099oBz5BOYtGHEnqQABHZ/yynpDnKa4/H4c4zHbmcnfn 9zVLlfHFXgoqLTGMdI2dlY+Qc1IJ8bCSexiUXuMJHWwa3xIEmRC3W1rF2SkQqfQTKJ hKn6RHZFgJGB/2vterYEUycCJLDu5AMDbw2722ADlTffkZ9XWTUZsBiCj+LclOpz9y fNuVebmENOc6A== Date: Thu, 22 Aug 2024 17:19:36 -0700 Subject: [PATCH 19/24] xfs: factor out a xfs_growfs_rt_alloc_fake_mount helper From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087576.59588.17128388413774079852.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Split the code to set up a fake mount point to calculate new RT geometry out of xfs_growfs_rt_bmblock so that it can be reused. Note that this changes the rmblocks calculation method to be based on the passed in rblocks and extsize and not the explicitly passed one, but both methods will always lead to the same result. The new version just does a little bit more math while being more general. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 52 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 2a694ad8ead2c..71e650b6c4253 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -734,6 +734,36 @@ xfs_rtginode_ensure( return xfs_rtginode_create(rtg, type, true); } +static struct xfs_mount * +xfs_growfs_rt_alloc_fake_mount( + const struct xfs_mount *mp, + xfs_rfsblock_t rblocks, + xfs_agblock_t rextsize) +{ + struct xfs_mount *nmp; + + nmp = kmemdup(mp, sizeof(*mp), GFP_KERNEL); + if (!nmp) + return NULL; + nmp->m_sb.sb_rextsize = rextsize; + xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb); + nmp->m_sb.sb_rblocks = rblocks; + nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); + nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp, + nmp->m_sb.sb_rextents); + nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); + nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; + nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, nmp->m_rsumlevels, + nmp->m_sb.sb_rbmblocks); + + if (rblocks > 0) + nmp->m_features |= XFS_FEAT_REALTIME; + + /* recompute growfsrt reservation from new rsumsize */ + xfs_trans_resv_calc(nmp, &nmp->m_resv); + return nmp; +} + static int xfs_growfs_rt_bmblock( struct xfs_rtgroup *rtg, @@ -756,25 +786,15 @@ xfs_growfs_rt_bmblock( xfs_rtbxlen_t freed_rtx; int error; - - nrblocks_step = (bmbno + 1) * NBBY * mp->m_sb.sb_blocksize * rextsize; - - nmp = nargs.mp = kmemdup(mp, sizeof(*mp), GFP_KERNEL); - if (!nmp) - return -ENOMEM; - /* * Calculate new sb and mount fields for this round. */ - nmp->m_sb.sb_rextsize = rextsize; - xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb); - nmp->m_sb.sb_rbmblocks = bmbno + 1; - nmp->m_sb.sb_rblocks = min(nrblocks, nrblocks_step); - nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); - nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); - nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; - nmp->m_rsumblocks = xfs_rtsummary_blockcount(mp, nmp->m_rsumlevels, - nmp->m_sb.sb_rbmblocks); + nrblocks_step = (bmbno + 1) * NBBY * mp->m_sb.sb_blocksize * rextsize; + nmp = nargs.mp = xfs_growfs_rt_alloc_fake_mount(mp, + min(nrblocks, nrblocks_step), rextsize); + if (!nmp) + return -ENOMEM; + rtg->rtg_extents = xfs_rtgroup_extents(nmp, rtg->rtg_rgno); /* From patchwork Fri Aug 23 00:19:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774435 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F3567171A5 for ; Fri, 23 Aug 2024 00:19:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372393; cv=none; b=aikq3vfZaqzFbXnf9lr7J6kbKsTy54Yekn2RnCtLx0s+Ujm36tddNMJ2Hz2v8HGmYAYAR63fIXehX+5/mklzuf18+tiw6nJZx53/AUfl0sSrYVkY46bq45C+TyNbKzoSH8TuOJd1SyTTiywz0VfhtnZyyZn2eUURSsUlqudWhjg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372393; c=relaxed/simple; bh=Oz1JfcgfD0qamXeNbpkwNpkRxlMbXxil0MX88dWWpCQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SPU6ZaqsPXEI62jbsfZVNzgRdziFizTa9/WRDhsYOJsVVLbXum3fw+8fGNBxBcTuCvUvGFhQJGh0fMShirZQxrlNu+b9iEXkNwNexWaplbQiIHuTFTu1aD0B3qQwTS0PB9O4imUxDUpyzwMFH+wdZQlkB5CZDH5m+7EAaqPnpcU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RLow2123; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RLow2123" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8ED7DC32782; Fri, 23 Aug 2024 00:19:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372392; bh=Oz1JfcgfD0qamXeNbpkwNpkRxlMbXxil0MX88dWWpCQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=RLow2123Wv+FQSyqJBA+3pK3JVp+SYPUWcUJ2RqqAZFtGplvGuc3HYIN5oqDDQi8k yhNukAzB3FnJs1sIvZ8XhZCRF3u3bDAhVHwFF4VtMOTkcDlxvB7NbBAW+HmT8J5iEK /uX29bHdV+DORpvQyFimckOBpnrRv26+/74k1Hh23xuXpypUE89FXgPv7e5XVBV2Ae paY4ZHll44BYfRP7C0aEzIFyNoEOIXZW+m2puaGFrEdX4I0mmYee8yXx2/GvIiHB0y ndUeRLSMFURYI0LzUMmJ7690tqyWVR4GMRPYxaaahla4oHvDHI/evx9cUlOmZAlvU0 mVRzeRFKOfXwA== Date: Thu, 22 Aug 2024 17:19:52 -0700 Subject: [PATCH 20/24] xfs: use xfs_growfs_rt_alloc_fake_mount in xfs_growfs_rt_alloc_blocks From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087593.59588.3393693654050943333.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Use xfs_growfs_rt_alloc_fake_mount instead of manually recalculating the RT bitmap geometry. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 71e650b6c4253..61231b1dc4b79 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -935,10 +935,10 @@ xfs_growfs_rt_alloc_blocks( struct xfs_mount *mp = rtg->rtg_mount; struct xfs_inode *rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP]; struct xfs_inode *rsumip = rtg->rtg_inodes[XFS_RTGI_SUMMARY]; - xfs_rtxnum_t nrextents = div_u64(nrblocks, rextsize); xfs_extlen_t orbmblocks; xfs_extlen_t orsumblocks; xfs_extlen_t nrsumblocks; + struct xfs_mount *nmp; int error; /* @@ -948,9 +948,13 @@ xfs_growfs_rt_alloc_blocks( orbmblocks = XFS_B_TO_FSB(mp, rbmip->i_disk_size); orsumblocks = XFS_B_TO_FSB(mp, rsumip->i_disk_size); - *nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); - nrsumblocks = xfs_rtsummary_blockcount(mp, - xfs_compute_rextslog(nrextents) + 1, *nrbmblocks); + nmp = xfs_growfs_rt_alloc_fake_mount(mp, nrblocks, rextsize); + if (!nmp) + return -ENOMEM; + + *nrbmblocks = nmp->m_sb.sb_rbmblocks; + nrsumblocks = nmp->m_rsumblocks; + kfree(nmp); error = xfs_rtfile_initialize_blocks(rtg, XFS_RTGI_BITMAP, orbmblocks, *nrbmblocks, NULL); From patchwork Fri Aug 23 00:20:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774436 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69507179AD for ; Fri, 23 Aug 2024 00:20:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372408; cv=none; b=noTVebYh1ocjSCntNEJAXldACNS7pVm68fa97PKEPG/VLA30WVVXsoE69NtWWpoySjQMu+hBgiUKTTOrh4DBzRtV8AGEjcVDQpDLBIyDq7fm+dlphjGEE7BeFeJDdCFAT+0QSXorRWoRQkaY4cDYYBZVZyMJvtODfA0T63UmHPI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372408; c=relaxed/simple; bh=LoFEKU8W417l/YHuSt27t7hwYTBXsHuVhdTGH7eiRJI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EdZfM+8GGFlfyFj63eRbCfsRLCsb77yOoQd562j7isebg2eC9CiR+zVPmegO0D8jRM7bu6uAzXY+gj2GCnJ5PCLEp2z5Zfh+QVma5iR/vgwO07PLnWOKEmYfOJIhJb7fPH0PqATRk98znen6x1f1y6eWGfu2Lh5mc5iDcuoVh0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FT9NhfdZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FT9NhfdZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3789BC32782; Fri, 23 Aug 2024 00:20:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372408; bh=LoFEKU8W417l/YHuSt27t7hwYTBXsHuVhdTGH7eiRJI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=FT9NhfdZ1CK12ZaWaMq2DZKbxfNxrdl2Io4lNSgJPCcGdGvpzKViLHh/hLjchoyq2 iAwlp3PhyJ40kG8FScA3AFa1S6sV8vCLk/1IjwjKOCuv/ehLs1C/ieRsETP+NkU+7N wJq3RyDnwGyFQNFEGsCoJUGE/iV2K3atcmzPc5235LNlUZhCIY4Ch/3dF+dMqmoppe ydLPDksO+xtz0GqaEA9TUj8gdFsatydIXrBfIjgvMlSDOi2XchW08BlPAlJHEeyNEr 9RrpeGpfiVWSCADhVYNuRNnmg64COTRXOv1Mu9c4lAiwYSBXcS5Yl09DRc3xpdrCxu 8yVB0kScC88QA== Date: Thu, 22 Aug 2024 17:20:07 -0700 Subject: [PATCH 21/24] xfs: factor out a xfs_growfs_check_rtgeom helper From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087611.59588.7898768503459548119.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Split the check that the rtsummary fits into the log into a separate helper, and use xfs_growfs_rt_alloc_fake_mount to calculate the new RT geometry. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong [djwong: avoid division for the 0-rtx growfs check] Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 61231b1dc4b79..78a3879ad6193 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1023,6 +1023,31 @@ xfs_growfs_rtg( return error; } +static int +xfs_growfs_check_rtgeom( + const struct xfs_mount *mp, + xfs_rfsblock_t rblocks, + xfs_extlen_t rextsize) +{ + struct xfs_mount *nmp; + int error = 0; + + nmp = xfs_growfs_rt_alloc_fake_mount(mp, rblocks, rextsize); + if (!nmp) + return -ENOMEM; + + /* + * New summary size can't be more than half the size of the log. This + * prevents us from getting a log overflow, since we'll log basically + * the whole summary file at once. + */ + if (nmp->m_rsumblocks > (mp->m_sb.sb_logblocks >> 1)) + error = -EINVAL; + + kfree(nmp); + return error; +} + /* * Grow the realtime area of the filesystem. */ @@ -1031,9 +1056,6 @@ xfs_growfs_rt( xfs_mount_t *mp, /* mount point for filesystem */ xfs_growfs_rt_t *in) /* growfs rt input struct */ { - xfs_rtxnum_t nrextents; - xfs_extlen_t nrbmblocks; - xfs_extlen_t nrsumblocks; struct xfs_buf *bp; xfs_agblock_t old_rextsize = mp->m_sb.sb_rextsize; int error; @@ -1082,20 +1104,13 @@ xfs_growfs_rt( /* * Calculate new parameters. These are the final values to be reached. */ - nrextents = div_u64(in->newblocks, in->extsize); error = -EINVAL; - if (nrextents == 0) + if (in->newblocks < in->extsize) goto out_unlock; - nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); - nrsumblocks = xfs_rtsummary_blockcount(mp, - xfs_compute_rextslog(nrextents) + 1, nrbmblocks); - /* - * New summary size can't be more than half the size of - * the log. This prevents us from getting a log overflow, - * since we'll log basically the whole summary file at once. - */ - if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1)) + /* Make sure the new fs size won't cause problems with the log. */ + error = xfs_growfs_check_rtgeom(mp, in->newblocks, in->extsize); + if (error) goto out_unlock; error = xfs_growfs_rtg(mp, in->newblocks, in->extsize); From patchwork Fri Aug 23 00:20:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774437 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09AFD2901 for ; Fri, 23 Aug 2024 00:20:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372424; cv=none; b=P0Ssds0cUs9spVhvRMj6rirkodtY9Uamtqr79rNyV8PMPgYilsSNZJoanqhM7NV6CqQtkeZcylv9s3fRCFql7gV2IrnP8FrURUn0KSsu755mNWwP2SzRPbB5OzsSjz7KwXiJHu2OrqHlYQGTpAhuOojFslgsnic6V6Ci8VQGEac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372424; c=relaxed/simple; bh=ClvXILjh5I7WtbZPNa54WiIkW1zRpqUa47/PhjV85ms=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tDFb6zBW7XhE9RQ9AkdGAUoPs411BIMe/5sIUe0Ru7j/OnLSMlpXyDhxLQJ9CqX+O/Cal3IN5E/gYB40sXZ6BeH0TcuAwhgNjugEnMBc2uGBnNsf0gbXUrEGf+CSLFgwcHsneKbwwcXCDMa+rLs25UDKRLczrUu+VSooipALWWU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LEFQoL3x; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LEFQoL3x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D362BC32782; Fri, 23 Aug 2024 00:20:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372423; bh=ClvXILjh5I7WtbZPNa54WiIkW1zRpqUa47/PhjV85ms=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=LEFQoL3x+gg+sPNkVBCvbJfW+lksFgiKMnIHLW2Xbzl9+5gedEUDSJ5WIOv5WEZxz nL1abkTyFhBqBFx6O4d+Cfo+2ZYsIYjFxIim3HJfRpmbAKFAdMhw/ed9a7keiOo8AK 3V3sX/TGpcsAXTpfx8Rca21kudwWUR+PQRpNd0KJau/JUuZhaSEceCd2EH1HtJaz6b bGIBZJGyKaXchJ7+xcb4/XW0WODkN+pHOl+QwXFscVF8ecLxJixZoAuW8auHfxhsjo wEHwWC9OvRyDVC4RkRL9D0cUgCUtheJ8OwW2rVcJTwmfwm70YkUgW83dNN/Akaskb1 0c6K3SNq1PHaw== Date: Thu, 22 Aug 2024 17:20:23 -0700 Subject: [PATCH 22/24] xfs: refactor xfs_rtbitmap_blockcount From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087628.59588.16837067030703641370.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Rename the existing xfs_rtbitmap_blockcount to xfs_rtbitmap_blockcount_len and add a new xfs_rtbitmap_blockcount wrapper around it that takes the number of extents from the mount structure. This will simplify the move to per-rtgroup bitmaps as those will need to pass in the number of extents per rtgroup instead. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtbitmap.c | 12 +++++++++++- fs/xfs/libxfs/xfs_rtbitmap.h | 7 ++++--- fs/xfs/libxfs/xfs_trans_resv.c | 2 +- fs/xfs/scrub/rtbitmap.c | 3 +-- fs/xfs/scrub/rtsummary.c | 7 ++----- fs/xfs/xfs_rtalloc.c | 3 +-- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 41de2f071934f..ea89503213c62 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1149,13 +1149,23 @@ xfs_rtalloc_extent_is_free( * extents. */ xfs_filblks_t -xfs_rtbitmap_blockcount( +xfs_rtbitmap_blockcount_len( struct xfs_mount *mp, xfs_rtbxlen_t rtextents) { return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); } +/* + * Compute the number of rtbitmap blocks used for a given file system. + */ +xfs_filblks_t +xfs_rtbitmap_blockcount( + struct xfs_mount *mp) +{ + return xfs_rtbitmap_blockcount_len(mp, mp->m_sb.sb_rextents); +} + /* Compute the number of rtsummary blocks needed to track the given rt space. */ xfs_filblks_t xfs_rtsummary_blockcount( diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index e4994a3e461d3..58672863053a9 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -307,8 +307,9 @@ int xfs_rtfree_extent(struct xfs_trans *tp, struct xfs_rtgroup *rtg, int xfs_rtfree_blocks(struct xfs_trans *tp, struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno, xfs_filblks_t rtlen); -xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t - rtextents); +xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp); +xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, + xfs_rtbxlen_t rtextents); xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, unsigned int rsumlevels, xfs_extlen_t rbmblocks); @@ -336,7 +337,7 @@ static inline int xfs_rtfree_blocks(struct xfs_trans *tp, # define xfs_rtbuf_cache_relse(a) (0) # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) static inline xfs_filblks_t -xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) +xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) { /* shut up gcc */ return 0; diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 2e6d7bb3b5a2f..5050fbcc37b75 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -224,7 +224,7 @@ xfs_rtalloc_block_count( xfs_rtxlen_t rtxlen; rtxlen = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN); - rtbmp_blocks = xfs_rtbitmap_blockcount(mp, rtxlen); + rtbmp_blocks = xfs_rtbitmap_blockcount_len(mp, rtxlen); return (rtbmp_blocks + 1) * num_ops; } diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 4a3e9d0302b51..3f090c3e3d11e 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -67,8 +67,7 @@ xchk_setup_rtbitmap( if (mp->m_sb.sb_rblocks) { rtb->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); rtb->rextslog = xfs_compute_rextslog(rtb->rextents); - rtb->rbmblocks = xfs_rtbitmap_blockcount(mp, - mp->m_sb.sb_rextents); + rtb->rbmblocks = xfs_rtbitmap_blockcount(mp); } return 0; diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index a756fb2c4abf8..e96aa24d89f62 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -107,8 +107,7 @@ xchk_setup_rtsummary( rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); rextslog = xfs_compute_rextslog(mp->m_sb.sb_rextents); rts->rsumlevels = rextslog + 1; - rts->rbmblocks = xfs_rtbitmap_blockcount(mp, - mp->m_sb.sb_rextents); + rts->rbmblocks = xfs_rtbitmap_blockcount(mp); rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, rts->rbmblocks); } @@ -215,11 +214,9 @@ xchk_rtsum_compute( { struct xfs_mount *mp = sc->mp; struct xfs_rtgroup *rtg = sc->sr.rtg; - unsigned long long rtbmp_blocks; /* If the bitmap size doesn't match the computed size, bail. */ - rtbmp_blocks = xfs_rtbitmap_blockcount(mp, mp->m_sb.sb_rextents); - if (XFS_FSB_TO_B(mp, rtbmp_blocks) != + if (XFS_FSB_TO_B(mp, xfs_rtbitmap_blockcount(mp)) != rtg->rtg_inodes[XFS_RTGI_BITMAP]->i_disk_size) return -EFSCORRUPTED; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 78a3879ad6193..fc35cdf856194 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -749,8 +749,7 @@ xfs_growfs_rt_alloc_fake_mount( xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb); nmp->m_sb.sb_rblocks = rblocks; nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); - nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp, - nmp->m_sb.sb_rextents); + nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp); nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, nmp->m_rsumlevels, From patchwork Fri Aug 23 00:20:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774438 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99D3E2901 for ; Fri, 23 Aug 2024 00:20:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372439; cv=none; b=HeyHjGorxw49+OUeaqzBsuld7JsTGWmAB/T5H+VTDkLVqArQYTM57vdtYFyqc+D1jYy3JjwUOdOm0f0ObpWMq8gYSfifqr5+6QjHEE7P7LKj5nWLKdDKcZH2+R9NEyWVA5Y0pZH6xaNHfDt6WcmtENnXrbBM0pD9l4hB0Ztulps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372439; c=relaxed/simple; bh=lEEF5NOlpRmqvVg8r1MKXkx3Bfjq8kfFlDg2wBYe6OE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rsAa48cCo0lAzdKVUiPXq2UtglxOEKm4Mh9ehio7T7/8opC9xeJGV8Td8iDa1QCByu60HFoWtR6eVF6JCIt03ueonts3/WItEaglwIJZlntUZGxbCqNh833xCee1wG+pZx5pIA4Lr72rHzbbwmcwT0f01loIdBu+vkmx+hX7ou4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZOcHLoYL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZOcHLoYL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75B2DC32782; Fri, 23 Aug 2024 00:20:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372439; bh=lEEF5NOlpRmqvVg8r1MKXkx3Bfjq8kfFlDg2wBYe6OE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ZOcHLoYLGPEJ2o4iZlfBC/5XCWKEVWZCcmNSzU0B4Y6U0Iq6t4HWbbvMVYxInXFhN 7NeirvhSgvCmLw66B58ESHJ2iXF63jQT8NWOQgZqnCcdFR/lxTEVkUpwbirtTAPCDm Ntt5LG0y7+sbiFAOxyEJ4OWCuD+6CeAZNkpeRc4tjWJUupCZUGoHogCwo6N7iAlEMM kAN5Ejm6wS2oljar/bZiVSnKEVq7o216peorg4J8uDBU5NzCDQbPfYYtiVCSGOG4AG OcldaZxHucLiZUcCjkMgYPfVJBXaTG94V1HRFSrXdbVCTAD71nDm4tPbQhGoY2tEk+ CnVu2iQjmzfiw== Date: Thu, 22 Aug 2024 17:20:39 -0700 Subject: [PATCH 23/24] xfs: refactor xfs_rtsummary_blockcount From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087646.59588.8776169412633182390.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Make xfs_rtsummary_blockcount take all the required information from the mount structure and return the number of summary levels from it as well. This cleans up many of the callers and prepares for making the rtsummary files per-rtgroup where they need to look at different value. This means we recalculate some values in some callers, but as all these calculations are outside the fast path and cheap that seems like a price worth paying. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtbitmap.c | 13 +++++++++---- fs/xfs/libxfs/xfs_rtbitmap.h | 3 +-- fs/xfs/scrub/rtsummary.c | 8 ++------ fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_rtalloc.c | 13 ++++--------- 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index ea89503213c62..7a848cacd561d 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -20,6 +20,7 @@ #include "xfs_error.h" #include "xfs_rtbitmap.h" #include "xfs_health.h" +#include "xfs_sb.h" /* * Realtime allocator bitmap functions shared with userspace. @@ -1166,16 +1167,20 @@ xfs_rtbitmap_blockcount( return xfs_rtbitmap_blockcount_len(mp, mp->m_sb.sb_rextents); } -/* Compute the number of rtsummary blocks needed to track the given rt space. */ +/* + * Compute the geometry of the rtsummary file needed to track the given rt + * space. + */ xfs_filblks_t xfs_rtsummary_blockcount( struct xfs_mount *mp, - unsigned int rsumlevels, - xfs_extlen_t rbmblocks) + unsigned int *rsumlevels) { unsigned long long rsumwords; - rsumwords = (unsigned long long)rsumlevels * rbmblocks; + *rsumlevels = xfs_compute_rextslog(mp->m_sb.sb_rextents) + 1; + + rsumwords = xfs_rtbitmap_blockcount(mp) * (*rsumlevels); return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); } diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 58672863053a9..776cca9e41bf0 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -311,7 +311,7 @@ xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp); xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, xfs_rtbxlen_t rtextents); xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, - unsigned int rsumlevels, xfs_extlen_t rbmblocks); + unsigned int *rsumlevels); int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb, @@ -342,7 +342,6 @@ xfs_rtbitmap_blockcount_len(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) /* shut up gcc */ return 0; } -# define xfs_rtsummary_blockcount(mp, l, b) (0) #endif /* CONFIG_XFS_RT */ #endif /* __XFS_RTBITMAP_H__ */ diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index e96aa24d89f62..3e2357f50b9d3 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -102,14 +102,10 @@ xchk_setup_rtsummary( */ xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP); if (mp->m_sb.sb_rblocks) { - int rextslog; - rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); - rextslog = xfs_compute_rextslog(mp->m_sb.sb_rextents); - rts->rsumlevels = rextslog + 1; rts->rbmblocks = xfs_rtbitmap_blockcount(mp); - rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, - rts->rbmblocks); + rts->rsumblocks = + xfs_rtsummary_blockcount(mp, &rts->rsumlevels); } return 0; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 2518977150295..137fb5f88307b 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -139,7 +139,7 @@ typedef struct xfs_mount { uint m_allocsize_blocks; /* min write size blocks */ int m_logbufs; /* number of log buffers */ int m_logbsize; /* size of each log buffer */ - uint m_rsumlevels; /* rt summary levels */ + unsigned int m_rsumlevels; /* rt summary levels */ xfs_filblks_t m_rsumblocks; /* size of rt summary, FSBs */ uint32_t m_rgblocks; /* size of rtgroup in rtblocks */ int m_fixedfsid[2]; /* unchanged for life of FS */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index fc35cdf856194..28d8cea4f84e3 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -751,9 +751,7 @@ xfs_growfs_rt_alloc_fake_mount( nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp); nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); - nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; - nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, nmp->m_rsumlevels, - nmp->m_sb.sb_rbmblocks); + nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, &nmp->m_rsumlevels); if (rblocks > 0) nmp->m_features |= XFS_FEAT_REALTIME; @@ -1138,21 +1136,18 @@ xfs_rtmount_init( struct xfs_mount *mp) /* file system mount structure */ { struct xfs_buf *bp; /* buffer for last block of subvolume */ - struct xfs_sb *sbp; /* filesystem superblock copy in mount */ xfs_daddr_t d; /* address of last block of subvolume */ int error; - sbp = &mp->m_sb; - if (sbp->sb_rblocks == 0) + if (mp->m_sb.sb_rblocks == 0) return 0; if (mp->m_rtdev_targp == NULL) { xfs_warn(mp, "Filesystem has a realtime volume, use rtdev=device option"); return -ENODEV; } - mp->m_rsumlevels = sbp->sb_rextslog + 1; - mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, - mp->m_sb.sb_rbmblocks); + + mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, &mp->m_rsumlevels); /* * Check that the realtime section is an ok size. From patchwork Fri Aug 23 00:20:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774439 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4387FAD49 for ; Fri, 23 Aug 2024 00:20:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372455; cv=none; b=ThKjHwvRIX96auf9bte0mWPHG6fr8bbnziOwegaZ/Ht9kE6AAxB2xkCTvfFhqXCoUs8+d5rUTO3/iUAbe3v6lsUs69AsV6GNYJMnMGSmDO59m98FebYFx6N24PJdbiABqjA4ZyBu6qI/M+pLyIBPHWWAvteDKe+WCdo2nqwKvaM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372455; c=relaxed/simple; bh=gpHkf9dERHZgBMpzXUguqL2Ix0E16HGD9Zmn+hAArwk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=a5a3KowOhd6O+lFuCwRsfbSJ1LrJd9Azz/e+yO7SHuqaxBdCqQ6nGLR91pRGoxbABsgm/ib5DRTHECJK9t25MlBO8UXnnu8eQLISQZ6uklhbiVbQQKYVB1As0Ylw7XFyWo2mIbeDV5GAFst4xK7KuzwM+0eG6ZuvcDMfjK7SBOU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Nju7eSqT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Nju7eSqT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A3F0C32782; Fri, 23 Aug 2024 00:20:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372455; bh=gpHkf9dERHZgBMpzXUguqL2Ix0E16HGD9Zmn+hAArwk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Nju7eSqTeCwVXbAmTJSZtMYmnBTGooTRgpue3fv4SNHTH2Z8W+1xs/nhT6JF9f9gQ cs5XWUTirx2uGfPO9oBMpUOvvifWhY6pFi0OcbUlmO+mOB/j8dpzzfdbWzOnGOT7uf y1dlUtMs7ORSCtE1Nqui4azOOqjXIWHvzvNl5CE8Typ+UvDQ3rDgpamH0S1iMGzkCu yTQk5dPzf5lsjWZiCv1Ndhsich3eYXASRa+3ghHUTTWcbSUaaW6zn4tGf49BhPXHMS NDlamSVjbz2mc8xLtpxdFUt6sEL1e6FR6Goxdju/oIn7fQ9LZ9qFPp0ql2uusjf0vO LwQOIEG5p8fbw== Date: Thu, 22 Aug 2024 17:20:54 -0700 Subject: [PATCH 24/24] xfs: make RT extent numbers relative to the rtgroup From: "Darrick J. Wong" To: djwong@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437087663.59588.9430224695312076827.stgit@frogsfrogsfrogs> In-Reply-To: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> References: <172437087178.59588.10818863865198159576.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig To prepare for adding per-rtgroup bitmap files, make the xfs_rtxnum_t type encode the RT extent number relative to the rtgroup. The biggest part of this to clearly distinguish between the relative extent number that gets masked when converting from a global block number and length values that just have a factor applied to them when converting from file system blocks. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 6 ++-- fs/xfs/libxfs/xfs_rtbitmap.h | 69 ++++++++++++++++++++++++++---------------- fs/xfs/scrub/rtbitmap.c | 9 ++--- fs/xfs/scrub/rtsummary.c | 6 ++-- fs/xfs/xfs_discard.c | 4 +- fs/xfs/xfs_fsmap.c | 4 +- fs/xfs/xfs_iomap.c | 4 +- fs/xfs/xfs_mount.c | 2 + fs/xfs/xfs_rtalloc.c | 4 +- fs/xfs/xfs_super.c | 3 +- 10 files changed, 64 insertions(+), 47 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a1ee8dc91d6ba..c056ca8ad6090 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4126,7 +4126,7 @@ xfs_bmapi_reserve_delalloc( fdblocks = indlen; if (XFS_IS_REALTIME_INODE(ip)) { - error = xfs_dec_frextents(mp, xfs_rtb_to_rtx(mp, alen)); + error = xfs_dec_frextents(mp, xfs_blen_to_rtbxlen(mp, alen)); if (error) goto out_unreserve_quota; } else { @@ -4161,7 +4161,7 @@ xfs_bmapi_reserve_delalloc( out_unreserve_frextents: if (XFS_IS_REALTIME_INODE(ip)) - xfs_add_frextents(mp, xfs_rtb_to_rtx(mp, alen)); + xfs_add_frextents(mp, xfs_blen_to_rtbxlen(mp, alen)); out_unreserve_quota: if (XFS_IS_QUOTA_ON(mp)) xfs_quota_unreserve_blkres(ip, alen); @@ -5088,7 +5088,7 @@ xfs_bmap_del_extent_delay( fdblocks = da_diff; if (isrt) - xfs_add_frextents(mp, xfs_rtb_to_rtx(mp, del->br_blockcount)); + xfs_add_frextents(mp, xfs_blen_to_rtbxlen(mp, del->br_blockcount)); else fdblocks += del->br_blockcount; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 776cca9e41bf0..cf21ae31bfaa4 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -22,13 +22,37 @@ struct xfs_rtalloc_args { static inline xfs_rtblock_t xfs_rtx_to_rtb( - struct xfs_mount *mp, + struct xfs_rtgroup *rtg, xfs_rtxnum_t rtx) +{ + struct xfs_mount *mp = rtg->rtg_mount; + xfs_rtblock_t start = xfs_rgno_start_rtb(mp, rtg->rtg_rgno); + + if (mp->m_rtxblklog >= 0) + return start + (rtx << mp->m_rtxblklog); + return start + (rtx * mp->m_sb.sb_rextsize); +} + +/* Convert an rgbno into an rt extent number. */ +static inline xfs_rtxnum_t +xfs_rgbno_to_rtx( + struct xfs_mount *mp, + xfs_rgblock_t rgbno) +{ + if (likely(mp->m_rtxblklog >= 0)) + return rgbno >> mp->m_rtxblklog; + return rgbno / mp->m_sb.sb_rextsize; +} + +static inline uint64_t +xfs_rtbxlen_to_blen( + struct xfs_mount *mp, + xfs_rtbxlen_t rtbxlen) { if (mp->m_rtxblklog >= 0) - return rtx << mp->m_rtxblklog; + return rtbxlen << mp->m_rtxblklog; - return rtx * mp->m_sb.sb_rextsize; + return rtbxlen * mp->m_sb.sb_rextsize; } static inline xfs_extlen_t @@ -65,16 +89,29 @@ xfs_extlen_to_rtxlen( return len / mp->m_sb.sb_rextsize; } +/* Convert an rt block count into an rt extent count. */ +static inline xfs_rtbxlen_t +xfs_blen_to_rtbxlen( + struct xfs_mount *mp, + uint64_t blen) +{ + if (likely(mp->m_rtxblklog >= 0)) + return blen >> mp->m_rtxblklog; + + return div_u64(blen, mp->m_sb.sb_rextsize); +} + /* Convert an rt block number into an rt extent number. */ static inline xfs_rtxnum_t xfs_rtb_to_rtx( struct xfs_mount *mp, xfs_rtblock_t rtbno) { - if (likely(mp->m_rtxblklog >= 0)) - return rtbno >> mp->m_rtxblklog; + uint64_t __rgbno = __xfs_rtb_to_rgbno(mp, rtbno); - return div_u64(rtbno, mp->m_sb.sb_rextsize); + if (likely(mp->m_rtxblklog >= 0)) + return __rgbno >> mp->m_rtxblklog; + return div_u64(__rgbno, mp->m_sb.sb_rextsize); } /* Return the offset of an rt block number within an rt extent. */ @@ -89,26 +126,6 @@ xfs_rtb_to_rtxoff( return do_div(rtbno, mp->m_sb.sb_rextsize); } -/* - * Convert an rt block number into an rt extent number, rounding up to the next - * rt extent if the rt block is not aligned to an rt extent boundary. - */ -static inline xfs_rtxnum_t -xfs_rtb_to_rtxup( - struct xfs_mount *mp, - xfs_rtblock_t rtbno) -{ - if (likely(mp->m_rtxblklog >= 0)) { - if (rtbno & mp->m_rtxblkmask) - return (rtbno >> mp->m_rtxblklog) + 1; - return rtbno >> mp->m_rtxblklog; - } - - if (do_div(rtbno, mp->m_sb.sb_rextsize)) - rtbno++; - return rtbno; -} - /* Round this rtblock up to the nearest rt extent size. */ static inline xfs_rtblock_t xfs_rtb_roundup_rtx( diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 3f090c3e3d11e..17aff4227721e 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -65,7 +65,7 @@ xchk_setup_rtbitmap( */ xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP); if (mp->m_sb.sb_rblocks) { - rtb->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); + rtb->rextents = xfs_blen_to_rtbxlen(mp, mp->m_sb.sb_rblocks); rtb->rextslog = xfs_compute_rextslog(rtb->rextents); rtb->rbmblocks = xfs_rtbitmap_blockcount(mp); } @@ -83,15 +83,14 @@ xchk_rtbitmap_rec( const struct xfs_rtalloc_rec *rec, void *priv) { - struct xfs_mount *mp = rtg->rtg_mount; struct xfs_scrub *sc = priv; xfs_rtblock_t startblock; xfs_filblks_t blockcount; - startblock = xfs_rtx_to_rtb(mp, rec->ar_startext); - blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount); + startblock = xfs_rtx_to_rtb(rtg, rec->ar_startext); + blockcount = xfs_rtxlen_to_extlen(rtg->rtg_mount, rec->ar_extcount); - if (!xfs_verify_rtbext(mp, startblock, blockcount)) + if (!xfs_verify_rtbext(rtg->rtg_mount, startblock, blockcount)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); return 0; } diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 3e2357f50b9d3..1f01ed9450388 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -102,7 +102,7 @@ xchk_setup_rtsummary( */ xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP); if (mp->m_sb.sb_rblocks) { - rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); + rts->rextents = xfs_blen_to_rtbxlen(mp, mp->m_sb.sb_rblocks); rts->rbmblocks = xfs_rtbitmap_blockcount(mp); rts->rsumblocks = xfs_rtsummary_blockcount(mp, &rts->rsumlevels); @@ -182,8 +182,8 @@ xchk_rtsum_record_free( lenlog = xfs_highbit64(rec->ar_extcount); offs = xfs_rtsumoffs(mp, lenlog, rbmoff); - rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); - rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); + rtbno = xfs_rtx_to_rtb(rtg, rec->ar_startext); + rtlen = xfs_rtxlen_to_extlen(mp, rec->ar_extcount); if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { xchk_ino_xref_set_corrupt(sc, diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index b2ef5ebe1f047..e1a024f68a68f 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -526,8 +526,8 @@ xfs_trim_gather_rtextent( return -ECANCELED; } - rbno = xfs_rtx_to_rtb(rtg->rtg_mount, rec->ar_startext); - rlen = xfs_rtx_to_rtb(rtg->rtg_mount, rec->ar_extcount); + rbno = xfs_rtx_to_rtb(rtg, rec->ar_startext); + rlen = xfs_rtxlen_to_extlen(rtg->rtg_mount, rec->ar_extcount); /* Ignore too small. */ if (rlen < tr->minlen_fsb) { diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 0e0ec3f0574b1..6ae929dd65b6e 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -726,9 +726,9 @@ xfs_getfsmap_rtdev_rtbitmap_helper( struct xfs_mount *mp = rtg->rtg_mount; struct xfs_getfsmap_info *info = priv; xfs_rtblock_t start_rtb = - xfs_rtx_to_rtb(mp, rec->ar_startext); + xfs_rtx_to_rtb(rtg, rec->ar_startext); uint64_t rtbcount = - xfs_rtx_to_rtb(mp, rec->ar_extcount); + xfs_rtbxlen_to_blen(mp, rec->ar_extcount); struct xfs_rmap_irec irec = { .rm_startblock = start_rtb, .rm_blockcount = rtbcount, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 72c981e3dc921..13cabd345e227 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -501,8 +501,8 @@ xfs_iomap_prealloc_size( alloc_blocks); if (unlikely(XFS_IS_REALTIME_INODE(ip))) - freesp = xfs_rtx_to_rtb(mp, - xfs_iomap_freesp(&mp->m_frextents, + freesp = xfs_rtbxlen_to_blen(mp, + xfs_iomap_freesp(&mp->m_frextents, mp->m_low_rtexts, &shift)); else freesp = xfs_iomap_freesp(&mp->m_fdblocks, mp->m_low_space, diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index e1e849101cdd4..5726ea597f5a2 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1472,7 +1472,7 @@ xfs_mod_delalloc( if (XFS_IS_REALTIME_INODE(ip)) { percpu_counter_add_batch(&mp->m_delalloc_rtextents, - xfs_rtb_to_rtx(mp, data_delta), + xfs_blen_to_rtbxlen(mp, data_delta), XFS_DELALLOC_BATCH); if (!ind_delta) return; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 28d8cea4f84e3..308049f2fb79d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -748,7 +748,7 @@ xfs_growfs_rt_alloc_fake_mount( nmp->m_sb.sb_rextsize = rextsize; xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb); nmp->m_sb.sb_rblocks = rblocks; - nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); + nmp->m_sb.sb_rextents = xfs_blen_to_rtbxlen(nmp, nmp->m_sb.sb_rblocks); nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp); nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, &nmp->m_rsumlevels); @@ -1464,7 +1464,7 @@ xfs_rtallocate( xfs_trans_mod_sb(tp, wasdel ? XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, -(long)len); - *bno = xfs_rtx_to_rtb(args.mp, rtx); + *bno = xfs_rtx_to_rtb(args.rtg, rtx); *blen = xfs_rtxlen_to_extlen(args.mp, len); out_release: diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index cee64c1a7d650..2767083612bf6 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -885,7 +885,8 @@ xfs_fs_statfs( statp->f_blocks = sbp->sb_rblocks; freertx = percpu_counter_sum_positive(&mp->m_frextents); - statp->f_bavail = statp->f_bfree = xfs_rtx_to_rtb(mp, freertx); + statp->f_bavail = statp->f_bfree = + xfs_rtbxlen_to_blen(mp, freertx); } return 0;