diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 35 |
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 | */ |
2968 | STATIC void | 2968 | STATIC int |
2969 | xlog_recover_process_efi( | 2969 | xlog_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 | */ |
3063 | STATIC void | 3069 | STATIC int |
3064 | xlog_recover_process_efis( | 3070 | xlog_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 |