Commit 712e1425 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull xfs fixes from Chandan Babu:

 - Allow stripe unit/width value passed via mount option to be written
   over existing values in the super block

 - Do not set current->journal_info to avoid its value from being miused
   by another filesystem context

* tag 'xfs-6.9-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: don't use current->journal_info
  xfs: allow sunit mount option to repair bad primary sb stripe values
parents fe764a75 f2e812c1
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -530,7 +530,8 @@ xfs_validate_sb_common(
	}

	if (!xfs_validate_stripe_geometry(mp, XFS_FSB_TO_B(mp, sbp->sb_unit),
			XFS_FSB_TO_B(mp, sbp->sb_width), 0, false))
			XFS_FSB_TO_B(mp, sbp->sb_width), 0,
			xfs_buf_daddr(bp) == XFS_SB_DADDR, false))
		return -EFSCORRUPTED;

	/*
@@ -1323,8 +1324,10 @@ xfs_sb_get_secondary(
}

/*
 * sunit, swidth, sectorsize(optional with 0) should be all in bytes,
 * so users won't be confused by values in error messages.
 * sunit, swidth, sectorsize(optional with 0) should be all in bytes, so users
 * won't be confused by values in error messages.  This function returns false
 * if the stripe geometry is invalid and the caller is unable to repair the
 * stripe configuration later in the mount process.
 */
bool
xfs_validate_stripe_geometry(
@@ -1332,20 +1335,21 @@ xfs_validate_stripe_geometry(
	__s64			sunit,
	__s64			swidth,
	int			sectorsize,
	bool			may_repair,
	bool			silent)
{
	if (swidth > INT_MAX) {
		if (!silent)
			xfs_notice(mp,
"stripe width (%lld) is too large", swidth);
		return false;
		goto check_override;
	}

	if (sunit > swidth) {
		if (!silent)
			xfs_notice(mp,
"stripe unit (%lld) is larger than the stripe width (%lld)", sunit, swidth);
		return false;
		goto check_override;
	}

	if (sectorsize && (int)sunit % sectorsize) {
@@ -1353,21 +1357,21 @@ xfs_validate_stripe_geometry(
			xfs_notice(mp,
"stripe unit (%lld) must be a multiple of the sector size (%d)",
				   sunit, sectorsize);
		return false;
		goto check_override;
	}

	if (sunit && !swidth) {
		if (!silent)
			xfs_notice(mp,
"invalid stripe unit (%lld) and stripe width of 0", sunit);
		return false;
		goto check_override;
	}

	if (!sunit && swidth) {
		if (!silent)
			xfs_notice(mp,
"invalid stripe width (%lld) and stripe unit of 0", swidth);
		return false;
		goto check_override;
	}

	if (sunit && (int)swidth % (int)sunit) {
@@ -1375,9 +1379,27 @@ xfs_validate_stripe_geometry(
			xfs_notice(mp,
"stripe width (%lld) must be a multiple of the stripe unit (%lld)",
				   swidth, sunit);
		return false;
		goto check_override;
	}
	return true;

check_override:
	if (!may_repair)
		return false;
	/*
	 * During mount, mp->m_dalign will not be set unless the sunit mount
	 * option was set. If it was set, ignore the bad stripe alignment values
	 * and allow the validation and overwrite later in the mount process to
	 * attempt to overwrite the bad stripe alignment values with the values
	 * supplied by mount options.
	 */
	if (!mp->m_dalign)
		return false;
	if (!silent)
		xfs_notice(mp,
"Will try to correct with specified mount options sunit (%d) and swidth (%d)",
			BBTOB(mp->m_dalign), BBTOB(mp->m_swidth));
	return true;
}

/*
+3 −2
Original line number Diff line number Diff line
@@ -35,8 +35,9 @@ extern int xfs_sb_get_secondary(struct xfs_mount *mp,
				struct xfs_trans *tp, xfs_agnumber_t agno,
				struct xfs_buf **bpp);

extern bool	xfs_validate_stripe_geometry(struct xfs_mount *mp,
		__s64 sunit, __s64 swidth, int sectorsize, bool silent);
bool	xfs_validate_stripe_geometry(struct xfs_mount *mp,
		__s64 sunit, __s64 swidth, int sectorsize, bool may_repair,
		bool silent);

uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);

+1 −3
Original line number Diff line number Diff line
@@ -1044,9 +1044,7 @@ xchk_irele(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip)
{
	if (current->journal_info != NULL) {
		ASSERT(current->journal_info == sc->tp);

	if (sc->tp) {
		/*
		 * If we are in a transaction, we /cannot/ drop the inode
		 * ourselves, because the VFS will trigger writeback, which
+0 −7
Original line number Diff line number Diff line
@@ -503,13 +503,6 @@ xfs_vm_writepages(
{
	struct xfs_writepage_ctx wpc = { };

	/*
	 * Writing back data in a transaction context can result in recursive
	 * transactions. This is bad, so issue a warning and get out of here.
	 */
	if (WARN_ON_ONCE(current->journal_info))
		return 0;

	xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
	return iomap_writepages(mapping, wbc, &wpc.ctx, &xfs_writeback_ops);
}
+5 −3
Original line number Diff line number Diff line
@@ -2039,8 +2039,10 @@ xfs_inodegc_want_queue_work(
 *  - Memory shrinkers queued the inactivation worker and it hasn't finished.
 *  - The queue depth exceeds the maximum allowable percpu backlog.
 *
 * Note: If the current thread is running a transaction, we don't ever want to
 * wait for other transactions because that could introduce a deadlock.
 * Note: If we are in a NOFS context here (e.g. current thread is running a
 * transaction) the we don't want to block here as inodegc progress may require
 * filesystem resources we hold to make progress and that could result in a
 * deadlock. Hence we skip out of here if we are in a scoped NOFS context.
 */
static inline bool
xfs_inodegc_want_flush_work(
@@ -2048,7 +2050,7 @@ xfs_inodegc_want_flush_work(
	unsigned int		items,
	unsigned int		shrinker_hits)
{
	if (current->journal_info)
	if (current->flags & PF_MEMALLOC_NOFS)
		return false;

	if (shrinker_hits > 0)
Loading