diff --git a/0002-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch b/0002-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch new file mode 100644 index 0000000000000000000000000000000000000000..1fe9fd7bcf6ed124e1730a8df0b50e89e0eb2367 --- /dev/null +++ b/0002-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch @@ -0,0 +1,110 @@ +From 0f24228d7661305ce050a6294e9b0fe4b484b791 Mon Sep 17 00:00:00 2001 +From: Zheng Bin +Date: Wed, 29 Apr 2020 14:10:49 -0400 +Subject: [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify + +Source kernel commit: d0c7feaf87678371c2c09b3709400be416b2dc62 + +We recently used fuzz(hydra) to test XFS and automatically generate +tmp.img(XFS v5 format, but some metadata is wrong) + +xfs_repair information(just one AG): +agf_freeblks 0, counted 3224 in ag 0 +agf_longest 536874136, counted 3224 in ag 0 +sb_fdblocks 613, counted 3228 + +Test as follows: +mount tmp.img tmpdir +cp file1M tmpdir +sync + +In 4.19-stable, sync will stuck, the reason is: +xfs_mountfs +xfs_check_summary_counts +if ((!xfs_sb_version_haslazysbcount(&mp->m_sb) || +XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) && +!xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS)) +return 0; -->just return, incore sb_fdblocks still be 613 +xfs_initialize_perag_data + +cp file1M tmpdir -->ok(write file to pagecache) +sync -->stuck(write pagecache to disk) +xfs_map_blocks +xfs_iomap_write_allocate +while (count_fsb != 0) { +nimaps = 0; +while (nimaps == 0) { --> endless loop +nimaps = 1; +xfs_bmapi_write(..., &nimaps) --> nimaps becomes 0 again +xfs_bmapi_write +xfs_bmap_alloc +xfs_bmap_btalloc +xfs_alloc_vextent +xfs_alloc_fix_freelist +xfs_alloc_space_available -->fail(agf_freeblks is 0) + +In linux-next, sync not stuck, cause commit c2b3164320b5 ("xfs: +use the latest extent at writeback delalloc conversion time") remove +the above while, dmesg is as follows: +[ 55.250114] XFS (loop0): page discard on page ffffea0008bc7380, inode 0x1b0c, offset 0. + +Users do not know why this page is discard, the better soultion is: +1. Like xfs_repair, make sure sb_fdblocks is equal to counted +(xfs_initialize_perag_data did this, who is not called at this mount) +2. Add agf verify, if fail, will tell users to repair + +This patch use the second soultion. + +Signed-off-by: Zheng Bin +Signed-off-by: Ren Xudong +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_alloc.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c +index a92ca524..09db6693 100644 +--- a/libxfs/xfs_alloc.c ++++ b/libxfs/xfs_alloc.c +@@ -2854,6 +2854,13 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp))) + return __this_address; + ++ if (be32_to_cpu(agf->agf_length) > mp->m_sb.sb_dblocks) ++ return __this_address; ++ ++ if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) || ++ be32_to_cpu(agf->agf_freeblks) > be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ + if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 || + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || +@@ -2865,6 +2872,10 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)) + return __this_address; + ++ if (xfs_sb_version_hasrmapbt(&mp->m_sb) && ++ be32_to_cpu(agf->agf_rmap_blocks) > be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ + /* + * during growfs operations, the perag is not fully initialised, + * so we can't use it for any useful checking. growfs ensures we can't +@@ -2878,6 +2889,11 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) + return __this_address; + ++ if (xfs_sb_version_hasreflink(&mp->m_sb) && ++ be32_to_cpu(agf->agf_refcount_blocks) > ++ be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ + if (xfs_sb_version_hasreflink(&mp->m_sb) && + (be32_to_cpu(agf->agf_refcount_level) < 1 || + be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)) +-- +2.27.0 + diff --git a/0003-xfs-don-t-ever-return-a-stale-pointer-from-__xfs_dir.patch b/0003-xfs-don-t-ever-return-a-stale-pointer-from-__xfs_dir.patch new file mode 100644 index 0000000000000000000000000000000000000000..b99da33aecb28aeb544d8b5ac41c71a618df579a --- /dev/null +++ b/0003-xfs-don-t-ever-return-a-stale-pointer-from-__xfs_dir.patch @@ -0,0 +1,40 @@ +From e28956c1490593cadd6f5c6bc4b35cd2b3b632d1 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 1 May 2020 17:37:09 -0400 +Subject: [PATCH] xfs: don't ever return a stale pointer from + __xfs_dir3_free_read + +Source kernel commit: 1cb5deb5bc095c070c09a4540c45f9c9ba24be43 + +If we decide that a directory free block is corrupt, we must take care +not to leak a buffer pointer to the caller. After xfs_trans_brelse +returns, the buffer can be freed or reused, which means that we have to +set *bpp back to NULL. + +Callers are supposed to notice the nonzero return value and not use the +buffer pointer, but we should code more defensively, even if all current +callers handle this situation correctly. + +Fixes: de14c5f541e7 ("xfs: verify free block header fields") +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_dir2_node.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c +index ffa136b..c2deafa 100644 +--- a/libxfs/xfs_dir2_node.c ++++ b/libxfs/xfs_dir2_node.c +@@ -225,6 +225,7 @@ __xfs_dir3_free_read( + if (fa) { + xfs_verifier_error(*bpp, -EFSCORRUPTED, fa); + xfs_trans_brelse(tp, *bpp); ++ *bpp = NULL; + return -EFSCORRUPTED; + } + +-- +2.27.0 + diff --git a/0004-xfs-xfs_dabuf_map-should-return-ENOMEM-when-map-allo.patch b/0004-xfs-xfs_dabuf_map-should-return-ENOMEM-when-map-allo.patch new file mode 100644 index 0000000000000000000000000000000000000000..a6203a17ec3952f64aac78acd48b0ebbbdd0aebf --- /dev/null +++ b/0004-xfs-xfs_dabuf_map-should-return-ENOMEM-when-map-allo.patch @@ -0,0 +1,41 @@ +From a2a0a99a70b02649250fe2c50ef9546f9e306d44 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 1 May 2020 17:37:09 -0400 +Subject: [PATCH] xfs: xfs_dabuf_map should return ENOMEM when map allocation + fails + +Source kernel commit: faf8ee8476c19b30fd16079ad616b2b0f56eaff4 + +If the xfs_buf_map array allocation in xfs_dabuf_map fails for whatever +reason, we bail out with error code zero. This will confuse callers, so +make sure that we return ENOMEM. Allocation failure should never happen +with the small size of the array, but code defensively anyway. + +Fixes: 45feef8f50b94d ("xfs: refactor xfs_dabuf_map") +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_da_btree.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c +index d785312f..4e909caa 100644 +--- a/libxfs/xfs_da_btree.c ++++ b/libxfs/xfs_da_btree.c +@@ -2518,8 +2518,10 @@ xfs_dabuf_map( + */ + if (nirecs > 1) { + map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS); +- if (!map) ++ if (!map) { ++ error = -ENOMEM; + goto out_free_irecs; ++ } + *mapp = map; + } + +-- +2.27.0 + diff --git a/0005-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch b/0005-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch new file mode 100644 index 0000000000000000000000000000000000000000..bf9bab03c76c26913bad3ab1b290f5d6f377b3cc --- /dev/null +++ b/0005-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch @@ -0,0 +1,36 @@ +From 2c711623374764cd7f9e95da7fdf4d9e90feb4c0 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 1 May 2020 17:37:09 -0400 +Subject: [PATCH] xfs: fix incorrect test in xfs_alloc_ag_vextent_lastblock + +Source kernel commit: 77ca1eed5a7d2bf0905562eb1a15aac76bc19fe4 + +When I lifted the code in xfs_alloc_ag_vextent_lastblock out of a loop, +I forgot to convert all the accesses to len to be pointer dereferences. + +Coverity-id: 1457918 +Fixes: 5113f8ec3753ed ("xfs: clean up weird while loop in xfs_alloc_ag_vextent_near") +Signed-off-by: Darrick J. Wong +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_alloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c +index 841b0305..fee4039c 100644 +--- a/libxfs/xfs_alloc.c ++++ b/libxfs/xfs_alloc.c +@@ -1510,7 +1510,7 @@ xfs_alloc_ag_vextent_lastblock( + * maxlen, go to the start of this block, and skip all those smaller + * than minlen. + */ +- if (len || args->alignment > 1) { ++ if (*len || args->alignment > 1) { + acur->cnt->bc_ptrs[0] = 1; + do { + error = xfs_alloc_get_rec(acur->cnt, bno, len, &i); +-- +2.27.0 + diff --git a/0006-xfs_db-fix-crc-invalidation-segfault.patch b/0006-xfs_db-fix-crc-invalidation-segfault.patch new file mode 100644 index 0000000000000000000000000000000000000000..3f6c1c30a93c6673f7bdc9198d31470099396e58 --- /dev/null +++ b/0006-xfs_db-fix-crc-invalidation-segfault.patch @@ -0,0 +1,41 @@ +From a19679ec0fa23fd360c510f21c498dd37d35713c Mon Sep 17 00:00:00 2001 +From: Anthony Iliopoulos +Date: Tue, 26 May 2020 14:35:51 -0400 +Subject: [PATCH] xfs_db: fix crc invalidation segfault + +The nowrite_ops var is declared within nested block scope but used +outside that scope, causing xfs_db to crash while trying to defererence +the verify_write pointer. Fix it by lifting the declaration to the outer +scope, where it is accessed. + +Fixes: b64af2c48220c8 ("xfs_db: add crc manipulation commands") +Reviewed-by: Eric Sandeen +Signed-off-by: Anthony Iliopoulos +Signed-off-by: Eric Sandeen +--- + db/crc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/db/crc.c b/db/crc.c +index 95161c6d..b23417a1 100644 +--- a/db/crc.c ++++ b/db/crc.c +@@ -53,6 +53,7 @@ crc_f( + char **argv) + { + const struct xfs_buf_ops *stashed_ops = NULL; ++ struct xfs_buf_ops nowrite_ops; + extern char *progname; + const field_t *fields; + const ftattr_t *fa; +@@ -127,7 +128,6 @@ crc_f( + } + + if (invalidate) { +- struct xfs_buf_ops nowrite_ops; + flist_t *sfl; + int bit_length; + int parentoffset; +-- +2.27.0 + diff --git a/0007-xfs_repair-fix-missing-dir-buffer-corruption-checks.patch b/0007-xfs_repair-fix-missing-dir-buffer-corruption-checks.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc1ace5c424ece9a8faaf875979f234f970c095d --- /dev/null +++ b/0007-xfs_repair-fix-missing-dir-buffer-corruption-checks.patch @@ -0,0 +1,124 @@ +From be752639294c8a1eb0f06275e77744f32e5bd277 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 10 Jul 2020 15:34:36 -0400 +Subject: [PATCH] xfs_repair: fix missing dir buffer corruption checks + +The da_read_buf() function operates in "salvage" mode, which means that +if the verifiers fail, it will return a buffer with b_error set. The +callers of da_read_buf, however, do not adequately check for verifier +errors, which means that repair can fail to flag a corrupt filesystem. + +Fix the callers to do this properly. The dabtree block walker and the +dabtree path checker functions to complain any time the da node / leafn +verifiers fail. Fix the directory block walking functions to complain +about EFSCORRUPTED, since they already dealt with EFSBADCRC. + +Found by running xfs/496 against lhdr.stale = middlebit. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + repair/da_util.c | 25 ++++++++++++++++--------- + repair/dir2.c | 21 +++++++++++++++++++++ + 2 files changed, 37 insertions(+), 9 deletions(-) + +diff --git a/repair/da_util.c b/repair/da_util.c +index 5061880f..7239c2e2 100644 +--- a/repair/da_util.c ++++ b/repair/da_util.c +@@ -134,6 +134,15 @@ _("can't read %s block %u for inode %" PRIu64 "\n"), + goto error_out; + } + ++ /* corrupt leafn/node; rebuild the dir. */ ++ if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) { ++ do_warn( ++_("corrupt %s tree block %u for inode %" PRIu64 "\n"), ++ FORKNAME(whichfork), bno, da_cursor->ino); ++ libxfs_buf_relse(bp); ++ goto error_out; ++ } ++ + node = bp->b_addr; + libxfs_da3_node_hdr_from_disk(mp, &nodehdr, node); + +@@ -160,15 +169,6 @@ _("bad %s magic number 0x%x in inode %" PRIu64 " bno = %u\n"), + goto error_out; + } + +- /* corrupt node; rebuild the dir. */ +- if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) { +- libxfs_buf_relse(bp); +- do_warn( +-_("corrupt %s tree block %u for inode %" PRIu64 "\n"), +- FORKNAME(whichfork), bno, da_cursor->ino); +- goto error_out; +- } +- + if (nodehdr.count > geo->node_ents) { + do_warn( + _("bad %s record count in inode %" PRIu64 ", count = %d, max = %d\n"), +@@ -562,6 +562,13 @@ _("can't read %s block %u for inode %" PRIu64 "\n"), + FORKNAME(whichfork), dabno, cursor->ino); + return 1; + } ++ if (bp->b_error == -EFSCORRUPTED || bp->b_error == -EFSBADCRC) { ++ do_warn( ++_("corrupt %s tree block %u for inode %" PRIu64 "\n"), ++ FORKNAME(whichfork), dabno, cursor->ino); ++ libxfs_buf_relse(bp); ++ return 1; ++ } + + newnode = bp->b_addr; + libxfs_da3_node_hdr_from_disk(mp, &nodehdr, newnode); +diff --git a/repair/dir2.c b/repair/dir2.c +index cbbce601..b374bc7b 100644 +--- a/repair/dir2.c ++++ b/repair/dir2.c +@@ -983,6 +983,13 @@ _("can't read block %u for directory inode %" PRIu64 "\n"), + mp->m_dir_geo->datablk, ino); + return 1; + } ++ if (bp->b_error == -EFSCORRUPTED) { ++ do_warn( ++_("corrupt directory block %u for inode %" PRIu64 "\n"), ++ mp->m_dir_geo->datablk, ino); ++ libxfs_buf_relse(bp); ++ return 1; ++ } + /* + * Verify the block + */ +@@ -1122,6 +1129,13 @@ _("can't read file block %u for directory inode %" PRIu64 "\n"), + da_bno, ino); + goto error_out; + } ++ if (bp->b_error == -EFSCORRUPTED) { ++ do_warn( ++_("corrupt directory leafn block %u for inode %" PRIu64 "\n"), ++ da_bno, ino); ++ libxfs_buf_relse(bp); ++ goto error_out; ++ } + leaf = bp->b_addr; + libxfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); + /* +@@ -1324,6 +1338,13 @@ _("can't read block %" PRIu64 " for directory inode %" PRIu64 "\n"), + dbno, ino); + continue; + } ++ if (bp->b_error == -EFSCORRUPTED) { ++ do_warn( ++_("corrupt directory data block %lu for inode %" PRIu64 "\n"), ++ dbno, ino); ++ libxfs_buf_relse(bp); ++ continue; ++ } + data = bp->b_addr; + if (!(be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC)) +-- +2.27.0 + diff --git a/0008-xfs-fix-inode-allocation-block-res-calculation-prece.patch b/0008-xfs-fix-inode-allocation-block-res-calculation-prece.patch new file mode 100644 index 0000000000000000000000000000000000000000..4967ab64b0f92502060de3771804fd2db8500317 --- /dev/null +++ b/0008-xfs-fix-inode-allocation-block-res-calculation-prece.patch @@ -0,0 +1,44 @@ +From 625c12fba2d613c209108c5e4f07af8309bcbafb Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Fri, 4 Sep 2020 16:01:20 -0400 +Subject: [PATCH] xfs: fix inode allocation block res calculation precedence + +Source kernel commit: b2a8864728683443f34a9fd33a2b78b860934cc1 + +The block reservation calculation for inode allocation is supposed +to consist of the blocks required for the inode chunk plus +(maxlevels-1) of the inode btree multiplied by the number of inode +btrees in the fs (2 when finobt is enabled, 1 otherwise). + +Instead, the macro returns (ialloc_blocks + 2) due to a precedence +error in the calculation logic. This leads to block reservation +overruns via generic/531 on small block filesystems with finobt +enabled. Add braces to fix the calculation and reserve the +appropriate number of blocks. + +Fixes: 9d43b180af67 ("xfs: update inode allocation/free transaction reservations for finobt") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_trans_space.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h +index 88221c7a..c6df01a2 100644 +--- a/libxfs/xfs_trans_space.h ++++ b/libxfs/xfs_trans_space.h +@@ -57,7 +57,7 @@ + XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) + #define XFS_IALLOC_SPACE_RES(mp) \ + (M_IGEO(mp)->ialloc_blks + \ +- (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \ ++ ((xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1) * \ + (M_IGEO(mp)->inobt_maxlevels - 1))) + + /* +-- +2.27.0 + diff --git a/0009-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch b/0009-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch new file mode 100644 index 0000000000000000000000000000000000000000..54d3825adef9789f6e49c828603d0350df785310 --- /dev/null +++ b/0009-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch @@ -0,0 +1,79 @@ +From d6e8deb14cbea11d8f265537f7163428717b93fb Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Tue, 15 Sep 2020 15:59:38 -0400 +Subject: [PATCH] xfs: fix off-by-one in inode alloc block reservation + calculation + +Source kernel commit: 657f101930bc6c5b41bd7d6c22565c4302a80d33 + +The inode chunk allocation transaction reserves inobt_maxlevels-1 +blocks to accommodate a full split of the inode btree. A full split +requires an allocation for every existing level and a new root +block, which means inobt_maxlevels is the worst case block +requirement for a transaction that inserts to the inobt. This can +lead to a transaction block reservation overrun when tmpfile +creation allocates an inode chunk and expands the inobt to its +maximum depth. This problem has been observed in conjunction with +overlayfs, which makes frequent use of tmpfiles internally. + +The existing reservation code goes back as far as the Linux git repo +history (v2.6.12). It was likely never observed as a problem because +the traditional file/directory creation transactions also include +worst case block reservation for directory modifications, which most +likely is able to make up for a single block deficiency in the inode +allocation portion of the calculation. tmpfile support is relatively +more recent (v3.15), less heavily used, and only includes the inode +allocation block reservation as tmpfiles aren't linked into the +directory tree on creation. + +Fix up the inode alloc block reservation macro and a couple of the +block allocator minleft parameters that enforce an allocation to +leave enough free blocks in the AG for a full inobt split. + +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_ialloc.c | 4 ++-- + libxfs/xfs_trans_space.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c +index 5f09ff5a..ce73feed 100644 +--- a/libxfs/xfs_ialloc.c ++++ b/libxfs/xfs_ialloc.c +@@ -683,7 +683,7 @@ xfs_ialloc_ag_alloc( + args.minalignslop = igeo->cluster_align - 1; + + /* Allow space for the inode btree to split. */ +- args.minleft = igeo->inobt_maxlevels - 1; ++ args.minleft = igeo->inobt_maxlevels; + if ((error = xfs_alloc_vextent(&args))) + return error; + +@@ -731,7 +731,7 @@ xfs_ialloc_ag_alloc( + /* + * Allow space for the inode btree to split. + */ +- args.minleft = igeo->inobt_maxlevels - 1; ++ args.minleft = igeo->inobt_maxlevels; + if ((error = xfs_alloc_vextent(&args))) + return error; + } +diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h +index c6df01a2..7ad3659c 100644 +--- a/libxfs/xfs_trans_space.h ++++ b/libxfs/xfs_trans_space.h +@@ -58,7 +58,7 @@ + #define XFS_IALLOC_SPACE_RES(mp) \ + (M_IGEO(mp)->ialloc_blks + \ + ((xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1) * \ +- (M_IGEO(mp)->inobt_maxlevels - 1))) ++ M_IGEO(mp)->inobt_maxlevels)) + + /* + * Space reservation values for various transactions. +-- +2.27.0 + diff --git a/0010-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch b/0010-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch new file mode 100644 index 0000000000000000000000000000000000000000..d5a83045dc5c19d350dd16952d44fe2710a189ba --- /dev/null +++ b/0010-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch @@ -0,0 +1,52 @@ +From be2f3d3984902d7ce1e30fc7ec745f7671b7ffdd Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Tue, 15 Sep 2020 15:59:38 -0400 +Subject: [PATCH] xfs: fix boundary test in xfs_attr_shortform_verify + +Source kernel commit: f4020438fab05364018c91f7e02ebdd192085933 + +The boundary test for the fixed-offset parts of xfs_attr_sf_entry in +xfs_attr_shortform_verify is off by one, because the variable array +at the end is defined as nameval[1] not nameval[]. +Hence we need to subtract 1 from the calculation. + +This can be shown by: + +# touch file +# setfattr -n root.a file + +and verifications will fail when it's written to disk. + +This only matters for a last attribute which has a single-byte name +and no value, otherwise the combination of namelen & valuelen will +push endp further out and this test won't fail. + +Fixes: 1e1bbd8e7ee06 ("xfs: create structure verifier function for shortform xattrs") +Signed-off-by: Eric Sandeen +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_attr_leaf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c +index a27107cc..4c871fc1 100644 +--- a/libxfs/xfs_attr_leaf.c ++++ b/libxfs/xfs_attr_leaf.c +@@ -1033,8 +1033,10 @@ xfs_attr_shortform_verify( + * struct xfs_attr_sf_entry has a variable length. + * Check the fixed-offset parts of the structure are + * within the data buffer. ++ * xfs_attr_sf_entry is defined with a 1-byte variable ++ * array at the end, so we must subtract that off. + */ +- if (((char *)sfep + sizeof(*sfep)) >= endp) ++ if (((char *)sfep + sizeof(*sfep) - 1) >= endp) + return __this_address; + + /* Don't allow names with known bad length. */ +-- +2.27.0 + diff --git a/0011-xfs-set-xefi_discard-when-creating-a-deferred-agfl-f.patch b/0011-xfs-set-xefi_discard-when-creating-a-deferred-agfl-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..f88a4abeb89953fe63c6e4d585172f0f88f7f3b6 --- /dev/null +++ b/0011-xfs-set-xefi_discard-when-creating-a-deferred-agfl-f.patch @@ -0,0 +1,53 @@ +From fc46ff14390ec9ee346f58b33486ea23157d981f Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 12 Nov 2020 17:39:58 -0500 +Subject: [PATCH] xfs: set xefi_discard when creating a deferred agfl free log + intent item + +Source kernel commit: 2c334e12f957cd8c6bb66b4aa3f79848b7c33cab + +Make sure that we actually initialize xefi_discard when we're scheduling +a deferred free of an AGFL block. This was (eventually) found by the +UBSAN while I was banging on realtime rmap problems, but it exists in +the upstream codebase. While we're at it, rearrange the structure to +reduce the struct size from 64 to 56 bytes. + +Fixes: fcb762f5de2e ("xfs: add bmapi nodiscard flag") +Signed-off-by: Darrick J. Wong +Reviewed-by: Brian Foster +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_alloc.c | 1 + + libxfs/xfs_bmap.h | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c +index 93043d59..92f61fae 100644 +--- a/libxfs/xfs_alloc.c ++++ b/libxfs/xfs_alloc.c +@@ -2463,6 +2463,7 @@ xfs_defer_agfl_block( + new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno); + new->xefi_blockcount = 1; + new->xefi_oinfo = *oinfo; ++ new->xefi_skip_discard = false; + + trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1); + +diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h +index e1bd484e..6747e97a 100644 +--- a/libxfs/xfs_bmap.h ++++ b/libxfs/xfs_bmap.h +@@ -52,9 +52,9 @@ struct xfs_extent_free_item + { + xfs_fsblock_t xefi_startblock;/* starting fs block number */ + xfs_extlen_t xefi_blockcount;/* number of blocks in extent */ ++ bool xefi_skip_discard; + struct list_head xefi_list; + struct xfs_owner_info xefi_oinfo; /* extent owner */ +- bool xefi_skip_discard; + }; + + #define XFS_BMAP_MAX_NMAP 4 +-- +2.27.0 + diff --git a/xfsprogs.spec b/xfsprogs.spec index 4687ee9bf269db77b2c534433efea085837c77ff..ae9bedf54a7a1606842f0fd90d10f10bdc522dbd 100644 --- a/xfsprogs.spec +++ b/xfsprogs.spec @@ -1,6 +1,6 @@ Name: xfsprogs Version: 5.6.0 -Release: 3 +Release: 4 Summary: Administration and debugging tools for the XFS file system License: GPL+ and LGPLv2+ URL: https://xfs.wiki.kernel.org @@ -8,6 +8,16 @@ URL: https://xfs.wiki.kernel.org Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz Patch1: 0001-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe-.patch +Patch2: 0002-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch +Patch3: 0003-xfs-don-t-ever-return-a-stale-pointer-from-__xfs_dir.patch +Patch4: 0004-xfs-xfs_dabuf_map-should-return-ENOMEM-when-map-allo.patch +Patch5: 0005-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch +Patch6: 0006-xfs_db-fix-crc-invalidation-segfault.patch +Patch7: 0007-xfs_repair-fix-missing-dir-buffer-corruption-checks.patch +Patch8: 0008-xfs-fix-inode-allocation-block-res-calculation-prece.patch +Patch9: 0009-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch +Patch10: 0010-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch +Patch11: 0011-xfs-set-xefi_discard-when-creating-a-deferred-agfl-f.patch BuildRequires: libtool libattr-devel libuuid-devel gcc git BuildRequires: readline-devel libblkid-devel >= 2.30 lvm2-devel libicu-devel >= 62.0 @@ -100,6 +110,9 @@ rm -rf %{buildroot}%{_datadir}/doc/xfsprogs/ %changelog +* Mon Mar 14 2022 wuguanghao - 5.6.0-4 +- backport bugfix patches from community + * Wed Mar 02 2022 Zhiqiang Liu - 5.6.0-3 - mkfs.xfs: fix ASSERT on to-small device with stripe geometry. Fix issue: https://gitee.com/src-openeuler/xfsprogs/issues/I4RZKQ