From patchwork Wed Apr 17 21:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633956 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 37C4169D3C for ; Wed, 17 Apr 2024 21:44: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=1713390285; cv=none; b=HIx/Xfqs1QTJo8TqFa58kcgxbPWF+WrBjxtXF5HlPIlk78Hy4qkzXSWZLAM/hea4RrP6L5TnIMFeXWrAtSfB246e89RqQ55kc/VhJe8NYKjAWiYNcY/4vESlIDmxAMiAvB5ODq/jSaUebxmXHuGw7JoRX2Z6H23gDbMeXfvAE2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390285; c=relaxed/simple; bh=ZGwRBpFzUE5SCzOBKrX1yLte3gU3tAsQ8D6CRAuvD+U=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VNin3fdYoRO1f8Ac3bsQpbK1AWphvJLM5R/ZQmFhpzypkhsV4tw6dD1k9QyKsBTYY4oh9aj8YVzmnglK72XHrAmz6DUx4Lm1ZVag/vW8gMuOrWC2HAWmPhgd20/IePBhIVaZmGDXNeP9njVr9aYSdX0UZes99495sJoVMX3noGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mkRmdeUW; 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="mkRmdeUW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08AE3C072AA; Wed, 17 Apr 2024 21:44:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390285; bh=ZGwRBpFzUE5SCzOBKrX1yLte3gU3tAsQ8D6CRAuvD+U=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=mkRmdeUWYHlVPwtYm5OWOVh+AxnXDjpOvC6t2nZbI/Cu+DbOmJZViRpO7n/Eq4hfi zqsPKq+/wzsezEa+mig+qJw9lWYicHD9UwHeDRWvF3zudCaEIUf/oiUxOlGt77ddAN lrbse5NC0tqrKxhkWcqq80Dm3w5abEj/mYBoOyslzzFDhbP3dkZOhKAu1p1cKMzyVD 2WZjmJvbrtsGkHM9N7LQ+c12urFIsgHcdAoTR3fs9LRsnQZL0/nU/9KP2ORRiLkF4y Tt2rfWOvX/7F1dbSVrrFcAl2/cc033adcaVvuihg4hmi7OqNAJ8rE0OXRcXWrQcP2F dESu/sAfS2Tzg== Date: Wed, 17 Apr 2024 14:44:44 -0700 Subject: [PATCH 1/8] xfs_db: add a bmbt inflation command From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845795.1856674.18346350417816337879.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 | 551 +++++++++++++++++++++++++++++++++++++++++++++++++++++ db/command.c | 1 db/command.h | 1 man/man8/xfs_db.8 | 23 ++ 5 files changed, 633 insertions(+), 8 deletions(-) create mode 100644 db/bmap_inflate.c diff --git a/db/Makefile b/db/Makefile index d00801ab4..83389376c 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 000000000..33b0c954d --- /dev/null +++ b/db/bmap_inflate.c @@ -0,0 +1,551 @@ +// 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); + + 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++; + + 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 2bbd7b0b2..6cda03e98 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 a89e71504..2c2926afd 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 f53ddd67d..a7f6d55ed 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 Apr 17 21:45:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633957 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 CBDF1171A1 for ; Wed, 17 Apr 2024 21:45:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390300; cv=none; b=aZBfuG+ERkOpqHwyW/6kK01LRNaeg0xyKKzD0Ofz/AJoev63x0zZyTEhfconCWzCPRNApV1B9Qejub9I7cCh7gzxVkX0Aw9PdOmQtPx27OHTjd6zvgoio4WgKsFwWzbK5xwTbywwXEuPWnL8Yw3Ik1HRKAkSCJ0ECT8x/PEtipE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390300; c=relaxed/simple; bh=Vp8ti0kuKfyEorao+46NuD5q8J4TILvzoQ9HXCqv+nk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=odzOimISCI0UmnrVLD6P9iay2706/OesPHbcR+sS0U4t2+ysUkj0KK/E/GWU2cVIhkr/b/+T1vdHeLMxdwZrU7E205iYcb6Vz6AGbpTorRe9MEfKggDvUqgEPuwXJgN0COha36L6Hwm+cgu0MqCHaxntYt9oY/WQP1qGUm6abZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bi3OTNAO; 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="bi3OTNAO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A27ABC072AA; Wed, 17 Apr 2024 21:45:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390300; bh=Vp8ti0kuKfyEorao+46NuD5q8J4TILvzoQ9HXCqv+nk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=bi3OTNAOCcAp83C9AdGsIzJ7QfCQEyPd2zOkDRsirN+6B5w7HlOdqYUYojcVVN4QA w418ZRfFjtMxKTC+tuvhMAbdNO16Q7vPgpvlq1smWvAOni6xLwNi7+wrF0yCLakxT/ VhfnaOtz/4N6SjvLEyV7MmNQux0rMDSh0enrHLt1BNRK/y9b5tCXz497GwaZbtoEpz pY+gW49ypK8CXwiETdmEJHhwoH1BT4GtDN7UyiN1QXGj0DJfN7FypTzskkuV7n4meu wfO1g+yZXtIbvAN/EZFASlAPC9P3OzjRIlySN2dHuzG18q8SMAKOSslqoihz3s+Ukb ArYh2dKmXPFVA== Date: Wed, 17 Apr 2024 14:45:00 -0700 Subject: [PATCH 2/8] xfs_repair: slab and bag structs need to track more than 2^32 items From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: "Darrick J. Wong" , Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845811.1856674.3595457479236993866.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 165f97efd..01bc4d426 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 aab46ecf1..077b45822 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 Apr 17 21:45:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633958 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 6850A171A1 for ; Wed, 17 Apr 2024 21:45:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390316; cv=none; b=IAC7KGjX8Oh9e+9eYnYSyISVXAtk+MhT/upcwKq6lYvFp3eJjDKEDNPFDRuo1DNNZ22Lm556MxWp9z9ri4RlksKT7UBLESY7FpYz+naG4FQOdFCkHn0o5zyIwUcHTV8YXjQzyu+jpEetubGw3mmRWYi9TGzQ6B25Dlt4HWu/7/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390316; c=relaxed/simple; bh=QMVv42qiJ2NwlcB6qgzJsrbI9AEkZpsNxdh4riLSfKg=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DlnFEcWi5Hkx/W/yDegl0IG5He6IvvC/kwGqM1Iytfl6yuLLcg+Xug/comZ1WFHwDvOV9ATBKAq86vHLE+ndduToKr/13em+eXPe9nyScB9ud1pYRq6LG1HrNIjPHsCUgPm131UVh/rz4RMXDYSpdRHY4NuMtA4ZDF5YgxX5QpA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DduXJud0; 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="DduXJud0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 42688C072AA; Wed, 17 Apr 2024 21:45:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390316; bh=QMVv42qiJ2NwlcB6qgzJsrbI9AEkZpsNxdh4riLSfKg=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=DduXJud0cZz0kXvS6CKT5RiDpt9B6Or1cHvFtOQVJall5nEaSwEJtE3Qd6CtYTooU dO4pMheIG6RMhbISAbyHFit4ebRPufSbBVY/1Ax9z7X1C4Yb5ZCnpexB/AbkQZ4IoV kwl+0R51YDRma/L5XchomJ5UWwpm+Q0qBuDQSbx/C6V20DSdy/U46Ta1gj9OHQsNpY VaES3XN7RXNv9XGWo5cZVghBTkSxxhQQlD+I9IX6hG0Z7WYm/YIMNKeXxoOfHdusam jX3McKi0qyGX+rscnMDUg79CcM5ghKCboNTq/6XXnpKk8LL9yOpD45cWWrqcgw0qZE bpG7pRXr5Ryqg== Date: Wed, 17 Apr 2024 14:45:15 -0700 Subject: [PATCH 3/8] xfs_repair: support more than 2^32 rmapbt records per AG From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: "Darrick J. Wong" , Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845826.1856674.2136380681034727010.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 a2291c7b3..c908429c9 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 1dad2f589..b074e2e87 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 Apr 17 21:45:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633959 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 531B1171A1 for ; Wed, 17 Apr 2024 21:45:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390332; cv=none; b=toFC5CynDMB9C7xUwYaJpwMG8aXpsCVRShI1kSTLGTiWrLz1ofsyZ6NUP8geOKjmToir59CuAVRbwB1+7RiHQiX7k61+8JBIBP8JCRQ3XXA2t12nmenwXTPSCQ88YQln8xs8G4csqUHIz0mdAUCcxwu00jAGCk2hke+ZAaom/AQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390332; c=relaxed/simple; bh=9dS1awVl7vN17Uy9uyjOppMj9xyLZaY11JeAWX8wmzw=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fNxTmriyC0jf5zMntFa6AbhTdy7F5YO95iLKRYuatv81622p2tfRjWKiZ1oaKrs7+VF7UkdFUAGpZNPjJjyb8hSUv+EYIR43P8LCvwF7q8gBIn07UpKp2+IeF0HrMci6Y8FDmYk2kcnxHfN5vB7GmQpPAlXIanoooVMKqN6MxAw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fyI13K6h; 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="fyI13K6h" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E9A97C072AA; Wed, 17 Apr 2024 21:45:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390332; bh=9dS1awVl7vN17Uy9uyjOppMj9xyLZaY11JeAWX8wmzw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=fyI13K6hHfUDJcKFFwCKDgm+eMoGbPtTkF5LU3tCNMCAzkQ8m1HaavEiFuoFe1O4h AXlHOoGMansGMkVtpBl3xc3I/naf1gUDzXkPezbZwAr9r7JFE3DzI3tl/1y1L4V/D2 JPAjcotdjm0IZUxASkxKZFkVd4K55kMrdSqsQkd78L6WdFbhSSWCMJ4YXr5mvlIC49 SulyludY3Ib4M/YFHIiTD4lgmdqlFbXO+BZSZzDakfnyBLRyZlgUBWce/j4+LqCxKM Nd/aERBO84gQ1nK/UpjntVIl3jweojwDtVYBIkVEdS0g9scr7kg0AWBJXt903WWQkr 4BoYOUy3Ce7Fg== Date: Wed, 17 Apr 2024 14:45:31 -0700 Subject: [PATCH 4/8] xfs_repair: support more than 2^32 owners per physical block From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: "Darrick J. Wong" , Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845840.1856674.17637883617247425261.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 | 17 ++++++++--------- repair/rmap.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/repair/rmap.c b/repair/rmap.c index c908429c9..032bf4942 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,8 @@ refcount_emit( agno, agbno, len, nr_rmaps); rlrec.rc_startblock = agbno; rlrec.rc_blockcount = len; - rlrec.rc_refcount = REFCOUNT_CLAMP(nr_rmaps); + nr_rmaps = min(nr_rmaps, MAXREFCOUNT); + rlrec.rc_refcount = nr_rmaps; rlrec.rc_domain = XFS_REFC_DOMAIN_SHARED; error = slab_add(rlslab, &rlrec); @@ -741,7 +741,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 +757,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 +1311,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 b074e2e87..1bc8c127d 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 Apr 17 21:45:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633960 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 B5FBE171A1 for ; Wed, 17 Apr 2024 21:45:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390347; cv=none; b=aHdivXfNuwPYAJawAhXksMDnVFY25EIJSkXn5R+7itSNEuLI6p1P+EJcqDW7ZsoVbSJsTr1GkbPt/ZQlIAy8ewQIIoTvdsrzIkjQhhpJ+mKz+MXMofpqLGKXA38vN7ZTccDERU9bqsPrL/wu7RI6m9SWN4Opagd8fm1Q66AmJho= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390347; c=relaxed/simple; bh=zAqHk8rp5caktCKS/cBKpDt+8LKlzgeud/DnJkv/ls8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hgueA9Ljzg3vv7ddFiA2JswjLiACfGago4U4dwfIopHW0bT8Gv7uqN7LpXMDiNYyvy0NmhAcvUrliXPw7awsO+ld2job7e0Ot3NeLE1acLpb3+pv1jmaL3w+5k1JCrm0p18418X96HusJ7d6VE+Ohc57gUL2OolERy8S5fDv16I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K3AaVEUU; 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="K3AaVEUU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8D665C072AA; Wed, 17 Apr 2024 21:45:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390347; bh=zAqHk8rp5caktCKS/cBKpDt+8LKlzgeud/DnJkv/ls8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=K3AaVEUU1mt4RJt6yg5O05uaZN4uZ5qIuiXTks0kE52ayIwLfQNNn721w2a0kxw6A FetWpq183Pam8uFTuukd+x2DCtyxgwr7+HGO/RziKFWtb3bXE3p1MjFvRUINMrU0+b KYOMvGCCyiC8hZqHDym1e/3+VpEHvn5dYV6OMJ4Bs8+Gh6xWpyt8nNCP+hsUzZJ8Ox 1Q0jsf0qkNkCTVTNsC7O1NZ3xHwNe0drW4qpTExHNP5VdwVCdoEpdVSp8O1gLmyXnI tcyYtVegCxtAvLwIfK230DkU9R7dg2EXrLs982Dy0XoO5pfM75nlC/UWBikoLamZTM NJr3i+LqlXMgQ== Date: Wed, 17 Apr 2024 14:45:47 -0700 Subject: [PATCH 5/8] xfs_repair: clean up lock resources From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: "Darrick J. Wong" , Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845855.1856674.16300821271746079157.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 2ed37a105..06edaf0d6 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 Apr 17 21:46:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633961 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 60E17171A1 for ; Wed, 17 Apr 2024 21:46:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390363; cv=none; b=O3HDC4unNDSpqf8fIbF23eiuxpvgRA5Kuu9pLwj7fpIKHvKArpZfbFY7bHMsezJaanVrEO+y5I8tN3sNg3XZU31k/3HQp0u3xzVUix+SOC4YtP6ndAIrtLd8B+6d/iOwWMl9IpZH/GZ03N+rEFU9aQljb0tEv3ygU3DP1DTJq+A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390363; c=relaxed/simple; bh=kgQr2r+IJ/XTgqyQXWOV4eNjZOZ0OLoL/pNAG+SoVQA=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nNYiVHeX2ZvfOIIB+0QuI69LalShXEJS3wXhldKGnLcNIi4Ge9FZRcq6vhW8r1YQQL7hr8ezRGrsZdoJfJkFQYMSCMv3RK+qIkGUXVfSqVMPJ/nxuN+jFj3BBOjqG3ycLvY02ryxTEUOF406d6h7eeDkxZdziZwl0nCOnN241Ho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fl8joxcw; 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="fl8joxcw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3D284C072AA; Wed, 17 Apr 2024 21:46:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390363; bh=kgQr2r+IJ/XTgqyQXWOV4eNjZOZ0OLoL/pNAG+SoVQA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=fl8joxcwqHkhF24mHwaY0GFMJFjy05e28AxgP+nAMXvzgwe6mmHzbRSBkl/QvAcSQ N70RFymlnu5nE5478bFnU/lOQBgb1rEBmg3kfMJX4Wxl1oAgxhbtD6KuzyFwMzME1A ULbs3/88FzfQkC8T3jeloyeYANAxwH4FtxMNxb84YQyXNM1Xy5GVEK2g2OWYQzdMgX pG90Ca1+t2cJAhV5/6VEC+O5cKfe5dLiRU+AvHr1tt7mdseEFpao23CIr5kbSFxR/e VFoEYydaQwNwjgGKNISKJgqvwDdm8mo681L0PXk37pS/+0kIqnsbXaf4rzJ2H7bfMu +VgEDuqWjBlTQ== Date: Wed, 17 Apr 2024 14:46:02 -0700 Subject: [PATCH 6/8] xfs_repair: constrain attr fork extent count From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845870.1856674.1799595037972812764.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 b8f5bf4e5..bf93a5790 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 Apr 17 21:46:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13633962 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 02896171A1 for ; Wed, 17 Apr 2024 21:46:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390379; cv=none; b=CrxJYO0CzN9WzCYzQhdnhLohiNIz0ToGcrbroQFybNESW1AF1TzV0OlL7vDMWkFhuyIXQ2D53V3aLrI4fKMeakeppO7BrRx6ohEj2kvHWgEVm+192zzmzCR+QpkIM6p/n9Pa7NDtAtSjRP5ZwXCVd21bZJ6o7d7ggCV5SmFwJvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390379; c=relaxed/simple; bh=nB73d/Rr7EyyWmy/GdhjOAfKf3ihw3Q4eAXZbo19YBk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gYaSNWWk3uDS/lLtleBdRfSBV4KfyFU3+bgcorZF2B0iOfXvAgs6glWNrP+oU91ibqXOAwAWNNxkKyLHtFMpRK1PIcwqbAXxMZPpuCWxOKzPkwfJwYx/JLXTZ1Z33T4cKiUu8XkVsBB/QVWJcH84RENB4jt7rNW3X4jrZp7iCqM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fh21mqwo; 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="fh21mqwo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA944C072AA; Wed, 17 Apr 2024 21:46:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390378; bh=nB73d/Rr7EyyWmy/GdhjOAfKf3ihw3Q4eAXZbo19YBk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=fh21mqwoi3+j3F8ZF27OekqCpEzf9rBxUtr3J7V1DF61CdxeirP/Bue0Uu0eSxeM1 Fv+3GkFVI8p/uyoLUyRGCmY2jAblYyuanwUV3EAhAcXgYiiZZtKImHKz3EWD6hA3Si 1vXA944uXNRMNx9p+uYrG6Vm0js+y6OeZyQ1jK5sp41zCWPx6RGMdj3r7R5SV7qAdt Folp7jakQKJrg64rlaAig8mreF574Kcu9KXYKoaNA6+3kyKWFATXXfleCEGgWKfSLJ vsdMgNIxPMWGbNIUPDxYRKbeZbchhbrhun5En2ZY2qjUWvABwH5EUI9cnzirJDyJ6A J9hszSYVBF4lg== Date: Wed, 17 Apr 2024 14:46:18 -0700 Subject: [PATCH 7/8] xfs_repair: don't create block maps for data files From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845885.1856674.12758541407573493199.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 realtime space metadata. 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 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index bf93a5790..94f5fdcb4 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -1930,8 +1930,14 @@ 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) + /* + * Repair doesn't care about the block maps for regular file data + * because it never tries to read data blocks. Only spend time on + * constructing a block map for directories, quota files, symlinks, + * and realtime space metadata. + */ + 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 Apr 17 21:46:34 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: 13633963 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 97AEA171A1 for ; Wed, 17 Apr 2024 21:46:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390394; cv=none; b=JejeIc1plv/U9waNDGCDjUdjQk4yEvjHfl4w2KtFHdp9OMWa7ooOJG7vlxCh0dxUGblW4jHuDMpbgekV7BOVuUnz9N7oyV0SfGPw0/nTgLifooy+ENVJknAdmsvKXK3LSxQ5rPyPxR+oRem3tp7T449JyS5DvpQytj7aG9kg7uE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713390394; c=relaxed/simple; bh=IkuUTzBPp4TL/+z0ECc8ZYZiuf2N+3ffodya7FYudBw=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mRlyef8Tc04EqjBZ+GZiDGPF+3AEfF9+qyhlKqJdjZLLnNzuWg8NU2Yy/ChqWheFpKpxNCDJ5uvSuRKweGNCPY7KvEcodlT3UMNWnEaVdyGj9/eRUfRmtbJrfpLW3xbOUup0Vc/IfY1V1Kdy539EwRquOgi9LJp3NHPTrhC4eXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Yr+0RZEz; 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="Yr+0RZEz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6BC43C072AA; Wed, 17 Apr 2024 21:46:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713390394; bh=IkuUTzBPp4TL/+z0ECc8ZYZiuf2N+3ffodya7FYudBw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Yr+0RZEzNyM374zu4G56C/tppRxEaVpjnKgX1Ue+FbMYOvUDd31qaVtlkEscKmIlb 71hgzf5iCgx6A0p3s8N+gvMKsAydbvByLcCM5ZB1ZYyaHexLEGjStaMw0Cl7XjMa1A V6TxAkAgUgqqmiveOcpvyGiQH5ZNmVPC5MLZE5cWarnggucBwSk+/9BQIDz8AGTEDH 4v42Kct3u7dtYNpXCsURrTEtyRsBRcmku+pZLYBHk9H3aY1ELDyJT7zvDZy4nwL/st 61Hz6zdnb9CUiW41SytyZePT1g9oI2SL8Fi/r9As8kffgMQ2xBvLtNsWAitYGeOc+r j/OrJvK8iDQUw== Date: Wed, 17 Apr 2024 14:46:34 -0700 Subject: [PATCH 8/8] xfs_repair: support more than INT_MAX block maps From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171338845900.1856674.8293398127672313074.stgit@frogsfrogsfrogs> In-Reply-To: <171338845773.1856674.2763970395218819820.stgit@frogsfrogsfrogs> References: <171338845773.1856674.2763970395218819820.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 | 23 ++++++++++++----------- repair/bmap.h | 7 ++++--- repair/dinode.c | 2 +- repair/dir2.c | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/repair/bmap.c b/repair/bmap.c index 7e32fff33..2b4f4fe98 100644 --- a/repair/bmap.c +++ b/repair/bmap.c @@ -43,6 +43,7 @@ blkmap_alloc( if (nex < 1) nex = 1; + nex = min(nex, XFS_MAX_EXTCNT_DATA_FORK_LARGE); if (sizeof(long) == 4 && nex > BLKMAP_NEXTS32_MAX) { do_warn( @@ -122,7 +123,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) @@ -144,7 +145,7 @@ blkmap_getn( { bmap_ext_t *bmp = NULL; bmap_ext_t *ext; - int i; + xfs_extnum_t i; int nex; if (nb == 1) { @@ -240,7 +241,7 @@ xfs_fileoff_t blkmap_next_off( blkmap_t *blkmap, xfs_fileoff_t o, - int *t) + xfs_extnum_t *t) { bmap_ext_t *ext; @@ -270,7 +271,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) @@ -287,18 +288,18 @@ blkmap_grow( if (sizeof(long) == 4 && new_naexts > BLKMAP_NEXTS32_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; } - 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 (%ld).\n"), - new_naexts, - sizeof(long) == 4 ? BLKMAP_NEXTS32_MAX : INT_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 df9602b31..7fa671ce8 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; @@ -43,6 +43,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 94f5fdcb4..9d2f71055 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 022b61b88..e46ae9ae4 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;