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

[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
...@@ -2965,7 +2965,7 @@ xlog_recover_process_data( ...@@ -2965,7 +2965,7 @@ xlog_recover_process_data(
* Process an extent free intent item that was recovered from * Process an extent free intent item that was recovered from
* the log. We need to free the extents that it describes. * the log. We need to free the extents that it describes.
*/ */
STATIC void STATIC int
xlog_recover_process_efi( xlog_recover_process_efi(
xfs_mount_t *mp, xfs_mount_t *mp,
xfs_efi_log_item_t *efip) xfs_efi_log_item_t *efip)
...@@ -2973,6 +2973,7 @@ xlog_recover_process_efi( ...@@ -2973,6 +2973,7 @@ xlog_recover_process_efi(
xfs_efd_log_item_t *efdp; xfs_efd_log_item_t *efdp;
xfs_trans_t *tp; xfs_trans_t *tp;
int i; int i;
int error = 0;
xfs_extent_t *extp; xfs_extent_t *extp;
xfs_fsblock_t startblock_fsb; xfs_fsblock_t startblock_fsb;
...@@ -2996,12 +2997,16 @@ xlog_recover_process_efi( ...@@ -2996,12 +2997,16 @@ xlog_recover_process_efi(
* free the memory associated with it. * free the memory associated with it.
*/ */
xfs_efi_release(efip, efip->efi_format.efi_nextents); xfs_efi_release(efip, efip->efi_format.efi_nextents);
return; return XFS_ERROR(EIO);
} }
} }
tp = xfs_trans_alloc(mp, 0); 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); efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
for (i = 0; i < efip->efi_format.efi_nextents; i++) { for (i = 0; i < efip->efi_format.efi_nextents; i++) {
...@@ -3013,6 +3018,7 @@ xlog_recover_process_efi( ...@@ -3013,6 +3018,7 @@ xlog_recover_process_efi(
efip->efi_flags |= XFS_EFI_RECOVERED; efip->efi_flags |= XFS_EFI_RECOVERED;
xfs_trans_commit(tp, 0); xfs_trans_commit(tp, 0);
return error;
} }
/* /*
...@@ -3060,7 +3066,7 @@ xlog_recover_check_ail( ...@@ -3060,7 +3066,7 @@ xlog_recover_check_ail(
* everything already in the AIL, we stop processing as soon as * everything already in the AIL, we stop processing as soon as
* we see something other than an EFI in the AIL. * we see something other than an EFI in the AIL.
*/ */
STATIC void STATIC int
xlog_recover_process_efis( xlog_recover_process_efis(
xlog_t *log) xlog_t *log)
{ {
...@@ -3068,6 +3074,7 @@ xlog_recover_process_efis( ...@@ -3068,6 +3074,7 @@ xlog_recover_process_efis(
xfs_efi_log_item_t *efip; xfs_efi_log_item_t *efip;
int gen; int gen;
xfs_mount_t *mp; xfs_mount_t *mp;
int error = 0;
mp = log->l_mp; mp = log->l_mp;
spin_lock(&mp->m_ail_lock); spin_lock(&mp->m_ail_lock);
...@@ -3092,11 +3099,14 @@ xlog_recover_process_efis( ...@@ -3092,11 +3099,14 @@ xlog_recover_process_efis(
} }
spin_unlock(&mp->m_ail_lock); 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); spin_lock(&mp->m_ail_lock);
lip = xfs_trans_next_ail(mp, lip, &gen, NULL); lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
} }
spin_unlock(&mp->m_ail_lock); spin_unlock(&mp->m_ail_lock);
return error;
} }
/* /*
...@@ -3116,8 +3126,8 @@ xlog_recover_clear_agi_bucket( ...@@ -3116,8 +3126,8 @@ xlog_recover_clear_agi_bucket(
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); 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, error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &agibp); XFS_FSS_TO_BB(mp, 1), 0, &agibp);
...@@ -3919,7 +3929,14 @@ xlog_recover_finish( ...@@ -3919,7 +3929,14 @@ xlog_recover_finish(
* rather than accepting new requests. * rather than accepting new requests.
*/ */
if (log->l_flags & XLOG_RECOVERY_NEEDED) { 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. * Sync the log to get all the EFIs out of the AIL.
* This isn't absolutely necessary, but it helps in * This isn't absolutely necessary, but it helps in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment