aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2008-04-09 22:21:11 -0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-17 21:58:08 -0400
commit3c1e2bbe5bcdcd435510a05eb121fa74b848e24f (patch)
tree1b53868f47e95afde9317964c642db0faa4b36ba /fs
parent5ca1f261a08d5cff5f29eaa0887b59baae2ae7f7 (diff)
[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: David Chinner <dgc@sgi.com> Signed-off-by: Niv Sardi <xaiki@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_log_recover.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index c37521467fdc..957b8caddf1e 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2965,7 +2965,7 @@ xlog_recover_process_data(
2965 * Process an extent free intent item that was recovered from 2965 * Process an extent free intent item that was recovered from
2966 * the log. We need to free the extents that it describes. 2966 * the log. We need to free the extents that it describes.
2967 */ 2967 */
2968STATIC void 2968STATIC int
2969xlog_recover_process_efi( 2969xlog_recover_process_efi(
2970 xfs_mount_t *mp, 2970 xfs_mount_t *mp,
2971 xfs_efi_log_item_t *efip) 2971 xfs_efi_log_item_t *efip)
@@ -2973,6 +2973,7 @@ xlog_recover_process_efi(
2973 xfs_efd_log_item_t *efdp; 2973 xfs_efd_log_item_t *efdp;
2974 xfs_trans_t *tp; 2974 xfs_trans_t *tp;
2975 int i; 2975 int i;
2976 int error = 0;
2976 xfs_extent_t *extp; 2977 xfs_extent_t *extp;
2977 xfs_fsblock_t startblock_fsb; 2978 xfs_fsblock_t startblock_fsb;
2978 2979
@@ -2996,12 +2997,16 @@ xlog_recover_process_efi(
2996 * free the memory associated with it. 2997 * free the memory associated with it.
2997 */ 2998 */
2998 xfs_efi_release(efip, efip->efi_format.efi_nextents); 2999 xfs_efi_release(efip, efip->efi_format.efi_nextents);
2999 return; 3000 return XFS_ERROR(EIO);
3000 } 3001 }
3001 } 3002 }
3002 3003
3003 tp = xfs_trans_alloc(mp, 0); 3004 tp = xfs_trans_alloc(mp, 0);
3004 xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0); 3005 error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
3006 if (error) {
3007 xfs_trans_cancel(tp, XFS_TRANS_ABORT);
3008 return error;
3009 }
3005 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); 3010 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
3006 3011
3007 for (i = 0; i < efip->efi_format.efi_nextents; i++) { 3012 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
@@ -3013,6 +3018,7 @@ xlog_recover_process_efi(
3013 3018
3014 efip->efi_flags |= XFS_EFI_RECOVERED; 3019 efip->efi_flags |= XFS_EFI_RECOVERED;
3015 xfs_trans_commit(tp, 0); 3020 xfs_trans_commit(tp, 0);
3021 return error;
3016} 3022}
3017 3023
3018/* 3024/*
@@ -3060,7 +3066,7 @@ xlog_recover_check_ail(
3060 * everything already in the AIL, we stop processing as soon as 3066 * everything already in the AIL, we stop processing as soon as
3061 * we see something other than an EFI in the AIL. 3067 * we see something other than an EFI in the AIL.
3062 */ 3068 */
3063STATIC void 3069STATIC int
3064xlog_recover_process_efis( 3070xlog_recover_process_efis(
3065 xlog_t *log) 3071 xlog_t *log)
3066{ 3072{
@@ -3068,6 +3074,7 @@ xlog_recover_process_efis(
3068 xfs_efi_log_item_t *efip; 3074 xfs_efi_log_item_t *efip;
3069 int gen; 3075 int gen;
3070 xfs_mount_t *mp; 3076 xfs_mount_t *mp;
3077 int error = 0;
3071 3078
3072 mp = log->l_mp; 3079 mp = log->l_mp;
3073 spin_lock(&mp->m_ail_lock); 3080 spin_lock(&mp->m_ail_lock);
@@ -3092,11 +3099,14 @@ xlog_recover_process_efis(
3092 } 3099 }
3093 3100
3094 spin_unlock(&mp->m_ail_lock); 3101 spin_unlock(&mp->m_ail_lock);
3095 xlog_recover_process_efi(mp, efip); 3102 error = xlog_recover_process_efi(mp, efip);
3103 if (error)
3104 return error;
3096 spin_lock(&mp->m_ail_lock); 3105 spin_lock(&mp->m_ail_lock);
3097 lip = xfs_trans_next_ail(mp, lip, &gen, NULL); 3106 lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
3098 } 3107 }
3099 spin_unlock(&mp->m_ail_lock); 3108 spin_unlock(&mp->m_ail_lock);
3109 return error;
3100} 3110}
3101 3111
3102/* 3112/*
@@ -3116,9 +3126,9 @@ xlog_recover_clear_agi_bucket(
3116 int error; 3126 int error;
3117 3127
3118 tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); 3128 tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
3119 xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0); 3129 error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
3120 3130 if (!error)
3121 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 3131 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
3122 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 3132 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
3123 XFS_FSS_TO_BB(mp, 1), 0, &agibp); 3133 XFS_FSS_TO_BB(mp, 1), 0, &agibp);
3124 if (error) { 3134 if (error) {
@@ -3919,7 +3929,14 @@ xlog_recover_finish(
3919 * rather than accepting new requests. 3929 * rather than accepting new requests.
3920 */ 3930 */
3921 if (log->l_flags & XLOG_RECOVERY_NEEDED) { 3931 if (log->l_flags & XLOG_RECOVERY_NEEDED) {
3922 xlog_recover_process_efis(log); 3932 int error;
3933 error = xlog_recover_process_efis(log);
3934 if (error) {
3935 cmn_err(CE_ALERT,
3936 "Failed to recover EFIs on filesystem: %s",
3937 log->l_mp->m_fsname);
3938 return error;
3939 }
3923 /* 3940 /*
3924 * Sync the log to get all the EFIs out of the AIL. 3941 * Sync the log to get all the EFIs out of the AIL.
3925 * This isn't absolutely necessary, but it helps in 3942 * This isn't absolutely necessary, but it helps in