From patchwork Wed Mar 13 02:14:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590925 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C42C0BA37 for ; Wed, 13 Mar 2024 02:14:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296096; cv=none; b=cIX03RazsWoxKgnaxPPByaYTIGy8UKAPicpv7D/8etllzEIkz/tnpo/uWFU4aPBJOvwJQnLNLxyZy49rXTSxeWXNqoAxHQNQ6jjM8l53P/9NZwgdCUGTRhtLRBXSoPteuQRpXkF3PDswc8j6vhPMZwy5Io+8ueMuYKVK1daBs0Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296096; c=relaxed/simple; bh=19QRp8pmfybXhHBqsoDecHbauX0izFZsN1jG6ieq5ZE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GX8D03HREcEoBs1a5TzAN++0uOpoODFabqWRlGap9CGosVNkA8xg97jMjSDINlGFRwC2igpxXPd7rlKFOKspDtOUVCVHvXsdS5V3QEmdthz/TOanjv8RJoecySVOa7QszgBhTE1rKyZ12Ke7Jm0deo4vXVDxYax7P3zwyUqDhuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k31k3Pag; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k31k3Pag" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5D50EC433F1; Wed, 13 Mar 2024 02:14:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296096; bh=19QRp8pmfybXhHBqsoDecHbauX0izFZsN1jG6ieq5ZE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=k31k3PagPwCqTGU7eeHWNspLY2Rk/NKrKHdX+ZUhwUTpwvInb4oBbboaqbWfyWtpb buEnqE9mVtGNGynJ0+/UdWYWqHCdecDXrqfw2WUSxLGkEv5x7fQvrBGA5J3xDF0tSG UuH8d+8giuCCvDhB3ebjk0aTDTNAeOjVJiiQiurZYMH+0hBRq0CL+sA3Ia4vt4BTFB xWsFIlVas8s8sgWxc68+5JgZEDVz0e/kMZSI3fHn3FtKbVMiu2Yyybeu0aYlf36pSE v+EbqRv2qV+7t6gu1o6+FZJf6lVmqBOsGMLP3ksdvprWESnL7HkTOuGYyLcGHjCZwl e2vBvYDqO+ouA== Date: Tue, 12 Mar 2024 19:14:55 -0700 Subject: [PATCH 1/8] xfs_db: add a bmbt inflation command From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Message-ID: <171029434743.2065824.10519572186358226724.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add a command to xfs_db to clone a data fork mapping over and over again. This will make it easier to exercise really high sharing counts. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- db/Makefile | 65 +++++- db/bmap_inflate.c | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++ db/command.c | 1 db/command.h | 1 man/man8/xfs_db.8 | 23 ++ 5 files changed, 646 insertions(+), 8 deletions(-) create mode 100644 db/bmap_inflate.c diff --git a/db/Makefile b/db/Makefile index d00801ab4739..83389376c36c 100644 --- a/db/Makefile +++ b/db/Makefile @@ -7,14 +7,63 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_db -HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ - btblock.h bmroot.h check.h command.h crc.h debug.h \ - dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ - flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ - io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \ - sig.h strvec.h text.h type.h write.h attrset.h symlink.h fsmap.h \ - fuzz.h obfuscate.h -CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c iunlink.c namei.c \ +HFILES = \ + addr.h \ + agf.h \ + agfl.h \ + agi.h \ + attr.h \ + attrset.h \ + attrshort.h \ + bit.h \ + block.h \ + bmap.h \ + bmroot.h \ + btblock.h \ + check.h \ + command.h \ + crc.h \ + debug.h \ + dir2.h \ + dir2sf.h \ + dquot.h \ + echo.h \ + faddr.h \ + field.h \ + flist.h \ + fprint.h \ + frag.h \ + freesp.h \ + fsmap.h \ + fuzz.h \ + hash.h \ + help.h \ + init.h \ + inode.h \ + input.h \ + io.h \ + logformat.h \ + malloc.h \ + metadump.h \ + obfuscate.h \ + output.h \ + print.h \ + quit.h \ + sb.h \ + sig.h \ + strvec.h \ + symlink.h \ + text.h \ + type.h \ + write.h +CFILES = $(HFILES:.h=.c) \ + bmap_inflate.c \ + btdump.c \ + btheight.c \ + convert.c \ + info.c \ + iunlink.c \ + namei.c \ timelimit.c LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh diff --git a/db/bmap_inflate.c b/db/bmap_inflate.c new file mode 100644 index 000000000000..a3ad6ad38323 --- /dev/null +++ b/db/bmap_inflate.c @@ -0,0 +1,564 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#include "libxfs.h" +#include "command.h" +#include "init.h" +#include "output.h" +#include "io.h" +#include "libfrog/convert.h" + +static void +bmapinflate_help(void) +{ + dbprintf(_( +"\n" +" Make the bmbt really big by cloning the first data fork mapping over and over.\n" +" -d Constrain dirty buffers to this many bytes.\n" +" -e Print the size and height of the btree and exit.\n" +" -n nr Create this many copies of the mapping.\n" +"\n" +)); + +} + +static int +find_mapping( + struct xfs_trans *tp, + struct xfs_inode *ip, + struct xfs_bmbt_irec *irec) +{ + struct xfs_iext_cursor icur; + int error; + + if (!xfs_has_reflink(ip->i_mount)) { + dbprintf(_("filesystem does not support reflink\n")); + return 1; + } + + if (ip->i_df.if_nextents != 1) { + dbprintf(_("inode must have only one data fork mapping\n")); + return 1; + } + + error = -libxfs_iread_extents(tp, ip, XFS_DATA_FORK); + if (error) { + dbprintf(_("could not read data fork, err %d\n"), error); + return 1; + } + + libxfs_iext_first(&ip->i_df, &icur); + if (!xfs_iext_get_extent(&ip->i_df, &icur, irec)) { + dbprintf(_("could not read data fork mapping\n")); + return 1; + } + + if (irec->br_state != XFS_EXT_NORM) { + dbprintf(_("cannot duplicate unwritten extent\n")); + return 1; + } + + return 0; +} + +static int +set_nrext64( + struct xfs_trans *tp, + struct xfs_inode *ip, + xfs_extnum_t nextents) +{ + xfs_extnum_t max_extents; + bool large_extcount; + + large_extcount = xfs_inode_has_large_extent_counts(ip); + max_extents = xfs_iext_max_nextents(large_extcount, XFS_DATA_FORK); + if (nextents <= max_extents) + return 0; + if (large_extcount) + return EFSCORRUPTED; + if (!xfs_has_large_extent_counts(ip->i_mount)) + return EFSCORRUPTED; + + max_extents = xfs_iext_max_nextents(true, XFS_DATA_FORK); + if (nextents > max_extents) + return EFSCORRUPTED; + + ip->i_diflags2 |= XFS_DIFLAG2_NREXT64; + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + return 0; +} + +static int +populate_extents( + struct xfs_trans *tp, + struct xfs_inode *ip, + struct xbtree_ifakeroot *ifake, + const struct xfs_bmbt_irec *template, + xfs_extnum_t nextents) +{ + struct xfs_bmbt_irec irec = { + .br_startoff = 0, + .br_startblock = template->br_startblock, + .br_blockcount = template->br_blockcount, + .br_state = XFS_EXT_NORM, + }; + struct xfs_iext_cursor icur; + struct xfs_ifork *ifp = ifake->if_fork; + unsigned long long i; + + /* Add all the mappings to the incore extent tree. */ + libxfs_iext_first(ifp, &icur); + for (i = 0; i < nextents; i++) { + libxfs_iext_insert_raw(ifp, &icur, &irec); + ifp->if_nextents++; + libxfs_iext_next(ifp, &icur); + +#ifdef BORK + dbprintf(_("[%llu] 0x%lx 0x%lx 0x%lx\n"), i, irec.br_startoff, + irec.br_startblock, + irec.br_blockcount); +#endif + + irec.br_startoff += irec.br_blockcount; + } + + ip->i_nblocks = template->br_blockcount * nextents; + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + return 0; +} + +struct bmbt_resv { + struct list_head list; + xfs_fsblock_t fsbno; + xfs_extlen_t len; + xfs_extlen_t used; +}; + +struct bmbt_data { + struct xfs_bmbt_irec irec; + struct list_head resv_list; + unsigned long long iblocks; + unsigned long long nr; +}; + +static int +alloc_bmbt_blocks( + struct xfs_trans **tpp, + struct xfs_inode *ip, + struct bmbt_data *bd, + uint64_t nr_blocks) +{ + struct xfs_mount *mp = ip->i_mount; + struct list_head *resv_list = &bd->resv_list; + int error = 0; + + while (nr_blocks > 0) { + struct xfs_alloc_arg args = { + .tp = *tpp, + .mp = mp, + .minlen = 1, + .maxlen = nr_blocks, + .prod = 1, + .resv = XFS_AG_RESV_NONE, + }; + struct bmbt_resv *resv; + xfs_fsblock_t target = 0; + + if (xfs_has_rmapbt(mp)) { + xfs_agnumber_t tgt_agno; + + /* + * Try to allocate bmbt blocks in a different AG so + * that we don't blow up the rmapbt with the bmbt + * records. + */ + tgt_agno = 1 + XFS_FSB_TO_AGNO(mp, + bd->irec.br_startblock); + if (tgt_agno >= mp->m_sb.sb_agcount) + tgt_agno = 0; + target = XFS_AGB_TO_FSB(mp, tgt_agno, 0); + } + + libxfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, + XFS_DATA_FORK); + + error = -libxfs_alloc_vextent_start_ag(&args, target); + if (error) + return error; + if (args.fsbno == NULLFSBLOCK) + return ENOSPC; + + resv = kmalloc(sizeof(struct bmbt_resv), 0); + if (!resv) + return ENOMEM; + + INIT_LIST_HEAD(&resv->list); + resv->fsbno = args.fsbno; + resv->len = args.len; + resv->used = 0; + list_add_tail(&resv->list, resv_list); + + nr_blocks -= args.len; + + error = -libxfs_trans_roll_inode(tpp, ip); + if (error) + return error; + } + + return 0; +} + +static int +get_bmbt_records( + struct xfs_btree_cur *cur, + unsigned int idx, + struct xfs_btree_block *block, + unsigned int nr_wanted, + void *priv) +{ + struct xfs_bmbt_irec *irec = &cur->bc_rec.b; + struct bmbt_data *bd = priv; + union xfs_btree_rec *block_rec; + struct xfs_ifork *ifp = cur->bc_ino.ifake->if_fork; + unsigned int loaded; + + for (loaded = 0; loaded < nr_wanted; loaded++, idx++) { + memcpy(irec, &bd->irec, sizeof(struct xfs_bmbt_irec)); + + block_rec = libxfs_btree_rec_addr(cur, idx, block); + cur->bc_ops->init_rec_from_cur(cur, block_rec); + ifp->if_nextents++; + +#ifdef BORK + dbprintf(_("[%llu] 0x%lx 0x%lx 0x%lx\n"), bd->nr++, + irec->br_startoff, + irec->br_startblock, + irec->br_blockcount); +#endif + + bd->irec.br_startoff += bd->irec.br_blockcount; + } + + return loaded; +} + +static int +claim_block( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + void *priv) +{ + struct bmbt_data *bd = priv; + struct bmbt_resv *resv; + xfs_fsblock_t fsb; + + /* + * The first item in the list should always have a free block unless + * we're completely out. + */ + resv = list_first_entry(&bd->resv_list, struct bmbt_resv, list); + if (resv->used == resv->len) + return ENOSPC; + + fsb = resv->fsbno + resv->used; + resv->used++; + + /* If we used all the blocks in this reservation, move it to the end. */ + if (resv->used == resv->len) + list_move_tail(&resv->list, &bd->resv_list); + + ptr->l = cpu_to_be64(fsb); + bd->iblocks++; + return 0; +} + +static size_t +iroot_size( + struct xfs_btree_cur *cur, + unsigned int level, + unsigned int nr_this_level, + void *priv) +{ + return XFS_BMAP_BROOT_SPACE_CALC(cur->bc_mp, nr_this_level); +} + +static int +populate_btree( + struct xfs_trans **tpp, + struct xfs_inode *ip, + uint16_t dirty_blocks, + struct xbtree_ifakeroot *ifake, + struct xfs_btree_cur *bmap_cur, + const struct xfs_bmbt_irec *template, + xfs_extnum_t nextents) +{ + struct xfs_btree_bload bmap_bload = { + .get_records = get_bmbt_records, + .claim_block = claim_block, + .iroot_size = iroot_size, + .max_dirty = dirty_blocks, + .leaf_slack = 1, + .node_slack = 1, + }; + struct bmbt_data bd = { + .irec = { + .br_startoff = 0, + .br_startblock = template->br_startblock, + .br_blockcount = template->br_blockcount, + .br_state = XFS_EXT_NORM, + }, + .iblocks = 0, + }; + struct bmbt_resv *resv, *n; + int error; + + error = -libxfs_btree_bload_compute_geometry(bmap_cur, &bmap_bload, + nextents); + if (error) + return error; + + error = -libxfs_trans_reserve_more(*tpp, bmap_bload.nr_blocks, 0); + if (error) + return error; + + INIT_LIST_HEAD(&bd.resv_list); + error = alloc_bmbt_blocks(tpp, ip, &bd, bmap_bload.nr_blocks); + if (error) + return error; + + error = -libxfs_btree_bload(bmap_cur, &bmap_bload, &bd); + if (error) + goto out_resv_list; + + ip->i_nblocks = bd.iblocks + (template->br_blockcount * nextents); + libxfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); + +out_resv_list: + /* Leak any unused blocks */ + list_for_each_entry_safe(resv, n, &bd.resv_list, list) { + list_del(&resv->list); + kmem_free(resv); + } + return error; +} + +static int +build_new_datafork( + struct xfs_trans **tpp, + struct xfs_inode *ip, + uint16_t dirty_blocks, + const struct xfs_bmbt_irec *irec, + xfs_extnum_t nextents) +{ + struct xbtree_ifakeroot ifake; + struct xfs_btree_cur *bmap_cur; + int error; + + error = set_nrext64(*tpp, ip, nextents); + if (error) + return error; + + /* Set up staging for the new bmbt */ + ifake.if_fork = kmem_cache_zalloc(xfs_ifork_cache, 0); + ifake.if_fork_size = xfs_inode_fork_size(ip, XFS_DATA_FORK); + bmap_cur = libxfs_bmbt_stage_cursor(ip->i_mount, ip, &ifake); + + /* + * Figure out the size and format of the new fork, then fill it with + * the bmap record we want. + */ + if (nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) { + ifake.if_fork->if_format = XFS_DINODE_FMT_EXTENTS; + error = populate_extents(*tpp, ip, &ifake, irec, nextents); + } else { + ifake.if_fork->if_format = XFS_DINODE_FMT_BTREE; + error = populate_btree(tpp, ip, dirty_blocks, &ifake, bmap_cur, + irec, nextents); + } + if (error) { + libxfs_btree_del_cursor(bmap_cur, 0); + goto err_ifork; + } + + /* Install the new fork in the inode. */ + libxfs_bmbt_commit_staged_btree(bmap_cur, *tpp, XFS_DATA_FORK); + libxfs_btree_del_cursor(bmap_cur, 0); + + /* Mark filesystem as needsrepair */ + dbprintf(_("filesystem is now inconsistent, xfs_repair required!\n")); + mp->m_sb.sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR; + libxfs_log_sb(*tpp); + +err_ifork: + kmem_cache_free(xfs_ifork_cache, ifake.if_fork); + return error; +} + +static int +estimate_size( + struct xfs_inode *ip, + unsigned long long dirty_blocks, + xfs_extnum_t nextents) +{ + struct xfs_btree_bload bmap_bload = { + .leaf_slack = 1, + .node_slack = 1, + }; + struct xbtree_ifakeroot ifake; + struct xfs_btree_cur *bmap_cur; + int error; + + /* FMT_EXTENTS means we report zero btblocks and zero height */ + if (nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) + goto report; + + ifake.if_fork = kmem_cache_zalloc(xfs_ifork_cache, 0); + ifake.if_fork_size = xfs_inode_fork_size(ip, XFS_DATA_FORK); + + bmap_cur = libxfs_bmbt_stage_cursor(ip->i_mount, ip, &ifake); + error = -libxfs_btree_bload_compute_geometry(bmap_cur, &bmap_bload, + nextents); + libxfs_btree_del_cursor(bmap_cur, error); + + kmem_cache_free(xfs_ifork_cache, ifake.if_fork); + + if (error) + return error; + +report: + dbprintf(_("ino 0x%llx nextents %llu btblocks %llu btheight %u dirty %u\n"), + ip->i_ino, nextents, bmap_bload.nr_blocks, + bmap_bload.btree_height, dirty_blocks); + + return 0; +} + +static int +bmapinflate_f( + int argc, + char **argv) +{ + struct xfs_bmbt_irec irec; + struct xfs_inode *ip; + struct xfs_trans *tp; + char *p; + unsigned long long nextents = 0; + unsigned long long dirty_bytes = 60U << 20; /* 60MiB */ + unsigned long long dirty_blocks; + unsigned int resblks; + bool estimate = false; + int c, error; + + if (iocur_top->ino == NULLFSINO) { + dbprintf(_("no current inode\n")); + return 0; + } + + optind = 0; + while ((c = getopt(argc, argv, "d:en:")) != EOF) { + switch (c) { + case 'e': + estimate = true; + break; + case 'n': + errno = 0; + nextents = strtoull(optarg, &p, 0); + if (errno) { + perror(optarg); + return 1; + } + break; + case 'd': + errno = 0; + dirty_bytes = cvtnum(mp->m_sb.sb_blocksize, + mp->m_sb.sb_sectsize, optarg); + if (errno) { + perror(optarg); + return 1; + } + break; + default: + dbprintf(_("bad option for bmap command\n")); + return 0; + } + } + + dirty_blocks = XFS_B_TO_FSBT(mp, dirty_bytes); + if (dirty_blocks >= UINT16_MAX) + dirty_blocks = UINT16_MAX - 1; + + error = -libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip); + if (error) { + dbprintf(_("could not grab inode 0x%llx, err %d\n"), + iocur_top->ino, error); + return 1; + } + + error = estimate_size(ip, dirty_blocks, nextents); + if (error) + goto out_irele; + if (estimate) + goto done; + + resblks = libxfs_bmbt_calc_size(mp, nextents); + error = -libxfs_trans_alloc_inode(ip, &M_RES(mp)->tr_itruncate, + resblks, 0, false, &tp); + if (error) { + dbprintf(_("could not allocate transaction, err %d\n"), + error); + return 1; + } + + error = find_mapping(tp, ip, &irec); + if (error) + goto out_cancel; + + error = build_new_datafork(&tp, ip, dirty_blocks, &irec, nextents); + if (error) { + dbprintf(_("could not build new data fork, err %d\n"), + error); + exitcode = 1; + goto out_cancel; + } + + error = -libxfs_trans_commit(tp); + if (error) { + dbprintf(_("could not commit transaction, err %d\n"), + error); + exitcode = 1; + return 1; + } + +done: + libxfs_irele(ip); + return 0; + +out_cancel: + libxfs_trans_cancel(tp); +out_irele: + libxfs_irele(ip); + return 1; +} + +static const struct cmdinfo bmapinflate_cmd = { + .name = "bmapinflate", + .cfunc = bmapinflate_f, + .argmin = 0, + .argmax = -1, + .canpush = 0, + .args = N_("[-n copies] [-e] [-d maxdirty]"), + .oneline = N_("inflate bmbt by copying mappings"), + .help = bmapinflate_help, +}; + +void +bmapinflate_init(void) +{ + if (!expert_mode) + return; + + add_command(&bmapinflate_cmd); +} diff --git a/db/command.c b/db/command.c index 2bbd7b0b24f9..6cda03e9856d 100644 --- a/db/command.c +++ b/db/command.c @@ -142,4 +142,5 @@ init_commands(void) fuzz_init(); timelimit_init(); iunlink_init(); + bmapinflate_init(); } diff --git a/db/command.h b/db/command.h index a89e71504f9c..2c2926afd7b5 100644 --- a/db/command.h +++ b/db/command.h @@ -35,3 +35,4 @@ extern void btheight_init(void); extern void timelimit_init(void); extern void namei_init(void); extern void iunlink_init(void); +extern void bmapinflate_init(void); diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index f53ddd67d87c..a7f6d55ed8be 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -388,6 +388,29 @@ and options are used to select the attribute or data area of the inode, if neither option is given then both areas are shown. .TP +.BI "bmapinflate [\-d " dirty_bytes "] [-e] [\-n " nr "] +Duplicates the first data fork mapping this many times, as if the mapping had +been repeatedly reflinked. +This is an expert-mode command for exercising high-refcount filesystems only. +Existing data fork mappings will be forgotten and the refcount btree will not +be updated. +This command leaves at least the refcount btree and the inode inconsistent; +.B xfs_repair +must be run afterwards. +.RS 1.0i +.TP 0.4i +.B \-d +Constrain the memory consumption of new dirty btree blocks to this quantity. +Defaults to 60MiB. +.TP 0.4i +.B \-e +Estimate the number of blocks and height of the new data fork mapping +structure and exit without changing anything. +.TP 0.4i +.B \-n +Create this many copies of the first mapping. +.RE +.TP .B btdump [-a] [-i] If the cursor points to a btree node, dump the btree from that block downward. If instead the cursor points to an inode, dump the data fork block mapping btree if there is one. From patchwork Wed Mar 13 02:15:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590926 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33328BA37 for ; Wed, 13 Mar 2024 02:15:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296112; cv=none; b=McKmOl+r4w+oEVZbCpytH8gWUFBq3sCU2yCYclj7gsnK3ONKTLACv+tPQPwiN60AL14uiL4ZT+mtWyHq5tEzXvzE6JtB/1rFh/tolDeVpbx/TaBgYyT9We4gQ7DkxtebZiKLdqKSoN9W/AUoBcSNmV/Bb4k8jwnAh3LTczzY638= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296112; c=relaxed/simple; bh=I3cRPGUpsKHYuooW8QWXBAj2XrnJSTEHnQEf/c7PT6E=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IIFPyf0Onj+x0SSnlyr9BtqXkj7SPwEx+JRpKRrWjXVblmghxatbQpG8jRyrYA7zaOm6PbGqxPMmZM5URnAWwlcaWOL9mDURGRMZXnU44KEAn815JwuQ7mG14RYp1mRikzzbDtPFl1S8SrtW/LxHVzltw9kEtPui+CO81rmxEis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Txn5RvJ3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Txn5RvJ3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10A5BC433F1; Wed, 13 Mar 2024 02:15:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296112; bh=I3cRPGUpsKHYuooW8QWXBAj2XrnJSTEHnQEf/c7PT6E=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Txn5RvJ3AQWLItbaGyFMY3b+0HP59VuB16mMIVWZWL+PT7y6gJ46zGChJ8yhva3Os 1dmRR4rGcPri7UK9dj0h8dHMfu/dY6d5SDSLpZJ2mjMQN04Tn+8m4TIkdt3SDRLFqk Oj/RyMbdcy04dCTUr+Xk+dDAzpHDQkd8ECuaa1LFYMLW+0XT+CafTf/TsLw1l6T4l+ d34aFofl7PcivSFPqu0MMMgHhma+8FBBRMNaR8VS4Gp11dwg7ICc/8IyZuJXrJ9CWI HpnJ6QGAFR9DEgdOXKZG4cCJtd1z1OkZrEjXzTARVGnUFaMy3lneb5wEG+gUJ5nAOf 2LXx1srfSaNZA== Date: Tue, 12 Mar 2024 19:15:11 -0700 Subject: [PATCH 2/8] xfs_repair: slab and bag structs need to track more than 2^32 items From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: "Darrick J. Wong" , linux-xfs@vger.kernel.org Message-ID: <171029434757.2065824.2289397432209492810.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Currently, the xfs_slab data structure in xfs_repair is used to stage incore reverse mapping and reference count records to build the ondisk rmapbt and refcountbt during phase 5. On a reflink filesystem, it's possible for there to be more than 2^32 forward mappings in an AG, which means that there could be more than 2^32 rmapbt records too. Widen the size_t fields of xfs_slab to u64 accomodate this. Similarly, the xfs_bag structure holds pointers to xfs_slab objects. This abstraction tracks rmapbt records as we walk through the AG space building refcount records. It's possible for there to be more than 2^32 mappings to a piece of physical space, so we need to side the size_t fields of xfs_bag to u64 as well. In the next patch we'll fix all the users of these two structures; this is merely the preparatory patch. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/slab.c | 36 ++++++++++++++++++------------------ repair/slab.h | 36 +++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/repair/slab.c b/repair/slab.c index 165f97efd29d..01bc4d426fea 100644 --- a/repair/slab.c +++ b/repair/slab.c @@ -41,18 +41,18 @@ /* and cannot be larger than 128M */ #define MAX_SLAB_SIZE (128 * 1048576) struct xfs_slab_hdr { - size_t sh_nr; - size_t sh_inuse; /* items in use */ + uint32_t sh_nr; + uint32_t sh_inuse; /* items in use */ struct xfs_slab_hdr *sh_next; /* next slab hdr */ /* objects follow */ }; struct xfs_slab { - size_t s_item_sz; /* item size */ - size_t s_nr_slabs; /* # of slabs */ - size_t s_nr_items; /* # of items */ + uint64_t s_nr_slabs; /* # of slabs */ + uint64_t s_nr_items; /* # of items */ struct xfs_slab_hdr *s_first; /* first slab header */ struct xfs_slab_hdr *s_last; /* last sh_next pointer */ + size_t s_item_sz; /* item size */ }; /* @@ -64,13 +64,13 @@ struct xfs_slab { */ struct xfs_slab_hdr_cursor { struct xfs_slab_hdr *hdr; /* a slab header */ - size_t loc; /* where we are in the slab */ + uint32_t loc; /* where we are in the slab */ }; typedef int (*xfs_slab_compare_fn)(const void *, const void *); struct xfs_slab_cursor { - size_t nr; /* # of per-slab cursors */ + uint64_t nr; /* # of per-slab cursors */ struct xfs_slab *slab; /* pointer to the slab */ struct xfs_slab_hdr_cursor *last_hcur; /* last header we took from */ xfs_slab_compare_fn compare_fn; /* compare items */ @@ -83,8 +83,8 @@ struct xfs_slab_cursor { */ #define MIN_BAG_SIZE 4096 struct xfs_bag { - size_t bg_nr; /* number of pointers */ - size_t bg_inuse; /* number of slots in use */ + uint64_t bg_nr; /* number of pointers */ + uint64_t bg_inuse; /* number of slots in use */ void **bg_ptrs; /* pointers */ }; #define BAG_END(bag) (&(bag)->bg_ptrs[(bag)->bg_nr]) @@ -137,7 +137,7 @@ static void * slab_ptr( struct xfs_slab *slab, struct xfs_slab_hdr *hdr, - size_t idx) + uint32_t idx) { char *p; @@ -155,12 +155,12 @@ slab_add( struct xfs_slab *slab, void *item) { - struct xfs_slab_hdr *hdr; + struct xfs_slab_hdr *hdr; void *p; hdr = slab->s_last; if (!hdr || hdr->sh_inuse == hdr->sh_nr) { - size_t n; + uint32_t n; n = (hdr ? hdr->sh_nr * 2 : MIN_SLAB_NR); if (n * slab->s_item_sz > MAX_SLAB_SIZE) @@ -308,7 +308,7 @@ peek_slab_cursor( struct xfs_slab_hdr_cursor *hcur; void *p = NULL; void *q; - size_t i; + uint64_t i; cur->last_hcur = NULL; @@ -370,7 +370,7 @@ pop_slab_cursor( /* * Return the number of items in the slab. */ -size_t +uint64_t slab_count( struct xfs_slab *slab) { @@ -429,7 +429,7 @@ bag_add( p = &bag->bg_ptrs[bag->bg_inuse]; if (p == BAG_END(bag)) { /* No free space, alloc more pointers */ - size_t nr; + uint64_t nr; nr = bag->bg_nr * 2; x = realloc(bag->bg_ptrs, nr * sizeof(void *)); @@ -450,7 +450,7 @@ bag_add( int bag_remove( struct xfs_bag *bag, - size_t nr) + uint64_t nr) { ASSERT(nr < bag->bg_inuse); memmove(&bag->bg_ptrs[nr], &bag->bg_ptrs[nr + 1], @@ -462,7 +462,7 @@ bag_remove( /* * Return the number of items in a bag. */ -size_t +uint64_t bag_count( struct xfs_bag *bag) { @@ -475,7 +475,7 @@ bag_count( void * bag_item( struct xfs_bag *bag, - size_t nr) + uint64_t nr) { if (nr >= bag->bg_inuse) return NULL; diff --git a/repair/slab.h b/repair/slab.h index aab46ecf1f08..077b45822149 100644 --- a/repair/slab.h +++ b/repair/slab.h @@ -9,29 +9,31 @@ struct xfs_slab; struct xfs_slab_cursor; -extern int init_slab(struct xfs_slab **, size_t); -extern void free_slab(struct xfs_slab **); +int init_slab(struct xfs_slab **slabp, size_t item_sz); +void free_slab(struct xfs_slab **slabp); -extern int slab_add(struct xfs_slab *, void *); -extern void qsort_slab(struct xfs_slab *, int (*)(const void *, const void *)); -extern size_t slab_count(struct xfs_slab *); +int slab_add(struct xfs_slab *slab, void *item); +void qsort_slab(struct xfs_slab *slab, + int (*compare)(const void *, const void *)); +uint64_t slab_count(struct xfs_slab *slab); -extern int init_slab_cursor(struct xfs_slab *, - int (*)(const void *, const void *), struct xfs_slab_cursor **); -extern void free_slab_cursor(struct xfs_slab_cursor **); +int init_slab_cursor(struct xfs_slab *slab, + int (*compare)(const void *, const void *), + struct xfs_slab_cursor **curp); +void free_slab_cursor(struct xfs_slab_cursor **curp); -extern void *peek_slab_cursor(struct xfs_slab_cursor *); -extern void advance_slab_cursor(struct xfs_slab_cursor *); -extern void *pop_slab_cursor(struct xfs_slab_cursor *); +void *peek_slab_cursor(struct xfs_slab_cursor *cur); +void advance_slab_cursor(struct xfs_slab_cursor *cur); +void *pop_slab_cursor(struct xfs_slab_cursor *cur); struct xfs_bag; -extern int init_bag(struct xfs_bag **); -extern void free_bag(struct xfs_bag **); -extern int bag_add(struct xfs_bag *, void *); -extern int bag_remove(struct xfs_bag *, size_t); -extern size_t bag_count(struct xfs_bag *); -extern void *bag_item(struct xfs_bag *, size_t); +int init_bag(struct xfs_bag **bagp); +void free_bag(struct xfs_bag **bagp); +int bag_add(struct xfs_bag *bag, void *item); +int bag_remove(struct xfs_bag *bag, uint64_t idx); +uint64_t bag_count(struct xfs_bag *bag); +void *bag_item(struct xfs_bag *bag, uint64_t idx); #define foreach_bag_ptr(bag, idx, ptr) \ for ((idx) = 0, (ptr) = bag_item((bag), (idx)); \ From patchwork Wed Mar 13 02:15:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590927 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA68A6FA7 for ; Wed, 13 Mar 2024 02:15:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296127; cv=none; b=Ide6kuqqZKd0/Pqtr5ttplCvPgLMRMFk38xB3YQ2f9CPxut2/dxwwAGgXqiW7Qk9aoLkxH4cMq6kqHcKJOYzvM+eB+ZzX6xt0qeLEZ38JgJ7x7lAILKu/BSRZo1dzeLe6kJQHqNcsVDJnXSDyHbR/iWQ1UenO2pQKGPQP6Q6sp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296127; c=relaxed/simple; bh=SBE4ioQgWWo/RyXxg/7CXpSstEJ+Dub2aw8GLWoGOIc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CuNy2dzkZmtIuTyzS8tRkEcL5B33ldNLDeucNjexvGq7hu2IDQz73hY7VNhGKljIUKwKc7iyVWUvvLnuE2yYOq0cX5epN+TeDoduUph6KeCmQjhJzqVUGUgiUOaJQsInb0jvLiEO9Nf0HY9CShiJ0UJyzjDDRhQMfC3WUN81bM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jWnmNtIl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jWnmNtIl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4A36C433F1; Wed, 13 Mar 2024 02:15:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296127; bh=SBE4ioQgWWo/RyXxg/7CXpSstEJ+Dub2aw8GLWoGOIc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=jWnmNtIlTWK8FImWLODeNLINdwKSIpAGV+4hN2LvGdK+CpdSRaC+IHIQk3rJ37a/h Ua2PltdqkCRE5RlbI7G1GNdGggKn+Bgs69GL0Nuo0eGVqxOQUwA+4CLbKhr8wJPXic yOXE5548AkxWsyuwhbywHJCPwYm85zLCY5oj3OF556VSmtLjffUCewNTulZ5NLqXwG vFZ5VvZ5ap437KshbUSHkGMTO/+cfIMJOmkmYnSeApt9fykmbZDXCrHRZt8TuyH5k8 zan/hgZxLAUKFlo2qzFW1A0j7QIN4m8rbPFOQmWEZlZuD1EQPYYOH3WENMA0AeYxPg K2o+npD4uytrw== Date: Tue, 12 Mar 2024 19:15:27 -0700 Subject: [PATCH 3/8] xfs_repair: support more than 2^32 rmapbt records per AG From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: "Darrick J. Wong" , linux-xfs@vger.kernel.org Message-ID: <171029434772.2065824.18696490895008470.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that the incore structures handle more than 2^32 records correctly, fix the rmapbt generation code to handle that many records. This fixes the problem where an extremely large rmapbt cannot be rebuilt properly because of integer truncation. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/rmap.c | 8 ++++---- repair/rmap.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/repair/rmap.c b/repair/rmap.c index a2291c7b3b01..c908429c9bf7 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -283,7 +283,7 @@ rmap_fold_raw_recs( { struct xfs_slab_cursor *cur = NULL; struct xfs_rmap_irec *prev, *rec; - size_t old_sz; + uint64_t old_sz; int error = 0; old_sz = slab_count(ag_rmaps[agno].ar_rmaps); @@ -690,7 +690,7 @@ mark_inode_rl( struct xfs_rmap_irec *rmap; struct ino_tree_node *irec; int off; - size_t idx; + uint64_t idx; xfs_agino_t ino; if (bag_count(rmaps) < 2) @@ -873,9 +873,9 @@ compute_refcounts( /* * Return the number of rmap objects for an AG. */ -size_t +uint64_t rmap_record_count( - struct xfs_mount *mp, + struct xfs_mount *mp, xfs_agnumber_t agno) { return slab_count(ag_rmaps[agno].ar_rmaps); diff --git a/repair/rmap.h b/repair/rmap.h index 1dad2f5890a4..b074e2e87860 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -26,7 +26,7 @@ extern bool rmaps_are_mergeable(struct xfs_rmap_irec *r1, struct xfs_rmap_irec * extern int rmap_add_fixed_ag_rec(struct xfs_mount *, xfs_agnumber_t); extern int rmap_store_ag_btree_rec(struct xfs_mount *, xfs_agnumber_t); -extern size_t rmap_record_count(struct xfs_mount *, xfs_agnumber_t); +uint64_t rmap_record_count(struct xfs_mount *mp, xfs_agnumber_t agno); extern int rmap_init_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void rmap_avoid_check(void); void rmaps_verify_btree(struct xfs_mount *mp, xfs_agnumber_t agno); From patchwork Wed Mar 13 02:15:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590928 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77E9B6FA7 for ; Wed, 13 Mar 2024 02:15:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296143; cv=none; b=nfushjllK64MNkHCN3EfXotE9I0GqRJYJaREi9+Wj7nAUYJrnOGNKgMAqj/e/ULsulk76osDXbWJnZf2hjuE2mEDMK44o24GLqJUZh0ImRQdoLCWNlt1Ntd+RGk84V4N+dGWWJIgPcAnnM1d2xRvmysh28RiVcHheGAED7Iz+eA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296143; c=relaxed/simple; bh=/axwi8OBLlDd8ynO4iSoDBHNGLVDxdzpK9cKMwvx6K8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Eh/2FPjK6z3f3W7XMrE+wl1mKeAikjJiKbw/uMOOTcFqVHjVRFATuTXZ0WNqt9f+6d66kPwqmLdSjtOzjVQSzZCgelTRhPpK79H7NKxHYRfgYdL1ojHjRYtZpwvLSKskVdk/kK8rLWgRfG8LwZIycPL0bgjuzYId6t+LNbYi1mE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lDHCEvDU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lDHCEvDU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4A289C433C7; Wed, 13 Mar 2024 02:15:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296143; bh=/axwi8OBLlDd8ynO4iSoDBHNGLVDxdzpK9cKMwvx6K8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=lDHCEvDUl5itJEaIlXtkbUKIYLYEEH3yHIjrVYXeksyxyNqCrMmjlqS6peTmgm/I4 v/T/c2Z6WwarydeuXhOwSYb+490kU62OX96+8+Z8AC3gBgvadWX26Rn4C7Hnj7vT5V gFy/rBfRFWZph924Bpc/w9WOx8mLa8Xggu78WfgqdSAAT6eF6+19W8v4qiIt9WlsL2 z28YXW1zMaLpMcXXUhvrwi0CAoLK5Dm67dqwRo8myPMsvtO7Nb2IPFQwArpR86J9im KZ0vqQc2GXX7eiAyhUqANsptFNEP0OoiQ32nzMwbOfCjy+kAmTRTPxlHRtGnSCl6vm J85oscJEuHDEA== Date: Tue, 12 Mar 2024 19:15:42 -0700 Subject: [PATCH 4/8] xfs_repair: support more than 2^32 owners per physical block From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: "Darrick J. Wong" , linux-xfs@vger.kernel.org Message-ID: <171029434786.2065824.14230923406122272720.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that the incore structures handle more than 2^32 records correctly, fix the refcountbt generation code to handle the case of that many rmap records pointing to a piece of space in an AG. This fixes the problem where the refcountbt cannot be rebuilt properly because of integer truncation if there are more than 4.3 billion owners of a piece of space. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/rmap.c | 18 +++++++++--------- repair/rmap.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/repair/rmap.c b/repair/rmap.c index c908429c9bf7..564e1cbf294e 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -713,14 +713,13 @@ mark_inode_rl( /* * Emit a refcount object for refcntbt reconstruction during phase 5. */ -#define REFCOUNT_CLAMP(nr) ((nr) > MAXREFCOUNT ? MAXREFCOUNT : (nr)) static void refcount_emit( - struct xfs_mount *mp, + struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, - size_t nr_rmaps) + uint64_t nr_rmaps) { struct xfs_refcount_irec rlrec; int error; @@ -733,7 +732,9 @@ refcount_emit( agno, agbno, len, nr_rmaps); rlrec.rc_startblock = agbno; rlrec.rc_blockcount = len; - rlrec.rc_refcount = REFCOUNT_CLAMP(nr_rmaps); + if (nr_rmaps > MAXREFCOUNT) + nr_rmaps = MAXREFCOUNT; + rlrec.rc_refcount = nr_rmaps; rlrec.rc_domain = XFS_REFC_DOMAIN_SHARED; error = slab_add(rlslab, &rlrec); @@ -741,7 +742,6 @@ refcount_emit( do_error( _("Insufficient memory while recreating refcount tree.")); } -#undef REFCOUNT_CLAMP /* * Transform a pile of physical block mapping observations into refcount data @@ -758,11 +758,11 @@ compute_refcounts( struct xfs_slab_cursor *rmaps_cur; struct xfs_rmap_irec *array_cur; struct xfs_rmap_irec *rmap; + uint64_t n, idx; + uint64_t old_stack_nr; xfs_agblock_t sbno; /* first bno of this rmap set */ xfs_agblock_t cbno; /* first bno of this refcount set */ xfs_agblock_t nbno; /* next bno where rmap set changes */ - size_t n, idx; - size_t old_stack_nr; int error; if (!xfs_has_reflink(mp)) @@ -1312,9 +1312,9 @@ _("Unable to fix reflink flag on inode %"PRIu64".\n"), /* * Return the number of refcount objects for an AG. */ -size_t +uint64_t refcount_record_count( - struct xfs_mount *mp, + struct xfs_mount *mp, xfs_agnumber_t agno) { return slab_count(ag_rmaps[agno].ar_refcount_items); diff --git a/repair/rmap.h b/repair/rmap.h index b074e2e87860..1bc8c127d0e5 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -37,7 +37,7 @@ extern void rmap_high_key_from_rec(struct xfs_rmap_irec *rec, struct xfs_rmap_irec *key); extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); -extern size_t refcount_record_count(struct xfs_mount *, xfs_agnumber_t); +uint64_t refcount_record_count(struct xfs_mount *mp, xfs_agnumber_t agno); extern int init_refcount_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void refcount_avoid_check(void); void check_refcounts(struct xfs_mount *mp, xfs_agnumber_t agno); From patchwork Wed Mar 13 02:15:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590929 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 212BBC13D for ; Wed, 13 Mar 2024 02:15:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296159; cv=none; b=VBTPGF+RVIQDU1A4y9gzZnoc8gLDrZhdxx35SZfLxJkkK6h0s5pbDi20kkjbazn6qfpkwMkR9EMzPKkg9WAmThQ+Drzbq2I9C1equEHm+U9Mh410X9jvm7TUI/fni9gp3PorbLPGCMXcbACuQ/0DVHv0MVozDQJtoSdgehKo1tM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296159; c=relaxed/simple; bh=ZnsI6GWbGchmRhLy6XBqBWnnFaLLHJfDgWNZErryit0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UhVGda/58XEpOeWMep18iWbZY5vSI578n6r0I03Yxuvn6KA9tCM0rDK0gXKeo3/pI3LAKRx1uFsRvev5faS3TxsGoacRASsaa+1+aSAsOKbm8N97GrT0A4oFN2gC35CVxt7y0w1oE+qf9gfsbq9etU9tRcW13xfTkteaKlRUKjc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Cbh0TU18; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Cbh0TU18" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE805C433F1; Wed, 13 Mar 2024 02:15:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296159; bh=ZnsI6GWbGchmRhLy6XBqBWnnFaLLHJfDgWNZErryit0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Cbh0TU18FPsYt2ZYm964wrYjbZ4vk4QJXxYEW1wEeYtXcoOlpa16OWoIsxABwaaDp 6kNDWpsf3rKbGaInVG/FQlKwgZdYCRVu4PFP9zPO3gERUBiyc9sTUVT/lzSASIzfW1 6ax0ADOb9jpU5x6zer82X6BNQWKaMn2GcjwhPT0jsbIT3dcTsnd1Ou1Qdxf8afOAk5 S8fqhFLoKz6qRfpBV/jUttQpdMZEmPdgjEic/oKFRQ8jBoPr692A1sLjtoXO51/udC fmWg61cmCZv8hvo0+YM8KThuyVPtuCpXrMLtUr3FjDhUAj7s6w/Sbnqs/YcGrxYqsa hhQNYrl2HPKcA== Date: Tue, 12 Mar 2024 19:15:58 -0700 Subject: [PATCH 5/8] xfs_repair: clean up lock resources From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: "Darrick J. Wong" , linux-xfs@vger.kernel.org Message-ID: <171029434801.2065824.8093618587875439562.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong When we free all the incore block mapping data, be sure to free the locks too. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/incore.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/repair/incore.c b/repair/incore.c index 2ed37a105ca7..06edaf0d6052 100644 --- a/repair/incore.c +++ b/repair/incore.c @@ -301,8 +301,17 @@ free_bmaps(xfs_mount_t *mp) { xfs_agnumber_t i; + pthread_mutex_destroy(&rt_lock.lock); + + for (i = 0; i < mp->m_sb.sb_agcount; i++) + pthread_mutex_destroy(&ag_locks[i].lock); + + free(ag_locks); + ag_locks = NULL; + for (i = 0; i < mp->m_sb.sb_agcount; i++) btree_destroy(ag_bmap[i]); + free(ag_bmap); ag_bmap = NULL; From patchwork Wed Mar 13 02:16:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590930 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3A65AD21 for ; Wed, 13 Mar 2024 02:16:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296174; cv=none; b=aBMsSoO09mVo3vF/FmpxMBIhUIh2ebcgeAB8ZeXJnnl+8jNXHUQfJzVFfc0PtSE3HY9oXtRiZDFcs7pYFDRL1RBPe5wx3Fb6CPwi1Nouws67PBlKaVPmkc4CWz9d0ifxYZk0TcW1fs9G35HjGythZiWhPw3KEyK7VEZB4NdFI9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296174; c=relaxed/simple; bh=W15nGSIuWd74hviyJHjc98vDvpHZV0616efXaXUCMM0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=F2oaVNVkanaQhe7MeEWPJ+9hasHsplQ0bZ8iZP/8V6df+beJbzMQ/KlVgSPWEUwQI7MKDOq8lsmlwDjMwECdWtWpMtBHloKL8mJyak9uQbIKtWPg83wZ71Pw/mJfiB3xG84lrID2m6vwBamAQvMU7AVmUxKsLAy+plKz9wh7fVY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F7iapB9y; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F7iapB9y" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88E81C43390; Wed, 13 Mar 2024 02:16:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296174; bh=W15nGSIuWd74hviyJHjc98vDvpHZV0616efXaXUCMM0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=F7iapB9ys8E71O7xuc+0e6+5RzAyJFKZoNS3jpVQ/Kz6m4E6IlmvQJX9hesPctDWw YPHZmO3FWfnIiGpj8PZCr8MPTiK010V5KPN7bdaiK8XUXIl8OuDz9rt4i5CNCRzCgg GrD8YOBIyTpvyFbmObV4eB9zBxljiGWkBdB41q2Hsz1cCz4F+qU1pfPtSawjezh/Oy njuvPP0Cg6UN3DybcAqq0Hr6qFnWMNFp+EC9+YzE9rniYzCPD+YTBhYLiZLq/x9zgC kuHoEesVXYm2w6cPdsSl7/cCQ2jnjcUuYY8z7mCILWZUy4gHECyDooN8JjcMC7FmbM EayMORZvgnLmA== Date: Tue, 12 Mar 2024 19:16:14 -0700 Subject: [PATCH 6/8] xfs_repair: constrain attr fork extent count From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Message-ID: <171029434815.2065824.10714570666464102685.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Don't let the attr fork extent count exceed the maximum possible value. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/dinode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/repair/dinode.c b/repair/dinode.c index b8f5bf4e550e..bf93a5790877 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2050,6 +2050,7 @@ process_inode_attr_fork( xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); struct xfs_dinode *dino = *dinop; struct blkmap *ablkmap = NULL; + xfs_extnum_t max_nex; int repair = 0; int err; int try_rebuild = -1; /* don't know yet */ @@ -2071,6 +2072,11 @@ process_inode_attr_fork( } *anextents = xfs_dfork_attr_extents(dino); + max_nex = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dino), + XFS_ATTR_FORK); + if (*anextents > max_nex) + *anextents = 1; if (*anextents > be64_to_cpu(dino->di_nblocks)) *anextents = 1; From patchwork Wed Mar 13 02:16:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590931 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D0EDBA39 for ; Wed, 13 Mar 2024 02:16:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296190; cv=none; b=fjmU5XVCLaI8+vLmCW7ZmGeBKAYNniYyjsHSvt6lnbullZMOc37ap8Vk4RimpGGdL8nEqBRwM2l7tpGIMd3aawjZ1/1bnlWFVYfaDHN2DTLlRQCGE1EYmbSx5TepSAiT+/NyNW1gXSe0wLnd5lOsVdPZ+N+8M/zPL/q3U876a1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296190; c=relaxed/simple; bh=cZSQZHTmg5gCKF1rmcvSgu+zjTn48l2ja2nWMx8zWlU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cqRpmgCh9/ltdN/0mzXHchuvppBUC16H4P4GTmQ0OZ1+PUrZCH2URrg2qcwLdPMukY7jh28AGvBLe3RoEPPf1k5RXf4S+pSlAl6u+VrskKHTV7y39z9sJt6evHWL46PLlDDwtNJGEv4KfPhLMaWmypudw9gBzuK+KxFY1qQNDXs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cOamjq6f; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cOamjq6f" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 226C3C433F1; Wed, 13 Mar 2024 02:16:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296190; bh=cZSQZHTmg5gCKF1rmcvSgu+zjTn48l2ja2nWMx8zWlU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=cOamjq6f9Yq/aHQIXaJmrOnrTWrE1++Om9ZrUrOPK1xcIJRVCn+RbdQS1k+PE3m6D cKZlrPNNxEc+k2+SW0RqDDGT9ybCbuHcQaYIWzhYtMwQ3YbnKgLhknlwfAbqMCXq/4 64QXRy0x8EKAjAMes17LkxJ8RBWdrhSNsBFyzRHpp2CxjygCGzqwdab6EZvqQAmWF0 k+VZXpJKmDoWKgpitA7hbh2RnYfluuXQToJ8k5/lNBBkJLeIW2iKxC3i+miKxKobjA wmvkQj34fCPvwHZzN9LbUePARkHh6NCMydY1vGpy/Bm/ePLrb6GO00PtX3ThSyCrti JbiLuItiU4qmw== Date: Tue, 12 Mar 2024 19:16:29 -0700 Subject: [PATCH 7/8] xfs_repair: don't create block maps for data files From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Message-ID: <171029434829.2065824.5706231368777334384.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Repair only queries inode block maps for inode forks that map filesystem metadata. IOWs, it only uses it for directories, quota files, symlinks, and extended attributes. It doesn't use it for regular files or realtime files, so exclude its use for these files to reduce processing times for heavily fragmented regular files. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/dinode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index bf93a5790877..9938bad1570b 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -1930,8 +1930,8 @@ process_inode_data_fork( if (*nextents > be64_to_cpu(dino->di_nblocks)) *nextents = 1; - - if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA) + if (dino->di_format != XFS_DINODE_FMT_LOCAL && + (type != XR_INO_RTDATA && type != XR_INO_DATA)) *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK); *nextents = 0; From patchwork Wed Mar 13 02:16:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13590932 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECD75C122 for ; Wed, 13 Mar 2024 02:16:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296206; cv=none; b=nnrLmMN9Ep6Lk4YiUMmpSmMja5vso7OwuE6cXF5Gh7mK6qodfefyFCBeiv4kHM54iQqKXl/E6h6S7HEQggiEapbKAN7rWI6Jsi8FMmrVfhBbVMUaShJUWkYlo+l8XTxy/u+a9B2hzhOzXRz7ytfIXkjXWwA2wY7TuLXw9CAM/Cg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710296206; c=relaxed/simple; bh=rYrseqeDpFGXRwOslZoV47VrGfTR590adjyWFx26bic=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hQnKc/cK8C1dpteCH9SXVVje6nPHMYgxzU7fCa/I3ro7SCQrKCtxuY9LZSjRYxneEcZRGmXmKVjju6rYSUkqMpziDe/HOsbvx/meFpE6atVC/UTxy3WUBrX7X7LF8pwYmsRJv/I8vEYTq8Y6TFytSOY67TgGup0GxygaChBv2t4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fvHkcjhR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fvHkcjhR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF720C433F1; Wed, 13 Mar 2024 02:16:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710296205; bh=rYrseqeDpFGXRwOslZoV47VrGfTR590adjyWFx26bic=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=fvHkcjhRIAAi2JFNUfmCGDQkypyBcVrLtAr6QqU8MigaspNn4RPciD/NwI4NWFh+W bRIvFGXhnkXFOJYqGfuJvKOAFJT8X3KzZCffxNFlYf7UBCB0ta4DceGvxkFZ3A1mA7 OT5JF15ZNDjPSWp8MyPKNzvQqJN0+9xPhMoKx20x2/zq1G00V1qzc9jltsd5/PJa4O Up5fSbZJaHtNYCpdGOoQwo0vFiE2HvM4uxVee7kTYnN149lKF+Obomo+VKAjBnj+av 4uLM3gVL69wEMC/wggW+uXx1f1mO6jKXwHVZjFUzvKjj8+xGH0Mhv9XCXYOjOifK66 STpldkiKMIOfA== Date: Tue, 12 Mar 2024 19:16:45 -0700 Subject: [PATCH 8/8] xfs_repair: support more than INT_MAX block maps From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Message-ID: <171029434843.2065824.16649539998389777667.stgit@frogsfrogsfrogs> In-Reply-To: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> References: <171029434718.2065824.435823109251685179.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that it's possible to have more than INT_MAX block mappings attached to a file fork, expand the counters used by this data structure so that it can support all possible block mappings. Note that in practice we're still never going to exceed 4 billion extents because the previous patch switched off the block mappings for regular files. This is still twice as much as memory as previous, but it's not totally unconstrained. Hopefully few people bloat the xattr structures that large. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- repair/bmap.c | 26 ++++++++++++++------------ repair/bmap.h | 9 ++++----- repair/dinode.c | 2 +- repair/dir2.c | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/repair/bmap.c b/repair/bmap.c index cd1a8b07b301..9ae28686107e 100644 --- a/repair/bmap.c +++ b/repair/bmap.c @@ -34,8 +34,9 @@ blkmap_alloc( if (nex < 1) nex = 1; + nex = min(nex, XFS_MAX_EXTCNT_DATA_FORK_LARGE); -#if (BITS_PER_LONG == 32) /* on 64-bit platforms this is never true */ +#ifdef BLKMAP_NEXTS_MAX if (nex > BLKMAP_NEXTS_MAX) { do_warn( _("Number of extents requested in blkmap_alloc (%llu) overflows 32 bits.\n" @@ -115,7 +116,7 @@ blkmap_get( xfs_fileoff_t o) { bmap_ext_t *ext = blkmap->exts; - int i; + xfs_extnum_t i; for (i = 0; i < blkmap->nexts; i++, ext++) { if (o >= ext->startoff && o < ext->startoff + ext->blockcount) @@ -137,7 +138,7 @@ blkmap_getn( { bmap_ext_t *bmp = NULL; bmap_ext_t *ext; - int i; + xfs_extnum_t i; int nex; if (nb == 1) { @@ -233,7 +234,7 @@ xfs_fileoff_t blkmap_next_off( blkmap_t *blkmap, xfs_fileoff_t o, - int *t) + xfs_extnum_t *t) { bmap_ext_t *ext; @@ -263,7 +264,7 @@ blkmap_grow( { pthread_key_t key = dblkmap_key; blkmap_t *new_blkmap; - int new_naexts; + xfs_extnum_t new_naexts; /* reduce the number of reallocations for large files */ if (blkmap->naexts < 1000) @@ -278,20 +279,21 @@ blkmap_grow( ASSERT(pthread_getspecific(key) == blkmap); } -#if (BITS_PER_LONG == 32) /* on 64-bit platforms this is never true */ +#ifdef BLKMAP_NEXTS_MAX if (new_naexts > BLKMAP_NEXTS_MAX) { do_error( - _("Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" + _("Number of extents requested in blkmap_grow (%llu) overflows 32 bits.\n" "You need a 64 bit system to repair this filesystem.\n"), - new_naexts); + (unsigned long long)new_naexts); return NULL; } #endif - if (new_naexts <= 0) { + if (new_naexts > XFS_MAX_EXTCNT_DATA_FORK_LARGE) { do_error( - _("Number of extents requested in blkmap_grow (%d) overflowed the\n" - "maximum number of supported extents (%d).\n"), - new_naexts, BLKMAP_NEXTS_MAX); + _("Number of extents requested in blkmap_grow (%llu) overflowed the\n" + "maximum number of supported extents (%llu).\n"), + (unsigned long long)new_naexts, + (unsigned long long)XFS_MAX_EXTCNT_DATA_FORK_LARGE); return NULL; } diff --git a/repair/bmap.h b/repair/bmap.h index 4b588df8c86f..3d6be94441c6 100644 --- a/repair/bmap.h +++ b/repair/bmap.h @@ -20,8 +20,8 @@ typedef struct bmap_ext { * Block map. */ typedef struct blkmap { - int naexts; - int nexts; + xfs_extnum_t naexts; + xfs_extnum_t nexts; bmap_ext_t exts[1]; } blkmap_t; @@ -37,8 +37,6 @@ typedef struct blkmap { */ #if BITS_PER_LONG == 32 #define BLKMAP_NEXTS_MAX ((INT_MAX / sizeof(bmap_ext_t)) - 1) -#else -#define BLKMAP_NEXTS_MAX INT_MAX #endif extern pthread_key_t dblkmap_key; @@ -56,6 +54,7 @@ int blkmap_getn(blkmap_t *blkmap, xfs_fileoff_t o, xfs_filblks_t nb, bmap_ext_t **bmpp, bmap_ext_t *bmpp_single); xfs_fileoff_t blkmap_last_off(blkmap_t *blkmap); -xfs_fileoff_t blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o, int *t); +xfs_fileoff_t blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o, + xfs_extnum_t *t); #endif /* _XFS_REPAIR_BMAP_H */ diff --git a/repair/dinode.c b/repair/dinode.c index 9938bad1570b..0bfbcba2b80b 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -1137,7 +1137,7 @@ process_quota_inode( xfs_dqid_t dqid; xfs_fileoff_t qbno; int i; - int t = 0; + xfs_extnum_t t = 0; int error; switch (ino_type) { diff --git a/repair/dir2.c b/repair/dir2.c index 022b61b885f6..e46ae9ae46f7 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -1327,7 +1327,7 @@ process_leaf_node_dir2( int i; xfs_fileoff_t ndbno; int nex; - int t; + xfs_extnum_t t; bmap_ext_t lbmp; int dirty = 0;