From patchwork Fri Dec 30 22:17:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085430 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D2C5C4332F for ; Sat, 31 Dec 2022 01:27:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236085AbiLaB1u (ORCPT ); Fri, 30 Dec 2022 20:27:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236093AbiLaB1t (ORCPT ); Fri, 30 Dec 2022 20:27:49 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC0001DF3A for ; Fri, 30 Dec 2022 17:27:46 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 617DFB81DEC for ; Sat, 31 Dec 2022 01:27:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25746C433EF; Sat, 31 Dec 2022 01:27:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450064; bh=DLvFWrCutW2WLkmEIE4W3B1OFOK+Pzdiizpy/al2+GY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=CJCvGcR4b4QNMg2Lt1W+F3IgH0MKP70qVVDPZtvnMW51jz99PiPAVATQPF/Oii0zx j2e8X73CTvxTk7E5IYY85FfZ6hLQAqBrUqgUoRZB4pNxKx4jnt3/jGpl/byN2X0kWb KQLM0jxdK0nws2x8xfpjsCofLxANq/j+WnfadJdWrTAi0kVMFOzyptX8flKKL91wOK WuWDbXc5mJnYbS1eR1OMbFxyWVOR++eL8plemGen8xQFZvqpTD+L0CVyw4CCbeBED/ L0eF+w7XB9ALFMzfYQpPRlTGNCJZQIjVHQpsnmbqN0C5x0k2z9MPJOsG9j3zXexi1M x4HtlujD80VSA== Subject: [PATCH 01/22] xfs: create incore realtime group structures From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:52 -0800 Message-ID: <167243867284.712847.15864310421589015183.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org 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. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_format.h | 8 ++ fs/xfs/libxfs/xfs_rtgroup.c | 214 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 121 ++++++++++++++++++++++++ fs/xfs/libxfs/xfs_sb.c | 5 + fs/xfs/libxfs/xfs_types.h | 4 + fs/xfs/xfs_log_recover.c | 6 + fs/xfs/xfs_mount.c | 12 ++ fs/xfs/xfs_mount.h | 6 + fs/xfs/xfs_rtalloc.c | 14 ++- fs/xfs/xfs_super.c | 2 fs/xfs/xfs_trace.h | 34 +++++++ 12 files changed, 423 insertions(+), 4 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 3d74696755c3..135a403c0edc 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -57,6 +57,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 946870eb492c..ca87a3f8704a 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -184,6 +184,14 @@ typedef struct xfs_sb { */ xfs_ino_t sb_metadirino; + /* + * Realtime group geometry information. On disk these fields live in + * the rsumino slot, but we cache them separately in the in-core super + * for easy access. + */ + xfs_rgblock_t sb_rgblocks; /* size of a realtime group */ + xfs_rgnumber_t sb_rgcount; /* number of realtime groups */ + /* 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 000000000000..ced2bd896106 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 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; + int ref = 0; + + rcu_read_lock(); + rtg = radix_tree_lookup(&mp->m_rtgroup_tree, rgno); + if (rtg) { + ASSERT(atomic_read(&rtg->rtg_ref) >= 0); + ref = atomic_inc_return(&rtg->rtg_ref); + } + rcu_read_unlock(); + trace_xfs_rtgroup_get(mp, rgno, ref, _RET_IP_); + return rtg; +} + +struct xfs_rtgroup * +xfs_rtgroup_bump( + struct xfs_rtgroup *rtg) +{ + if (!atomic_inc_not_zero(&rtg->rtg_ref)) { + ASSERT(0); + return NULL; + } + + trace_xfs_rtgroup_bump(rtg->rtg_mount, rtg->rtg_rgno, + atomic_read(&rtg->rtg_ref), _RET_IP_); + return rtg; +} + +void +xfs_rtgroup_put( + struct xfs_rtgroup *rtg) +{ + int ref; + + ASSERT(atomic_read(&rtg->rtg_ref) > 0); + ref = atomic_dec_return(&rtg->rtg_ref); + trace_xfs_rtgroup_put(rtg->rtg_mount, rtg->rtg_rgno, ref, _RET_IP_); +} + +int +xfs_initialize_rtgroups( + struct xfs_mount *mp, + xfs_rgnumber_t rgcount) +{ + struct xfs_rtgroup *rtg; + xfs_rgnumber_t index; + xfs_rgnumber_t first_initialised = NULLRGNUMBER; + int error; + + if (!xfs_has_rtgroups(mp)) + return 0; + + /* + * Walk the current rtgroup tree so we don't try to initialise rt + * groups that already exist (growfs case). Allocate and insert all the + * rtgroups we don't find ready for initialisation. + */ + for (index = 0; index < rgcount; index++) { + rtg = xfs_rtgroup_get(mp, index); + if (rtg) { + xfs_rtgroup_put(rtg); + continue; + } + + rtg = kmem_zalloc(sizeof(struct xfs_rtgroup), KM_MAYFAIL); + if (!rtg) { + error = -ENOMEM; + goto out_unwind_new_rtgs; + } + rtg->rtg_rgno = index; + rtg->rtg_mount = mp; + + error = radix_tree_preload(GFP_NOFS); + if (error) + goto out_free_rtg; + + spin_lock(&mp->m_rtgroup_lock); + if (radix_tree_insert(&mp->m_rtgroup_tree, index, rtg)) { + WARN_ON_ONCE(1); + spin_unlock(&mp->m_rtgroup_lock); + radix_tree_preload_end(); + error = -EEXIST; + goto out_free_rtg; + } + spin_unlock(&mp->m_rtgroup_lock); + radix_tree_preload_end(); + +#ifdef __KERNEL__ + /* Place kernel structure only init below this point. */ + spin_lock_init(&rtg->rtg_state_lock); +#endif /* __KERNEL__ */ + + /* first new rtg is fully initialized */ + if (first_initialised == NULLRGNUMBER) + first_initialised = index; + } + + return 0; + +out_free_rtg: + kmem_free(rtg); +out_unwind_new_rtgs: + /* unwind any prior newly initialized rtgs */ + for (index = first_initialised; index < rgcount; index++) { + rtg = radix_tree_delete(&mp->m_rtgroup_tree, index); + if (!rtg) + break; + kmem_free(rtg); + } + return error; +} + +STATIC void +__xfs_free_rtgroups( + struct rcu_head *head) +{ + struct xfs_rtgroup *rtg; + + rtg = container_of(head, struct xfs_rtgroup, rcu_head); + kmem_free(rtg); +} + +/* + * Free up the rtgroup resources associated with the mount structure. + */ +void +xfs_free_rtgroups( + struct xfs_mount *mp) +{ + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; + + if (!xfs_has_rtgroups(mp)) + return; + + for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) { + spin_lock(&mp->m_rtgroup_lock); + rtg = radix_tree_delete(&mp->m_rtgroup_tree, rgno); + spin_unlock(&mp->m_rtgroup_lock); + ASSERT(rtg); + XFS_IS_CORRUPT(rtg->rtg_mount, atomic_read(&rtg->rtg_ref) != 0); + + call_rcu(&rtg->rcu_head, __xfs_free_rtgroups); + } +} + +/* Find the size of the rtgroup, in blocks. */ +static xfs_rgblock_t +__xfs_rtgroup_block_count( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + xfs_rgnumber_t rgcount, + xfs_rfsblock_t rblocks) +{ + ASSERT(rgno < rgcount); + + if (rgno < rgcount - 1) + return mp->m_sb.sb_rgblocks; + return xfs_rtb_rounddown_rtx(mp, + rblocks - (rgno * mp->m_sb.sb_rgblocks)); +} + +/* Compute the number of blocks in this realtime group. */ +xfs_rgblock_t +xfs_rtgroup_block_count( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + return __xfs_rtgroup_block_count(mp, rgno, mp->m_sb.sb_rgcount, + mp->m_sb.sb_rblocks); +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h new file mode 100644 index 000000000000..f414218a66f2 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022 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; + + /* for rcu-safe freeing */ + struct rcu_head rcu_head; + + /* Number of blocks in this group */ + xfs_rgblock_t rtg_blockcount; + +#ifdef __KERNEL__ + /* -- kernel only structures below this line -- */ + spinlock_t rtg_state_lock; +#endif /* __KERNEL__ */ +}; + +#ifdef CONFIG_XFS_RT +struct xfs_rtgroup *xfs_rtgroup_get(struct xfs_mount *mp, xfs_rgnumber_t rgno); +struct xfs_rtgroup *xfs_rtgroup_bump(struct xfs_rtgroup *rtg); +void xfs_rtgroup_put(struct xfs_rtgroup *rtg); +int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t rgcount); +void xfs_free_rtgroups(struct xfs_mount *mp); +#else +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_bump(struct xfs_rtgroup *rtg) +{ + ASSERT(rtg == NULL); + return NULL; +} +# define xfs_rtgroup_put(rtg) ((void)0) +# define xfs_initialize_rtgroups(mp, rgcount) (0) +# define xfs_free_rtgroups(mp) ((void)0) +#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_put(rtg); + if (*rgno > end_rgno) + return NULL; + return xfs_rtgroup_get(mp, *rgno); +} + +#define for_each_rtgroup_range(mp, rgno, end_rgno, rtg) \ + for ((rtg) = xfs_rtgroup_get((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) +{ + if (rgbno >= rtg->rtg_blockcount) + return false; + if (rgbno < rtg->rtg_mount->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); +} + +#ifdef CONFIG_XFS_RT +xfs_rgblock_t xfs_rtgroup_block_count(struct xfs_mount *mp, + xfs_rgnumber_t rgno); +#else +# define xfs_rtgroup_block_count(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 83930abf935f..48cfb9c8296b 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -641,6 +641,9 @@ __xfs_sb_from_disk( to->sb_gquotino = NULLFSINO; to->sb_pquotino = NULLFSINO; } + + to->sb_rgcount = 0; + to->sb_rgblocks = 0; } void @@ -954,6 +957,8 @@ xfs_sb_mount_common( mp->m_blockwmask = mp->m_blockwsize - 1; mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); + mp->m_rgblklog = 0; + mp->m_rgblkmask = 0; mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index f4615c5be34f..c27c84561b5e 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 */ @@ -54,7 +56,9 @@ typedef void * xfs_failaddr_t; #define NULLRTEXTNO ((xfs_rtxnum_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 006ceff1959d..8e6da3f34585 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) @@ -3341,6 +3342,11 @@ xlog_do_recover( xfs_warn(mp, "Failed post-recovery per-ag init: %d", error); return error; } + error = xfs_initialize_rtgroups(mp, sbp->sb_rgcount); + 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 3957c60d5d07..bcfeaaf11536 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -35,6 +35,7 @@ #include "xfs_trace.h" #include "xfs_ag.h" #include "xfs_imeta.h" +#include "xfs_rtgroup.h" static DEFINE_MUTEX(xfs_uuid_table_mutex); static int xfs_uuid_table_size; @@ -830,10 +831,16 @@ xfs_mountfs( goto out_free_dir; } + error = xfs_initialize_rtgroups(mp, sbp->sb_rgcount); + if (error) { + xfs_warn(mp, "Failed rtgroup init: %d", error); + goto out_free_perag; + } + 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); @@ -1058,6 +1065,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_rtgroup: + xfs_free_rtgroups(mp); out_free_perag: xfs_free_perag(mp); out_free_dir: @@ -1138,6 +1147,7 @@ xfs_unmountfs( xfs_errortag_clearall(mp); #endif unregister_shrinker(&mp->m_inodegc_shrinker); + xfs_free_rtgroups(mp); xfs_free_perag(mp); xfs_errortag_del(mp); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index bad926f3e102..674938008a97 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -119,6 +119,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 */ @@ -153,6 +154,7 @@ typedef struct xfs_mount { 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 */ @@ -201,6 +203,8 @@ typedef struct xfs_mount { */ atomic64_t m_allocbt_blks; + struct radix_tree_root m_rtgroup_tree; /* per-rt group info */ + spinlock_t m_rtgroup_lock; /* lock for m_rtgroup_tree */ 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 */ @@ -285,6 +289,7 @@ typedef struct xfs_mount { #define XFS_FEAT_NEEDSREPAIR (1ULL << 25) /* needs xfs_repair */ #define XFS_FEAT_NREXT64 (1ULL << 26) /* large extent counters */ #define XFS_FEAT_METADIR (1ULL << 27) /* metadata directory tree */ +#define XFS_FEAT_RTGROUPS (1ULL << 28) /* realtime groups */ /* Mount features */ #define XFS_FEAT_NOATTR2 (1ULL << 48) /* disable attr2 creation */ @@ -349,6 +354,7 @@ __XFS_HAS_FEAT(bigtime, BIGTIME) __XFS_HAS_FEAT(needsrepair, NEEDSREPAIR) __XFS_HAS_FEAT(large_extent_counts, NREXT64) __XFS_HAS_FEAT(metadir, METADIR) +__XFS_HAS_FEAT(rtgroups, RTGROUPS) /* * Mount features diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index c131738efd0f..3b13352cfbfc 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -25,6 +25,7 @@ #include "xfs_da_format.h" #include "xfs_imeta.h" #include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" /* * Realtime metadata files are not quite regular files because userspace can't @@ -1409,10 +1410,12 @@ xfs_rtmount_iread_extents( */ int /* error */ xfs_rtmount_inodes( - xfs_mount_t *mp) /* file system mount structure */ + struct xfs_mount *mp) /* file system mount structure */ { - int error; /* error return value */ - xfs_sb_t *sbp; + struct xfs_sb *sbp; + struct xfs_rtgroup *rtg; + xfs_rgnumber_t rgno; + int error; /* error return value */ sbp = &mp->m_sb; error = xfs_rt_iget(mp, mp->m_sb.sb_rbmino, &xfs_rbmip_key, @@ -1439,6 +1442,11 @@ xfs_rtmount_inodes( if (error) goto out_rele_summary; + for_each_rtgroup(mp, rgno, rtg) { + rtg->rtg_blockcount = xfs_rtgroup_block_count(mp, + rtg->rtg_rgno); + } + xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); return 0; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 19a22f9225e4..737c51333d09 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1932,6 +1932,8 @@ static int xfs_init_fs_context( spin_lock_init(&mp->m_agirotor_lock); INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); spin_lock_init(&mp->m_perag_lock); + INIT_RADIX_TREE(&mp->m_rtgroup_tree, GFP_ATOMIC); + spin_lock_init(&mp->m_rtgroup_lock); 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.h b/fs/xfs/xfs_trace.h index b92efe4eaeae..f72f694b4656 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -206,6 +206,40 @@ DEFINE_PERAG_REF_EVENT(xfs_perag_put); 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_mount *mp, xfs_rgnumber_t rgno, int refcount, + unsigned long caller_ip), + TP_ARGS(mp, rgno, refcount, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_rgnumber_t, rgno) + __field(int, refcount) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->rgno = rgno; + __entry->refcount = refcount; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d rgno 0x%x refcount %d caller %pS", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->rgno, + __entry->refcount, + (char *)__entry->caller_ip) +); + +#define DEFINE_RTGROUP_REF_EVENT(name) \ +DEFINE_EVENT(xfs_rtgroup_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_rgnumber_t rgno, int refcount, \ + unsigned long caller_ip), \ + TP_ARGS(mp, rgno, refcount, caller_ip)) +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_get); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_bump); +DEFINE_RTGROUP_REF_EVENT(xfs_rtgroup_put); +#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 Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62FCDC4332F for ; Sat, 31 Dec 2022 01:28:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236090AbiLaB2F (ORCPT ); Fri, 30 Dec 2022 20:28:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236091AbiLaB2E (ORCPT ); Fri, 30 Dec 2022 20:28:04 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7AF6B1C93A for ; Fri, 30 Dec 2022 17:28:02 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 0C79AB81DE3 for ; Sat, 31 Dec 2022 01:28:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB40AC433EF; Sat, 31 Dec 2022 01:27:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450079; bh=fdPqoK0o02Z2l7EKrNh0RpGp0XPn5mtBZca0Mgwcp7Q=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=YqIOy6+QMqgNAuzdaP4bGeEKlBMsZbF8KBWvto9cjUup+VH2m7phmofJUtr4dVOv3 HeW1C1UitzOFGTeSdvg/JY4m0SpeoWSPVvOXkfB7UmYwT6WooByTe7Oav6xj5jgPf/ MYXwCnTxLfHO+/S+uzBi25rRP+xrALzQ/eS04o/74FsvK+dHYObGt/P+lHWQZ9ay7t EEJcPU1BTJuUQt7jkcpZwlGyp2EBeorpTftLL0Zzq0tVqG4bLnTeC8ALFiPKDauXkz qjEuuRvko4MnQJ+vngOGz1bp83+ELzH6y5oyYfWJJcBPsaMIvXbU+oHm26GFMqiZIM 6Mhf+hbNJ0nkA== Subject: [PATCH 02/22] xfs: define the format of rt groups From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867299.712847.10904510582883426329.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Define the ondisk format of realtime group metadata. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 62 +++++++++++++++++++++++++++- fs/xfs/libxfs/xfs_rtgroup.c | 96 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 83 +++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_sb.c | 86 +++++++++++++++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_shared.h | 1 fs/xfs/xfs_ondisk.h | 1 6 files changed, 324 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index ca87a3f8704a..a38e1499bd4b 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -216,7 +216,17 @@ struct xfs_dsb { * pointers are no longer used. */ __be64 sb_rbmino; - __be64 sb_rsumino; /* summary inode for rt bitmap */ + /* + * rtgroups requires metadir, so we reuse the rsumino space to hold + * the rg block count and shift values. + */ + union { + __be64 sb_rsumino; /* summary inode for rt bitmap */ + struct { + __be32 sb_rgcount; /* # of realtime groups */ + __be32 sb_rgblocks; /* rtblocks per group */ + }; + }; __be32 sb_rextsize; /* realtime extent size, blocks */ __be32 sb_agblocks; /* size of an allocation group */ __be32 sb_agcount; /* number of allocation groups */ @@ -397,6 +407,7 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ #define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */ +#define XFS_SB_FEAT_INCOMPAT_RTGROUPS (1 << 30) /* realtime groups */ #define XFS_SB_FEAT_INCOMPAT_METADIR (1U << 31) /* metadata dir tree */ #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ @@ -741,6 +752,55 @@ union xfs_suminfo_ondisk { __u32 raw; }; +/* + * Realtime allocation groups break the rt section into multiple pieces that + * could be locked independently. Realtime block group numbers are 32-bit + * quantities. Block numbers within a group are also 32-bit quantities, but + * the upper bit must never be set. + */ +#define XFS_MAX_RGBLOCKS ((xfs_rgblock_t)(1U << 31) - 1) +#define XFS_MAX_RGNUMBER ((xfs_rgnumber_t)(-1U)) + +#define XFS_RTSB_MAGIC 0x58524750 /* 'XRGP' */ + +/* + * Realtime superblock - on disk version. Must be padded to 64 bit alignment. + * The first block of each realtime group contains this superblock; this is + * how we avoid having file data extents cross a group boundary. + */ +struct xfs_rtsb { + __be32 rsb_magicnum; /* magic number == XFS_RTSB_MAGIC */ + __be32 rsb_blocksize; /* logical block size, bytes */ + __be64 rsb_rblocks; /* number of realtime blocks */ + + __be64 rsb_rextents; /* number of realtime extents */ + __be64 rsb_lsn; /* last write sequence */ + + __be32 rsb_rgcount; /* # of realtime groups */ + char rsb_fname[XFSLABEL_MAX]; /* rt volume name */ + + uuid_t rsb_uuid; /* user-visible file system unique id */ + + __be32 rsb_rextsize; /* realtime extent size, blocks */ + __be32 rsb_rbmblocks; /* number of rt bitmap blocks */ + + __be32 rsb_rgblocks; /* rt blocks per group */ + __u8 rsb_blocklog; /* log2 of sb_blocksize */ + __u8 rsb_sectlog; /* log2 of sb_sectsize */ + __u8 rsb_rextslog; /* log2 of sb_rextents */ + __u8 rsb_pad; + + __le32 rsb_crc; /* superblock crc */ + __le32 rsb_pad2; + + uuid_t rsb_meta_uuid; /* metadata file system unique id */ + + /* must be padded to 64 bit alignment */ +}; + +#define XFS_RTSB_CRC_OFF offsetof(struct xfs_rtsb, rsb_crc) +#define XFS_RTSB_DADDR ((xfs_daddr_t)0) /* daddr in rt section */ + /* * XFS Timestamps * ============== diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index ced2bd896106..edbc427725c3 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -28,6 +28,7 @@ #include "xfs_trace.h" #include "xfs_inode.h" #include "xfs_icache.h" +#include "xfs_buf_item.h" #include "xfs_rtgroup.h" #include "xfs_rtbitmap.h" @@ -212,3 +213,98 @@ xfs_rtgroup_block_count( return __xfs_rtgroup_block_count(mp, rgno, mp->m_sb.sb_rgcount, mp->m_sb.sb_rblocks); } + +static xfs_failaddr_t +xfs_rtsb_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_mount; + struct xfs_rtsb *rsb = bp->b_addr; + + if (!xfs_verify_magic(bp, rsb->rsb_magicnum)) + return __this_address; + if (be32_to_cpu(rsb->rsb_blocksize) != mp->m_sb.sb_blocksize) + return __this_address; + if (be64_to_cpu(rsb->rsb_rblocks) != mp->m_sb.sb_rblocks) + return __this_address; + + if (be64_to_cpu(rsb->rsb_rextents) != mp->m_sb.sb_rextents) + return __this_address; + + if (!uuid_equal(&rsb->rsb_uuid, &mp->m_sb.sb_uuid)) + return __this_address; + + if (be32_to_cpu(rsb->rsb_rgcount) != mp->m_sb.sb_rgcount) + return __this_address; + + if (be32_to_cpu(rsb->rsb_rextsize) != mp->m_sb.sb_rextsize) + return __this_address; + if (be32_to_cpu(rsb->rsb_rbmblocks) != mp->m_sb.sb_rbmblocks) + return __this_address; + + if (be32_to_cpu(rsb->rsb_rgblocks) != mp->m_sb.sb_rgblocks) + return __this_address; + if (rsb->rsb_blocklog != mp->m_sb.sb_blocklog) + return __this_address; + if (rsb->rsb_sectlog != mp->m_sb.sb_sectlog) + return __this_address; + if (rsb->rsb_rextslog != mp->m_sb.sb_rextslog) + return __this_address; + if (rsb->rsb_pad) + return __this_address; + + if (rsb->rsb_pad2) + return __this_address; + + if (!uuid_equal(&rsb->rsb_meta_uuid, &mp->m_sb.sb_meta_uuid)) + return __this_address; + + /* Everything to the end of the fs block must be zero */ + if (memchr_inv(rsb + 1, 0, BBTOB(bp->b_length) - sizeof(*rsb))) + return __this_address; + + return NULL; +} + +static void +xfs_rtsb_read_verify( + struct xfs_buf *bp) +{ + xfs_failaddr_t fa; + + if (!xfs_buf_verify_cksum(bp, XFS_RTSB_CRC_OFF)) + xfs_verifier_error(bp, -EFSBADCRC, __this_address); + else { + fa = xfs_rtsb_verify(bp); + if (fa) + xfs_verifier_error(bp, -EFSCORRUPTED, fa); + } +} + +static void +xfs_rtsb_write_verify( + struct xfs_buf *bp) +{ + struct xfs_rtsb *rsb = bp->b_addr; + struct xfs_buf_log_item *bip = bp->b_log_item; + xfs_failaddr_t fa; + + fa = xfs_rtsb_verify(bp); + if (fa) { + xfs_verifier_error(bp, -EFSCORRUPTED, fa); + return; + } + + if (bip) + rsb->rsb_lsn = cpu_to_be64(bip->bli_item.li_lsn); + + xfs_buf_update_cksum(bp, XFS_RTSB_CRC_OFF); +} + +const struct xfs_buf_ops xfs_rtsb_buf_ops = { + .name = "xfs_rtsb", + .magic = { 0, cpu_to_be32(XFS_RTSB_MAGIC) }, + .verify_read = xfs_rtsb_read_verify, + .verify_write = xfs_rtsb_write_verify, + .verify_struct = xfs_rtsb_verify, +}; diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index f414218a66f2..ff9b01d8c501 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -111,6 +111,89 @@ xfs_verify_rgbext( return xfs_verify_rgbno(rtg, rgbno + len - 1); } +static inline xfs_rtblock_t +xfs_rgbno_to_rtb( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + xfs_rgblock_t rgbno) +{ + ASSERT(xfs_has_rtgroups(mp)); + + if (mp->m_rgblklog >= 0) + return ((xfs_rtblock_t)rgno << mp->m_rgblklog) | rgbno; + + return ((xfs_rtblock_t)rgno * mp->m_sb.sb_rgblocks) + rgbno; +} + +static inline xfs_rgnumber_t +xfs_rtb_to_rgno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + ASSERT(xfs_has_rtgroups(mp)); + + if (mp->m_rgblklog >= 0) + return rtbno >> mp->m_rgblklog; + + return div_u64(rtbno, mp->m_sb.sb_rgblocks); +} + +static inline xfs_rgblock_t +xfs_rtb_to_rgbno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno, + xfs_rgnumber_t *rgno) +{ + uint32_t rem; + + ASSERT(xfs_has_rtgroups(mp)); + + if (mp->m_rgblklog >= 0) { + *rgno = rtbno >> mp->m_rgblklog; + return rtbno & mp->m_rgblkmask; + } + + *rgno = div_u64_rem(rtbno, mp->m_sb.sb_rgblocks, &rem); + return rem; +} + +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; +} + +static inline xfs_rgnumber_t +xfs_daddr_to_rgno( + struct xfs_mount *mp, + xfs_daddr_t daddr) +{ + xfs_rtblock_t rtb = daddr >> mp->m_blkbb_log; + + return xfs_rtb_to_rgno(mp, rtb); +} + +static inline xfs_rgblock_t +xfs_daddr_to_rgbno( + struct xfs_mount *mp, + xfs_daddr_t daddr) +{ + xfs_rtblock_t rtb = daddr >> mp->m_blkbb_log; + xfs_rgnumber_t rgno; + + return xfs_rtb_to_rgbno(mp, rtb, &rgno); +} + #ifdef CONFIG_XFS_RT xfs_rgblock_t xfs_rtgroup_block_count(struct xfs_mount *mp, xfs_rgnumber_t rgno); diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 48cfb9c8296b..bbadf78b4628 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -176,6 +176,8 @@ xfs_sb_version_to_features( features |= XFS_FEAT_NREXT64; if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR) features |= XFS_FEAT_METADIR; + if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) + features |= XFS_FEAT_RTGROUPS; return features; } @@ -302,6 +304,64 @@ xfs_validate_sb_write( return 0; } +static int +xfs_validate_sb_rtgroups( + struct xfs_mount *mp, + struct xfs_sb *sbp) +{ + uint64_t groups; + + if (!(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR)) { + xfs_warn(mp, +"Realtime groups require metadata directory tree."); + return -EINVAL; + } + + if (sbp->sb_rgblocks > XFS_MAX_RGBLOCKS) { + xfs_warn(mp, +"Realtime group size (%u) must be less than %u.", + sbp->sb_rgblocks, XFS_MAX_RGBLOCKS); + return -EINVAL; + } + + if (sbp->sb_rextsize == 0) { + xfs_warn(mp, +"Realtime extent size must not be zero."); + return -EINVAL; + } + + if (sbp->sb_rgblocks % sbp->sb_rextsize != 0) { + xfs_warn(mp, +"Realtime group size (%u) must be an even multiple of extent size (%u).", + sbp->sb_rgblocks, sbp->sb_rextsize); + return -EINVAL; + } + + if (sbp->sb_rgblocks < (sbp->sb_rextsize << 1)) { + xfs_warn(mp, +"Realtime group size (%u) must be greater than 1 rt extent.", + sbp->sb_rgblocks); + return -EINVAL; + } + + if (sbp->sb_rgcount > XFS_MAX_RGNUMBER) { + xfs_warn(mp, +"Realtime groups (%u) must be less than %u.", + sbp->sb_rgcount, XFS_MAX_RGNUMBER); + return -EINVAL; + } + + groups = howmany_64(sbp->sb_rblocks, sbp->sb_rgblocks); + if (groups != sbp->sb_rgcount) { + xfs_warn(mp, +"Realtime groups (%u) do not cover the entire rt section; need (%llu) groups.", + sbp->sb_rgcount, groups); + return -EINVAL; + } + + return 0; +} + /* Check the validity of the SB. */ STATIC int xfs_validate_sb_common( @@ -313,6 +373,7 @@ xfs_validate_sb_common( uint32_t agcount = 0; uint32_t rem; bool has_dalign; + int error; if (!xfs_verify_magic(bp, dsb->sb_magicnum)) { xfs_warn(mp, @@ -362,6 +423,12 @@ xfs_validate_sb_common( return -EINVAL; } } + + if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) { + error = xfs_validate_sb_rtgroups(mp, sbp); + if (error) + return error; + } } else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) { xfs_notice(mp, @@ -642,8 +709,13 @@ __xfs_sb_from_disk( to->sb_pquotino = NULLFSINO; } - to->sb_rgcount = 0; - to->sb_rgblocks = 0; + if (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) { + to->sb_rgcount = be32_to_cpu(from->sb_rgcount); + to->sb_rgblocks = be32_to_cpu(from->sb_rgblocks); + } else { + to->sb_rgcount = 0; + to->sb_rgblocks = 0; + } } void @@ -803,6 +875,12 @@ xfs_sb_to_disk( to->sb_gquotino = cpu_to_be64(NULLFSINO); to->sb_pquotino = cpu_to_be64(NULLFSINO); } + + if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) { + /* must come after setting to_rsumino */ + to->sb_rgcount = cpu_to_be32(from->sb_rgcount); + to->sb_rgblocks = cpu_to_be32(from->sb_rgblocks); + } } /* @@ -957,8 +1035,8 @@ xfs_sb_mount_common( mp->m_blockwmask = mp->m_blockwsize - 1; mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); - mp->m_rgblklog = 0; - mp->m_rgblkmask = 0; + mp->m_rgblklog = log2_if_power2(sbp->sb_rgblocks); + mp->m_rgblkmask = mask64_if_power2(sbp->sb_rgblocks); mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 46754fe57361..e76e735b1d05 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -39,6 +39,7 @@ extern const struct xfs_buf_ops xfs_inode_buf_ra_ops; extern const struct xfs_buf_ops xfs_refcountbt_buf_ops; extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; extern const struct xfs_buf_ops xfs_rtbuf_ops; +extern const struct xfs_buf_ops xfs_rtsb_buf_ops; extern const struct xfs_buf_ops xfs_sb_buf_ops; extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; extern const struct xfs_buf_ops xfs_symlink_buf_ops; diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h index f4d700ce185c..61909355731d 100644 --- a/fs/xfs/xfs_ondisk.h +++ b/fs/xfs/xfs_ondisk.h @@ -53,6 +53,7 @@ xfs_check_ondisk_structs(void) XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t, 4); XFS_CHECK_STRUCT_SIZE(xfs_refcount_ptr_t, 4); XFS_CHECK_STRUCT_SIZE(xfs_rmap_ptr_t, 4); + XFS_CHECK_STRUCT_SIZE(struct xfs_rtsb, 104); /* dir/attr trees */ XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_leaf_hdr, 80); From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085432 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 530DBC4332F for ; Sat, 31 Dec 2022 01:28:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236092AbiLaB2T (ORCPT ); Fri, 30 Dec 2022 20:28:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236091AbiLaB2S (ORCPT ); Fri, 30 Dec 2022 20:28:18 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB3C51DF18 for ; Fri, 30 Dec 2022 17:28:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 906A0B81DED for ; Sat, 31 Dec 2022 01:28:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C6BBC433EF; Sat, 31 Dec 2022 01:28:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450095; bh=TBQB+myFor72BEdjPpqdyIyQ5EVN1BYYRwIFfBcw5mk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Qlw+eDvedbOwHypAquxE752O+aFl0eKKVsC2L/ab8sMbw8ImQg4byfTal3c2BM+Z+ L/qwRXQP6wLsYUHUcrJpInBAK4HMSu2rVeIpGcL7zu9rkuuv94THmbuJ9FcOPHzMGd jlKWrUR+5c27Bw/AfIYSds73UbdPGPHfO9XTyMyDc4dLcJr1QNgxXh/D7KXNYfWI6+ kCydKrfxbQJ7fHWQYD+MmCFsReI5W5wZ2Yv1AWn7EyV5PASXXnFQjfpKCOdnzriq59 9UIi7QQWLOO4qGPoEZaiednUABsGi+DHkNgW7rUZPfsQvu1VY9Fy7hR+DuNtcLepVl DmR51Emc+Dx4g== Subject: [PATCH 03/22] xfs: check the realtime superblock at mount time From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867313.712847.15088416523614287132.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Check the realtime superblock at mount time, to ensure that the label actually matches the primary superblock. If the rt superblock is good, attach it to the xfs_mount so that the log can use ordered buffers to keep this primary in sync with the primary super on the data device. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_rtalloc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_rtalloc.h | 5 +++++ fs/xfs/xfs_super.c | 16 ++++++++++++++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 674938008a97..7f0a80a8dcd4 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -82,6 +82,7 @@ typedef struct xfs_mount { struct super_block *m_super; struct xfs_ail *m_ail; /* fs active log item list */ struct xfs_buf *m_sb_bp; /* buffer for superblock */ + struct xfs_buf *m_rtsb_bp; /* realtime superblock */ char *m_rtname; /* realtime device name */ char *m_logname; /* external log device name */ struct xfs_da_geometry *m_dir_geo; /* directory block geometry */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 3b13352cfbfc..9c842237c452 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1263,6 +1263,56 @@ xfs_rtallocate_extent( return 0; } +/* Read the primary realtime group's superblock and attach it to the mount. */ +int +xfs_rtmount_readsb( + struct xfs_mount *mp) +{ + struct xfs_buf *bp; + int error; + + if (!xfs_has_rtgroups(mp)) + return 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; + } + + /* m_blkbb_log is not set up yet */ + error = xfs_buf_read_uncached(mp->m_rtdev_targp, XFS_RTSB_DADDR, + mp->m_sb.sb_blocksize >> BBSHIFT, XBF_NO_IOACCT, &bp, + &xfs_rtsb_buf_ops); + if (error) { + xfs_warn(mp, "rt sb validate failed with error %d.", error); + /* bad CRC means corrupted metadata */ + if (error == -EFSBADCRC) + error = -EFSCORRUPTED; + return error; + } + + mp->m_rtsb_bp = bp; + xfs_buf_unlock(bp); + return 0; +} + +/* Detach the realtime superblock from the mount and free it. */ +void +xfs_rtmount_freesb( + struct xfs_mount *mp) +{ + struct xfs_buf *bp = mp->m_rtsb_bp; + + if (!bp) + return; + + xfs_buf_lock(bp); + mp->m_rtsb_bp = NULL; + xfs_buf_relse(bp); +} + /* * Initialize realtime fields in the mount structure. */ diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 5ac9c15948c8..d0fd49db77bd 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -33,6 +33,9 @@ xfs_rtallocate_extent( xfs_rtxnum_t *rtblock); /* out: start rtext allocated */ +int xfs_rtmount_readsb(struct xfs_mount *mp); +void xfs_rtmount_freesb(struct xfs_mount *mp); + /* * Initialize realtime fields in the mount structure. */ @@ -81,6 +84,8 @@ int xfs_rtfile_convert_unwritten(struct xfs_inode *ip, loff_t pos, # define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS) # define xfs_growfs_rt(mp,in) (-ENOSYS) # define xfs_rtalloc_reinit_frextents(m) (0) +# define xfs_rtmount_readsb(mp) (0) +# define xfs_rtmount_freesb(mp) ((void)0) static inline int /* error */ xfs_rtmount_init( xfs_mount_t *mp) /* file system mount structure */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 737c51333d09..bfe93ca6eed4 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -44,6 +44,7 @@ #include "scrub/rcbag_btree.h" #include "xfs_swapext_item.h" #include "xfs_rtbitmap.h" +#include "xfs_rtalloc.h" #include #include @@ -1117,6 +1118,7 @@ xfs_fs_put_super( xfs_filestream_unmount(mp); xfs_unmountfs(mp); + xfs_rtmount_freesb(mp); xfs_freesb(mp); free_percpu(mp->m_stats.xs_stats); xfs_mount_list_del(mp); @@ -1599,9 +1601,13 @@ xfs_fs_fill_super( goto out_free_sb; } + error = xfs_rtmount_readsb(mp); + if (error) + goto out_free_sb; + error = xfs_filestream_mount(mp); if (error) - goto out_free_sb; + goto out_free_rtsb; /* * we must configure the block size in the superblock before we run the @@ -1645,6 +1651,10 @@ xfs_fs_fill_super( xfs_warn(mp, "EXPERIMENTAL metadata directory feature in use. Use at your own risk!"); + if (xfs_has_rtgroups(mp)) + xfs_warn(mp, +"EXPERIMENTAL realtime allocation group feature in use. Use at your own risk!"); + if (xfs_has_reflink(mp)) { if (mp->m_sb.sb_rblocks) { xfs_alert(mp, @@ -1689,6 +1699,8 @@ xfs_fs_fill_super( out_filestream_unmount: xfs_filestream_unmount(mp); + out_free_rtsb: + xfs_rtmount_freesb(mp); out_free_sb: xfs_freesb(mp); out_free_stats: @@ -1710,7 +1722,7 @@ xfs_fs_fill_super( out_unmount: xfs_filestream_unmount(mp); xfs_unmountfs(mp); - goto out_free_sb; + goto out_free_rtsb; } static int From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085433 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18B45C4332F for ; Sat, 31 Dec 2022 01:28:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236091AbiLaB2g (ORCPT ); Fri, 30 Dec 2022 20:28:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235752AbiLaB2e (ORCPT ); Fri, 30 Dec 2022 20:28:34 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C0031DF18 for ; Fri, 30 Dec 2022 17:28:33 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 2FC93B81DE5 for ; Sat, 31 Dec 2022 01:28:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DB4EFC433EF; Sat, 31 Dec 2022 01:28:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450110; bh=p72jB2EPhzVpfxP9g6KvsnDwVXJsHhlij6e85O5oPQ4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KspKB4Xm3Uf48jP56fGvM/8ly0MH381BYiGgWbthjYew+f//33yDqXAk4H5sCiy64 Yvl6h6bXsSi1Wt95loSG0bPe3Yye97UJG2WfSIRuUAKq/ozVd5UjOGRnyrTP1sNQ+/ KwJEu+thwHXk2+wCZECzholci5xSIfnzBU9Cyw0xp4Giu4z7OeJO1Kf6bu0iRB9XhF DxPMP05GKRVm0WWQTS1NXaQPRxyckVWHT6vALbhRBWG4DOB1IdDvk+8RdeuvpMdJNO 9PNTwF6IefUEHfXs8J55acZbmfwTNf/LnFqCmKLY2p181cMKVVwmo4monBfxUpxB0y oA1vJlKSwdVQw== Subject: [PATCH 04/22] xfs: update primary realtime super every time we update the primary fs super From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867327.712847.16568431395173815876.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Every time we update parts of the primary filesystem superblock that are echoed in the primary rt super, we should update that primary realtime super. Avoid an ondisk log format change by using ordered buffers to write the primary rt super. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtgroup.c | 74 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 6 +++ fs/xfs/libxfs/xfs_sb.c | 13 +++++++ fs/xfs/xfs_buf_item_recover.c | 18 ++++++++++ fs/xfs/xfs_trans.c | 10 ++++++ fs/xfs/xfs_trans.h | 1 + fs/xfs/xfs_trans_buf.c | 25 +++++++++++--- 7 files changed, 142 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index edbc427725c3..e9655e699f4f 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -308,3 +308,77 @@ const struct xfs_buf_ops xfs_rtsb_buf_ops = { .verify_write = xfs_rtsb_write_verify, .verify_struct = xfs_rtsb_verify, }; + +/* Update a realtime superblock from the primary fs super */ +void +xfs_rtgroup_update_super( + struct xfs_buf *rtsb_bp, + const struct xfs_buf *sb_bp) +{ + const struct xfs_dsb *dsb = sb_bp->b_addr; + struct xfs_rtsb *rsb = rtsb_bp->b_addr; + const uuid_t *meta_uuid; + + rsb->rsb_magicnum = cpu_to_be32(XFS_RTSB_MAGIC); + rsb->rsb_blocksize = dsb->sb_blocksize; + rsb->rsb_rblocks = dsb->sb_rblocks; + + rsb->rsb_rextents = dsb->sb_rextents; + rsb->rsb_lsn = 0; + + memcpy(&rsb->rsb_uuid, &dsb->sb_uuid, sizeof(rsb->rsb_uuid)); + + rsb->rsb_rgcount = dsb->sb_rgcount; + memcpy(&rsb->rsb_fname, &dsb->sb_fname, XFSLABEL_MAX); + + rsb->rsb_rextsize = dsb->sb_rextsize; + rsb->rsb_rbmblocks = dsb->sb_rbmblocks; + + rsb->rsb_rgblocks = dsb->sb_rgblocks; + rsb->rsb_blocklog = dsb->sb_blocklog; + rsb->rsb_sectlog = dsb->sb_sectlog; + rsb->rsb_rextslog = dsb->sb_rextslog; + rsb->rsb_pad = 0; + rsb->rsb_pad2 = 0; + + /* + * The metadata uuid is the fs uuid if the metauuid feature is not + * enabled. + */ + if (dsb->sb_features_incompat & + cpu_to_be32(XFS_SB_FEAT_INCOMPAT_META_UUID)) + meta_uuid = &dsb->sb_meta_uuid; + else + meta_uuid = &dsb->sb_uuid; + memcpy(&rsb->rsb_meta_uuid, meta_uuid, sizeof(rsb->rsb_meta_uuid)); +} + +/* + * Update the primary realtime superblock from a filesystem superblock and + * log it to the given transaction. + */ +void +xfs_rtgroup_log_super( + struct xfs_trans *tp, + const struct xfs_buf *sb_bp) +{ + struct xfs_buf *rtsb_bp; + + if (!xfs_has_rtgroups(tp->t_mountp)) + return; + + rtsb_bp = xfs_trans_getrtsb(tp); + if (!rtsb_bp) { + /* + * It's possible for the rtgroups feature to be enabled but + * there is no incore rt superblock buffer if the rt geometry + * was specified at mkfs time but the rt section has not yet + * been attached. In this case, rblocks must be zero. + */ + ASSERT(tp->t_mountp->m_sb.sb_rblocks == 0); + return; + } + + xfs_rtgroup_update_super(rtsb_bp, sb_bp); + xfs_trans_ordered_buf(tp, rtsb_bp); +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index ff9b01d8c501..c6db6b0d2ae5 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -197,8 +197,14 @@ xfs_daddr_to_rgbno( #ifdef CONFIG_XFS_RT xfs_rgblock_t xfs_rtgroup_block_count(struct xfs_mount *mp, xfs_rgnumber_t rgno); + +void xfs_rtgroup_update_super(struct xfs_buf *rtsb_bp, + const struct xfs_buf *sb_bp); +void xfs_rtgroup_log_super(struct xfs_trans *tp, const struct xfs_buf *sb_bp); #else # define xfs_rtgroup_block_count(mp, rgno) (0) +# define xfs_rtgroup_update_super(bp, sb_bp) ((void)0) +# define xfs_rtgroup_log_super(tp, sb_bp) ((void)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 bbadf78b4628..2e8ec9214c6c 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -26,6 +26,7 @@ #include "xfs_health.h" #include "xfs_ag.h" #include "xfs_swapext.h" +#include "xfs_rtgroup.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -1100,6 +1101,8 @@ xfs_log_sb( xfs_sb_to_disk(bp->b_addr, &mp->m_sb); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1); + + xfs_rtgroup_log_super(tp, bp); } /* @@ -1216,6 +1219,7 @@ xfs_sync_sb_buf( { struct xfs_trans *tp; struct xfs_buf *bp; + struct xfs_buf *rtsb_bp = NULL; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0, 0, &tp); @@ -1225,6 +1229,11 @@ xfs_sync_sb_buf( bp = xfs_trans_getsb(tp); xfs_log_sb(tp); xfs_trans_bhold(tp, bp); + if (xfs_has_rtgroups(mp)) { + rtsb_bp = xfs_trans_getrtsb(tp); + if (rtsb_bp) + xfs_trans_bhold(tp, rtsb_bp); + } xfs_trans_set_sync(tp); error = xfs_trans_commit(tp); if (error) @@ -1233,7 +1242,11 @@ xfs_sync_sb_buf( * write out the sb buffer to get the changes to disk */ error = xfs_bwrite(bp); + if (!error && rtsb_bp) + error = xfs_bwrite(rtsb_bp); out: + if (rtsb_bp) + xfs_buf_relse(rtsb_bp); xfs_buf_relse(bp); return error; } diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index ffa94102094d..6587d18b21c3 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -22,6 +22,7 @@ #include "xfs_inode.h" #include "xfs_dir2.h" #include "xfs_quota.h" +#include "xfs_rtgroup.h" /* * This is the number of entries in the l_buf_cancel_table used during @@ -985,6 +986,23 @@ xlog_recover_buf_commit_pass2( ASSERT(bp->b_mount == mp); bp->b_flags |= _XBF_LOGRECOVERY; xfs_buf_delwri_queue(bp, buffer_list); + + /* + * Update the primary rt super if we just recovered the primary + * fs super. + */ + if (xfs_has_rtgroups(mp) && bp->b_ops == &xfs_sb_buf_ops) { + struct xfs_buf *rtsb_bp = mp->m_rtsb_bp; + + if (rtsb_bp) { + xfs_buf_lock(rtsb_bp); + xfs_buf_hold(rtsb_bp); + xfs_rtgroup_update_super(rtsb_bp, bp); + rtsb_bp->b_flags |= _XBF_LOGRECOVERY; + xfs_buf_delwri_queue(rtsb_bp, buffer_list); + xfs_buf_relse(rtsb_bp); + } + } } out_release: diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index f39c5daeef86..979aba1b2fc8 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -25,6 +25,7 @@ #include "xfs_dquot.h" #include "xfs_icache.h" #include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" struct kmem_cache *xfs_trans_cache; @@ -531,6 +532,7 @@ xfs_trans_apply_sb_deltas( { struct xfs_dsb *sbp; struct xfs_buf *bp; + bool update_rtsb = false; int whole = 0; bp = xfs_trans_getsb(tp); @@ -591,22 +593,27 @@ xfs_trans_apply_sb_deltas( if (tp->t_rextsize_delta) { be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta); whole = 1; + update_rtsb = true; } if (tp->t_rbmblocks_delta) { be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); whole = 1; + update_rtsb = true; } if (tp->t_rblocks_delta) { be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta); whole = 1; + update_rtsb = true; } if (tp->t_rextents_delta) { be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta); whole = 1; + update_rtsb = true; } if (tp->t_rextslog_delta) { sbp->sb_rextslog += tp->t_rextslog_delta; whole = 1; + update_rtsb = true; } xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); @@ -623,6 +630,9 @@ xfs_trans_apply_sb_deltas( xfs_trans_log_buf(tp, bp, offsetof(struct xfs_dsb, sb_icount), offsetof(struct xfs_dsb, sb_frextents) + sizeof(sbp->sb_frextents) - 1); + + if (update_rtsb) + xfs_rtgroup_log_super(tp, bp); } /* diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 0a9ec6929bbc..37cde68f3a31 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -216,6 +216,7 @@ xfs_trans_read_buf( } struct xfs_buf *xfs_trans_getsb(struct xfs_trans *); +struct xfs_buf *xfs_trans_getrtsb(struct xfs_trans *tp); void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index e28ab74af4f0..8e886ecfd69a 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -168,12 +168,11 @@ xfs_trans_get_buf_map( /* * Get and lock the superblock buffer for the given transaction. */ -struct xfs_buf * -xfs_trans_getsb( - struct xfs_trans *tp) +static struct xfs_buf * +__xfs_trans_getsb( + struct xfs_trans *tp, + struct xfs_buf *bp) { - struct xfs_buf *bp = tp->t_mountp->m_sb_bp; - /* * Just increment the lock recursion count if the buffer is already * attached to this transaction. @@ -197,6 +196,22 @@ xfs_trans_getsb( return bp; } +struct xfs_buf * +xfs_trans_getsb( + struct xfs_trans *tp) +{ + return __xfs_trans_getsb(tp, tp->t_mountp->m_sb_bp); +} + +struct xfs_buf * +xfs_trans_getrtsb( + struct xfs_trans *tp) +{ + if (!tp->t_mountp->m_rtsb_bp) + return NULL; + return __xfs_trans_getsb(tp, tp->t_mountp->m_rtsb_bp); +} + /* * Get and lock the buffer for the caller if it is not already * locked within the given transaction. If it has not yet been From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085434 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A82CC4332F for ; Sat, 31 Dec 2022 01:28:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236093AbiLaB2t (ORCPT ); Fri, 30 Dec 2022 20:28:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235752AbiLaB2s (ORCPT ); Fri, 30 Dec 2022 20:28:48 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 795B11C93A for ; Fri, 30 Dec 2022 17:28:47 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 15E9661CAB for ; Sat, 31 Dec 2022 01:28:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76BCAC433EF; Sat, 31 Dec 2022 01:28:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450126; bh=OpzWkWaDZ5JicG7K9cUyUmAtVR7YHhUa4ekNcDHQw6s=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hj8ra8aJAjRvvmiSW5Ad1/qDiIbfRfS6AC7KRkrfYyhbjy4Bz1EgWBvIenrWJRcJd +XeWH9itvgFU4QORoaOyz/NFyUTId04r87VrdEFexcUvrEjvi+NAy0nh5Hjgu+XjOI sxWyJHyJSYCtymuFWjrcwLJZWgUN6i81G2TdC4WAWVh2guAKog6IBJTYYGrVnlgiSy xD0qHuF5UcBTCbv5svMhT39juuljrZWXzjsfvnbeEAtkhsCzDbknoLB7XrImOzKutU Bwxb57Bg9i5jRFuglXq+KLTk27xNbB8LrPUnJlVlIQhl/NPxncEwnKi1k62eYFSjM9 M/+RRuJveh76A== Subject: [PATCH 05/22] xfs: write secondary realtime superblocks to disk From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867341.712847.732913902847227497.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create some library functions to make it easy to update all the secondary realtime superblocks on disk; this will be used by growfs, xfs_db, mkfs, and xfs_repair. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtgroup.c | 117 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 2 + 2 files changed, 119 insertions(+) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index e9655e699f4f..037506b73384 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -382,3 +382,120 @@ xfs_rtgroup_log_super( xfs_rtgroup_update_super(rtsb_bp, sb_bp); xfs_trans_ordered_buf(tp, rtsb_bp); } + +/* Initialize a secondary realtime superblock. */ +static int +xfs_rtgroup_init_secondary_super( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + struct xfs_buf **bpp) +{ + struct xfs_buf *bp; + struct xfs_rtsb *rsb; + xfs_rtblock_t rtbno; + int error; + + ASSERT(rgno != 0); + + error = xfs_buf_get_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, 1), + 0, &bp); + if (error) + return error; + + rtbno = xfs_rgbno_to_rtb(mp, rgno, 0); + bp->b_maps[0].bm_bn = xfs_rtb_to_daddr(mp, rtbno); + bp->b_ops = &xfs_rtsb_buf_ops; + xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); + + rsb = bp->b_addr; + rsb->rsb_magicnum = cpu_to_be32(XFS_RTSB_MAGIC); + rsb->rsb_blocksize = cpu_to_be32(mp->m_sb.sb_blocksize); + rsb->rsb_rblocks = cpu_to_be64(mp->m_sb.sb_rblocks); + + rsb->rsb_rextents = cpu_to_be64(mp->m_sb.sb_rextents); + + memcpy(&rsb->rsb_uuid, &mp->m_sb.sb_uuid, sizeof(rsb->rsb_uuid)); + + rsb->rsb_rgcount = cpu_to_be32(mp->m_sb.sb_rgcount); + memcpy(&rsb->rsb_fname, &mp->m_sb.sb_fname, XFSLABEL_MAX); + + rsb->rsb_rextsize = cpu_to_be32(mp->m_sb.sb_rextsize); + rsb->rsb_rbmblocks = cpu_to_be32(mp->m_sb.sb_rbmblocks); + + rsb->rsb_rgblocks = cpu_to_be32(mp->m_sb.sb_rgblocks); + rsb->rsb_blocklog = mp->m_sb.sb_blocklog; + rsb->rsb_sectlog = mp->m_sb.sb_sectlog; + rsb->rsb_rextslog = mp->m_sb.sb_rextslog; + + memcpy(&rsb->rsb_meta_uuid, &mp->m_sb.sb_meta_uuid, + sizeof(rsb->rsb_meta_uuid)); + + *bpp = bp; + return 0; +} + +/* + * Update all the realtime superblocks to match the new state of the primary. + * Because we are completely overwriting all the existing fields in the + * secondary superblock buffers, there is no need to read them in from disk. + * Just get a new buffer, stamp it and write it. + * + * The rt super buffers do not need to be kept them in memory once they are + * written so we mark them as a one-shot buffer. + */ +int +xfs_rtgroup_update_secondary_sbs( + struct xfs_mount *mp) +{ + LIST_HEAD (buffer_list); + struct xfs_rtgroup *rtg; + xfs_rgnumber_t start_rgno = 1; + int saved_error = 0; + int error = 0; + + for_each_rtgroup_from(mp, start_rgno, rtg) { + struct xfs_buf *bp; + + error = xfs_rtgroup_init_secondary_super(mp, rtg->rtg_rgno, + &bp); + /* + * If we get an error reading or writing alternate superblocks, + * continue. If we break early, we'll leave more superblocks + * un-updated than updated. + */ + if (error) { + xfs_warn(mp, + "error allocating secondary superblock for rt group %d", + rtg->rtg_rgno); + if (!saved_error) + saved_error = error; + continue; + } + + xfs_buf_oneshot(bp); + xfs_buf_delwri_queue(bp, &buffer_list); + xfs_buf_relse(bp); + + /* don't hold too many buffers at once */ + if (rtg->rtg_rgno % 16) + continue; + + error = xfs_buf_delwri_submit(&buffer_list); + if (error) { + xfs_warn(mp, + "write error %d updating a secondary superblock near rt group %u", + error, rtg->rtg_rgno); + if (!saved_error) + saved_error = error; + continue; + } + } + error = xfs_buf_delwri_submit(&buffer_list); + if (error) { + xfs_warn(mp, + "write error %d updating a secondary superblock near rt group %u", + error, start_rgno); + } + + return saved_error ? saved_error : error; +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index c6db6b0d2ae5..d8723fabeb57 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -201,10 +201,12 @@ xfs_rgblock_t xfs_rtgroup_block_count(struct xfs_mount *mp, void xfs_rtgroup_update_super(struct xfs_buf *rtsb_bp, const struct xfs_buf *sb_bp); void xfs_rtgroup_log_super(struct xfs_trans *tp, const struct xfs_buf *sb_bp); +int xfs_rtgroup_update_secondary_sbs(struct xfs_mount *mp); #else # define xfs_rtgroup_block_count(mp, rgno) (0) # define xfs_rtgroup_update_super(bp, sb_bp) ((void)0) # define xfs_rtgroup_log_super(tp, sb_bp) ((void)0) +# define xfs_rtgroup_update_secondary_sbs(mp) (0) #endif /* CONFIG_XFS_RT */ #endif /* __LIBXFS_RTGROUP_H */ From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77B5CC4332F for ; Sat, 31 Dec 2022 01:29:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236094AbiLaB3G (ORCPT ); Fri, 30 Dec 2022 20:29:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235752AbiLaB3F (ORCPT ); Fri, 30 Dec 2022 20:29:05 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8663C1C93A for ; Fri, 30 Dec 2022 17:29:04 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 33FE6B81DD0 for ; Sat, 31 Dec 2022 01:29:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2442C433D2; Sat, 31 Dec 2022 01:29:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450142; bh=9esKn37BJ/++77uXwoBht9uWOcjbeeMyeX4LmJiOeHw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SJTUOdSZSmxqvwyGanv3VF3h57In0H3kf55TeurDGGEMFfbEIo1YofAZ+vkGzlxVx gCwsUi5yS9Q87Be8QDepZCDD1LHUn3QQuR/abFILLQWNgHZB3g7LwY87XkdP41o/tb LZUoARtwdXagKajCrPUGilCK2CEvmz4Y2aMnLxnRRCqFEHexTB0RGYkUa7oDdssr67 PLZZdMW+mm5NHDcLOqm93V8GG9ARY297RaIdfOqRn3vqHmlpYEXD/410ZZlLsV8+rv fEGfp7PVcAWw8R+p2xhPCy88JKM1lso0F/XuFa4lBDsAhBlDgwLXfbSHZ5eeosUmET cvCsGy4VJH3TA== Subject: [PATCH 06/22] xfs: grow the realtime section when realtime groups are enabled From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867356.712847.17316307632362464090.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Enable growing the rt section when realtime groups are enabled. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_shared.h | 1 fs/xfs/xfs_rtalloc.c | 139 ++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/xfs_trans.c | 10 +++ fs/xfs/xfs_trans.h | 1 4 files changed, 145 insertions(+), 6 deletions(-) diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index e76e735b1d05..bcdf298889af 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -111,6 +111,7 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, #define XFS_TRANS_SB_RBLOCKS 0x00000800 #define XFS_TRANS_SB_REXTENTS 0x00001000 #define XFS_TRANS_SB_REXTSLOG 0x00002000 +#define XFS_TRANS_SB_RGCOUNT 0x00004000 /* * Here we centralize the specification of XFS meta-data buffer reference count diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 9c842237c452..9d8d91fa0ecf 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -930,6 +930,92 @@ xfs_alloc_rsum_cache( * Visible (exported) functions. */ +static int +xfs_growfs_rt_free_new( + struct xfs_trans *tp, + struct xfs_mount *nmp, + xfs_rtbxlen_t *freed_rtx) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_sb *sbp = &mp->m_sb; + struct xfs_sb *nsbp = &nmp->m_sb; + struct xfs_buf *bp = NULL; + xfs_fileoff_t sumbno; + xfs_rtblock_t rtbno, next_rtbno; + int error = 0; + + if (!xfs_has_rtgroups(mp)) { + *freed_rtx = nsbp->sb_rextents - sbp->sb_rextents; + return xfs_rtfree_range(nmp, tp, sbp->sb_rextents, *freed_rtx, + &bp, &sumbno); + } + + *freed_rtx = 0; + + rtbno = xfs_rtx_to_rtb(nmp, sbp->sb_rextents); + next_rtbno = xfs_rtx_to_rtb(nmp, nsbp->sb_rextents); + while (rtbno < next_rtbno) { + xfs_rtxnum_t start_rtx, next_rtx; + xfs_rtblock_t next_free_rtbno; + xfs_rgnumber_t rgno; + xfs_rgblock_t rgbno; + + /* + * Compute the first new extent that we want to free, being + * careful to skip past a realtime superblock at the start of + * the new region. + */ + rgbno = xfs_rtb_to_rgbno(nmp, rtbno, &rgno); + if (rgbno == 0) { + rtbno += nsbp->sb_rextsize; + if (rtbno >= next_rtbno) + break; + } + + start_rtx = xfs_rtb_to_rtxt(nmp, rtbno); + + /* + * Stop freeing either at the end of the new rt section or at + * the start of the next realtime group. + */ + next_free_rtbno = xfs_rgbno_to_rtb(nmp, rgno + 1, 0); + next_rtx = xfs_rtb_to_rtxt(nmp, next_free_rtbno); + next_rtx = min(next_rtx, nsbp->sb_rextents); + + bp = NULL; + *freed_rtx += next_rtx - start_rtx; + error = xfs_rtfree_range(nmp, tp, start_rtx, + next_rtx - start_rtx, &bp, &sumbno); + if (error) + break; + + rtbno = next_free_rtbno; + } + + return error; +} + +static int +xfs_growfs_rt_init_primary( + struct xfs_mount *mp) +{ + struct xfs_buf *rtsb_bp; + int error; + + error = xfs_buf_get_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, 1), + 0, &rtsb_bp); + if (error) + return error; + + rtsb_bp->b_maps[0].bm_bn = XFS_RTSB_DADDR; + rtsb_bp->b_ops = &xfs_rtsb_buf_ops; + + xfs_rtgroup_update_super(rtsb_bp, mp->m_sb_bp); + mp->m_rtsb_bp = rtsb_bp; + xfs_buf_unlock(rtsb_bp); + return 0; +} + /* * Grow the realtime area of the filesystem. */ @@ -953,8 +1039,8 @@ xfs_growfs_rt( xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ xfs_extlen_t rsumblocks; /* current number of rt summary blks */ xfs_sb_t *sbp; /* old superblock */ - xfs_fileoff_t sumbno; /* summary block number */ uint8_t *rsum_cache; /* old summary cache */ + xfs_rgnumber_t new_rgcount = 0; sbp = &mp->m_sb; @@ -1019,6 +1105,30 @@ xfs_growfs_rt( */ if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1)) return -EINVAL; + + /* Allocate the new rt group structures */ + if (xfs_has_rtgroups(mp)) { + /* + * We don't support changing the group size to match the extent + * size, even if the size of the rt section is currently zero. + */ + if (mp->m_sb.sb_rgblocks % in->extsize != 0) + return -EOPNOTSUPP; + + if (mp->m_sb.sb_rblocks == 0) { + error = xfs_growfs_rt_init_primary(mp); + if (error) + return error; + } + + new_rgcount = howmany_64(nrblocks, mp->m_sb.sb_rgblocks); + if (new_rgcount > mp->m_sb.sb_rgcount) { + error = xfs_initialize_rtgroups(mp, new_rgcount); + if (error) + return error; + } + } + /* * Get the old block counts for bitmap and summary inodes. * These can't change since other growfs callers are locked out. @@ -1054,7 +1164,10 @@ xfs_growfs_rt( bmbno < nrbmblocks; bmbno++) { struct xfs_trans *tp; + struct xfs_rtgroup *rtg; xfs_rfsblock_t nrblocks_step; + xfs_rtbxlen_t freed_rtx = 0; + xfs_rgnumber_t last_rgno = mp->m_sb.sb_rgcount - 1; *nmp = *mp; nsbp = &nmp->m_sb; @@ -1074,6 +1187,11 @@ xfs_growfs_rt( nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nsbp->sb_rbmblocks); nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); + + if (xfs_has_rtgroups(mp)) + nsbp->sb_rgcount = howmany_64(nsbp->sb_rblocks, + nsbp->sb_rgblocks); + /* * Start a transaction, get the log reservation. */ @@ -1113,6 +1231,7 @@ xfs_growfs_rt( if (error) goto error_cancel; } + /* * Update superblock fields. */ @@ -1131,12 +1250,13 @@ xfs_growfs_rt( if (nsbp->sb_rextslog != sbp->sb_rextslog) xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG, nsbp->sb_rextslog - sbp->sb_rextslog); + if (nsbp->sb_rgcount != sbp->sb_rgcount) + xfs_trans_mod_sb(tp, XFS_TRANS_SB_RGCOUNT, + nsbp->sb_rgcount - sbp->sb_rgcount); /* * Free new extent. */ - bp = NULL; - error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, - nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); + error = xfs_growfs_rt_free_new(tp, nmp, &freed_rtx); if (error) { error_cancel: xfs_trans_cancel(tp); @@ -1145,8 +1265,7 @@ xfs_growfs_rt( /* * Mark more blocks free in the superblock. */ - xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, - nsbp->sb_rextents - sbp->sb_rextents); + xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, freed_rtx); /* * Update mp values into the real mp structure. */ @@ -1157,6 +1276,10 @@ xfs_growfs_rt( if (error) break; + for_each_rtgroup_from(mp, last_rgno, rtg) + rtg->rtg_blockcount = xfs_rtgroup_block_count(mp, + rtg->rtg_rgno); + /* Ensure the mount RT feature flag is now set. */ mp->m_features |= XFS_FEAT_REALTIME; } @@ -1165,6 +1288,10 @@ xfs_growfs_rt( /* Update secondary superblocks now the physical grow has completed */ error = xfs_update_secondary_sbs(mp); + if (error) + goto out_free; + + error = xfs_rtgroup_update_secondary_sbs(mp); out_free: /* diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 979aba1b2fc8..a6f46cd9e60c 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -510,6 +510,10 @@ xfs_trans_mod_sb( case XFS_TRANS_SB_REXTSLOG: tp->t_rextslog_delta += delta; break; + case XFS_TRANS_SB_RGCOUNT: + ASSERT(delta > 0); + tp->t_rgcount_delta += delta; + break; default: ASSERT(0); return; @@ -615,6 +619,11 @@ xfs_trans_apply_sb_deltas( whole = 1; update_rtsb = true; } + if (tp->t_rgcount_delta) { + be32_add_cpu(&sbp->sb_rgcount, tp->t_rgcount_delta); + whole = 1; + update_rtsb = true; + } xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); if (whole) @@ -728,6 +737,7 @@ xfs_trans_unreserve_and_mod_sb( mp->m_sb.sb_rblocks += tp->t_rblocks_delta; mp->m_sb.sb_rextents += tp->t_rextents_delta; mp->m_sb.sb_rextslog += tp->t_rextslog_delta; + mp->m_sb.sb_rgcount += tp->t_rgcount_delta; spin_unlock(&mp->m_sb_lock); /* diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 37cde68f3a31..efa7eace0859 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -150,6 +150,7 @@ typedef struct xfs_trans { int64_t t_rblocks_delta;/* superblock rblocks change */ int64_t t_rextents_delta;/* superblocks rextents chg */ int64_t t_rextslog_delta;/* superblocks rextslog chg */ + int64_t t_rgcount_delta; /* realtime group count */ struct list_head t_items; /* log item descriptors */ struct list_head t_busy; /* list of busy extents */ struct list_head t_dfops; /* deferred operations */ From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4319DC4332F for ; Sat, 31 Dec 2022 01:29:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236095AbiLaB3V (ORCPT ); Fri, 30 Dec 2022 20:29:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235752AbiLaB3U (ORCPT ); Fri, 30 Dec 2022 20:29:20 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B93F1C93A for ; Fri, 30 Dec 2022 17:29:20 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E890AB81DF6 for ; Sat, 31 Dec 2022 01:29:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EAD2C433EF; Sat, 31 Dec 2022 01:29:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450157; bh=H8PO59YUb5fVpa4deZx/Xh1fE9TenlGDCeufENoCXOA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=atOimetyaj0IQH6I6hv4GaI55kmVkH9ucoAl6dRcTR8T+2rg4MgTgpW+E22wElvQz Vsfjb4BU8RFpKNloJUvC6qvP+zyWK4ksNQmTY2N6WAmFhvfcjbQu0YT2V7UpzEsap7 z/LH2b+XsNn+laBazBvef4tI1ehBHLBDkmuqmuGvc+HUH6I07nx3p94chqBfJSpukd lKRIYm3wGXm815/L6xSmnk/sHKXbJO2bIiFX+Gu/TqbLKnXUL8XmaB1vua5eCFEn1S M/bppU900uBQAe2kC7ns2Jp/30tYBy8APuQn5VZUdQ01jK0OWJm81snD/FBqYwFJfr RxeKEuwzlF0cg== Subject: [PATCH 07/22] xfs: always update secondary rt supers when we update secondary fs supers From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867370.712847.5894942816627973910.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Make sure that any update to the secondary superblocks in the data section are also echoed to the secondary superblocks in the realtime section. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_fsops.c | 4 ++++ fs/xfs/xfs_ioctl.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 13851c0d640b..2da86f05e0e5 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -21,6 +21,7 @@ #include "xfs_ag.h" #include "xfs_ag_resv.h" #include "xfs_trace.h" +#include "xfs_rtgroup.h" /* * Write new AG headers to disk. Non-transactional, but need to be @@ -306,6 +307,9 @@ xfs_growfs_data( /* Update secondary superblocks now the physical grow has completed */ error = xfs_update_secondary_sbs(mp); + if (error) + goto out_error; + error = xfs_rtgroup_update_secondary_sbs(mp); out_error: /* diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index e3e6d377d958..46deb26b7cc5 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -39,6 +39,7 @@ #include "xfs_ioctl.h" #include "xfs_xattr.h" #include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" #include #include @@ -1719,6 +1720,8 @@ xfs_ioc_setlabel( */ mutex_lock(&mp->m_growlock); error = xfs_update_secondary_sbs(mp); + if (!error) + error = xfs_rtgroup_update_secondary_sbs(mp); mutex_unlock(&mp->m_growlock); invalidate_bdev(bdev); From patchwork Fri Dec 30 22:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2289C4332F for ; Sat, 31 Dec 2022 01:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236096AbiLaB3h (ORCPT ); Fri, 30 Dec 2022 20:29:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235752AbiLaB3g (ORCPT ); Fri, 30 Dec 2022 20:29:36 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6CA91C93A for ; Fri, 30 Dec 2022 17:29:35 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 64CEAB81DF9 for ; Sat, 31 Dec 2022 01:29:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 106FAC433EF; Sat, 31 Dec 2022 01:29:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450173; bh=t+2ExIwGmerb3jtuvbB/8014xZi47Vu3VmD00UVuz78=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=ukPQW64+lBrhlMtBbN32omYkkvN/f7BDuPg8nZIEveQVs6MMZvsui5ibCB+HsaTgV YD+a/G/Icp1dJvnTFKa0lZN+49H2lOyEM6+DnQRhrWfioNRvWcGRpLBolStZ8m6xCV YoNoZIfpQB7615VtbWlzIHPBN9KaAqZMJhMyuc7Q5qcPtuOCh6hgclutlewkpWeNBe GIxB0K4zGZsZmA+xzlwdW0SdMuJt3Eictfvo5+Jt07H0ThAC9Dy5hE0lyt6qgd3ju9 V/IYCNGzK40VFQZLwRJU5Hmg+BwtlsMWgrF8YzbQFAsrNFdrK9/ePZPpy31Tci/zOV 6e/zUJZxRbRKg== Subject: [PATCH 08/22] xfs: export realtime group geometry via XFS_FSOP_GEOM From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:53 -0800 Message-ID: <167243867383.712847.16833344594803385713.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Export the realtime geometry information so that userspace can query it. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 4 +++- fs/xfs/libxfs/xfs_sb.c | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index c4995f6557d2..ba90649c54e0 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -186,7 +186,9 @@ struct xfs_fsop_geom { __u32 logsunit; /* log stripe unit, bytes */ uint32_t sick; /* o: unhealthy fs & rt metadata */ uint32_t checked; /* o: checked fs & rt metadata */ - __u64 reserved[17]; /* reserved space */ + __u32 rgblocks; /* rtblocks in a realtime group */ + __u32 rgcount; /* number of realtime groups */ + __u64 reserved[16]; /* reserved space */ }; #define XFS_FSOP_GEOM_SICK_COUNTERS (1 << 0) /* summary counters */ diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 2e8ec9214c6c..db88f601e24b 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -1348,6 +1348,11 @@ xfs_fs_geometry( return; geo->version = XFS_FSOP_GEOM_VERSION_V5; + + if (xfs_has_rtgroups(mp)) { + geo->rgcount = sbp->sb_rgcount; + geo->rgblocks = sbp->sb_rgblocks; + } } /* Read a secondary superblock. */ From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6859C4332F for ; Sat, 31 Dec 2022 01:29:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235752AbiLaB3v (ORCPT ); Fri, 30 Dec 2022 20:29:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236097AbiLaB3u (ORCPT ); Fri, 30 Dec 2022 20:29:50 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 971AF1DF3A for ; Fri, 30 Dec 2022 17:29:49 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 33D6761CBC for ; Sat, 31 Dec 2022 01:29:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9173CC433EF; Sat, 31 Dec 2022 01:29:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450188; bh=8srK5RWwn8vJFyd3rd1rKd8W+EErFGCXh+Dw72oUsMY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SnADZ27aaaiAzUIulOUvZBQ3xh7X78mqRnoX0d31VG0T12xj/dILPF+7Xh3gLdq7C bjauw2LhJ2mL0kYROB9Zdr8mkDxPWojbKOxUaGxWN5D+x6sY/39fxn58kcU9Jaa4b9 c7l5SMGMtNBsh7Z/zIEk3l6+RQArfV/ahxha0bneviKmcaLbyATaW1w4SX8DfHlN4y NFk1uIHjgySSTGwEj/nGqCv6e8WOAq71ruxhRoboBdjcb4llZEXQlQQK1NkSrAQVaE zAaspKvo3wKQ5lW62Afje/x1FUwzeLhEtKv9dwdWNrhZBGLjui63mtCMWjbPUtXPdt tMqdQqSqeQcgw== Subject: [PATCH 09/22] xfs: check that rtblock extents do not overlap with the rt group metadata From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867397.712847.17825138506134800655.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong The ondisk format specifies that the start of each realtime group must have a superblock so that rt space mappings never cross an rtgroup boundary. Check that rt block pointers obey this. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_types.c | 46 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index b1fa715e5f39..34d02b2bfdd1 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c @@ -13,6 +13,8 @@ #include "xfs_mount.h" #include "xfs_ag.h" #include "xfs_imeta.h" +#include "xfs_rtbitmap.h" +#include "xfs_rtgroup.h" /* @@ -133,6 +135,26 @@ xfs_verify_dir_ino( return xfs_verify_ino(mp, ino); } +/* + * Verify that an rtgroup block number pointer neither points outside the + * rtgroup nor points at static metadata. + */ +static inline bool +xfs_verify_rgno_rgbno( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + xfs_rgblock_t rgbno) +{ + xfs_rgblock_t eorg; + + eorg = xfs_rtgroup_block_count(mp, rgno); + if (rgbno >= eorg) + return false; + if (rgbno < mp->m_sb.sb_rextsize) + return false; + return true; +} + /* * Verify that an realtime block number pointer doesn't point off the * end of the realtime device. @@ -142,7 +164,20 @@ xfs_verify_rtbno( struct xfs_mount *mp, xfs_rtblock_t rtbno) { - return rtbno < mp->m_sb.sb_rblocks; + xfs_rgnumber_t rgno; + xfs_rgblock_t rgbno; + + if (rtbno >= mp->m_sb.sb_rblocks) + return false; + + if (!xfs_has_rtgroups(mp)) + return true; + + rgbno = xfs_rtb_to_rgbno(mp, rtbno, &rgno); + if (rgno >= mp->m_sb.sb_rgcount) + return false; + + return xfs_verify_rgno_rgbno(mp, rgno, rgbno); } /* Verify that a realtime device extent is fully contained inside the volume. */ @@ -158,7 +193,14 @@ xfs_verify_rtbext( if (!xfs_verify_rtbno(mp, rtbno)) return false; - return xfs_verify_rtbno(mp, rtbno + len - 1); + if (!xfs_verify_rtbno(mp, rtbno + len - 1)) + return false; + + if (xfs_has_rtgroups(mp) && + xfs_rtb_to_rgno(mp, rtbno) != xfs_rtb_to_rgno(mp, rtbno + len - 1)) + return false; + + return true; } /* Calculate the range of valid icount values. */ From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085439 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7E58C4332F for ; Sat, 31 Dec 2022 01:30:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236098AbiLaBaI (ORCPT ); Fri, 30 Dec 2022 20:30:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236097AbiLaBaF (ORCPT ); Fri, 30 Dec 2022 20:30:05 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A5101DF18 for ; Fri, 30 Dec 2022 17:30:05 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BDE5561CBD for ; Sat, 31 Dec 2022 01:30:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A3E9C433D2; Sat, 31 Dec 2022 01:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450204; bh=P2PNLXVClgGP5uOcM3KOBWi2FiU5Tuv+4kSoblPLQ/c=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KBcnFYfgrAn2iG6tMj885IlIWd/Zx399f33sEZqeM+QAA2On2W3hMovub/37mHwuF YKwd7F7RZbEu9OElrVICQG3NOYovcreEBwOTohidsFW/Wp1AZVqrcBKGls3f6vQ48z Ei65QzZCeP5fkyWBDKdV6N91FjwKUtnOl0dEZmYVmHiVm7ardJWTpYYqk3aI0UR68x cgvXo7hQ0m8jWSkC8i4N1Iw4VVMBIEaFdeD3j/ksAdHRqm92WHD0NDqCz+KJdCh8Aw PTpYy2rEBs/r6Yo+zd1APME6S+YTP4YKkmza+Z9j8WR9Zjfo0em4uk3oG6iQiGfTfQ z3Tj6dfw91msA== Subject: [PATCH 10/22] xfs: add frextents to the lazysbcounters when rtgroups enabled From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867411.712847.9218677001627679490.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Make the free rt extent count a part of the lazy sb counters when the realtime groups feature is enabled. This is possible because the patch to recompute frextents from the rtbitmap during log recovery predates the code adding rtgroup support, hence we know that the value will always be correct during runtime. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_sb.c | 5 +++++ fs/xfs/xfs_trans.c | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index db88f601e24b..ee4e59453edc 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -1089,6 +1089,9 @@ xfs_log_sb( * sb counters, despite having a percpu counter. It is always kept * consistent with the ondisk rtbitmap by xfs_trans_apply_sb_deltas() * and hence we don't need have to update it here. + * + * sb_frextents was added to the lazy sb counters when the rt groups + * feature was introduced. */ if (xfs_has_lazysbcount(mp)) { mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount); @@ -1097,6 +1100,8 @@ xfs_log_sb( mp->m_sb.sb_icount); mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks); } + if (xfs_has_rtgroups(mp)) + mp->m_sb.sb_frextents = percpu_counter_sum(&mp->m_frextents); xfs_sb_to_disk(bp->b_addr, &mp->m_sb); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index a6f46cd9e60c..05e93af190df 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -475,6 +475,8 @@ xfs_trans_mod_sb( ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res); } tp->t_frextents_delta += delta; + if (xfs_has_rtgroups(mp)) + flags &= ~XFS_TRANS_SB_DIRTY; break; case XFS_TRANS_SB_RES_FREXTENTS: /* @@ -569,8 +571,14 @@ xfs_trans_apply_sb_deltas( * * Don't touch m_frextents because it includes incore reservations, * and those are handled by the unreserve function. + * + * sb_frextents was added to the lazy sb counters when the rt groups + * feature was introduced. This is possible because we know that all + * kernels supporting rtgroups will also recompute frextents from the + * realtime bitmap. */ - if (tp->t_frextents_delta || tp->t_res_frextents_delta) { + if ((tp->t_frextents_delta || tp->t_res_frextents_delta) && + !xfs_has_rtgroups(tp->t_mountp)) { struct xfs_mount *mp = tp->t_mountp; int64_t rtxdelta; @@ -684,7 +692,8 @@ xfs_trans_unreserve_and_mod_sb( if (tp->t_rtx_res > 0) rtxdelta = tp->t_rtx_res; if ((tp->t_frextents_delta != 0) && - (tp->t_flags & XFS_TRANS_SB_DIRTY)) + (xfs_has_rtgroups(mp) || + (tp->t_flags & XFS_TRANS_SB_DIRTY))) rtxdelta += tp->t_frextents_delta; if (xfs_has_lazysbcount(mp) || @@ -723,8 +732,11 @@ xfs_trans_unreserve_and_mod_sb( * Do not touch sb_frextents here because we are dealing with incore * reservation. sb_frextents is not part of the lazy sb counters so it * must be consistent with the ondisk rtbitmap and must never include - * incore reservations. + * incore reservations. sb_frextents was added to the lazy sb counters + * when the realtime groups feature was introduced. */ + if (xfs_has_rtgroups(mp)) + mp->m_sb.sb_frextents += rtxdelta; mp->m_sb.sb_dblocks += tp->t_dblocks_delta; mp->m_sb.sb_agcount += tp->t_agcount_delta; mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta; From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29B78C4332F for ; Sat, 31 Dec 2022 01:30:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236099AbiLaBaW (ORCPT ); Fri, 30 Dec 2022 20:30:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236097AbiLaBaV (ORCPT ); Fri, 30 Dec 2022 20:30:21 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4B581C93A for ; Fri, 30 Dec 2022 17:30:20 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 53A2B61CBD for ; Sat, 31 Dec 2022 01:30:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B65FFC433EF; Sat, 31 Dec 2022 01:30:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450219; bh=xDt0LxEVdf6t3YtUYl+tYYZaWTXMaeF/lgg0bLFFQf4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=MlqCCXMI7XkvazPK+tpBlZxHuKufTS0NBw4dUXe0UI4plIEbtx/6FY4PFI9/O0Ft+ nRKiYZ+YbwugjjURohEooY1pc8TKc3hXBGNhwSNWAbG6DisnDNvyeo5M5JBJEg01rb GVViI+OId57DfVUDb0Utq1TMibWhkufKsQrmIQBNScBYGGxzYxkVs97/NOkqyPyv6O wU4oycRmYFsYBYSE3AVPcPV6sKUkAbvMG8CGObYV7YKaggzGaHiBK32rdINjjKF2PS kh6FljDJFQsAQRLiCK4LH5D5E88M/nbaV2TV1oyhyP9P3dAKklbST8Ca4fkD7G2ul1 M2YUUM+GG9xdA== Subject: [PATCH 11/22] xfs: record rt group superblock errors in the health system From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867425.712847.12469199718186901143.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Record the state of per-rtgroup metadata sickness in the rtgroup structure for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_health.h | 28 ++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 8 ++++ fs/xfs/scrub/health.c | 24 ++++++++++++ fs/xfs/xfs_health.c | 86 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_trace.c | 1 + fs/xfs/xfs_trace.h | 26 +++++++++++++ 6 files changed, 172 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 99d53bae9c13..0beb4153a43e 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -52,6 +52,7 @@ struct xfs_inode; struct xfs_fsop_geom; struct xfs_btree_cur; struct xfs_da_args; +struct xfs_rtgroup; /* Observable health issues for metadata spanning the entire filesystem. */ #define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */ @@ -65,6 +66,7 @@ struct xfs_da_args; /* Observable health issues for realtime volume metadata. */ #define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */ #define XFS_SICK_RT_SUMMARY (1 << 1) /* realtime summary */ +#define XFS_SICK_RT_SUPER (1 << 2) /* rt group superblock */ /* Observable health issues for AG metadata. */ #define XFS_SICK_AG_SB (1 << 0) /* superblock */ @@ -101,7 +103,8 @@ struct xfs_da_args; XFS_SICK_FS_METADIR) #define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \ - XFS_SICK_RT_SUMMARY) + XFS_SICK_RT_SUMMARY | \ + XFS_SICK_RT_SUPER) #define XFS_SICK_AG_PRIMARY (XFS_SICK_AG_SB | \ XFS_SICK_AG_AGF | \ @@ -176,6 +179,14 @@ void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask); void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick, unsigned int *checked); +void xfs_rgno_mark_sick(struct xfs_mount *mp, xfs_rgnumber_t rgno, + unsigned int mask); +void xfs_rtgroup_mark_sick(struct xfs_rtgroup *rtg, unsigned int mask); +void xfs_rtgroup_mark_checked(struct xfs_rtgroup *rtg, unsigned int mask); +void xfs_rtgroup_mark_healthy(struct xfs_rtgroup *rtg, unsigned int mask); +void xfs_rtgroup_measure_sickness(struct xfs_rtgroup *rtg, unsigned int *sick, + unsigned int *checked); + void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int mask); void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask); @@ -225,6 +236,15 @@ xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask) return sick & mask; } +static inline bool +xfs_rtgroup_has_sickness(struct xfs_rtgroup *rtg, unsigned int mask) +{ + unsigned int sick, checked; + + xfs_rtgroup_measure_sickness(rtg, &sick, &checked); + return sick & mask; +} + static inline bool xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask) { @@ -246,6 +266,12 @@ xfs_rt_is_healthy(struct xfs_mount *mp) return !xfs_rt_has_sickness(mp, -1U); } +static inline bool +xfs_rtgroup_is_healthy(struct xfs_rtgroup *rtg) +{ + return !xfs_rtgroup_has_sickness(rtg, -1U); +} + static inline bool xfs_ag_is_healthy(struct xfs_perag *pag) { diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index d8723fabeb57..0e664e2436b0 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -23,6 +23,14 @@ struct xfs_rtgroup { /* Number of blocks in this group */ xfs_rgblock_t rtg_blockcount; + /* + * Bitsets of per-rtgroup metadata that have been checked and/or are + * sick. Callers should hold rtg_state_lock before accessing this + * field. + */ + uint16_t rtg_checked; + uint16_t rtg_sick; + #ifdef __KERNEL__ /* -- kernel only structures below this line -- */ spinlock_t rtg_state_lock; diff --git a/fs/xfs/scrub/health.c b/fs/xfs/scrub/health.c index cdf059f47656..9a8d4c348cc9 100644 --- a/fs/xfs/scrub/health.c +++ b/fs/xfs/scrub/health.c @@ -14,6 +14,7 @@ #include "xfs_mount.h" #include "xfs_ag.h" #include "xfs_health.h" +#include "xfs_rtgroup.h" #include "scrub/scrub.h" #include "scrub/health.h" #include "scrub/common.h" @@ -76,6 +77,7 @@ enum xchk_health_group { XHG_RT, XHG_AG, XHG_INO, + XHG_RTGROUP, }; struct xchk_health_map { @@ -130,12 +132,16 @@ xchk_mark_all_healthy( struct xfs_mount *mp) { struct xfs_perag *pag; + struct xfs_rtgroup *rtg; xfs_agnumber_t agno; + xfs_rgnumber_t rgno; xfs_fs_mark_healthy(mp, XFS_SICK_FS_INDIRECT); xfs_rt_mark_healthy(mp, XFS_SICK_RT_INDIRECT); for_each_perag(mp, agno, pag) xfs_ag_mark_healthy(pag, XFS_SICK_AG_INDIRECT); + for_each_rtgroup(mp, rgno, rtg) + xfs_rtgroup_mark_healthy(rtg, XFS_SICK_RT_INDIRECT); } /* @@ -153,6 +159,7 @@ xchk_update_health( struct xfs_scrub *sc) { struct xfs_perag *pag; + struct xfs_rtgroup *rtg; bool bad; /* @@ -215,6 +222,15 @@ xchk_update_health( } else xfs_rt_mark_healthy(sc->mp, sc->sick_mask); break; + case XHG_RTGROUP: + rtg = xfs_rtgroup_get(sc->mp, sc->sm->sm_agno); + if (bad) { + xfs_rtgroup_mark_sick(rtg, sc->sick_mask); + xfs_rtgroup_mark_checked(rtg, sc->sick_mask); + } else + xfs_rtgroup_mark_healthy(rtg, sc->sick_mask); + xfs_rtgroup_put(rtg); + break; default: ASSERT(0); break; @@ -302,7 +318,9 @@ xchk_health_record( { struct xfs_mount *mp = sc->mp; struct xfs_perag *pag; + struct xfs_rtgroup *rtg; xfs_agnumber_t agno; + xfs_rgnumber_t rgno; unsigned int sick; unsigned int checked; @@ -321,5 +339,11 @@ xchk_health_record( xchk_set_corrupt(sc); } + for_each_rtgroup(mp, rgno, rtg) { + xfs_rtgroup_measure_sickness(rtg, &sick, &checked); + if (sick & XFS_SICK_RT_PRIMARY) + xchk_set_corrupt(sc); + } + return 0; } diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 61f7a6aca6b1..fe05b565427f 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -18,6 +18,7 @@ #include "xfs_da_format.h" #include "xfs_da_btree.h" #include "xfs_quota_defs.h" +#include "xfs_rtgroup.h" /* * Warn about metadata corruption that we detected but haven't fixed, and @@ -29,7 +30,9 @@ xfs_health_unmount( struct xfs_mount *mp) { struct xfs_perag *pag; + struct xfs_rtgroup *rtg; xfs_agnumber_t agno; + xfs_rgnumber_t rgno; unsigned int sick = 0; unsigned int checked = 0; bool warn = false; @@ -46,6 +49,15 @@ xfs_health_unmount( } } + /* Measure realtime group corruption levels. */ + for_each_rtgroup(mp, rgno, rtg) { + xfs_rtgroup_measure_sickness(rtg, &sick, &checked); + if (sick) { + trace_xfs_rtgroup_unfixed_corruption(rtg, sick); + warn = true; + } + } + /* Measure realtime volume corruption levels. */ xfs_rt_measure_sickness(mp, &sick, &checked); if (sick) { @@ -280,6 +292,80 @@ xfs_ag_measure_sickness( spin_unlock(&pag->pag_state_lock); } +/* Mark unhealthy per-rtgroup metadata given a raw rt group number. */ +void +xfs_rgno_mark_sick( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + unsigned int mask) +{ + struct xfs_rtgroup *rtg = xfs_rtgroup_get(mp, rgno); + + /* per-rtgroup structure not set up yet? */ + if (!rtg) + return; + + xfs_rtgroup_mark_sick(rtg, mask); + xfs_rtgroup_put(rtg); +} + +/* Mark unhealthy per-rtgroup metadata. */ +void +xfs_rtgroup_mark_sick( + struct xfs_rtgroup *rtg, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_RT_ALL)); + trace_xfs_rtgroup_mark_sick(rtg, mask); + + spin_lock(&rtg->rtg_state_lock); + rtg->rtg_sick |= mask; + spin_unlock(&rtg->rtg_state_lock); +} + +/* Mark per-rtgroup metadata as having been checked. */ +void +xfs_rtgroup_mark_checked( + struct xfs_rtgroup *rtg, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY)); + + spin_lock(&rtg->rtg_state_lock); + rtg->rtg_checked |= mask; + spin_unlock(&rtg->rtg_state_lock); +} + +/* Mark per-rtgroup metadata ok. */ +void +xfs_rtgroup_mark_healthy( + struct xfs_rtgroup *rtg, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_RT_ALL)); + trace_xfs_rtgroup_mark_healthy(rtg, mask); + + spin_lock(&rtg->rtg_state_lock); + rtg->rtg_sick &= ~mask; + if (!(rtg->rtg_sick & XFS_SICK_RT_PRIMARY)) + rtg->rtg_sick &= ~XFS_SICK_RT_SECONDARY; + rtg->rtg_checked |= mask; + spin_unlock(&rtg->rtg_state_lock); +} + +/* Sample which per-rtgroup metadata are unhealthy. */ +void +xfs_rtgroup_measure_sickness( + struct xfs_rtgroup *rtg, + unsigned int *sick, + unsigned int *checked) +{ + spin_lock(&rtg->rtg_state_lock); + *sick = rtg->rtg_sick; + *checked = rtg->rtg_checked; + spin_unlock(&rtg->rtg_state_lock); +} + /* Mark the unhealthy parts of an inode. */ void xfs_inode_mark_sick( diff --git a/fs/xfs/xfs_trace.c b/fs/xfs/xfs_trace.c index e38814f4380c..36109a57fca6 100644 --- a/fs/xfs/xfs_trace.c +++ b/fs/xfs/xfs_trace.c @@ -42,6 +42,7 @@ #include "xfs_bmap.h" #include "xfs_swapext.h" #include "xfs_xchgrange.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 f72f694b4656..ec9aa1914a93 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -82,6 +82,7 @@ struct xfs_icwalk; struct xfs_bmap_intent; struct xfs_swapext_intent; struct xfs_swapext_req; +struct xfs_rtgroup; #define XFS_ATTR_FILTER_FLAGS \ { XFS_ATTR_ROOT, "ROOT" }, \ @@ -4233,6 +4234,31 @@ DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_sick); DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_healthy); DEFINE_AG_CORRUPT_EVENT(xfs_ag_unfixed_corruption); +DECLARE_EVENT_CLASS(xfs_rtgroup_corrupt_class, + TP_PROTO(struct xfs_rtgroup *rtg, unsigned int flags), + TP_ARGS(rtg, flags), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_rgnumber_t, rgno) + __field(unsigned int, flags) + ), + TP_fast_assign( + __entry->dev = rtg->rtg_mount->m_super->s_dev; + __entry->rgno = rtg->rtg_rgno; + __entry->flags = flags; + ), + TP_printk("dev %d:%d rgno 0x%x flags 0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->rgno, __entry->flags) +); +#define DEFINE_RTGROUP_CORRUPT_EVENT(name) \ +DEFINE_EVENT(xfs_rtgroup_corrupt_class, name, \ + TP_PROTO(struct xfs_rtgroup *rtg, unsigned int flags), \ + TP_ARGS(rtg, flags)) +DEFINE_RTGROUP_CORRUPT_EVENT(xfs_rtgroup_mark_sick); +DEFINE_RTGROUP_CORRUPT_EVENT(xfs_rtgroup_mark_healthy); +DEFINE_RTGROUP_CORRUPT_EVENT(xfs_rtgroup_unfixed_corruption); + DECLARE_EVENT_CLASS(xfs_inode_corrupt_class, TP_PROTO(struct xfs_inode *ip, unsigned int flags), TP_ARGS(ip, flags), From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3804EC4332F for ; Sat, 31 Dec 2022 01:30:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236097AbiLaBai (ORCPT ); Fri, 30 Dec 2022 20:30:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236087AbiLaBah (ORCPT ); Fri, 30 Dec 2022 20:30:37 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 579EA1C93A for ; Fri, 30 Dec 2022 17:30:36 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E77DA61C3A for ; Sat, 31 Dec 2022 01:30:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 505C4C433EF; Sat, 31 Dec 2022 01:30:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450235; bh=5aTVkfyHbwuA/QgQB9IFTy0gSFQz+plIdWl2IP3LrNA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=gsLdoOqeEjVX88J3v5KKMmAI4FKkzG+wWYCVnTjaPefOFqDX2Boo1OFmrBRcop5KR P7Ax7MEv7fFhQf0c0nfN0rh2vndQEWuDSzZEtnEYJHsxGIaXc+ZXvqWzbe/lgv442f X7OroclUYBxr3YGkBYaaByinHFXmFm6wMhGE5rTc+JPExyVdYG5bZPTknIUjZz2mee nEAJL+kRmUkoha4vOfeM4KLCiuSMla5cG1Y5CnU6xXUnR0bbZ/wwtQ1mxReAr6LarW nMaBtGrkZHTNNl4MPvEEtqQgzESSRYvNG/ApRw1AfpLYZgvieARlfyuGJsJIo542Cs nsLihxIhXVmxg== Subject: [PATCH 12/22] xfs: define locking primitives for realtime groups From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867440.712847.15115410677101836922.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org 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 --- fs/xfs/libxfs/xfs_rtgroup.c | 33 +++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 14 ++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 037506b73384..3bf85ab524f6 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -499,3 +499,36 @@ xfs_rtgroup_update_secondary_sbs( return saved_error ? saved_error : error; } + +/* Lock metadata inodes associated with this rt group. */ +void +xfs_rtgroup_lock( + 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) || + !(rtglock_flags & XFS_RTGLOCK_BITMAP)); + + if (rtglock_flags & XFS_RTGLOCK_BITMAP) + xfs_rtbitmap_lock(tp, 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); +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index 0e664e2436b0..b1e53af5a65b 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -210,11 +210,25 @@ void xfs_rtgroup_update_super(struct xfs_buf *rtsb_bp, const struct xfs_buf *sb_bp); void xfs_rtgroup_log_super(struct xfs_trans *tp, const struct xfs_buf *sb_bp); int xfs_rtgroup_update_secondary_sbs(struct xfs_mount *mp); + +/* 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_trans *tp, struct xfs_rtgroup *rtg, + unsigned int rtglock_flags); +void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); #else # define xfs_rtgroup_block_count(mp, rgno) (0) # define xfs_rtgroup_update_super(bp, sb_bp) ((void)0) # define xfs_rtgroup_log_super(tp, sb_bp) ((void)0) # define xfs_rtgroup_update_secondary_sbs(mp) (0) +# define xfs_rtgroup_lock(tp, rtg, gf) ((void)0) +# define xfs_rtgroup_unlock(rtg, gf) ((void)0) #endif /* CONFIG_XFS_RT */ #endif /* __LIBXFS_RTGROUP_H */ From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C2F2C4332F for ; Sat, 31 Dec 2022 01:30:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236100AbiLaBaz (ORCPT ); Fri, 30 Dec 2022 20:30:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236087AbiLaBax (ORCPT ); Fri, 30 Dec 2022 20:30:53 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1F3A2197 for ; Fri, 30 Dec 2022 17:30:51 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7EE6C61C3A for ; Sat, 31 Dec 2022 01:30:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E189AC433EF; Sat, 31 Dec 2022 01:30:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450250; bh=eojTddfxiLIdrCNn2iEVPmh7lnA3a+0HNVLiMxglrrI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=n9ja5k6/OqLSwDbaf7noD9OLzN+uGR8TX6xkb9/i6ALQQUOPit2fiNJanmtM1K2Ph ksLbwnBoscakgI8I9fzwMlxGsJQa0HMn/CaWtTlgOoBDzy43+0wsmNA+ZoaOkFuVGP oOr9iqEDMk9pdyOoC6ejoQ5J3QGpAj3QL6dvSZa7uARAKGxVZ/VXAwqxkyHd53W78b Il4kcO7Ts5aKLrU712DdKfPKQXS+4BOPc418UTH68eGQIJYxd7YCB+uST0etZoGugE LgODneKWstahwjoPLR7+TauqmH/9MyLo0EaCFb35U1b0r6iCTzjek9RGkB4EKRM6/I BjrINUMMaIxsw== Subject: [PATCH 13/22] xfs: export the geometry of realtime groups to userspace From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867453.712847.14152633807388489415.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create an ioctl so that the kernel can report the status of realtime groups to userspace. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 16 ++++++++++++++++ fs/xfs/libxfs/xfs_health.h | 2 ++ fs/xfs/libxfs/xfs_rtgroup.c | 14 ++++++++++++++ fs/xfs/libxfs/xfs_rtgroup.h | 4 ++++ fs/xfs/xfs_health.c | 28 ++++++++++++++++++++++++++++ fs/xfs/xfs_ioctl.c | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index ba90649c54e0..e3d87665e4a5 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -299,6 +299,21 @@ struct xfs_ag_geometry { #define XFS_AG_GEOM_SICK_REFCNTBT (1 << 9) /* reference counts */ #define XFS_AG_GEOM_SICK_INODES (1 << 10) /* bad inodes were seen */ +/* + * Output for XFS_IOC_RTGROUP_GEOMETRY + */ +struct xfs_rtgroup_geometry { + uint32_t rg_number; /* i/o: rtgroup number */ + uint32_t rg_length; /* o: length in blocks */ + uint32_t rg_sick; /* o: sick things in ag */ + uint32_t rg_checked; /* o: checked metadata in ag */ + uint32_t rg_flags; /* i/o: flags for this ag */ + uint32_t rg_pad; /* o: zero */ + uint64_t rg_reserved[13];/* o: zero */ +}; +#define XFS_RTGROUP_GEOM_SICK_SUPER (1 << 0) /* superblock */ +#define XFS_RTGROUP_GEOM_SICK_BITMAP (1 << 1) /* rtbitmap for this group */ + /* * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT */ @@ -819,6 +834,7 @@ struct xfs_scrub_metadata { /* XFS_IOC_GETFSMAP ------ hoisted 59 */ #define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata) #define XFS_IOC_AG_GEOMETRY _IOWR('X', 61, struct xfs_ag_geometry) +#define XFS_IOC_RTGROUP_GEOMETRY _IOWR('X', 62, struct xfs_rtgroup_geometry) /* * ioctl commands that replace IRIX syssgi()'s diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 0beb4153a43e..44137c4983fc 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -286,6 +286,8 @@ xfs_inode_is_healthy(struct xfs_inode *ip) void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo); void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); +void xfs_rtgroup_geom_health(struct xfs_rtgroup *rtg, + struct xfs_rtgroup_geometry *rgeo); void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs); #define xfs_metadata_is_sick(error) \ diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 3bf85ab524f6..a428dff81888 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -532,3 +532,17 @@ xfs_rtgroup_unlock( else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) xfs_rtbitmap_unlock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP); } + +/* Retrieve rt group geometry. */ +int +xfs_rtgroup_get_geometry( + struct xfs_rtgroup *rtg, + struct xfs_rtgroup_geometry *rgeo) +{ + /* Fill out form. */ + memset(rgeo, 0, sizeof(*rgeo)); + rgeo->rg_number = rtg->rtg_rgno; + rgeo->rg_length = rtg->rtg_blockcount; + xfs_rtgroup_geom_health(rtg, rgeo); + return 0; +} diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index b1e53af5a65b..1fec49c496d4 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -222,6 +222,9 @@ int xfs_rtgroup_update_secondary_sbs(struct xfs_mount *mp); void xfs_rtgroup_lock(struct xfs_trans *tp, struct xfs_rtgroup *rtg, unsigned int rtglock_flags); void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); + +int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg, + struct xfs_rtgroup_geometry *rgeo); #else # define xfs_rtgroup_block_count(mp, rgno) (0) # define xfs_rtgroup_update_super(bp, sb_bp) ((void)0) @@ -229,6 +232,7 @@ void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags); # define xfs_rtgroup_update_secondary_sbs(mp) (0) # define xfs_rtgroup_lock(tp, rtg, gf) ((void)0) # define xfs_rtgroup_unlock(rtg, gf) ((void)0) +# define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP) #endif /* CONFIG_XFS_RT */ #endif /* __LIBXFS_RTGROUP_H */ diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index fe05b565427f..33f332ee8044 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -528,6 +528,34 @@ xfs_ag_geom_health( } } +static const struct ioctl_sick_map rtgroup_map[] = { + { XFS_SICK_RT_SUPER, XFS_RTGROUP_GEOM_SICK_SUPER }, + { XFS_SICK_RT_BITMAP, XFS_RTGROUP_GEOM_SICK_BITMAP }, + { 0, 0 }, +}; + +/* Fill out rtgroup geometry health info. */ +void +xfs_rtgroup_geom_health( + struct xfs_rtgroup *rtg, + struct xfs_rtgroup_geometry *rgeo) +{ + const struct ioctl_sick_map *m; + unsigned int sick; + unsigned int checked; + + rgeo->rg_sick = 0; + rgeo->rg_checked = 0; + + xfs_rtgroup_measure_sickness(rtg, &sick, &checked); + for (m = rtgroup_map; m->sick_mask; m++) { + if (checked & m->sick_mask) + rgeo->rg_checked |= m->ioctl_mask; + if (sick & m->sick_mask) + rgeo->rg_sick |= m->ioctl_mask; + } +} + static const struct ioctl_sick_map ino_map[] = { { XFS_SICK_INO_CORE, XFS_BS_SICK_INODE }, { XFS_SICK_INO_BMBTD, XFS_BS_SICK_BMBTD }, diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 46deb26b7cc5..fbe9bc50fc20 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -991,6 +991,36 @@ xfs_ioc_ag_geometry( return 0; } +STATIC int +xfs_ioc_rtgroup_geometry( + struct xfs_mount *mp, + void __user *arg) +{ + struct xfs_rtgroup *rtg; + struct xfs_rtgroup_geometry rgeo; + int error; + + if (copy_from_user(&rgeo, arg, sizeof(rgeo))) + return -EFAULT; + if (rgeo.rg_flags || rgeo.rg_pad) + return -EINVAL; + if (memchr_inv(&rgeo.rg_reserved, 0, sizeof(rgeo.rg_reserved))) + return -EINVAL; + + rtg = xfs_rtgroup_get(mp, rgeo.rg_number); + if (!rtg) + return -EINVAL; + + error = xfs_rtgroup_get_geometry(rtg, &rgeo); + xfs_rtgroup_put(rtg); + if (error) + return error; + + if (copy_to_user(arg, &rgeo, sizeof(rgeo))) + return -EFAULT; + return 0; +} + /* * Linux extended inode flags interface. */ @@ -1852,6 +1882,8 @@ xfs_file_ioctl( case XFS_IOC_AG_GEOMETRY: return xfs_ioc_ag_geometry(mp, arg); + case XFS_IOC_RTGROUP_GEOMETRY: + return xfs_ioc_rtgroup_geometry(mp, arg); case XFS_IOC_GETVERSION: return put_user(inode->i_generation, (int __user *)arg); From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B90EC4332F for ; Sat, 31 Dec 2022 01:31:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236101AbiLaBbJ (ORCPT ); Fri, 30 Dec 2022 20:31:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236087AbiLaBbJ (ORCPT ); Fri, 30 Dec 2022 20:31:09 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D6492197 for ; Fri, 30 Dec 2022 17:31:07 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 18AE961C3A for ; Sat, 31 Dec 2022 01:31:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D05FC433D2; Sat, 31 Dec 2022 01:31:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450266; bh=x8+Hy5puTuW68AR/R6ztJMZZ7mDuT6mo/Gq/DyDEEjs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=bO24sjFDWGK25RwRHW2cRkzWVGFrRKpLA+nBQSZ88r2hIj5gZEZxmmwlgNQQzo7Ap uMJUp1i5R50E0wjdTVbpiiU/lNfquTWXX5HKrSO4Fz19rUvspWboRVzzg4KcWBQ+ax MrHPKoKI51Ap5lZc8ECHmhNo+Y1qA8aB5/C2t0AQ7yIEFNe0llzeDZNRbGIpQp8Cz2 Snz8/SZhwt6a3U8bspWK/ziyLc1svpKZdafyxAHU/bQjyJY9yf4M1H0Up4hHECKk6d MIC0CkKf/IdKjvMP/XyfQfwWy4d/h4ZXJrQNd+KHfT/c8RpSNWW9/n4TbPI3dAqaOG fCfmMstuCDt4g== Subject: [PATCH 14/22] xfs: add block headers to realtime bitmap blocks From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867467.712847.13563897655051444408.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Upgrade rtbitmap blocks to have self describing metadata like most every other thing in XFS. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 14 ++++++ fs/xfs/libxfs/xfs_rtbitmap.c | 100 +++++++++++++++++++++++++++++++++++++---- fs/xfs/libxfs/xfs_rtbitmap.h | 30 ++++++++++++ fs/xfs/libxfs/xfs_sb.c | 18 ++++++- fs/xfs/libxfs/xfs_shared.h | 1 fs/xfs/xfs_buf_item_recover.c | 20 +++++++- fs/xfs/xfs_mount.h | 3 + fs/xfs/xfs_ondisk.h | 1 fs/xfs/xfs_rtalloc.c | 60 ++++++++++++++++++------- 9 files changed, 213 insertions(+), 34 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index a38e1499bd4b..4096d3f069a3 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1284,6 +1284,20 @@ static inline bool xfs_dinode_has_large_extent_counts( /* * RT bit manipulation macros. */ +#define XFS_RTBITMAP_MAGIC 0x424D505A /* BMPZ */ + +struct xfs_rtbuf_blkinfo { + __be32 rt_magic; /* validity check on block */ + __be32 rt_crc; /* CRC of block */ + __be64 rt_owner; /* inode that owns the block */ + __be64 rt_blkno; /* first block of the buffer */ + __be64 rt_lsn; /* sequence number of last write */ + uuid_t rt_uuid; /* filesystem we belong to */ +}; + +#define XFS_RTBUF_CRC_OFF \ + offsetof(struct xfs_rtbuf_blkinfo, rt_crc) + #define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) #define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 4237b5703a64..05b0e4e92a0a 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -18,28 +18,84 @@ #include "xfs_error.h" #include "xfs_health.h" #include "xfs_rtbitmap.h" +#include "xfs_log.h" +#include "xfs_buf_item.h" /* * Realtime allocator bitmap functions shared with userspace. */ -/* - * Real time buffers need verifiers to avoid runtime warnings during IO. - * We don't have anything to verify, however, so these are just dummy - * operations. - */ +static xfs_failaddr_t +xfs_rtbuf_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_mount; + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + + if (!xfs_verify_magic(bp, hdr->rt_magic)) + return __this_address; + if (!xfs_has_rtgroups(mp)) + return __this_address; + if (!xfs_has_crc(mp)) + return __this_address; + if (!uuid_equal(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid)) + return __this_address; + if (hdr->rt_blkno != cpu_to_be64(xfs_buf_daddr(bp))) + return __this_address; + return NULL; +} + static void xfs_rtbuf_verify_read( - struct xfs_buf *bp) + struct xfs_buf *bp) { + struct xfs_mount *mp = bp->b_mount; + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + xfs_failaddr_t fa; + + if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops) + return; + + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr->rt_lsn))) { + fa = __this_address; + goto fail; + } + + if (!xfs_buf_verify_cksum(bp, XFS_RTBUF_CRC_OFF)) { + fa = __this_address; + goto fail; + } + + fa = xfs_rtbuf_verify(bp); + if (fa) + goto fail; + return; +fail: + xfs_verifier_error(bp, -EFSCORRUPTED, fa); } static void xfs_rtbuf_verify_write( struct xfs_buf *bp) { - return; + struct xfs_mount *mp = bp->b_mount; + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + struct xfs_buf_log_item *bip = bp->b_log_item; + xfs_failaddr_t fa; + + if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops) + return; + + fa = xfs_rtbuf_verify(bp); + if (fa) { + xfs_verifier_error(bp, -EFSCORRUPTED, fa); + return; + } + + if (bip) + hdr->rt_lsn = cpu_to_be64(bip->bli_item.li_lsn); + xfs_buf_update_cksum(bp, XFS_RTBUF_CRC_OFF); } const struct xfs_buf_ops xfs_rtbuf_ops = { @@ -48,6 +104,14 @@ const struct xfs_buf_ops xfs_rtbuf_ops = { .verify_write = xfs_rtbuf_verify_write, }; +const struct xfs_buf_ops xfs_rtbitmap_buf_ops = { + .name = "xfs_rtbitmap", + .magic = { 0, cpu_to_be32(XFS_RTBITMAP_MAGIC) }, + .verify_read = xfs_rtbuf_verify_read, + .verify_write = xfs_rtbuf_verify_write, + .verify_struct = xfs_rtbuf_verify, +}; + /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. @@ -81,13 +145,26 @@ xfs_rtbuf_get( ASSERT(map.br_startblock != NULLFSBLOCK); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, map.br_startblock), - mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); + mp->m_bsize, 0, &bp, + xfs_rtblock_ops(mp, issum)); if (xfs_metadata_is_sick(error)) xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY : XFS_SICK_RT_BITMAP); if (error) return error; + if (xfs_has_rtgroups(mp) && !issum) { + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + + if (hdr->rt_owner != cpu_to_be64(ip->i_ino)) { + xfs_buf_mark_corrupt(bp); + xfs_trans_brelse(tp, bp); + xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY : + XFS_SICK_RT_BITMAP); + return -EFSCORRUPTED; + } + } + xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF : XFS_BLFT_RTBITMAP_BUF); *bpp = bp; @@ -1205,7 +1282,12 @@ xfs_rtbitmap_blockcount( struct xfs_mount *mp, xfs_rtbxlen_t rtextents) { - return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); + unsigned int rbmblock_bytes = mp->m_sb.sb_blocksize; + + if (xfs_has_rtgroups(mp)) + rbmblock_bytes -= sizeof(struct xfs_rtbuf_blkinfo); + + return howmany_64(rtextents, NBBY * rbmblock_bytes); } /* diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index f6a2a48973ab..c1f740fd27b8 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -100,6 +100,9 @@ xfs_rtx_to_rbmblock( struct xfs_mount *mp, xfs_rtxnum_t rtx) { + if (xfs_has_rtgroups(mp)) + return div_u64(rtx, mp->m_rtx_per_rbmblock); + return rtx >> mp->m_blkbit_log; } @@ -109,6 +112,13 @@ xfs_rtx_to_rbmword( struct xfs_mount *mp, xfs_rtxnum_t rtx) { + if (xfs_has_rtgroups(mp)) { + unsigned int mod; + + div_u64_rem(rtx >> XFS_NBWORDLOG, mp->m_blockwsize, &mod); + return mod; + } + return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); } @@ -118,16 +128,24 @@ xfs_rbmblock_to_rtx( struct xfs_mount *mp, xfs_fileoff_t rbmoff) { + if (xfs_has_rtgroups(mp)) + return rbmoff * mp->m_rtx_per_rbmblock; + return rbmoff << mp->m_blkbit_log; } /* Return a pointer to a bitmap word within a rt bitmap block buffer. */ static inline union xfs_rtword_ondisk * xfs_rbmbuf_wordptr( + struct xfs_mount *mp, void *buf, unsigned int rbmword) { union xfs_rtword_ondisk *wordp = buf; + struct xfs_rtbuf_blkinfo *hdr = buf; + + if (xfs_has_rtgroups(mp)) + wordp = (union xfs_rtword_ondisk *)(hdr + 1); return &wordp[rbmword]; } @@ -138,7 +156,7 @@ xfs_rbmblock_wordptr( struct xfs_buf *bp, unsigned int rbmword) { - return xfs_rbmbuf_wordptr(bp->b_addr, rbmword); + return xfs_rbmbuf_wordptr(bp->b_mount, bp->b_addr, rbmword); } /* @@ -200,6 +218,16 @@ xfs_rsumblock_infoptr( return xfs_rsumbuf_infoptr(bp->b_addr, infoword); } +static inline const struct xfs_buf_ops * +xfs_rtblock_ops( + struct xfs_mount *mp, + bool issum) +{ + if (xfs_has_rtgroups(mp) && !issum) + return &xfs_rtbitmap_buf_ops; + return &xfs_rtbuf_ops; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index ee4e59453edc..dbbea5b86f27 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -518,10 +518,15 @@ xfs_validate_sb_common( } else { uint64_t rexts; uint64_t rbmblocks; + unsigned int rbmblock_bytes = sbp->sb_blocksize; rexts = div_u64(sbp->sb_rblocks, sbp->sb_rextsize); - rbmblocks = howmany_64(sbp->sb_rextents, - NBBY * sbp->sb_blocksize); + + if (xfs_sb_is_v5(sbp) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS)) + rbmblock_bytes -= sizeof(struct xfs_rtbuf_blkinfo); + + rbmblocks = howmany_64(sbp->sb_rextents, NBBY * rbmblock_bytes); if (sbp->sb_rextents != rexts || sbp->sb_rextslog != xfs_highbit32(sbp->sb_rextents) || @@ -1032,8 +1037,13 @@ xfs_sb_mount_common( mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; mp->m_blockmask = sbp->sb_blocksize - 1; - mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; - mp->m_blockwmask = mp->m_blockwsize - 1; + if (xfs_has_rtgroups(mp)) + mp->m_blockwsize = (sbp->sb_blocksize - + sizeof(struct xfs_rtbuf_blkinfo)) >> + XFS_WORDLOG; + else + mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; + mp->m_rtx_per_rbmblock = mp->m_blockwsize << XFS_NBWORDLOG; mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); mp->m_rgblklog = log2_if_power2(sbp->sb_rgblocks); diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index bcdf298889af..1c86163915cf 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -38,6 +38,7 @@ extern const struct xfs_buf_ops xfs_inode_buf_ops; extern const struct xfs_buf_ops xfs_inode_buf_ra_ops; extern const struct xfs_buf_ops xfs_refcountbt_buf_ops; extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; +extern const struct xfs_buf_ops xfs_rtbitmap_buf_ops; extern const struct xfs_buf_ops xfs_rtbuf_ops; extern const struct xfs_buf_ops xfs_rtsb_buf_ops; extern const struct xfs_buf_ops xfs_sb_buf_ops; diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 6587d18b21c3..4dcd5d9d2c7c 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -23,6 +23,7 @@ #include "xfs_dir2.h" #include "xfs_quota.h" #include "xfs_rtgroup.h" +#include "xfs_rtbitmap.h" /* * This is the number of entries in the l_buf_cancel_table used during @@ -391,9 +392,15 @@ xlog_recover_validate_buf_type( break; #ifdef CONFIG_XFS_RT case XFS_BLFT_RTBITMAP_BUF: + if (xfs_has_rtgroups(mp) && magic32 != XFS_RTBITMAP_MAGIC) { + warnmsg = "Bad rtbitmap magic!"; + break; + } + bp->b_ops = xfs_rtblock_ops(mp, false); + break; case XFS_BLFT_RTSUMMARY_BUF: /* no magic numbers for verification of RT buffers */ - bp->b_ops = &xfs_rtbuf_ops; + bp->b_ops = xfs_rtblock_ops(mp, true); break; #endif /* CONFIG_XFS_RT */ default: @@ -728,11 +735,20 @@ xlog_recover_get_buf_lsn( * UUIDs, so we must recover them immediately. */ blft = xfs_blft_from_flags(buf_f); - if (blft == XFS_BLFT_RTBITMAP_BUF || blft == XFS_BLFT_RTSUMMARY_BUF) + if (!xfs_has_rtgroups(mp) && blft == XFS_BLFT_RTBITMAP_BUF) + goto recover_immediately; + if (blft == XFS_BLFT_RTSUMMARY_BUF) goto recover_immediately; magic32 = be32_to_cpu(*(__be32 *)blk); switch (magic32) { + case XFS_RTBITMAP_MAGIC: { + struct xfs_rtbuf_blkinfo *hdr = blk; + + lsn = be64_to_cpu(hdr->rt_lsn); + uuid = &hdr->rt_uuid; + break; + } case XFS_ABTB_CRC_MAGIC: case XFS_ABTC_CRC_MAGIC: case XFS_ABTB_MAGIC: diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7f0a80a8dcd4..176b2e71da9e 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -123,7 +123,8 @@ typedef struct xfs_mount { 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 */ + /* number of rt extents per rt bitmap block if rtgroups enabled */ + unsigned int m_rtx_per_rbmblock; uint m_alloc_mxr[2]; /* max alloc btree records */ uint m_alloc_mnr[2]; /* min alloc btree records */ uint m_bmap_dmxr[2]; /* max bmap btree records */ diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h index 61909355731d..17e541d35194 100644 --- a/fs/xfs/xfs_ondisk.h +++ b/fs/xfs/xfs_ondisk.h @@ -76,6 +76,7 @@ xfs_check_ondisk_structs(void) /* realtime structures */ XFS_CHECK_STRUCT_SIZE(union xfs_rtword_ondisk, 4); XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_ondisk, 4); + XFS_CHECK_STRUCT_SIZE(struct xfs_rtbuf_blkinfo, 48); /* * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 9d8d91fa0ecf..9e013a8e3149 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -791,6 +791,42 @@ xfs_rtallocate_extent_size( return 0; } +/* Get a buffer for the block. */ +static int +xfs_growfs_init_rtbuf( + struct xfs_trans *tp, + struct xfs_inode *ip, + xfs_fsblock_t fsbno, + enum xfs_blft buf_type) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_buf *bp; + xfs_daddr_t d; + int error; + + d = XFS_FSB_TO_DADDR(mp, fsbno); + error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, 0, + &bp); + if (error) + return error; + + xfs_trans_buf_set_type(tp, bp, buf_type); + bp->b_ops = xfs_rtblock_ops(mp, buf_type == XFS_BLFT_RTSUMMARY_BUF); + memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); + + if (xfs_has_rtgroups(mp) && buf_type == XFS_BLFT_RTBITMAP_BUF) { + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + + hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC); + hdr->rt_owner = cpu_to_be64(ip->i_ino); + hdr->rt_blkno = cpu_to_be64(d); + uuid_copy(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid); + } + + xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); + return 0; +} + /* * Allocate space to the bitmap or summary file, and zero it, for growfs. */ @@ -802,8 +838,6 @@ xfs_growfs_rt_alloc( struct xfs_inode *ip) /* inode (bitmap/summary) */ { xfs_fileoff_t bno; /* block number in file */ - struct xfs_buf *bp; /* temporary buffer for zeroing */ - xfs_daddr_t d; /* disk block address */ int error; /* error return value */ xfs_fsblock_t fsbno; /* filesystem block for bno */ struct xfs_bmbt_irec map; /* block map output */ @@ -878,19 +912,11 @@ xfs_growfs_rt_alloc( */ xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - /* - * Get a buffer for the block. - */ - d = XFS_FSB_TO_DADDR(mp, fsbno); - error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, - mp->m_bsize, 0, &bp); + + error = xfs_growfs_init_rtbuf(tp, ip, fsbno, buf_type); if (error) goto out_trans_cancel; - xfs_trans_buf_set_type(tp, bp, buf_type); - bp->b_ops = &xfs_rtbuf_ops; - memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); - xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); /* * Commit the transaction. */ @@ -1159,10 +1185,10 @@ xfs_growfs_rt( * Skip the current block if it is exactly full. * This also deals with the case where there were no rtextents before. */ - for (bmbno = sbp->sb_rbmblocks - - ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); - bmbno < nrbmblocks; - bmbno++) { + bmbno = sbp->sb_rbmblocks; + if (xfs_rtx_to_rbmword(mp, sbp->sb_rextents) != 0) + bmbno--; + for (; bmbno < nrbmblocks; bmbno++) { struct xfs_trans *tp; struct xfs_rtgroup *rtg; xfs_rfsblock_t nrblocks_step; @@ -1177,7 +1203,7 @@ xfs_growfs_rt( nsbp->sb_rextsize = in->extsize; nmp->m_rtxblklog = -1; /* don't use shift or masking */ nsbp->sb_rbmblocks = bmbno + 1; - nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * + nrblocks_step = (bmbno + 1) * mp->m_rtx_per_rbmblock * nsbp->sb_rextsize; nsbp->sb_rblocks = min(nrblocks, nrblocks_step); nsbp->sb_rextents = xfs_rtb_to_rtxt(nmp, nsbp->sb_rblocks); From patchwork Fri Dec 30 22:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085444 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E12AC4332F for ; Sat, 31 Dec 2022 01:31:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236087AbiLaBbZ (ORCPT ); Fri, 30 Dec 2022 20:31:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236102AbiLaBbY (ORCPT ); Fri, 30 Dec 2022 20:31:24 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 072BDDECF for ; Fri, 30 Dec 2022 17:31:23 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 980C661C3A for ; Sat, 31 Dec 2022 01:31:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 054D1C433EF; Sat, 31 Dec 2022 01:31:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450282; bh=bkEFSfYcyQ5RYf4PND9D1QFDLzol4sRnwrFjLRpjkuk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Ks+2qTlo9He0Aup94tM5eESuDtiGxLRatwFx4fy6z3tfNB04zRbJdIbgb8E8L4Ryk brlrBA8dkUjkehKqjT9UyYCjCDXw4oVveZ3xgtTpa9/0DyexHn7dmTh2lap8XjmYa6 TSivm9jsFp4QRozJhGesqsYHVLIGAVQA5giqc061o1MsdK7qwAb73ViCY+46320Wdc qi51m/guDOg+mb7ZlpYs9KH1IxTFegdeiHar6M3HmVSiPXlnYKWfxBfBosgEcaAoRB cCNmQZfdFMg4/hG30fTx/susL883zZ77VysxPTAjzowDuhCPuuCsLC4lQi9S9e3saZ fFM8kQZeN8AUA== Subject: [PATCH 15/22] xfs: encode the rtbitmap in little endian format From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:54 -0800 Message-ID: <167243867482.712847.6507400689250147833.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Currently, the ondisk realtime bitmap file is accessed in units of 32-bit words. There's no endian translation of the contents of this file, which means that the Bad Things Happen(tm) if you go from (say) x86 to powerpc. Since we have a new feature flag, let's take the opportunity to enforce an endianness on the file. The natural format of a bitmap is (IMHO) little endian, because the byte offsets of the bitmap data should always increase in step with the information being indexed. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 4 +++- fs/xfs/libxfs/xfs_rtbitmap.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 4096d3f069a3..c7752aaa4478 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -738,10 +738,12 @@ struct xfs_agfl { /* * Realtime bitmap information is accessed by the word, which is currently - * stored in host-endian format. + * stored in host-endian format. Starting with the realtime groups feature, + * the words are stored in le32 ondisk. */ union xfs_rtword_ondisk { __u32 raw; + __le32 rtg; }; /* diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 05b0e4e92a0a..3e99afea78a6 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -177,6 +177,9 @@ xfs_rtbitmap_getword( struct xfs_mount *mp, union xfs_rtword_ondisk *wordptr) { + if (xfs_has_rtgroups(mp)) + return le32_to_cpu(wordptr->rtg); + return wordptr->raw; } @@ -187,7 +190,10 @@ xfs_rtbitmap_setword( union xfs_rtword_ondisk *wordptr, xfs_rtword_t incore) { - wordptr->raw = incore; + if (xfs_has_rtgroups(mp)) + wordptr->rtg = cpu_to_le32(incore); + else + wordptr->raw = incore; } /* From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 454AAC4332F for ; Sat, 31 Dec 2022 01:31:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236102AbiLaBbn (ORCPT ); Fri, 30 Dec 2022 20:31:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBbl (ORCPT ); Fri, 30 Dec 2022 20:31:41 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 551E8DEB7 for ; Fri, 30 Dec 2022 17:31:40 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 0B659B81DFC for ; Sat, 31 Dec 2022 01:31:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DE46C433D2; Sat, 31 Dec 2022 01:31:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450297; bh=L7RxfY9rMIxVcd6ta+cPT8w9NutqU3HrJWcOhk5VY7g=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=VDhmVXd7XwASL0zwxLBJqyhnHcUfv21l0i+ks9yWj7NONSluD2IvR52tpL8Nxa7D/ njR/4QcxKCP5U4ZlpE1lWwAHUgybHrDRhJDPnLABzo+0NAH6U/0ME18Q7IaXs0xgdz xSf1nPAPqKbZAFmfOp0j/A63cUt9k9VBQ6IJIe4irSOIkDiyYlhl9JjYdrSgb5VDq4 jT/K1Dv3VPJfWLwH6DfKYdT7bMAEJIGLRNoNoJPmIJCO6iXY9/zC7RNX/hHyzmGUte N0BUhu5Y0GQoLrXeGH5L8MZhp0NmtSKFQYkRUd5+3MjdX5YOSx4YSo0sYb4B/yKl7Y 2fTEgwbD/ZEBg== Subject: [PATCH 16/22] xfs: add block headers to realtime summary blocks From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867496.712847.15425012463500364332.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Upgrade rtsummary blocks to have self describing metadata like most every other thing in XFS. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 1 + fs/xfs/libxfs/xfs_rtbitmap.c | 18 +++++++++++++++--- fs/xfs/libxfs/xfs_rtbitmap.h | 18 ++++++++++++++++-- fs/xfs/libxfs/xfs_shared.h | 1 + fs/xfs/scrub/rtsummary_repair.c | 15 +++++++++++++-- fs/xfs/xfs_buf_item_recover.c | 11 +++++++---- fs/xfs/xfs_rtalloc.c | 7 +++++-- 7 files changed, 58 insertions(+), 13 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index c7752aaa4478..47b2e31e2560 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1287,6 +1287,7 @@ static inline bool xfs_dinode_has_large_extent_counts( * RT bit manipulation macros. */ #define XFS_RTBITMAP_MAGIC 0x424D505A /* BMPZ */ +#define XFS_RTSUMMARY_MAGIC 0x53554D59 /* SUMY */ struct xfs_rtbuf_blkinfo { __be32 rt_magic; /* validity check on block */ diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 3e99afea78a6..3d5b14cc0f3a 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -53,7 +53,7 @@ xfs_rtbuf_verify_read( struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; xfs_failaddr_t fa; - if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops) + if (!xfs_has_rtgroups(mp)) return; if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr->rt_lsn))) { @@ -84,7 +84,7 @@ xfs_rtbuf_verify_write( struct xfs_buf_log_item *bip = bp->b_log_item; xfs_failaddr_t fa; - if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops) + if (!xfs_has_rtgroups(mp)) return; fa = xfs_rtbuf_verify(bp); @@ -112,6 +112,14 @@ const struct xfs_buf_ops xfs_rtbitmap_buf_ops = { .verify_struct = xfs_rtbuf_verify, }; +const struct xfs_buf_ops xfs_rtsummary_buf_ops = { + .name = "xfs_rtsummary", + .magic = { 0, cpu_to_be32(XFS_RTSUMMARY_MAGIC) }, + .verify_read = xfs_rtbuf_verify_read, + .verify_write = xfs_rtbuf_verify_write, + .verify_struct = xfs_rtbuf_verify, +}; + /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. @@ -153,7 +161,7 @@ xfs_rtbuf_get( if (error) return error; - if (xfs_has_rtgroups(mp) && !issum) { + if (xfs_has_rtgroups(mp)) { struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; if (hdr->rt_owner != cpu_to_be64(ip->i_ino)) { @@ -1321,6 +1329,10 @@ xfs_rtsummary_blockcount( unsigned long long rsumwords; rsumwords = (unsigned long long)rsumlevels * rbmblocks; + + if (xfs_has_rtgroups(mp)) + return howmany_64(rsumwords, mp->m_blockwsize); + 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 c1f740fd27b8..cebbb72c4376 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -181,6 +181,9 @@ xfs_rtsumoffs_to_block( struct xfs_mount *mp, xfs_rtsumoff_t rsumoff) { + if (xfs_has_rtgroups(mp)) + return rsumoff / mp->m_blockwsize; + return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); } @@ -195,16 +198,24 @@ xfs_rtsumoffs_to_infoword( { unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; + if (xfs_has_rtgroups(mp)) + return rsumoff % mp->m_blockwsize; + return rsumoff & mask; } /* Return a pointer to a summary info word within a rt summary block buffer. */ static inline union xfs_suminfo_ondisk * xfs_rsumbuf_infoptr( + struct xfs_mount *mp, void *buf, unsigned int infoword) { union xfs_suminfo_ondisk *infop = buf; + struct xfs_rtbuf_blkinfo *hdr = buf; + + if (xfs_has_rtgroups(mp)) + infop = (union xfs_suminfo_ondisk *)(hdr + 1); return &infop[infoword]; } @@ -215,7 +226,7 @@ xfs_rsumblock_infoptr( struct xfs_buf *bp, unsigned int infoword) { - return xfs_rsumbuf_infoptr(bp->b_addr, infoword); + return xfs_rsumbuf_infoptr(bp->b_mount, bp->b_addr, infoword); } static inline const struct xfs_buf_ops * @@ -223,8 +234,11 @@ xfs_rtblock_ops( struct xfs_mount *mp, bool issum) { - if (xfs_has_rtgroups(mp) && !issum) + if (xfs_has_rtgroups(mp)) { + if (issum) + return &xfs_rtsummary_buf_ops; return &xfs_rtbitmap_buf_ops; + } return &xfs_rtbuf_ops; } diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 1c86163915cf..62839fc87b50 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -39,6 +39,7 @@ extern const struct xfs_buf_ops xfs_inode_buf_ra_ops; extern const struct xfs_buf_ops xfs_refcountbt_buf_ops; extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; extern const struct xfs_buf_ops xfs_rtbitmap_buf_ops; +extern const struct xfs_buf_ops xfs_rtsummary_buf_ops; extern const struct xfs_buf_ops xfs_rtbuf_ops; extern const struct xfs_buf_ops xfs_rtsb_buf_ops; extern const struct xfs_buf_ops xfs_sb_buf_ops; diff --git a/fs/xfs/scrub/rtsummary_repair.c b/fs/xfs/scrub/rtsummary_repair.c index 713b79a1f52a..0836c1e10504 100644 --- a/fs/xfs/scrub/rtsummary_repair.c +++ b/fs/xfs/scrub/rtsummary_repair.c @@ -88,13 +88,24 @@ xrep_rtsummary_prep_buf( struct xfs_mount *mp = sc->mp; int error; - bp->b_ops = &xfs_rtbuf_ops; - error = xfsum_copyout(sc, rs->prep_wordoff, xfs_rsumblock_infoptr(bp, 0), mp->m_blockwsize); if (error) return error; + if (xfs_has_rtgroups(sc->mp)) { + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + + hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC); + hdr->rt_owner = cpu_to_be64(sc->ip->i_ino); + hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp)); + hdr->rt_lsn = 0; + uuid_copy(&hdr->rt_uuid, &sc->mp->m_sb.sb_meta_uuid); + bp->b_ops = &xfs_rtsummary_buf_ops; + } else { + bp->b_ops = &xfs_rtbuf_ops; + } + rs->prep_wordoff += mp->m_blockwsize; xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_RTSUMMARY_BUF); return 0; diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 4dcd5d9d2c7c..b74d40f5beb1 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -399,7 +399,10 @@ xlog_recover_validate_buf_type( bp->b_ops = xfs_rtblock_ops(mp, false); break; case XFS_BLFT_RTSUMMARY_BUF: - /* no magic numbers for verification of RT buffers */ + if (xfs_has_rtgroups(mp) && magic32 != XFS_RTSUMMARY_MAGIC) { + warnmsg = "Bad rtsummary magic!"; + break; + } bp->b_ops = xfs_rtblock_ops(mp, true); break; #endif /* CONFIG_XFS_RT */ @@ -735,13 +738,13 @@ xlog_recover_get_buf_lsn( * UUIDs, so we must recover them immediately. */ blft = xfs_blft_from_flags(buf_f); - if (!xfs_has_rtgroups(mp) && blft == XFS_BLFT_RTBITMAP_BUF) - goto recover_immediately; - if (blft == XFS_BLFT_RTSUMMARY_BUF) + if (!xfs_has_rtgroups(mp) && (blft == XFS_BLFT_RTBITMAP_BUF || + blft == XFS_BLFT_RTSUMMARY_BUF)) goto recover_immediately; magic32 = be32_to_cpu(*(__be32 *)blk); switch (magic32) { + case XFS_RTSUMMARY_MAGIC: case XFS_RTBITMAP_MAGIC: { struct xfs_rtbuf_blkinfo *hdr = blk; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 9e013a8e3149..f8f0557dc46c 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -814,10 +814,13 @@ xfs_growfs_init_rtbuf( bp->b_ops = xfs_rtblock_ops(mp, buf_type == XFS_BLFT_RTSUMMARY_BUF); memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); - if (xfs_has_rtgroups(mp) && buf_type == XFS_BLFT_RTBITMAP_BUF) { + if (xfs_has_rtgroups(mp)) { struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; - hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC); + if (buf_type == XFS_BLFT_RTBITMAP_BUF) + hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC); + else + hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC); hdr->rt_owner = cpu_to_be64(ip->i_ino); hdr->rt_blkno = cpu_to_be64(d); uuid_copy(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid); From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085446 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 537A1C4332F for ; Sat, 31 Dec 2022 01:32:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236103AbiLaBb5 (ORCPT ); Fri, 30 Dec 2022 20:31:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBb5 (ORCPT ); Fri, 30 Dec 2022 20:31:57 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C93F0DEB7 for ; Fri, 30 Dec 2022 17:31:55 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 83631B81DD0 for ; Sat, 31 Dec 2022 01:31:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 349D8C433D2; Sat, 31 Dec 2022 01:31:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450313; bh=mDLx1acuzkQ7LnkS9OCmISCHVJ8P8KiYkElI2JHKUEk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=PhxmPoh4G0wNsSncVCeNsn3mynDxwlnmt4qudKhibJ5YS2/nSuH//dYGZ+HBi7b5m K2ust3Oz0vTV56i4YRMwL9mLOvnqLdWBSlFvhCA4fQ/q+1819+UqdccfIImaD1xNWI urUP+bDh/CFplaOvi+QxjYoovFIAe6438ZQfllk9LsTDTKsI0FnF/lfifeF/f3Aod/ bkTu261BBUB5ViXWATFNeodjVbwJbhQLGPX5O5QlBwqimX7H95p7ulsH2ast4JX8uZ OOjeipb+TJnNWzEJe2B2azLYUMCLjLCI3PO2856SeSLJ+Y7rbRvDQh3qqD1r/S2Zy1 Oyx5KbA5wB3uw== Subject: [PATCH 17/22] xfs: encode the rtsummary in big endian format From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867511.712847.4394753972902151622.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Currently, the ondisk realtime summary file counters are accessed in units of 32-bit words. There's no endian translation of the contents of this file, which means that the Bad Things Happen(tm) if you go from (say) x86 to powerpc. Since we have a new feature flag, let's take the opportunity to enforce an endianness on the file. Encode the summary information in big endian format, like most of the rest of the filesystem. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 4 +++- fs/xfs/libxfs/xfs_rtbitmap.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 47b2e31e2560..7e76bedda688 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -748,10 +748,12 @@ union xfs_rtword_ondisk { /* * Realtime summary counts are accessed by the word, which is currently - * stored in host-endian format. + * stored in host-endian format. Starting with the realtime groups feature, + * the words are stored in be32 ondisk. */ union xfs_suminfo_ondisk { __u32 raw; + __be32 rtg; }; /* diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 3d5b14cc0f3a..ccefbfc70f8b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -562,6 +562,9 @@ xfs_suminfo_get( struct xfs_mount *mp, union xfs_suminfo_ondisk *infoptr) { + if (xfs_has_rtgroups(mp)) + return be32_to_cpu(infoptr->rtg); + return infoptr->raw; } @@ -571,7 +574,10 @@ xfs_suminfo_add( union xfs_suminfo_ondisk *infoptr, int delta) { - infoptr->raw += delta; + if (xfs_has_rtgroups(mp)) + be32_add_cpu(&infoptr->rtg, delta); + else + infoptr->raw += delta; } /* From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085447 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D51C1C4332F for ; Sat, 31 Dec 2022 01:32:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236104AbiLaBcL (ORCPT ); Fri, 30 Dec 2022 20:32:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBcL (ORCPT ); Fri, 30 Dec 2022 20:32:11 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9DFC18387 for ; Fri, 30 Dec 2022 17:32:09 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5964D61CC4 for ; Sat, 31 Dec 2022 01:32:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE2D2C433EF; Sat, 31 Dec 2022 01:32:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450328; bh=mCRhIQuJSqqFN4dEbzx2qxj0Xc5dxZ9n3mr4qasj790=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=lsF0ObNXxTVztN10Iezwnh57tTIzdQzLIbjo+KazwfL+F7fOBDs+gRgeCQq8o3ntr 69cA5mO92+gxEPMaKSajbL/nyGMz+RANyaEzyfKYzLjFnwPJqlDcMQp4IO9gFq3Zpr vG+I8rsvYQRCwf6KsyjuXjlyWwdbNKm75p5dC8Y+1j1uo1b87TK7aT4tTfNLYs42Db k61JJa6J9/gUum+waxgVnJy7VPj1ZZDkH3y9mA7zOW6vbAXM28TeizwO4rJA41QEDI phmfdTAhMaYuoE0UEauCBpWrdZf2dZyH2lcC+Dd1hV8yHWGiSV1vugklqbPNLM+90M YKCXmmMo6nS/A== Subject: [PATCH 18/22] xfs: store rtgroup information with a bmap intent From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867524.712847.2285503341227488941.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Make the bmap intent items take an active reference to the rtgroup containing the space that is being mapped or unmapped. We will need this functionality once we start enabling rmap and reflink on the rt volume. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.h | 5 ++++- fs/xfs/xfs_bmap_item.c | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index d870c6a62e40..05097b1d5c7d 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -241,7 +241,10 @@ struct xfs_bmap_intent { enum xfs_bmap_intent_type bi_type; int bi_whichfork; struct xfs_inode *bi_owner; - struct xfs_perag *bi_pag; + union { + struct xfs_perag *bi_pag; + struct xfs_rtgroup *bi_rtg; + }; struct xfs_bmbt_irec bi_bmap; }; diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index bf52d30d7d1c..04eeae9aef79 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -25,6 +25,7 @@ #include "xfs_log_priv.h" #include "xfs_log_recover.h" #include "xfs_ag.h" +#include "xfs_rtgroup.h" struct kmem_cache *xfs_bui_cache; struct kmem_cache *xfs_bud_cache; @@ -362,8 +363,18 @@ xfs_bmap_update_get_group( { xfs_agnumber_t agno; - if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork)) + if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork)) { + if (xfs_has_rtgroups(mp)) { + xfs_rgnumber_t rgno; + + rgno = xfs_rtb_to_rgno(mp, bi->bi_bmap.br_startblock); + bi->bi_rtg = xfs_rtgroup_get(mp, rgno); + } else { + bi->bi_rtg = NULL; + } + return; + } agno = XFS_FSB_TO_AGNO(mp, bi->bi_bmap.br_startblock); bi->bi_pag = xfs_perag_get(mp, agno); @@ -383,8 +394,11 @@ static inline void xfs_bmap_update_put_group( struct xfs_bmap_intent *bi) { - if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork)) + if (xfs_ifork_is_realtime(bi->bi_owner, bi->bi_whichfork)) { + if (xfs_has_rtgroups(bi->bi_owner->i_mount)) + xfs_rtgroup_put(bi->bi_rtg); return; + } xfs_perag_drop_intents(bi->bi_pag); xfs_perag_put(bi->bi_pag); From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085448 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BC9DC4332F for ; Sat, 31 Dec 2022 01:32:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236105AbiLaBcb (ORCPT ); Fri, 30 Dec 2022 20:32:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBc2 (ORCPT ); Fri, 30 Dec 2022 20:32:28 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DF81DEB7 for ; Fri, 30 Dec 2022 17:32:27 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 9C93BB81E01 for ; Sat, 31 Dec 2022 01:32:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48F62C433D2; Sat, 31 Dec 2022 01:32:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450344; bh=/KF70EJzvgd7fcguBqJo/W+FA1CLAQkzyn7JHFNbGtE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Ns9Sc6i0DSpuZuprC/GQ6lOvJyYWLORo5W4I37rAwY6/CpALrjK9U3KYnu2YJviC1 bUoMXQgnarBhTXY3qDDquhi/xdgIYV2+26uebYxJRnZ6dvOpd5ad/0ZHjaXy0FG8TQ milHVc4sHCOHFiQTCVoiFrxR+ywFOX/P1errg/TMlFefFMAa2+0et3a6qFZl2sCUoB R7qU7d+GR6w22mEVzvuNRJ4VO15Jk7D5BwVJ+owRa1GLQhwZMNv+BhBK9unKg6cYH+ i+MFNNCTrQcqbXOy/wKyhA3I99BCcvFdHjnJSgsNLaiUQKWOdZTh1sMYqq8+Ta5HQl 3JQOc5tZY3NmA== Subject: [PATCH 19/22] xfs: scrub the realtime group superblock From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867539.712847.15291040944782337347.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Enable scrubbing of realtime group superblocks. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_fs.h | 3 +- fs/xfs/scrub/common.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/common.h | 46 ++++++++++++++----------- fs/xfs/scrub/health.c | 1 + fs/xfs/scrub/rgsuper.c | 77 ++++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/scrub.c | 20 ++++++++++- fs/xfs/scrub/scrub.h | 40 ++++++++++------------ fs/xfs/scrub/trace.h | 4 ++ 9 files changed, 236 insertions(+), 44 deletions(-) create mode 100644 fs/xfs/scrub/rgsuper.c diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 135a403c0edc..a02fb09fed64 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -178,6 +178,7 @@ xfs-y += $(addprefix scrub/, \ ) xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \ + rgsuper.o \ rtbitmap.o \ rtsummary.o \ ) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index e3d87665e4a5..c12be9dbb59d 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -741,9 +741,10 @@ struct xfs_scrub_metadata { #define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */ #define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */ #define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */ +#define XFS_SCRUB_TYPE_RGSUPER 28 /* realtime superblock */ /* Number of scrub subcommands. */ -#define XFS_SCRUB_TYPE_NR 28 +#define XFS_SCRUB_TYPE_NR 29 /* i: Repair this metadata. */ #define XFS_SCRUB_IFLAG_REPAIR (1u << 0) diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 1b48726fcc65..b63b5c016841 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -34,6 +34,7 @@ #include "xfs_quota.h" #include "xfs_swapext.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, @@ -132,6 +144,17 @@ xchk_xref_process_error( XFS_SCRUB_OFLAG_XFAIL, __return_address); } +bool +xchk_xref_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_XFAIL, __return_address); +} + /* Check for operational errors for a file offset. */ static bool __xchk_fblock_process_error( @@ -691,6 +714,7 @@ xchk_rt_init( XCHK_RTLOCK_BITMAP_SHARED)) < 2); ASSERT(hweight32(rtlock_flags & (XCHK_RTLOCK_SUMMARY | XCHK_RTLOCK_SUMMARY_SHARED)) < 2); + ASSERT(sr->rtg == NULL); if (rtlock_flags & XCHK_RTLOCK_BITMAP) xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_EXCL); @@ -714,6 +738,8 @@ xchk_rt_unlock( struct xfs_scrub *sc, struct xchk_rt *sr) { + ASSERT(sr->rtg == NULL); + if (!sr->rtlock_flags) return; @@ -730,6 +756,68 @@ xchk_rt_unlock( sr->rtlock_flags = 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, + unsigned int rtglock_flags) +{ + ASSERT(sr->rtg == NULL); + ASSERT(sr->rtlock_flags == 0); + + sr->rtg = xfs_rtgroup_get(sc->mp, rgno); + if (!sr->rtg) + return -ENOENT; + + xfs_rtgroup_lock(NULL, sr->rtg, rtglock_flags); + sr->rtlock_flags = rtglock_flags; + return 0; +} + +/* + * Unlock the realtime group. This must be done /after/ committing (or + * cancelling) the scrub transaction. + */ +void +xchk_rtgroup_unlock( + struct xfs_scrub *sc, + 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(sc, 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 e41224065421..96bb8bc676e7 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -37,11 +37,15 @@ 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); bool xchk_xref_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); +bool xchk_xref_process_rt_error(struct xfs_scrub *sc, + xfs_rgnumber_t rgno, xfs_rgblock_t rgbno, int *error); bool xchk_fblock_xref_process_error(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error); @@ -78,6 +82,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); @@ -95,17 +104,11 @@ int xchk_setup_parent(struct xfs_scrub *sc); #ifdef CONFIG_XFS_RT int xchk_setup_rtbitmap(struct xfs_scrub *sc); int xchk_setup_rtsummary(struct xfs_scrub *sc); +int xchk_setup_rgsuperblock(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 +# define xchk_setup_rgsuperblock xchk_setup_nothing #endif #ifdef CONFIG_XFS_QUOTA int xchk_ino_dqattach(struct xfs_scrub *sc); @@ -117,16 +120,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); @@ -169,6 +164,17 @@ xchk_ag_init_existing( void xchk_rt_init(struct xfs_scrub *sc, struct xchk_rt *sr, unsigned int xchk_rtlock_flags); void xchk_rt_unlock(struct xfs_scrub *sc, struct xchk_rt *sr); + +#ifdef CONFIG_XFS_RT +int xchk_rtgroup_init(struct xfs_scrub *sc, xfs_rgnumber_t rgno, + struct xchk_rt *sr, unsigned int rtglock_flags); +void xchk_rtgroup_unlock(struct xfs_scrub *sc, struct xchk_rt *sr); +void xchk_rtgroup_free(struct xfs_scrub *sc, struct xchk_rt *sr); +#else +# define xchk_rtgroup_init(sc, rgno, sr, lockflags) (-ENOSYS) +# define xchk_rtgroup_free(sc, sr) ((void)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/health.c b/fs/xfs/scrub/health.c index 9a8d4c348cc9..a71d4d9087b2 100644 --- a/fs/xfs/scrub/health.c +++ b/fs/xfs/scrub/health.c @@ -112,6 +112,7 @@ static const struct xchk_health_map type_to_health_flag[XFS_SCRUB_TYPE_NR] = { [XFS_SCRUB_TYPE_FSCOUNTERS] = { XHG_FS, XFS_SICK_FS_COUNTERS }, [XFS_SCRUB_TYPE_QUOTACHECK] = { XHG_FS, XFS_SICK_FS_QUOTACHECK }, [XFS_SCRUB_TYPE_NLINKS] = { XHG_FS, XFS_SICK_FS_NLINKS }, + [XFS_SCRUB_TYPE_RGSUPER] = { XHG_RTGROUP, XFS_SICK_RT_SUPER }, }; /* Return the health status mask for this scrub type. */ diff --git a/fs/xfs/scrub/rgsuper.c b/fs/xfs/scrub/rgsuper.c new file mode 100644 index 000000000000..a85ad580aa62 --- /dev/null +++ b/fs/xfs/scrub/rgsuper.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 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_mount.h" +#include "xfs_rtgroup.h" +#include "scrub/scrub.h" +#include "scrub/common.h" + +/* Set us up with a transaction and an empty context. */ +int +xchk_setup_rgsuperblock( + struct xfs_scrub *sc) +{ + return xchk_trans_alloc(sc, 0); +} + +/* Cross-reference with the other rt metadata. */ +STATIC void +xchk_rgsuperblock_xref( + struct xfs_scrub *sc) +{ + struct xfs_mount *mp = sc->mp; + xfs_rgnumber_t rgno = sc->sr.rtg->rtg_rgno; + xfs_rtblock_t rtbno; + + if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) + return; + + rtbno = xfs_rgbno_to_rtb(mp, rgno, 0); + xchk_xref_is_used_rt_space(sc, rtbno, 1); +} + +int +xchk_rgsuperblock( + struct xfs_scrub *sc) +{ + struct xfs_buf *bp; + xfs_rgnumber_t rgno = sc->sm->sm_agno; + int error; + + /* + * Grab an active reference to the rtgroup structure. If we can't get + * it, we're racing with something that's tearing down the group, so + * signal that the group no longer exists. Take the rtbitmap in shared + * mode so that the group can't change while we're doing things. + */ + error = xchk_rtgroup_init(sc, rgno, &sc->sr, XFS_RTGLOCK_BITMAP_SHARED); + if (error) + return error; + + /* + * If this is the primary rtgroup superblock, we know it passed the + * verifier checks at mount time and do not need to load the buffer + * again. + */ + if (sc->sr.rtg->rtg_rgno == 0) { + xchk_rgsuperblock_xref(sc); + return 0; + } + + /* The secondary rt super is checked by the read verifier. */ + error = xfs_buf_read_uncached(sc->mp->m_rtdev_targp, XFS_RTSB_DADDR, + XFS_FSB_TO_BB(sc->mp, 1), 0, &bp, &xfs_rtsb_buf_ops); + if (!xchk_process_rt_error(sc, rgno, 0, &error)) + return error; + + xchk_rgsuperblock_xref(sc); + xfs_buf_relse(bp); + return 0; +} diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 1b3820b30384..6c54f00b516c 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -189,7 +189,10 @@ xchk_teardown( xfs_trans_cancel(sc->tp); sc->tp = NULL; } - xchk_rt_unlock(sc, &sc->sr); + if (sc->sr.rtg) + xchk_rtgroup_free(sc, &sc->sr); + else + xchk_rt_unlock(sc, &sc->sr); if (sc->ip) { if (sc->ilock_flags) xchk_iunlock(sc, sc->ilock_flags); @@ -406,6 +409,13 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .scrub = xchk_health_record, .repair = xrep_notsupported, }, + [XFS_SCRUB_TYPE_RGSUPER] = { /* realtime group superblock */ + .type = ST_RTGROUP, + .setup = xchk_setup_rgsuperblock, + .scrub = xchk_rgsuperblock, + .has = xfs_has_rtgroups, + .repair = xrep_notsupported, + }, }; static int @@ -453,6 +463,14 @@ xchk_validate_inputs( if (sm->sm_agno || (sm->sm_gen && !sm->sm_ino)) goto out; break; + case ST_RTGROUP: + if (sm->sm_ino || sm->sm_gen) + goto out; + if (!xfs_has_rtgroups(mp) && sm->sm_agno != 0) + goto out; + if (xfs_has_rtgroups(mp) && sm->sm_agno >= mp->m_sb.sb_rgcount) + goto out; + break; default: goto out; } diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index 38437104fc86..6e5b96b6db81 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -23,6 +23,7 @@ enum xchk_type { ST_PERAG, /* per-AG metadata */ ST_FS, /* per-FS metadata */ ST_INODE, /* per-inode metadata */ + ST_RTGROUP, /* rtgroup metadata */ }; struct xchk_meta_ops { @@ -69,7 +70,13 @@ struct xchk_ag { /* Inode lock state for the RT volume. */ struct xchk_rt { - /* XCHK_RTLOCK_* lock state */ + /* incore rtgroup, if applicable */ + struct xfs_rtgroup *rtg; + + /* + * XCHK_RTLOCK_* lock state if rtg == NULL, or XFS_RTGLOCK_* lock state + * if rtg != NULL. + */ unsigned int rtlock_flags; }; @@ -153,6 +160,11 @@ struct xfs_scrub { XCHK_FSHOOKS_NLINKS | \ XCHK_FSHOOKS_RMAP) +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); @@ -176,32 +188,18 @@ int xchk_parent(struct xfs_scrub *sc); #ifdef CONFIG_XFS_RT int xchk_rtbitmap(struct xfs_scrub *sc); int xchk_rtsummary(struct xfs_scrub *sc); +int xchk_rgsuperblock(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 +# define xchk_rgsuperblock 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); diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 749cf4333c8a..a88ad16c90db 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -74,6 +74,7 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FSCOUNTERS); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_QUOTACHECK); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_NLINKS); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY); +TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGSUPER); #define XFS_SCRUB_TYPE_STRINGS \ { XFS_SCRUB_TYPE_PROBE, "probe" }, \ @@ -103,7 +104,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY); { XFS_SCRUB_TYPE_FSCOUNTERS, "fscounters" }, \ { XFS_SCRUB_TYPE_QUOTACHECK, "quotacheck" }, \ { XFS_SCRUB_TYPE_NLINKS, "nlinks" }, \ - { XFS_SCRUB_TYPE_HEALTHY, "healthy" } + { XFS_SCRUB_TYPE_HEALTHY, "healthy" }, \ + { XFS_SCRUB_TYPE_RGSUPER, "rgsuper" } #define XFS_SCRUB_FLAG_STRINGS \ { XFS_SCRUB_IFLAG_REPAIR, "repair" }, \ From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8736AC4332F for ; Sat, 31 Dec 2022 01:32:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236107AbiLaBcm (ORCPT ); Fri, 30 Dec 2022 20:32:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBcl (ORCPT ); Fri, 30 Dec 2022 20:32:41 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB1C9DECF for ; Fri, 30 Dec 2022 17:32:40 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 77ACC61CC6 for ; Sat, 31 Dec 2022 01:32:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D76E6C433D2; Sat, 31 Dec 2022 01:32:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450359; bh=ntyEQBUMZOoYePgbavHf9Ga0DUgoAabAeItp0cdz5GM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=pFVFt/cnFe0tuCQsd/u2iigLJCxhRKPjIU0owvyr9ZSl9o49xugqFFqcuc7tUw5hC YPuALeZlIHG4a63B1G4Q2TLeJsXc/V80plqppx1QHeEPcAlrSougO6vWz5wnjVXrxW N1Z3XD0rW/CPsrWoRtw9lLaF+kLYlWovSIDmboBhGAc/rX0I7LKK2wB1MRRbx/Fxbl aNbk8nWyK5Qmz0Oh8CLxYWyk1doIBYi1nKY5MiuAnCC8LIt08BImunHuX65YbNN01f jiauQaCaKwoN6v3K+zSbVK7RpFsqPM4uiUql8Br074Un8vxj+hTCjEq8sHTJQ+OwVJ qb8pQK2rXg16g== Subject: [PATCH 20/22] xfs: repair secondary realtime group superblocks From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867553.712847.11659815081440228135.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Repair secondary realtime group superblocks. They're not critical for anything, but some consistency would be a good idea. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_rtgroup.c | 2 +- fs/xfs/libxfs/xfs_rtgroup.h | 3 +++ fs/xfs/scrub/repair.h | 3 +++ fs/xfs/scrub/rgsuper_repair.c | 48 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/scrub.c | 2 +- 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 fs/xfs/scrub/rgsuper_repair.c diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a02fb09fed64..4bf6d663272b 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -217,6 +217,7 @@ xfs-y += $(addprefix scrub/, \ ) xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \ + rgsuper_repair.o \ rtbitmap_repair.o \ rtsummary_repair.o \ ) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index a428dff81888..4d9e2c0f2fd3 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -384,7 +384,7 @@ xfs_rtgroup_log_super( } /* Initialize a secondary realtime superblock. */ -static int +int xfs_rtgroup_init_secondary_super( struct xfs_mount *mp, xfs_rgnumber_t rgno, diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index 1fec49c496d4..3c9572677f79 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -210,6 +210,8 @@ void xfs_rtgroup_update_super(struct xfs_buf *rtsb_bp, const struct xfs_buf *sb_bp); void xfs_rtgroup_log_super(struct xfs_trans *tp, const struct xfs_buf *sb_bp); int xfs_rtgroup_update_secondary_sbs(struct xfs_mount *mp); +int xfs_rtgroup_init_secondary_super(struct xfs_mount *mp, xfs_rgnumber_t rgno, + struct xfs_buf **bpp); /* Lock the rt bitmap inode in exclusive mode */ #define XFS_RTGLOCK_BITMAP (1U << 0) @@ -230,6 +232,7 @@ int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg, # define xfs_rtgroup_update_super(bp, sb_bp) ((void)0) # define xfs_rtgroup_log_super(tp, sb_bp) ((void)0) # define xfs_rtgroup_update_secondary_sbs(mp) (0) +# define xfs_rtgroup_init_secondary_super(mp, rgno, bpp) (-EOPNOTSUPP) # define xfs_rtgroup_lock(tp, rtg, gf) ((void)0) # define xfs_rtgroup_unlock(rtg, gf) ((void)0) # define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP) diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index c6461acd1112..292e252efae3 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -131,9 +131,11 @@ int xrep_symlink(struct xfs_scrub *sc); #ifdef CONFIG_XFS_RT int xrep_rtbitmap(struct xfs_scrub *sc); int xrep_rtsummary(struct xfs_scrub *sc); +int xrep_rgsuperblock(struct xfs_scrub *sc); #else # define xrep_rtbitmap xrep_notsupported # define xrep_rtsummary xrep_notsupported +# define xrep_rgsuperblock xrep_notsupported #endif /* CONFIG_XFS_RT */ #ifdef CONFIG_XFS_QUOTA @@ -248,6 +250,7 @@ static inline int xrep_setup_symlink(struct xfs_scrub *sc, unsigned int *x) #define xrep_directory xrep_notsupported #define xrep_parent xrep_notsupported #define xrep_symlink xrep_notsupported +#define xrep_rgsuperblock xrep_notsupported #endif /* CONFIG_XFS_ONLINE_REPAIR */ diff --git a/fs/xfs/scrub/rgsuper_repair.c b/fs/xfs/scrub/rgsuper_repair.c new file mode 100644 index 000000000000..9dc379c593ba --- /dev/null +++ b/fs/xfs/scrub/rgsuper_repair.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 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_mount.h" +#include "xfs_defer.h" +#include "xfs_btree.h" +#include "xfs_inode.h" +#include "xfs_bit.h" +#include "xfs_log_format.h" +#include "xfs_trans.h" +#include "xfs_rtgroup.h" +#include "xfs_sb.h" +#include "scrub/scrub.h" +#include "scrub/repair.h" + +int +xrep_rgsuperblock( + struct xfs_scrub *sc) +{ + struct xfs_buf *bp; + int error; + + /* + * If this is the primary rtgroup superblock, log a superblock update + * to force both to disk. + */ + if (sc->sr.rtg->rtg_rgno == 0) { + xfs_log_sb(sc->tp); + return 0; + } + + /* Otherwise just write a new secondary to disk directly. */ + error = xfs_rtgroup_init_secondary_super(sc->mp, sc->sr.rtg->rtg_rgno, + &bp); + if (error) + return error; + + error = xfs_bwrite(bp); + xfs_buf_relse(bp); + return error; +} diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 6c54f00b516c..5e07150e8f14 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -414,7 +414,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .setup = xchk_setup_rgsuperblock, .scrub = xchk_rgsuperblock, .has = xfs_has_rtgroups, - .repair = xrep_notsupported, + .repair = xrep_rgsuperblock, }, }; From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085450 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A107AC4332F for ; Sat, 31 Dec 2022 01:32:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236106AbiLaBc6 (ORCPT ); Fri, 30 Dec 2022 20:32:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236082AbiLaBc5 (ORCPT ); Fri, 30 Dec 2022 20:32:57 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63068DEB7 for ; Fri, 30 Dec 2022 17:32:56 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F291D61CC1 for ; Sat, 31 Dec 2022 01:32:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5FB49C433EF; Sat, 31 Dec 2022 01:32:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450375; bh=uK5umrqeFxRtLoDlsiRjf9B+yujrv83N4nm+pdXKqFw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=QIhdf/bVl7vfzvz0qtPvkmmY3znAtzW64beRNJ50WYB0K/++QEGoj0JeO+bp2NLlg MwDouzP+u4Fs+krItNGXFUXAIeuLULd/kzdDIQsMEzLGEnL3kLRFwD7RO++uMVV9/R a9yvXkHKwQ4oxObI+4W3Ih6M03GGHiqnnY8zzUoctkvAy9MJQRcbv5F0ZpnVT9zI3L Hx5+VbmwCZiD211GYLpdk9IyjGLG9KkLwMzDwXdhtrav4RYzdgOpVyH2F0NxKuahIl 79FSkk4Q8IpO4/pt0XerPD40ikeg4Tsw8dsL7zBXakJG5RJlyHnsEzTxkoYhT2T+Ym zn+Er/W9o7lrQ== Subject: [PATCH 21/22] xfs: scrub each rtgroup's portion of the rtbitmap separately From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867567.712847.13451659455960114242.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new scrub type code so that userspace can scrub each rtgroup's portion of the rtbitmap file separately. This reduces the long tail latency that results from scanning the entire bitmap all at once, and prepares us for future patchsets, wherein we'll need to be able to lock a specific rtgroup so that we can rebuild that rtgroup's part of the rtbitmap contents from the rtgroup's rmap btree. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 3 +- fs/xfs/scrub/common.h | 6 ++++ fs/xfs/scrub/rtbitmap.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/scrub/scrub.c | 7 +++++ fs/xfs/scrub/scrub.h | 2 + fs/xfs/scrub/trace.h | 4 ++- 6 files changed, 90 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index c12be9dbb59d..7e9d7d7bb40b 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -742,9 +742,10 @@ struct xfs_scrub_metadata { #define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */ #define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */ #define XFS_SCRUB_TYPE_RGSUPER 28 /* realtime superblock */ +#define XFS_SCRUB_TYPE_RGBITMAP 29 /* realtime group bitmap */ /* Number of scrub subcommands. */ -#define XFS_SCRUB_TYPE_NR 29 +#define XFS_SCRUB_TYPE_NR 30 /* i: Repair this metadata. */ #define XFS_SCRUB_IFLAG_REPAIR (1u << 0) diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 96bb8bc676e7..e83e88b44e5b 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -105,10 +105,12 @@ int xchk_setup_parent(struct xfs_scrub *sc); int xchk_setup_rtbitmap(struct xfs_scrub *sc); int xchk_setup_rtsummary(struct xfs_scrub *sc); int xchk_setup_rgsuperblock(struct xfs_scrub *sc); +int xchk_setup_rgbitmap(struct xfs_scrub *sc); #else # define xchk_setup_rtbitmap xchk_setup_nothing # define xchk_setup_rtsummary xchk_setup_nothing # define xchk_setup_rgsuperblock xchk_setup_nothing +# define xchk_setup_rgbitmap xchk_setup_nothing #endif #ifdef CONFIG_XFS_QUOTA int xchk_ino_dqattach(struct xfs_scrub *sc); @@ -166,6 +168,10 @@ void xchk_rt_init(struct xfs_scrub *sc, struct xchk_rt *sr, void xchk_rt_unlock(struct xfs_scrub *sc, struct xchk_rt *sr); #ifdef CONFIG_XFS_RT + +/* All the locks we need to check an rtgroup. */ +#define XCHK_RTGLOCK_ALL (XFS_RTGLOCK_BITMAP_SHARED) + int xchk_rtgroup_init(struct xfs_scrub *sc, xfs_rgnumber_t rgno, struct xchk_rt *sr, unsigned int rtglock_flags); void xchk_rtgroup_unlock(struct xfs_scrub *sc, struct xchk_rt *sr); diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index a50b0580f3d8..d847773e5f66 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -14,10 +14,34 @@ #include "xfs_rtbitmap.h" #include "xfs_inode.h" #include "xfs_bmap.h" +#include "xfs_rtgroup.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/repair.h" +/* Set us up with the realtime group metadata locked. */ +int +xchk_setup_rgbitmap( + struct xfs_scrub *sc) +{ + int error; + + error = xchk_trans_alloc(sc, 0); + if (error) + return error; + + error = xchk_install_live_inode(sc, sc->mp->m_rbmip); + if (error) + return error; + + error = xchk_ino_dqattach(sc); + if (error) + return error; + + return xchk_rtgroup_init(sc, sc->sm->sm_agno, &sc->sr, + XCHK_RTGLOCK_ALL); +} + /* Set us up with the realtime metadata locked. */ int xchk_setup_rtbitmap( @@ -105,6 +129,43 @@ xchk_rtbitmap_check_extents( return error; } +/* Scrub this group's realtime bitmap. */ +int +xchk_rgbitmap( + struct xfs_scrub *sc) +{ + struct xfs_rtalloc_rec keys[2]; + struct xfs_rtgroup *rtg = sc->sr.rtg; + xfs_rtblock_t rtbno; + xfs_rgblock_t last_rgbno = rtg->rtg_blockcount - 1; + int error; + + /* Sanity check the realtime bitmap size. */ + if (sc->mp->m_rbmip->i_disk_size != + XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) { + xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino); + return 0; + } + + /* + * Check only the portion of the rtbitmap that corresponds to this + * realtime group. + */ + rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, 0); + keys[0].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno); + + rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno); + keys[1].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno); + keys[0].ar_extcount = keys[1].ar_extcount = 0; + + error = xfs_rtalloc_query_range(sc->mp, sc->tp, &keys[0], &keys[1], + xchk_rtbitmap_rec, sc); + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) + return error; + + return 0; +} + /* Scrub the realtime bitmap. */ int xchk_rtbitmap( @@ -128,12 +189,18 @@ xchk_rtbitmap( if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; + /* + * Each rtgroup checks its portion of the rt bitmap, so if we don't + * have that feature, we have to check the bitmap contents now. + */ + if (xfs_has_rtgroups(sc->mp)) + return 0; + error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, sc); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) - goto out; + return error; -out: - return error; + return 0; } /* xref check that the extent is not free in the rtbitmap */ diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 5e07150e8f14..6066673953cb 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -416,6 +416,13 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .has = xfs_has_rtgroups, .repair = xrep_rgsuperblock, }, + [XFS_SCRUB_TYPE_RGBITMAP] = { /* realtime group bitmap */ + .type = ST_RTGROUP, + .setup = xchk_setup_rgbitmap, + .scrub = xchk_rgbitmap, + .has = xfs_has_rtgroups, + .repair = xrep_notsupported, + }, }; static int diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index 6e5b96b6db81..48114bda2f4a 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -189,10 +189,12 @@ int xchk_parent(struct xfs_scrub *sc); int xchk_rtbitmap(struct xfs_scrub *sc); int xchk_rtsummary(struct xfs_scrub *sc); int xchk_rgsuperblock(struct xfs_scrub *sc); +int xchk_rgbitmap(struct xfs_scrub *sc); #else # define xchk_rtbitmap xchk_nothing # define xchk_rtsummary xchk_nothing # define xchk_rgsuperblock xchk_nothing +# define xchk_rgbitmap xchk_nothing #endif #ifdef CONFIG_XFS_QUOTA int xchk_quota(struct xfs_scrub *sc); diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index a88ad16c90db..9a51eb404fae 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -75,6 +75,7 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_QUOTACHECK); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_NLINKS); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY); TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGSUPER); +TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGBITMAP); #define XFS_SCRUB_TYPE_STRINGS \ { XFS_SCRUB_TYPE_PROBE, "probe" }, \ @@ -105,7 +106,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGSUPER); { XFS_SCRUB_TYPE_QUOTACHECK, "quotacheck" }, \ { XFS_SCRUB_TYPE_NLINKS, "nlinks" }, \ { XFS_SCRUB_TYPE_HEALTHY, "healthy" }, \ - { XFS_SCRUB_TYPE_RGSUPER, "rgsuper" } + { XFS_SCRUB_TYPE_RGSUPER, "rgsuper" }, \ + { XFS_SCRUB_TYPE_RGBITMAP, "rgbitmap" } #define XFS_SCRUB_FLAG_STRINGS \ { XFS_SCRUB_IFLAG_REPAIR, "repair" }, \ From patchwork Fri Dec 30 22:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085451 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42BCAC4332F for ; Sat, 31 Dec 2022 01:33:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231231AbiLaBdN (ORCPT ); Fri, 30 Dec 2022 20:33:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229750AbiLaBdM (ORCPT ); Fri, 30 Dec 2022 20:33:12 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBE07DEB7 for ; Fri, 30 Dec 2022 17:33:11 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8827061CC1 for ; Sat, 31 Dec 2022 01:33:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E5A8EC433D2; Sat, 31 Dec 2022 01:33:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672450391; bh=Uordkm4zZNGEdm1Nl3fTt8tJNL5AgifVQrvmqqZYkxE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=nwEAuSwi56klH+ceNvvX98dHGms951lF8WYwD/B6C97aXATCtehtR68zB+mFLSHjX kpdDcIrzWVzsA5+LbvvPqW5S7nNMiEJWLhDogL45mkqNy3r1/Q4apfd1viEaJrpEBp dc7I9Eqo3JjFfnDa6nVDWvJNxqgLsThqKphEYh+xBRu6WbD7FD0nJhMEPA/QZysPkF qcOyVBvYYEJgd79hJSN0N+GHAUz3JGi76mzO52RMxBMrHeuMdJHKmcwirOUjSojUmK 22/FritknlSzyzU2zZY3x+glpT9g2rwbgDw6fE7EKzC8UF1Bv8ZRtTPFmWSCJn0wke vLPHL7tC3WO3g== Subject: [PATCH 22/22] xfs: enable realtime group feature From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:55 -0800 Message-ID: <167243867582.712847.5494133812184915458.stgit@magnolia> In-Reply-To: <167243867242.712847.10106105868862621775.stgit@magnolia> References: <167243867242.712847.10106105868862621775.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 7e76bedda688..e4f3b2c5c054 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -416,6 +416,7 @@ xfs_sb_has_ro_compat_feature( XFS_SB_FEAT_INCOMPAT_BIGTIME| \ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \ XFS_SB_FEAT_INCOMPAT_NREXT64 | \ + XFS_SB_FEAT_INCOMPAT_RTGROUPS | \ XFS_SB_FEAT_INCOMPAT_METADIR) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL