Commit 9e1fd794 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-5.1-merge-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs updates from Darrick Wong:
 "Here are a number of new features and bug fixes for 5.1

  They've undergone a week's worth of fstesting and merge cleanly with
  master as of this morning

  Most of the changes center on improving metadata validation and fixing
  problems with online fsck, though there's also a new cache to speed up
  unlinked inode handling and cleanup of the copy on write code in
  preparation for future features

  Changes for Linux 5.1:

   - Fix online fsck to handle inode btrees correctly on 64k block
     filesystems

   - Teach online fsck to check directory and attribute names for
     invalid characters

   - Miscellanous fixes for online fsck

   - Introduce a new panic mask so that we can halt immediately on
     metadata corruption (for debugging purposes)

   - Fix a block mapping race during writeback

   - Cache unlinked inode list backrefs in memory to speed up list
     processing

   - Separate the bnobt/cntbt and inobt/finobt buffer verifiers so that
     we can detect crosslinked btrees

   - Refactor magic number verification so that we can standardize it

   - Strengthen ondisk metadata structure offset build time verification

   - Fix a memory corruption problem in the listxattr code

   - Fix a shutdown problem during log recovery due to unreserved finobt
     expansion

   - Fix a referential integrity problem where O_TMPFILE inodes were put
     on the unlinked list with nlink > 0 which would cause asserts
     during log recovery if the system went down immediately

   - Refactor the delayed allocation allocator to be more clever about
     the possibility that its mapping might be stale

   - Various fixes to the copy on write mechanism

   - Make CoW preallocation suitable for use even with writes that
     wouldn't otherwise require it

   - Refactor an internal API

   - Fix some statx implementation bugs

   - Fix miscellaneous compiler and static checker complaints"

* tag 'xfs-5.1-merge-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (70 commits)
  xfs: fix reporting supported extra file attributes for statx()
  xfs: fix backwards endian conversion in scrub
  xfs: fix uninitialized error variables
  xfs: rework breaking of shared extents in xfs_file_iomap_begin
  xfs: don't pass iomap flags to xfs_reflink_allocate_cow
  xfs: fix uninitialized error variable
  xfs: introduce an always_cow mode
  xfs: report IOMAP_F_SHARED from xfs_file_iomap_begin_delay
  xfs: make COW fork unwritten extent conversions more robust
  xfs: merge COW handling into xfs_file_iomap_begin_delay
  xfs: also truncate holes covered by COW blocks
  xfs: don't use delalloc extents for COW on files with extsize hints
  xfs: fix SEEK_DATA for speculative COW fork preallocation
  xfs: make xfs_bmbt_to_iomap more useful
  xfs: fix xfs_buf magic number endian checks
  xfs: retry COW fork delalloc conversion when no extent was found
  xfs: remove the truncate short cut in xfs_map_blocks
  xfs: move xfs_iomap_write_allocate to xfs_aops.c
  xfs: move stat accounting to xfs_bmapi_convert_delalloc
  xfs: move transaction handling to xfs_bmapi_convert_delalloc
  ..
parents b1e24395 1b9598c8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ The following sysctls are available for the XFS filesystem:
		XFS_ERRLEVEL_LOW:       1
		XFS_ERRLEVEL_HIGH:      5

  fs.xfs.panic_mask		(Min: 0  Default: 0  Max: 255)
  fs.xfs.panic_mask		(Min: 0  Default: 0  Max: 256)
	Causes certain error conditions to call BUG(). Value is a bitmask;
	OR together the tags which represent errors which should cause panics:

@@ -285,6 +285,7 @@ The following sysctls are available for the XFS filesystem:
		XFS_PTAG_SHUTDOWN_IOERROR       0x00000020
		XFS_PTAG_SHUTDOWN_LOGERROR      0x00000040
		XFS_PTAG_FSBLOCK_ZERO           0x00000080
		XFS_PTAG_VERIFIER_ERROR         0x00000100

	This option is intended for debugging only.

+3 −3
Original line number Diff line number Diff line
@@ -339,14 +339,14 @@ xfs_ag_init_headers(
	{ /* BNO root block */
		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_BNO_BLOCK(mp)),
		.numblks = BTOBB(mp->m_sb.sb_blocksize),
		.ops = &xfs_allocbt_buf_ops,
		.ops = &xfs_bnobt_buf_ops,
		.work = &xfs_bnoroot_init,
		.need_init = true
	},
	{ /* CNT root block */
		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_CNT_BLOCK(mp)),
		.numblks = BTOBB(mp->m_sb.sb_blocksize),
		.ops = &xfs_allocbt_buf_ops,
		.ops = &xfs_cntbt_buf_ops,
		.work = &xfs_cntroot_init,
		.need_init = true
	},
@@ -361,7 +361,7 @@ xfs_ag_init_headers(
	{ /* FINO root block */
		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_FIBT_BLOCK(mp)),
		.numblks = BTOBB(mp->m_sb.sb_blocksize),
		.ops = &xfs_inobt_buf_ops,
		.ops = &xfs_finobt_buf_ops,
		.work = &xfs_btroot_init,
		.type = XFS_BTNUM_FINO,
		.need_init =  xfs_sb_version_hasfinobt(&mp->m_sb)
+1 −1
Original line number Diff line number Diff line
@@ -281,7 +281,7 @@ xfs_ag_resv_init(
			 */
			ask = used = 0;

			mp->m_inotbt_nores = true;
			mp->m_finobt_nores = true;

			error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask,
					&used);
+8 −4
Original line number Diff line number Diff line
@@ -568,9 +568,9 @@ xfs_agfl_verify(
	if (!xfs_sb_version_hascrc(&mp->m_sb))
		return NULL;

	if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
	if (!xfs_verify_magic(bp, agfl->agfl_magicnum))
		return __this_address;
	if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)
	if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
		return __this_address;
	/*
	 * during growfs operations, the perag is not fully initialised,
@@ -643,6 +643,7 @@ xfs_agfl_write_verify(

const struct xfs_buf_ops xfs_agfl_buf_ops = {
	.name = "xfs_agfl",
	.magic = { cpu_to_be32(XFS_AGFL_MAGIC), cpu_to_be32(XFS_AGFL_MAGIC) },
	.verify_read = xfs_agfl_read_verify,
	.verify_write = xfs_agfl_write_verify,
	.verify_struct = xfs_agfl_verify,
@@ -2587,8 +2588,10 @@ xfs_agf_verify(
			return __this_address;
	}

	if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
	      XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
	if (!xfs_verify_magic(bp, agf->agf_magicnum))
		return __this_address;

	if (!(XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
	      be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
	      be32_to_cpu(agf->agf_flfirst) < xfs_agfl_size(mp) &&
	      be32_to_cpu(agf->agf_fllast) < xfs_agfl_size(mp) &&
@@ -2670,6 +2673,7 @@ xfs_agf_write_verify(

const struct xfs_buf_ops xfs_agf_buf_ops = {
	.name = "xfs_agf",
	.magic = { cpu_to_be32(XFS_AGF_MAGIC), cpu_to_be32(XFS_AGF_MAGIC) },
	.verify_read = xfs_agf_read_verify,
	.verify_write = xfs_agf_write_verify,
	.verify_struct = xfs_agf_verify,
+35 −39
Original line number Diff line number Diff line
@@ -297,48 +297,34 @@ xfs_allocbt_verify(
	struct xfs_perag	*pag = bp->b_pag;
	xfs_failaddr_t		fa;
	unsigned int		level;
	xfs_btnum_t		btnum = XFS_BTNUM_BNOi;

	/*
	 * magic number and level verification
	 *
	 * During growfs operations, we can't verify the exact level or owner as
	 * the perag is not fully initialised and hence not attached to the
	 * buffer.  In this case, check against the maximum tree depth.
	 *
	 * Similarly, during log recovery we will have a perag structure
	 * attached, but the agf information will not yet have been initialised
	 * from the on disk AGF. Again, we can only check against maximum limits
	 * in this case.
	 */
	level = be16_to_cpu(block->bb_level);
	switch (block->bb_magic) {
	case cpu_to_be32(XFS_ABTB_CRC_MAGIC):
		fa = xfs_btree_sblock_v5hdr_verify(bp);
		if (fa)
			return fa;
		/* fall through */
	case cpu_to_be32(XFS_ABTB_MAGIC):
		if (pag && pag->pagf_init) {
			if (level >= pag->pagf_levels[XFS_BTNUM_BNOi])
				return __this_address;
		} else if (level >= mp->m_ag_maxlevels)
	if (!xfs_verify_magic(bp, block->bb_magic))
		return __this_address;
		break;
	case cpu_to_be32(XFS_ABTC_CRC_MAGIC):

	if (xfs_sb_version_hascrc(&mp->m_sb)) {
		fa = xfs_btree_sblock_v5hdr_verify(bp);
		if (fa)
			return fa;
		/* fall through */
	case cpu_to_be32(XFS_ABTC_MAGIC):
	}

	/*
	 * The perag may not be attached during grow operations or fully
	 * initialized from the AGF during log recovery. Therefore we can only
	 * check against maximum tree depth from those contexts.
	 *
	 * Otherwise check against the per-tree limit. Peek at one of the
	 * verifier magic values to determine the type of tree we're verifying
	 * against.
	 */
	level = be16_to_cpu(block->bb_level);
	if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC))
		btnum = XFS_BTNUM_CNTi;
	if (pag && pag->pagf_init) {
			if (level >= pag->pagf_levels[XFS_BTNUM_CNTi])
		if (level >= pag->pagf_levels[btnum])
			return __this_address;
	} else if (level >= mp->m_ag_maxlevels)
		return __this_address;
		break;
	default:
		return __this_address;
	}

	return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]);
}
@@ -377,13 +363,23 @@ xfs_allocbt_write_verify(

}

const struct xfs_buf_ops xfs_allocbt_buf_ops = {
	.name = "xfs_allocbt",
const struct xfs_buf_ops xfs_bnobt_buf_ops = {
	.name = "xfs_bnobt",
	.magic = { cpu_to_be32(XFS_ABTB_MAGIC),
		   cpu_to_be32(XFS_ABTB_CRC_MAGIC) },
	.verify_read = xfs_allocbt_read_verify,
	.verify_write = xfs_allocbt_write_verify,
	.verify_struct = xfs_allocbt_verify,
};

const struct xfs_buf_ops xfs_cntbt_buf_ops = {
	.name = "xfs_cntbt",
	.magic = { cpu_to_be32(XFS_ABTC_MAGIC),
		   cpu_to_be32(XFS_ABTC_CRC_MAGIC) },
	.verify_read = xfs_allocbt_read_verify,
	.verify_write = xfs_allocbt_write_verify,
	.verify_struct = xfs_allocbt_verify,
};

STATIC int
xfs_bnobt_keys_inorder(
@@ -448,7 +444,7 @@ static const struct xfs_btree_ops xfs_bnobt_ops = {
	.init_rec_from_cur	= xfs_allocbt_init_rec_from_cur,
	.init_ptr_from_cur	= xfs_allocbt_init_ptr_from_cur,
	.key_diff		= xfs_bnobt_key_diff,
	.buf_ops		= &xfs_allocbt_buf_ops,
	.buf_ops		= &xfs_bnobt_buf_ops,
	.diff_two_keys		= xfs_bnobt_diff_two_keys,
	.keys_inorder		= xfs_bnobt_keys_inorder,
	.recs_inorder		= xfs_bnobt_recs_inorder,
@@ -470,7 +466,7 @@ static const struct xfs_btree_ops xfs_cntbt_ops = {
	.init_rec_from_cur	= xfs_allocbt_init_rec_from_cur,
	.init_ptr_from_cur	= xfs_allocbt_init_ptr_from_cur,
	.key_diff		= xfs_cntbt_key_diff,
	.buf_ops		= &xfs_allocbt_buf_ops,
	.buf_ops		= &xfs_cntbt_buf_ops,
	.diff_two_keys		= xfs_cntbt_diff_two_keys,
	.keys_inorder		= xfs_cntbt_keys_inorder,
	.recs_inorder		= xfs_cntbt_recs_inorder,
Loading