Commit 4800575d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-fixes-6.13-rc3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Carlos Maiolino:

 - Fixes for scrub subsystem

 - Fix quota crashes

 - Fix sb_spino_align checons on large fsblock sizes

 - Fix discarded superblock updates

 - Fix stuck unmount due to a locked inode

* tag 'xfs-fixes-6.13-rc3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (28 commits)
  xfs: port xfs_ioc_start_commit to multigrain timestamps
  xfs: return from xfs_symlink_verify early on V4 filesystems
  xfs: fix zero byte checking in the superblock scrubber
  xfs: check pre-metadir fields correctly
  xfs: don't crash on corrupt /quotas dirent
  xfs: don't move nondir/nonreg temporary repair files to the metadir namespace
  xfs: fix sb_spino_align checks for large fsblock sizes
  xfs: convert quotacheck to attach dquot buffers
  xfs: attach dquot buffer to dquot log item buffer
  xfs: clean up log item accesses in xfs_qm_dqflush{,_done}
  xfs: separate dquot buffer reads from xfs_dqflush
  xfs: don't lose solo dquot update transactions
  xfs: don't lose solo superblock counter update transactions
  xfs: avoid nested calls to __xfs_trans_commit
  xfs: only run precommits once per transaction object
  xfs: unlock inodes when erroring out of xfs_trans_alloc_dir
  xfs: fix scrub tracepoints when inode-rooted btrees are involved
  xfs: update btree keys correctly when _insrec splits an inode root block
  xfs: fix error bailout in xfs_rtginode_create
  xfs: fix null bno_hint handling in xfs_rtallocate_rtg
  ...
parents 01af50af bf354410
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -3557,14 +3557,31 @@ xfs_btree_insrec(
	xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);

	/*
	 * If we just inserted into a new tree block, we have to
	 * recalculate nkey here because nkey is out of date.
	 * Update btree keys to reflect the newly added record or keyptr.
	 * There are three cases here to be aware of.  Normally, all we have to
	 * do is walk towards the root, updating keys as necessary.
	 *
	 * Otherwise we're just updating an existing block (having shoved
	 * some records into the new tree block), so use the regular key
	 * update mechanism.
	 */
	if (bp && xfs_buf_daddr(bp) != old_bn) {
	 * If the caller had us target a full block for the insertion, we dealt
	 * with that by calling the _make_block_unfull function.  If the
	 * "make unfull" function splits the block, it'll hand us back the key
	 * and pointer of the new block.  We haven't yet added the new block to
	 * the next level up, so if we decide to add the new record to the new
	 * block (bp->b_bn != old_bn), we have to update the caller's pointer
	 * so that the caller adds the new block with the correct key.
	 *
	 * However, there is a third possibility-- if the selected block is the
	 * root block of an inode-rooted btree and cannot be expanded further,
	 * the "make unfull" function moves the root block contents to a new
	 * block and updates the root block to point to the new block.  In this
	 * case, no block pointer is passed back because the block has already
	 * been added to the btree.  In this case, we need to use the regular
	 * key update function, just like the first case.  This is critical for
	 * overlapping btrees, because the high key must be updated to reflect
	 * the entire tree, not just the subtree accessible through the first
	 * child of the root (which is now two levels down from the root).
	 */
	if (!xfs_btree_ptr_is_null(cur, &nptr) &&
	    bp && xfs_buf_daddr(bp) != old_bn) {
		xfs_btree_get_keys(cur, block, lkey);
	} else if (xfs_btree_needs_key_update(cur, optr)) {
		error = xfs_btree_update_keys(cur, level);
@@ -5144,7 +5161,7 @@ xfs_btree_count_blocks_helper(
	int			level,
	void			*data)
{
	xfs_extlen_t		*blocks = data;
	xfs_filblks_t		*blocks = data;
	(*blocks)++;

	return 0;
@@ -5154,7 +5171,7 @@ xfs_btree_count_blocks_helper(
int
xfs_btree_count_blocks(
	struct xfs_btree_cur	*cur,
	xfs_extlen_t		*blocks)
	xfs_filblks_t		*blocks)
{
	*blocks = 0;
	return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper,
+1 −1
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level,
int xfs_btree_visit_blocks(struct xfs_btree_cur *cur,
		xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data);

int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks);
int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_filblks_t *blocks);

union xfs_btree_rec *xfs_btree_rec_addr(struct xfs_btree_cur *cur, int n,
		struct xfs_btree_block *block);
+3 −1
Original line number Diff line number Diff line
@@ -744,6 +744,7 @@ xfs_finobt_count_blocks(
{
	struct xfs_buf		*agbp = NULL;
	struct xfs_btree_cur	*cur;
	xfs_filblks_t		blocks;
	int			error;

	error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
@@ -751,9 +752,10 @@ xfs_finobt_count_blocks(
		return error;

	cur = xfs_finobt_init_cursor(pag, tp, agbp);
	error = xfs_btree_count_blocks(cur, tree_blocks);
	error = xfs_btree_count_blocks(cur, &blocks);
	xfs_btree_del_cursor(cur, error);
	xfs_trans_brelse(tp, agbp);
	*tree_blocks = blocks;

	return error;
}
+1 −1
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ xfs_rtginode_create(

	error = xfs_metadir_create(&upd, S_IFREG);
	if (error)
		return error;
		goto out_cancel;

	xfs_rtginode_lockdep_setup(upd.ip, rtg_rgno(rtg), type);

+6 −5
Original line number Diff line number Diff line
@@ -494,12 +494,13 @@ xfs_validate_sb_common(
				return -EINVAL;
			}

			if (!sbp->sb_spino_align ||
			    sbp->sb_spino_align > sbp->sb_inoalignmt ||
			    (sbp->sb_inoalignmt % sbp->sb_spino_align) != 0) {
			if (sbp->sb_spino_align &&
			    (sbp->sb_spino_align > sbp->sb_inoalignmt ||
			     (sbp->sb_inoalignmt % sbp->sb_spino_align) != 0)) {
				xfs_warn(mp,
				"Sparse inode alignment (%u) is invalid.",
					sbp->sb_spino_align);
"Sparse inode alignment (%u) is invalid, must be integer factor of (%u).",
					sbp->sb_spino_align,
					sbp->sb_inoalignmt);
				return -EINVAL;
			}
		} else if (sbp->sb_spino_align) {
Loading