From c0efb51212065b91a76c4e56018e574c9d2a8725 Mon Sep 17 00:00:00 2001 From: Ferry Meng Date: Tue, 16 May 2023 21:30:50 +0800 Subject: [PATCH] xfsprogs: bug fix about mkfs.xfs & xfs_repair. backporting upstream patches to fix bugs. - xfs_repair: ignore empty xattr leaf blocks. - mkfs.xfs: cherry-pick some patches about bug fix. Signed-off-by: Ferry Meng --- ...factor-data-device-extent-validation.patch | 89 +++++++++++++ ...nternal-logs-bump-the-root-dir-inode.patch | 105 +++++++++++++++ ...-validation-of-l-size-against-maximu.patch | 91 +++++++++++++ ...0-mkfs-improve-log-extent-validation.patch | 72 +++++++++++ ...rnal-log-size-when-log-stripe-units-.patch | 107 ++++++++++++++++ ...ize-down-if-rounding-log-start-up-ca.patch | 46 +++++++ ...-terminate-getsubopt-arrays-properly.patch | 120 ++++++++++++++++++ ...epair-ignore-empty-xattr-leaf-blocks.patch | 56 ++++++++ xfsprogs.spec | 14 +- 9 files changed, 699 insertions(+), 1 deletion(-) create mode 100644 xfsprogs-5.11.0-xfs-refactor-data-device-extent-validation.patch create mode 100644 xfsprogs-5.18.0-mkfs-don-t-let-internal-logs-bump-the-root-dir-inode.patch create mode 100644 xfsprogs-5.18.0-mkfs-fix-missing-validation-of-l-size-against-maximu.patch create mode 100644 xfsprogs-5.18.0-mkfs-improve-log-extent-validation.patch create mode 100644 xfsprogs-5.18.0-mkfs-reduce-internal-log-size-when-log-stripe-units-.patch create mode 100644 xfsprogs-5.18.0-mkfs-round-log-size-down-if-rounding-log-start-up-ca.patch create mode 100644 xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch create mode 100644 xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch diff --git a/xfsprogs-5.11.0-xfs-refactor-data-device-extent-validation.patch b/xfsprogs-5.11.0-xfs-refactor-data-device-extent-validation.patch new file mode 100644 index 0000000..d350098 --- /dev/null +++ b/xfsprogs-5.11.0-xfs-refactor-data-device-extent-validation.patch @@ -0,0 +1,89 @@ +From 7e84359f60250be357ed15a1fa626b2e9e2e2dfd Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 7 Jan 2021 15:59:17 -0500 +Subject: [PATCH] xfs: refactor data device extent validation + +Source kernel commit: 67457eb0d225521a0e81327aef808cd0f9075880 + +Refactor all the open-coded validation of non-static data device extents +into a single helper. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Reviewed-by: Brian Foster +Signed-off-by: Eric Sandeen +Signed-off-by: Ferry Meng +--- + libxfs/xfs_bmap.c | 8 ++------ + libxfs/xfs_types.c | 23 +++++++++++++++++++++++ + libxfs/xfs_types.h | 2 ++ + 3 files changed, 27 insertions(+), 6 deletions(-) + +diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c +index e0ca8b05..b25e32d4 100644 +--- a/libxfs/xfs_bmap.c ++++ b/libxfs/xfs_bmap.c +@@ -6230,12 +6230,8 @@ xfs_bmap_validate_extent( + if (!xfs_verify_rtbno(mp, endfsb)) + return __this_address; + } else { +- if (!xfs_verify_fsbno(mp, irec->br_startblock)) +- return __this_address; +- if (!xfs_verify_fsbno(mp, endfsb)) +- return __this_address; +- if (XFS_FSB_TO_AGNO(mp, irec->br_startblock) != +- XFS_FSB_TO_AGNO(mp, endfsb)) ++ if (!xfs_verify_fsbext(mp, irec->br_startblock, ++ irec->br_blockcount)) + return __this_address; + } + if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK) +diff --git a/libxfs/xfs_types.c b/libxfs/xfs_types.c +index fa113727..3e6921e0 100644 +--- a/libxfs/xfs_types.c ++++ b/libxfs/xfs_types.c +@@ -61,6 +61,29 @@ xfs_verify_fsbno( + return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); + } + ++/* ++ * Verify that a data device extent is fully contained inside the filesystem, ++ * does not cross an AG boundary, and does not point at static metadata. ++ */ ++bool ++xfs_verify_fsbext( ++ struct xfs_mount *mp, ++ xfs_fsblock_t fsbno, ++ xfs_fsblock_t len) ++{ ++ if (fsbno + len <= fsbno) ++ return false; ++ ++ if (!xfs_verify_fsbno(mp, fsbno)) ++ return false; ++ ++ if (!xfs_verify_fsbno(mp, fsbno + len - 1)) ++ return false; ++ ++ return XFS_FSB_TO_AGNO(mp, fsbno) == ++ XFS_FSB_TO_AGNO(mp, fsbno + len - 1); ++} ++ + /* Calculate the first and last possible inode number in an AG. */ + void + xfs_agino_range( +diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h +index 397d9477..7feaaac2 100644 +--- a/libxfs/xfs_types.h ++++ b/libxfs/xfs_types.h +@@ -184,6 +184,8 @@ xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno); + bool xfs_verify_agbno(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno); + bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno); ++bool xfs_verify_fsbext(struct xfs_mount *mp, xfs_fsblock_t fsbno, ++ xfs_fsblock_t len); + + void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agino_t *first, xfs_agino_t *last); +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.18.0-mkfs-don-t-let-internal-logs-bump-the-root-dir-inode.patch b/xfsprogs-5.18.0-mkfs-don-t-let-internal-logs-bump-the-root-dir-inode.patch new file mode 100644 index 0000000..7725b60 --- /dev/null +++ b/xfsprogs-5.18.0-mkfs-don-t-let-internal-logs-bump-the-root-dir-inode.patch @@ -0,0 +1,105 @@ +From fd421160515ed875f8221e52dfebebf06c1c4659 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 11 Mar 2022 17:32:02 -0800 +Subject: [PATCH] mkfs: don't let internal logs bump the root dir inode chunk + to AG 1 + +Currently, we don't let an internal log consume every last block in an +AG. According to the comment, we're doing this to avoid tripping AGF +verifiers if freeblks==0, but on a modern filesystem this isn't +sufficient to avoid problems because we need to have enough space in the +AG to allocate an aligned root inode chunk, if it should be the case +that the log also ends up in AG 0: + +$ truncate -s 6366g /tmp/a ; mkfs.xfs -f /tmp/a -d agcount=3200 -l agnum=0 +meta-data=/tmp/a isize=512 agcount=3200, agsize=521503 blks + = sectsz=512 attr=2, projid32bit=1 + = crc=1 finobt=1, sparse=1, rmapbt=0 + = reflink=1 bigtime=0 inobtcount=0 +data = bsize=4096 blocks=1668808704, imaxpct=5 + = sunit=0 swidth=0 blks +naming =version 2 bsize=4096 ascii-ci=0, ftype=1 +log =internal log bsize=4096 blocks=521492, version=2 + = sectsz=512 sunit=0 blks, lazy-count=1 +realtime =none extsz=4096 blocks=0, rtextents=0 +mkfs.xfs: root inode created in AG 1, not AG 0 + +Therefore, modify the maximum internal log size calculation to constrain +the maximum internal log size so that the aligned inode chunk allocation +will always succeed. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Ferry Meng +Reviewed-by: Joseph Qi +--- + mkfs/xfs_mkfs.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index 64a19490..3c5b6f3c 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -3241,6 +3241,49 @@ validate_log_size(uint64_t logblocks, int blocklog, int min_logblocks) + } + } + ++static void ++adjust_ag0_internal_logblocks( ++ struct mkfs_params *cfg, ++ struct xfs_mount *mp, ++ int min_logblocks, ++ int *max_logblocks) ++{ ++ int backoff = 0; ++ int ichunk_blocks; ++ ++ /* ++ * mkfs will trip over the write verifiers if the log is allocated in ++ * AG 0 and consumes enough space that we cannot allocate a non-sparse ++ * inode chunk for the root directory. The inode allocator requires ++ * that the AG have enough free space for the chunk itself plus enough ++ * to fix up the freelist with aligned blocks if we need to fill the ++ * allocation from the AGFL. ++ */ ++ ichunk_blocks = XFS_INODES_PER_CHUNK * cfg->inodesize >> cfg->blocklog; ++ backoff = ichunk_blocks * 4; ++ ++ /* ++ * We try to align inode allocations to the data device stripe unit, ++ * so ensure there's enough space to perform an aligned allocation. ++ * The inode geometry structure isn't set up yet, so compute this by ++ * hand. ++ */ ++ backoff = max(backoff, cfg->dsunit * 2); ++ ++ *max_logblocks -= backoff; ++ ++ /* If the specified log size is too big, complain. */ ++ if (cli_opt_set(&lopts, L_SIZE) && cfg->logblocks > *max_logblocks) { ++ fprintf(stderr, ++_("internal log size %lld too large, must be less than %d\n"), ++ (long long)cfg->logblocks, ++ *max_logblocks); ++ usage(); ++ } ++ ++ cfg->logblocks = min(cfg->logblocks, *max_logblocks); ++} ++ + static void + calculate_log_size( + struct mkfs_params *cfg, +@@ -3364,6 +3407,10 @@ _("log ag number %lld too large, must be less than %lld\n"), + } else + cfg->logagno = (xfs_agnumber_t)(sbp->sb_agcount / 2); + ++ if (cfg->logagno == 0) ++ adjust_ag0_internal_logblocks(cfg, mp, min_logblocks, ++ &max_logblocks); ++ + cfg->logstart = XFS_AGB_TO_FSB(mp, cfg->logagno, + libxfs_prealloc_blocks(mp)); + +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.18.0-mkfs-fix-missing-validation-of-l-size-against-maximu.patch b/xfsprogs-5.18.0-mkfs-fix-missing-validation-of-l-size-against-maximu.patch new file mode 100644 index 0000000..b5ec33f --- /dev/null +++ b/xfsprogs-5.18.0-mkfs-fix-missing-validation-of-l-size-against-maximu.patch @@ -0,0 +1,91 @@ +From 5e779a76d0a627b4e8e7c897d8ee31d7699b2ce7 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 4 Apr 2022 11:29:34 -0700 +Subject: [PATCH] mkfs: fix missing validation of -l size against maximum + internal log size + +If a sysadmin specifies a log size explicitly, we don't actually check +that against the maximum internal log size that we compute for the +default log size computation. We're going to add more validation soon, +so refactor the max internal log blocks into a common variable and +add a check. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Ferry Meng +Reviewed-by: Joseph Qi +--- + mkfs/xfs_mkfs.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index 0581843f..8c94bdf8 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -3246,6 +3246,7 @@ calculate_log_size( + { + struct xfs_sb *sbp = &mp->m_sb; + int min_logblocks; ++ int max_logblocks; /* absolute max for this AG */ + struct xfs_mount mount; + + /* we need a temporary mount to calculate the minimum log size. */ +@@ -3285,6 +3286,18 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\ + return; + } + ++ /* ++ * Make sure the log fits wholly within an AG ++ * ++ * XXX: If agf->freeblks ends up as 0 because the log uses all ++ * the free space, it causes the kernel all sorts of problems ++ * with per-ag reservations. Right now just back it off one ++ * block, but there's a whole can of worms here that needs to be ++ * opened to decide what is the valid maximum size of a log in ++ * an AG. ++ */ ++ max_logblocks = libxfs_alloc_ag_max_usable(mp) - 1; ++ + /* internal log - if no size specified, calculate automatically */ + if (!cfg->logblocks) { + if (cfg->dblocks < GIGABYTES(1, cfg->blocklog)) { +@@ -3310,21 +3323,9 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\ + cfg->logblocks = cfg->logblocks >> cfg->blocklog; + } + +- /* Ensure the chosen size meets minimum log size requirements */ ++ /* Ensure the chosen size fits within log size requirements */ + cfg->logblocks = max(min_logblocks, cfg->logblocks); +- +- /* +- * Make sure the log fits wholly within an AG +- * +- * XXX: If agf->freeblks ends up as 0 because the log uses all +- * the free space, it causes the kernel all sorts of problems +- * with per-ag reservations. Right now just back it off one +- * block, but there's a whole can of worms here that needs to be +- * opened to decide what is the valid maximum size of a log in +- * an AG. +- */ +- cfg->logblocks = min(cfg->logblocks, +- libxfs_alloc_ag_max_usable(mp) - 1); ++ cfg->logblocks = min(cfg->logblocks, max_logblocks); + + /* and now clamp the size to the maximum supported size */ + cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS); +@@ -3332,6 +3333,13 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\ + cfg->logblocks = XFS_MAX_LOG_BYTES >> cfg->blocklog; + + validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks); ++ } else if (cfg->logblocks > max_logblocks) { ++ /* check specified log size */ ++ fprintf(stderr, ++_("internal log size %lld too large, must be less than %d\n"), ++ (long long)cfg->logblocks, ++ max_logblocks); ++ usage(); + } + + if (cfg->logblocks > sbp->sb_agblocks - libxfs_prealloc_blocks(mp)) { +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.18.0-mkfs-improve-log-extent-validation.patch b/xfsprogs-5.18.0-mkfs-improve-log-extent-validation.patch new file mode 100644 index 0000000..1adbbf4 --- /dev/null +++ b/xfsprogs-5.18.0-mkfs-improve-log-extent-validation.patch @@ -0,0 +1,72 @@ +From 7374106f0474657636ab061dd68cd6bacfdd2baf Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 14 Apr 2022 13:29:37 -0700 +Subject: [PATCH] mkfs: improve log extent validation + +Use the standard libxfs fsblock verifiers to check the start and end of +the internal log. The current code does not catch the case of a +(segmented) fsblock that is beyond agf_blocks but not so large to change +the agno part of the segmented fsblock. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Ferry Meng +--- + libxfs/libxfs_api_defs.h | 1 + + mkfs/xfs_mkfs.c | 10 ++++------ + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h +index 9492955d..a0cb756a 100644 +--- a/libxfs/libxfs_api_defs.h ++++ b/libxfs/libxfs_api_defs.h +@@ -195,6 +195,7 @@ + #define xfs_verify_agino libxfs_verify_agino + #define xfs_verify_cksum libxfs_verify_cksum + #define xfs_verify_dir_ino libxfs_verify_dir_ino ++#define xfs_verify_fsbext libxfs_verify_fsbext + #define xfs_verify_fsbno libxfs_verify_fsbno + #define xfs_verify_ino libxfs_verify_ino + #define xfs_verify_rtbno libxfs_verify_rtbno +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index 3c5b6f3c..370c0dcb 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -3189,15 +3189,13 @@ align_internal_log( + int sunit, + int max_logblocks) + { +- uint64_t logend; +- + /* round up log start if necessary */ + if ((cfg->logstart % sunit) != 0) + cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit; + + /* If our log start overlaps the next AG's metadata, fail. */ +- if (XFS_FSB_TO_AGBNO(mp, cfg->logstart) <= XFS_AGFL_BLOCK(mp)) { +- fprintf(stderr, ++ if (!libxfs_verify_fsbno(mp, cfg->logstart)) { ++ fprintf(stderr, + _("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n" + "within an allocation group.\n"), + (long long) cfg->logstart); +@@ -3208,8 +3206,7 @@ _("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n" + align_log_size(cfg, sunit, max_logblocks); + + /* check the aligned log still starts and ends in the same AG. */ +- logend = cfg->logstart + cfg->logblocks - 1; +- if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend)) { ++ if (!libxfs_verify_fsbext(mp, cfg->logstart, cfg->logblocks)) { + fprintf(stderr, + _("Due to stripe alignment, the internal log size (%lld) is too large.\n" + "Must fit within an allocation group.\n"), +@@ -3447,6 +3444,7 @@ start_superblock_setup( + sbp->sb_agblocks = (xfs_agblock_t)cfg->agsize; + sbp->sb_agblklog = (uint8_t)log2_roundup(cfg->agsize); + sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount; ++ sbp->sb_dblocks = (xfs_rfsblock_t)cfg->dblocks; + + sbp->sb_inodesize = (uint16_t)cfg->inodesize; + sbp->sb_inodelog = (uint8_t)cfg->inodelog; +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.18.0-mkfs-reduce-internal-log-size-when-log-stripe-units-.patch b/xfsprogs-5.18.0-mkfs-reduce-internal-log-size-when-log-stripe-units-.patch new file mode 100644 index 0000000..ade3b36 --- /dev/null +++ b/xfsprogs-5.18.0-mkfs-reduce-internal-log-size-when-log-stripe-units-.patch @@ -0,0 +1,107 @@ +From 4f977d3a3480dc301b72cf8c44861e4a3a5bd118 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 4 Apr 2022 10:10:24 -0700 +Subject: [PATCH] mkfs: reduce internal log size when log stripe units are in + play + +Currently, one can feed mkfs a combination of options like this: + +$ truncate -s 6366g /tmp/a ; mkfs.xfs -f /tmp/a -d agcount=3200 -d su=256k,sw=4 +meta-data=/tmp/a isize=512 agcount=3200, agsize=521536 blks + = sectsz=512 attr=2, projid32bit=1 + = crc=1 finobt=1, sparse=1, rmapbt=0 + = reflink=1 bigtime=0 inobtcount=0 +data = bsize=4096 blocks=1668808704, imaxpct=5 + = sunit=64 swidth=256 blks +naming =version 2 bsize=4096 ascii-ci=0, ftype=1 +log =internal log bsize=4096 blocks=521536, version=2 + = sectsz=512 sunit=64 blks, lazy-count=1 +realtime =none extsz=4096 blocks=0, rtextents=0 +Metadata corruption detected at 0x55e88052c6b6, xfs_agf block 0x1/0x200 +libxfs_bwrite: write verifier failed on xfs_agf bno 0x1/0x1 +mkfs.xfs: writing AG headers failed, err=117 + +The format fails because the internal log size sizing algorithm +specifies a log size of 521492 blocks to avoid taking all the space in +the AG, but align_log_size sees the stripe unit and rounds that up to +the next stripe unit, which is 521536 blocks. + +Fix this problem by rounding the log size down if rounding up would +result in a log that consumes more space in the AG than we allow. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Ferry Meng +--- + mkfs/xfs_mkfs.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index 8c94bdf8..64a19490 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -3151,9 +3151,10 @@ sb_set_features( + static void + align_log_size( + struct mkfs_params *cfg, +- int sunit) ++ int sunit, ++ int max_logblocks) + { +- uint64_t tmp_logblocks; ++ uint64_t tmp_logblocks; + + /* nothing to do if it's already aligned. */ + if ((cfg->logblocks % sunit) == 0) +@@ -3170,7 +3171,8 @@ _("log size %lld is not a multiple of the log stripe unit %d\n"), + + /* If the log is too large, round down instead of round up */ + if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) || +- ((tmp_logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES)) { ++ ((tmp_logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES) || ++ tmp_logblocks > max_logblocks) { + tmp_logblocks = (cfg->logblocks / sunit) * sunit; + } + cfg->logblocks = tmp_logblocks; +@@ -3184,7 +3186,8 @@ static void + align_internal_log( + struct mkfs_params *cfg, + struct xfs_mount *mp, +- int sunit) ++ int sunit, ++ int max_logblocks) + { + uint64_t logend; + +@@ -3202,7 +3205,7 @@ _("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n" + } + + /* round up/down the log size now */ +- align_log_size(cfg, sunit); ++ align_log_size(cfg, sunit, max_logblocks); + + /* check the aligned log still starts and ends in the same AG. */ + logend = cfg->logstart + cfg->logblocks - 1; +@@ -3280,7 +3283,7 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\ + cfg->logstart = 0; + cfg->logagno = 0; + if (cfg->lsunit) +- align_log_size(cfg, cfg->lsunit); ++ align_log_size(cfg, cfg->lsunit, XFS_MAX_LOG_BLOCKS); + + validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks); + return; +@@ -3368,9 +3371,9 @@ _("log ag number %lld too large, must be less than %lld\n"), + * Align the logstart at stripe unit boundary. + */ + if (cfg->lsunit) { +- align_internal_log(cfg, mp, cfg->lsunit); ++ align_internal_log(cfg, mp, cfg->lsunit, max_logblocks); + } else if (cfg->dsunit) { +- align_internal_log(cfg, mp, cfg->dsunit); ++ align_internal_log(cfg, mp, cfg->dsunit, max_logblocks); + } + validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks); + } +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.18.0-mkfs-round-log-size-down-if-rounding-log-start-up-ca.patch b/xfsprogs-5.18.0-mkfs-round-log-size-down-if-rounding-log-start-up-ca.patch new file mode 100644 index 0000000..a48ff35 --- /dev/null +++ b/xfsprogs-5.18.0-mkfs-round-log-size-down-if-rounding-log-start-up-ca.patch @@ -0,0 +1,46 @@ +From 75421026425013a5601c899d2aca89d180853111 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 14 Apr 2022 13:32:32 -0700 +Subject: [PATCH] mkfs: round log size down if rounding log start up causes + overflow + +If rounding the log start up to the next stripe unit would cause the log +to overrun the end of the AG, round the log size down by a stripe unit. +We already ensured that logblocks was small enough to fit inside the AG, +so the minor adjustment should suffice. + +This can be reproduced with: +mkfs.xfs -dsu=44k,sw=1,size=300m,file,name=fsfile -m rmapbt=0 +and: +mkfs.xfs -dsu=48k,sw=1,size=512m,file,name=fsfile -m rmapbt=0 + +Reported-by: Eric Sandeen +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Ferry Meng +--- + mkfs/xfs_mkfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index 370c0dcb..beeb70f3 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -3205,6 +3205,15 @@ _("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n" + /* round up/down the log size now */ + align_log_size(cfg, sunit, max_logblocks); + ++ /* ++ * If the end of the log has been rounded past the end of the AG, ++ * reduce logblocks by a stripe unit to try to get it back under EOAG. ++ */ ++ if (!libxfs_verify_fsbext(mp, cfg->logstart, cfg->logblocks) && ++ cfg->logblocks > sunit) { ++ cfg->logblocks -= sunit; ++ } ++ + /* check the aligned log still starts and ends in the same AG. */ + if (!libxfs_verify_fsbext(mp, cfg->logstart, cfg->logblocks)) { + fprintf(stderr, +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch b/xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch new file mode 100644 index 0000000..e7a9e51 --- /dev/null +++ b/xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch @@ -0,0 +1,120 @@ +From 4d6cd5c34b713465463ecb36455864d158a362ac Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Wed, 13 Jul 2022 20:58:28 -0500 +Subject: [PATCH] mkfs: terminate getsubopt arrays properly + +Having not drank any (or maybe too much) coffee this morning, I typed: + +$ mkfs.xfs -d agcount=3 -d nrext64=0 +Segmentation fault + +I traced this down to getsubopt walking off the end of the dopts.subopts +array. The manpage says you're supposed to terminate the suboptions +string array with a NULL entry, but the structure definition uses +MAX_SUBOPTS/D_MAX_OPTS directly, which means there is no terminator. + +Explicitly terminate each suboption array with a NULL entry after +making room for it. + +Signed-off-by: Darrick J. Wong +[sandeen: explicitly add NULL terminators & clarify comment] +Reviewed-by: Eric Sandeen +Signed-off-by: Eric Sandeen +Signed-off-by: Ferry Meng +Reviewed-by: Joseph Qi +--- + mkfs/xfs_mkfs.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c +index beeb70f3..ecd13fca 100644 +--- a/mkfs/xfs_mkfs.c ++++ b/mkfs/xfs_mkfs.c +@@ -130,8 +130,11 @@ enum { + M_MAX_OPTS, + }; + +-/* Just define the max options array size manually right now */ +-#define MAX_SUBOPTS D_MAX_OPTS ++/* ++ * Just define the max options array size manually to the largest ++ * enum right now, leaving room for a NULL terminator at the end ++ */ ++#define MAX_SUBOPTS (D_MAX_OPTS + 1) + + #define SUBOPT_NEEDS_VAL (-1LL) + #define MAX_CONFLICTS 8 +@@ -241,6 +244,7 @@ static struct opt_params bopts = { + .ini_section = "block", + .subopts = { + [B_SIZE] = "size", ++ [B_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = B_SIZE, +@@ -267,6 +271,7 @@ static struct opt_params copts = { + .name = 'c', + .subopts = { + [C_OPTFILE] = "options", ++ [C_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = C_OPTFILE, +@@ -296,6 +301,7 @@ static struct opt_params dopts = { + [D_EXTSZINHERIT] = "extszinherit", + [D_COWEXTSIZE] = "cowextsize", + [D_DAXINHERIT] = "daxinherit", ++ [D_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = D_AGCOUNT, +@@ -432,6 +438,7 @@ static struct opt_params iopts = { + [I_ATTR] = "attr", + [I_PROJID32BIT] = "projid32bit", + [I_SPINODES] = "sparse", ++ [I_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = I_ALIGN, +@@ -498,6 +505,7 @@ static struct opt_params lopts = { + [L_FILE] = "file", + [L_NAME] = "name", + [L_LAZYSBCNTR] = "lazy-count", ++ [L_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = L_AGNUM, +@@ -590,6 +598,7 @@ static struct opt_params nopts = { + [N_SIZE] = "size", + [N_VERSION] = "version", + [N_FTYPE] = "ftype", ++ [N_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = N_SIZE, +@@ -625,6 +634,7 @@ static struct opt_params ropts = { + [R_FILE] = "file", + [R_NAME] = "name", + [R_NOALIGN] = "noalign", ++ [R_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = R_EXTSIZE, +@@ -672,6 +682,7 @@ static struct opt_params sopts = { + .subopts = { + [S_SIZE] = "size", + [S_SECTSIZE] = "sectsize", ++ [S_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = S_SIZE, +@@ -708,6 +719,7 @@ static struct opt_params mopts = { + [M_REFLINK] = "reflink", + [M_INOBTCNT] = "inobtcount", + [M_BIGTIME] = "bigtime", ++ [M_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = M_CRC, +-- +2.19.1.6.gb485710b diff --git a/xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch b/xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch new file mode 100644 index 0000000..5146f7c --- /dev/null +++ b/xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch @@ -0,0 +1,56 @@ +From 768a8c511e1f2e43a5da7fe9e3ccf75aec836178 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Wed, 13 Jul 2022 20:58:25 -0500 +Subject: [PATCH] xfs_repair: ignore empty xattr leaf blocks + +As detailed in the commit: + +5e572d1a xfs: empty xattr leaf header blocks are not corruption + +empty xattr leaf blocks can be the benign byproduct of the system +going down during the multi-step process of adding a large xattr +to a file that has no xattrs. If we find one at attr fork offset 0, +we should clear it, but this isn't a corruption. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Eric Sandeen +Signed-off-by: Ferry Meng +Reviewed-by: Joseph Qi +--- + repair/attr_repair.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/repair/attr_repair.c b/repair/attr_repair.c +index ba39c2b5..090b5cae 100644 +--- a/repair/attr_repair.c ++++ b/repair/attr_repair.c +@@ -579,6 +579,26 @@ process_leaf_attr_block( + firstb = mp->m_sb.sb_blocksize; + stop = xfs_attr3_leaf_hdr_size(leaf); + ++ /* ++ * Empty leaf blocks at offset zero can occur as a race between ++ * setxattr and the system going down, so we only take action if we're ++ * running in modify mode. See xfs_attr3_leaf_verify for details of ++ * how we've screwed this up many times. ++ */ ++ if (!leafhdr.count && da_bno == 0) { ++ if (no_modify) { ++ do_log( ++ _("would clear empty leaf attr block 0, inode %" PRIu64 "\n"), ++ ino); ++ return 0; ++ } ++ ++ do_warn( ++ _("will clear empty leaf attr block 0, inode %" PRIu64 "\n"), ++ ino); ++ return 1; ++ } ++ + /* does the count look sorta valid? */ + if (!leafhdr.count || + leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop > +-- +2.19.1.6.gb485710b diff --git a/xfsprogs.spec b/xfsprogs.spec index 42a9d66..4d004e4 100644 --- a/xfsprogs.spec +++ b/xfsprogs.spec @@ -1,4 +1,4 @@ -%define anolis_release 1 +%define anolis_release 2 Name: xfsprogs Version: 5.10.0 @@ -37,6 +37,14 @@ Patch05: xfsprogs-5.13.0-xfs-remove-the-unused-xfs_icdinode_has_bigtime-helpe.pa Patch06: xfsprogs-5.13.0-xfs-rename-struct-xfs_legacy_ictimestamp.patch Patch07: xfsprogs-5.13.0-xfs-rename-xfs_ictimestamp_t.patch Patch08: xfsprogs-5.18.0-mkfs-don-t-trample-the-gid-set-in-the-protofile.patch +Patch09: xfsprogs-5.11.0-xfs-refactor-data-device-extent-validation.patch +Patch10: xfsprogs-5.18.0-mkfs-fix-missing-validation-of-l-size-against-maximu.patch +Patch11: xfsprogs-5.18.0-mkfs-reduce-internal-log-size-when-log-stripe-units-.patch +Patch12: xfsprogs-5.18.0-mkfs-don-t-let-internal-logs-bump-the-root-dir-inode.patch +Patch13: xfsprogs-5.18.0-mkfs-improve-log-extent-validation.patch +Patch14: xfsprogs-5.18.0-mkfs-round-log-size-down-if-rounding-log-start-up-ca.patch +Patch15: xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch +Patch16: xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch # Begin: Anolis customized patches Patch1001: 1001-xfsprogs-add-atomic-write-support.patch @@ -158,6 +166,10 @@ rm -rf %{buildroot}/%{abidir}/help %{_libdir}/*.so %changelog +* Tue May 16 2023 Ferry Meng - 5.10.0-2 +- Add mkfs.xfs fixed patches from upstream +- xfs_repair: ignore empty xattr leaf blocks + * Fri Oct 28 2022 Ziyang Zhang - 5.10.0-1 - Rollback to 5.10.0 - Add patches cherry-picked from upstream 5.10 to 5.18 -- Gitee