Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c1e2bbe authored by David Chinner's avatar David Chinner Committed by Lachlan McIlroy
Browse files

[XFS] Propagate xfs_trans_reserve() errors.



xfs_trans_reserve() reports errors that should not be ignored. For
example, a shutdown filesystem will report errors through
xfs_trans_reserve() to prevent further changes from being attempted on a
damaged filesystem. Catch and propagate all error conditions from
xfs_trans_reserve().

SGI-PV: 980084
SGI-Modid: xfs-linux-melb:xfs-kern:30794a

Signed-off-by: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarNiv Sardi <xaiki@sgi.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent 5ca1f261
Loading
Loading
Loading
Loading
+26 −9
Original line number Diff line number Diff line
@@ -2965,7 +2965,7 @@ xlog_recover_process_data(
 * Process an extent free intent item that was recovered from
 * the log.  We need to free the extents that it describes.
 */
STATIC void
STATIC int
xlog_recover_process_efi(
	xfs_mount_t		*mp,
	xfs_efi_log_item_t	*efip)
@@ -2973,6 +2973,7 @@ xlog_recover_process_efi(
	xfs_efd_log_item_t	*efdp;
	xfs_trans_t		*tp;
	int			i;
	int			error = 0;
	xfs_extent_t		*extp;
	xfs_fsblock_t		startblock_fsb;

@@ -2996,12 +2997,16 @@ xlog_recover_process_efi(
			 * free the memory associated with it.
			 */
			xfs_efi_release(efip, efip->efi_format.efi_nextents);
			return;
			return XFS_ERROR(EIO);
		}
	}

	tp = xfs_trans_alloc(mp, 0);
	xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
	error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
	if (error) {
		xfs_trans_cancel(tp, XFS_TRANS_ABORT);
		return error;
	}
	efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);

	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
@@ -3013,6 +3018,7 @@ xlog_recover_process_efi(

	efip->efi_flags |= XFS_EFI_RECOVERED;
	xfs_trans_commit(tp, 0);
	return error;
}

/*
@@ -3060,7 +3066,7 @@ xlog_recover_check_ail(
 * everything already in the AIL, we stop processing as soon as
 * we see something other than an EFI in the AIL.
 */
STATIC void
STATIC int
xlog_recover_process_efis(
	xlog_t			*log)
{
@@ -3068,6 +3074,7 @@ xlog_recover_process_efis(
	xfs_efi_log_item_t	*efip;
	int			gen;
	xfs_mount_t		*mp;
	int			error = 0;

	mp = log->l_mp;
	spin_lock(&mp->m_ail_lock);
@@ -3092,11 +3099,14 @@ xlog_recover_process_efis(
		}

		spin_unlock(&mp->m_ail_lock);
		xlog_recover_process_efi(mp, efip);
		error = xlog_recover_process_efi(mp, efip);
		if (error)
			return error;
		spin_lock(&mp->m_ail_lock);
		lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
	}
	spin_unlock(&mp->m_ail_lock);
	return error;
}

/*
@@ -3116,8 +3126,8 @@ xlog_recover_clear_agi_bucket(
	int		error;

	tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
	xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);

	error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
	if (!error)
		error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
				   XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
				   XFS_FSS_TO_BB(mp, 1), 0, &agibp);
@@ -3919,7 +3929,14 @@ xlog_recover_finish(
	 * rather than accepting new requests.
	 */
	if (log->l_flags & XLOG_RECOVERY_NEEDED) {
		xlog_recover_process_efis(log);
		int	error;
		error = xlog_recover_process_efis(log);
		if (error) {
			cmn_err(CE_ALERT,
				"Failed to recover EFIs on filesystem: %s",
				log->l_mp->m_fsname);
			return error;
		}
		/*
		 * Sync the log to get all the EFIs out of the AIL.
		 * This isn't absolutely necessary, but it helps in