diff options
author | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 07:34:25 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 07:34:25 -0400 |
commit | f838bad1b3be8ca0c785ee0e0c570dfda74cf377 (patch) | |
tree | 5a842a8056a708cfad55a20fa8ab733dd94b0903 /fs/xfs/xfs_log_recover.c | |
parent | dd919660aacdf4adfcd279556aa03e595f7f0fc2 (diff) | |
parent | 807501475fce0ebe68baedf87f202c3e4ee0d12c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 139 |
1 files changed, 93 insertions, 46 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b82d5d4d2462..e65ab4af0955 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "xfs_trans_priv.h" | 46 | #include "xfs_trans_priv.h" |
47 | #include "xfs_quota.h" | 47 | #include "xfs_quota.h" |
48 | #include "xfs_rw.h" | 48 | #include "xfs_rw.h" |
49 | #include "xfs_utils.h" | ||
49 | 50 | ||
50 | STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *); | 51 | STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *); |
51 | STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t); | 52 | STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t); |
@@ -120,7 +121,8 @@ xlog_bread( | |||
120 | XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp); | 121 | XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp); |
121 | 122 | ||
122 | xfsbdstrat(log->l_mp, bp); | 123 | xfsbdstrat(log->l_mp, bp); |
123 | if ((error = xfs_iowait(bp))) | 124 | error = xfs_iowait(bp); |
125 | if (error) | ||
124 | xfs_ioerror_alert("xlog_bread", log->l_mp, | 126 | xfs_ioerror_alert("xlog_bread", log->l_mp, |
125 | bp, XFS_BUF_ADDR(bp)); | 127 | bp, XFS_BUF_ADDR(bp)); |
126 | return error; | 128 | return error; |
@@ -191,7 +193,7 @@ xlog_header_check_dump( | |||
191 | { | 193 | { |
192 | int b; | 194 | int b; |
193 | 195 | ||
194 | cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__); | 196 | cmn_err(CE_DEBUG, "%s: SB : uuid = ", __func__); |
195 | for (b = 0; b < 16; b++) | 197 | for (b = 0; b < 16; b++) |
196 | cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]); | 198 | cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]); |
197 | cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT); | 199 | cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT); |
@@ -478,7 +480,7 @@ xlog_find_verify_log_record( | |||
478 | * reset last_blk. Only when last_blk points in the middle of a log | 480 | * reset last_blk. Only when last_blk points in the middle of a log |
479 | * record do we update last_blk. | 481 | * record do we update last_blk. |
480 | */ | 482 | */ |
481 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 483 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
482 | uint h_size = be32_to_cpu(head->h_size); | 484 | uint h_size = be32_to_cpu(head->h_size); |
483 | 485 | ||
484 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; | 486 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; |
@@ -888,7 +890,7 @@ xlog_find_tail( | |||
888 | * unmount record if there is one, so we pass the lsn of the | 890 | * unmount record if there is one, so we pass the lsn of the |
889 | * unmount record rather than the block after it. | 891 | * unmount record rather than the block after it. |
890 | */ | 892 | */ |
891 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 893 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
892 | int h_size = be32_to_cpu(rhead->h_size); | 894 | int h_size = be32_to_cpu(rhead->h_size); |
893 | int h_version = be32_to_cpu(rhead->h_version); | 895 | int h_version = be32_to_cpu(rhead->h_version); |
894 | 896 | ||
@@ -1101,7 +1103,7 @@ xlog_add_record( | |||
1101 | recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); | 1103 | recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
1102 | recp->h_cycle = cpu_to_be32(cycle); | 1104 | recp->h_cycle = cpu_to_be32(cycle); |
1103 | recp->h_version = cpu_to_be32( | 1105 | recp->h_version = cpu_to_be32( |
1104 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); | 1106 | xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1); |
1105 | recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block)); | 1107 | recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block)); |
1106 | recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block)); | 1108 | recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block)); |
1107 | recp->h_fmt = cpu_to_be32(XLOG_FMT); | 1109 | recp->h_fmt = cpu_to_be32(XLOG_FMT); |
@@ -1160,10 +1162,14 @@ xlog_write_log_records( | |||
1160 | if (j == 0 && (start_block + endcount > ealign)) { | 1162 | if (j == 0 && (start_block + endcount > ealign)) { |
1161 | offset = XFS_BUF_PTR(bp); | 1163 | offset = XFS_BUF_PTR(bp); |
1162 | balign = BBTOB(ealign - start_block); | 1164 | balign = BBTOB(ealign - start_block); |
1163 | XFS_BUF_SET_PTR(bp, offset + balign, BBTOB(sectbb)); | 1165 | error = XFS_BUF_SET_PTR(bp, offset + balign, |
1164 | if ((error = xlog_bread(log, ealign, sectbb, bp))) | 1166 | BBTOB(sectbb)); |
1167 | if (!error) | ||
1168 | error = xlog_bread(log, ealign, sectbb, bp); | ||
1169 | if (!error) | ||
1170 | error = XFS_BUF_SET_PTR(bp, offset, bufblks); | ||
1171 | if (error) | ||
1165 | break; | 1172 | break; |
1166 | XFS_BUF_SET_PTR(bp, offset, bufblks); | ||
1167 | } | 1173 | } |
1168 | 1174 | ||
1169 | offset = xlog_align(log, start_block, endcount, bp); | 1175 | offset = xlog_align(log, start_block, endcount, bp); |
@@ -2280,7 +2286,9 @@ xlog_recover_do_inode_trans( | |||
2280 | * invalidate the buffer when we write it out below. | 2286 | * invalidate the buffer when we write it out below. |
2281 | */ | 2287 | */ |
2282 | imap.im_blkno = 0; | 2288 | imap.im_blkno = 0; |
2283 | xfs_imap(log->l_mp, NULL, ino, &imap, 0); | 2289 | error = xfs_imap(log->l_mp, NULL, ino, &imap, 0); |
2290 | if (error) | ||
2291 | goto error; | ||
2284 | } | 2292 | } |
2285 | 2293 | ||
2286 | /* | 2294 | /* |
@@ -2964,7 +2972,7 @@ xlog_recover_process_data( | |||
2964 | * Process an extent free intent item that was recovered from | 2972 | * Process an extent free intent item that was recovered from |
2965 | * the log. We need to free the extents that it describes. | 2973 | * the log. We need to free the extents that it describes. |
2966 | */ | 2974 | */ |
2967 | STATIC void | 2975 | STATIC int |
2968 | xlog_recover_process_efi( | 2976 | xlog_recover_process_efi( |
2969 | xfs_mount_t *mp, | 2977 | xfs_mount_t *mp, |
2970 | xfs_efi_log_item_t *efip) | 2978 | xfs_efi_log_item_t *efip) |
@@ -2972,6 +2980,7 @@ xlog_recover_process_efi( | |||
2972 | xfs_efd_log_item_t *efdp; | 2980 | xfs_efd_log_item_t *efdp; |
2973 | xfs_trans_t *tp; | 2981 | xfs_trans_t *tp; |
2974 | int i; | 2982 | int i; |
2983 | int error = 0; | ||
2975 | xfs_extent_t *extp; | 2984 | xfs_extent_t *extp; |
2976 | xfs_fsblock_t startblock_fsb; | 2985 | xfs_fsblock_t startblock_fsb; |
2977 | 2986 | ||
@@ -2995,23 +3004,32 @@ xlog_recover_process_efi( | |||
2995 | * free the memory associated with it. | 3004 | * free the memory associated with it. |
2996 | */ | 3005 | */ |
2997 | xfs_efi_release(efip, efip->efi_format.efi_nextents); | 3006 | xfs_efi_release(efip, efip->efi_format.efi_nextents); |
2998 | return; | 3007 | return XFS_ERROR(EIO); |
2999 | } | 3008 | } |
3000 | } | 3009 | } |
3001 | 3010 | ||
3002 | tp = xfs_trans_alloc(mp, 0); | 3011 | tp = xfs_trans_alloc(mp, 0); |
3003 | xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0); | 3012 | error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0); |
3013 | if (error) | ||
3014 | goto abort_error; | ||
3004 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); | 3015 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); |
3005 | 3016 | ||
3006 | for (i = 0; i < efip->efi_format.efi_nextents; i++) { | 3017 | for (i = 0; i < efip->efi_format.efi_nextents; i++) { |
3007 | extp = &(efip->efi_format.efi_extents[i]); | 3018 | extp = &(efip->efi_format.efi_extents[i]); |
3008 | xfs_free_extent(tp, extp->ext_start, extp->ext_len); | 3019 | error = xfs_free_extent(tp, extp->ext_start, extp->ext_len); |
3020 | if (error) | ||
3021 | goto abort_error; | ||
3009 | xfs_trans_log_efd_extent(tp, efdp, extp->ext_start, | 3022 | xfs_trans_log_efd_extent(tp, efdp, extp->ext_start, |
3010 | extp->ext_len); | 3023 | extp->ext_len); |
3011 | } | 3024 | } |
3012 | 3025 | ||
3013 | efip->efi_flags |= XFS_EFI_RECOVERED; | 3026 | efip->efi_flags |= XFS_EFI_RECOVERED; |
3014 | xfs_trans_commit(tp, 0); | 3027 | error = xfs_trans_commit(tp, 0); |
3028 | return error; | ||
3029 | |||
3030 | abort_error: | ||
3031 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | ||
3032 | return error; | ||
3015 | } | 3033 | } |
3016 | 3034 | ||
3017 | /* | 3035 | /* |
@@ -3059,7 +3077,7 @@ xlog_recover_check_ail( | |||
3059 | * everything already in the AIL, we stop processing as soon as | 3077 | * everything already in the AIL, we stop processing as soon as |
3060 | * we see something other than an EFI in the AIL. | 3078 | * we see something other than an EFI in the AIL. |
3061 | */ | 3079 | */ |
3062 | STATIC void | 3080 | STATIC int |
3063 | xlog_recover_process_efis( | 3081 | xlog_recover_process_efis( |
3064 | xlog_t *log) | 3082 | xlog_t *log) |
3065 | { | 3083 | { |
@@ -3067,6 +3085,7 @@ xlog_recover_process_efis( | |||
3067 | xfs_efi_log_item_t *efip; | 3085 | xfs_efi_log_item_t *efip; |
3068 | int gen; | 3086 | int gen; |
3069 | xfs_mount_t *mp; | 3087 | xfs_mount_t *mp; |
3088 | int error = 0; | ||
3070 | 3089 | ||
3071 | mp = log->l_mp; | 3090 | mp = log->l_mp; |
3072 | spin_lock(&mp->m_ail_lock); | 3091 | spin_lock(&mp->m_ail_lock); |
@@ -3091,11 +3110,14 @@ xlog_recover_process_efis( | |||
3091 | } | 3110 | } |
3092 | 3111 | ||
3093 | spin_unlock(&mp->m_ail_lock); | 3112 | spin_unlock(&mp->m_ail_lock); |
3094 | xlog_recover_process_efi(mp, efip); | 3113 | error = xlog_recover_process_efi(mp, efip); |
3114 | if (error) | ||
3115 | return error; | ||
3095 | spin_lock(&mp->m_ail_lock); | 3116 | spin_lock(&mp->m_ail_lock); |
3096 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | 3117 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); |
3097 | } | 3118 | } |
3098 | spin_unlock(&mp->m_ail_lock); | 3119 | spin_unlock(&mp->m_ail_lock); |
3120 | return error; | ||
3099 | } | 3121 | } |
3100 | 3122 | ||
3101 | /* | 3123 | /* |
@@ -3115,21 +3137,18 @@ xlog_recover_clear_agi_bucket( | |||
3115 | int error; | 3137 | int error; |
3116 | 3138 | ||
3117 | tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); | 3139 | tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); |
3118 | xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0); | 3140 | error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0); |
3119 | 3141 | if (!error) | |
3120 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, | 3142 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, |
3121 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | 3143 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), |
3122 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 3144 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); |
3123 | if (error) { | 3145 | if (error) |
3124 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | 3146 | goto out_abort; |
3125 | return; | ||
3126 | } | ||
3127 | 3147 | ||
3148 | error = EINVAL; | ||
3128 | agi = XFS_BUF_TO_AGI(agibp); | 3149 | agi = XFS_BUF_TO_AGI(agibp); |
3129 | if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { | 3150 | if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) |
3130 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | 3151 | goto out_abort; |
3131 | return; | ||
3132 | } | ||
3133 | 3152 | ||
3134 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); | 3153 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); |
3135 | offset = offsetof(xfs_agi_t, agi_unlinked) + | 3154 | offset = offsetof(xfs_agi_t, agi_unlinked) + |
@@ -3137,7 +3156,17 @@ xlog_recover_clear_agi_bucket( | |||
3137 | xfs_trans_log_buf(tp, agibp, offset, | 3156 | xfs_trans_log_buf(tp, agibp, offset, |
3138 | (offset + sizeof(xfs_agino_t) - 1)); | 3157 | (offset + sizeof(xfs_agino_t) - 1)); |
3139 | 3158 | ||
3140 | (void) xfs_trans_commit(tp, 0); | 3159 | error = xfs_trans_commit(tp, 0); |
3160 | if (error) | ||
3161 | goto out_error; | ||
3162 | return; | ||
3163 | |||
3164 | out_abort: | ||
3165 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | ||
3166 | out_error: | ||
3167 | xfs_fs_cmn_err(CE_WARN, mp, "xlog_recover_clear_agi_bucket: " | ||
3168 | "failed to clear agi %d. Continuing.", agno); | ||
3169 | return; | ||
3141 | } | 3170 | } |
3142 | 3171 | ||
3143 | /* | 3172 | /* |
@@ -3214,7 +3243,8 @@ xlog_recover_process_iunlinks( | |||
3214 | * next inode in the bucket. | 3243 | * next inode in the bucket. |
3215 | */ | 3244 | */ |
3216 | error = xfs_itobp(mp, NULL, ip, &dip, | 3245 | error = xfs_itobp(mp, NULL, ip, &dip, |
3217 | &ibp, 0, 0); | 3246 | &ibp, 0, 0, |
3247 | XFS_BUF_LOCK); | ||
3218 | ASSERT(error || (dip != NULL)); | 3248 | ASSERT(error || (dip != NULL)); |
3219 | } | 3249 | } |
3220 | 3250 | ||
@@ -3247,7 +3277,7 @@ xlog_recover_process_iunlinks( | |||
3247 | if (ip->i_d.di_mode == 0) | 3277 | if (ip->i_d.di_mode == 0) |
3248 | xfs_iput_new(ip, 0); | 3278 | xfs_iput_new(ip, 0); |
3249 | else | 3279 | else |
3250 | VN_RELE(XFS_ITOV(ip)); | 3280 | IRELE(ip); |
3251 | } else { | 3281 | } else { |
3252 | /* | 3282 | /* |
3253 | * We can't read in the inode | 3283 | * We can't read in the inode |
@@ -3348,7 +3378,7 @@ xlog_pack_data( | |||
3348 | dp += BBSIZE; | 3378 | dp += BBSIZE; |
3349 | } | 3379 | } |
3350 | 3380 | ||
3351 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3381 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
3352 | xhdr = (xlog_in_core_2_t *)&iclog->ic_header; | 3382 | xhdr = (xlog_in_core_2_t *)&iclog->ic_header; |
3353 | for ( ; i < BTOBB(size); i++) { | 3383 | for ( ; i < BTOBB(size); i++) { |
3354 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3384 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
@@ -3388,7 +3418,7 @@ xlog_unpack_data_checksum( | |||
3388 | be32_to_cpu(rhead->h_chksum), chksum); | 3418 | be32_to_cpu(rhead->h_chksum), chksum); |
3389 | cmn_err(CE_DEBUG, | 3419 | cmn_err(CE_DEBUG, |
3390 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); | 3420 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); |
3391 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3421 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
3392 | cmn_err(CE_DEBUG, | 3422 | cmn_err(CE_DEBUG, |
3393 | "XFS: LogR this is a LogV2 filesystem\n"); | 3423 | "XFS: LogR this is a LogV2 filesystem\n"); |
3394 | } | 3424 | } |
@@ -3415,7 +3445,7 @@ xlog_unpack_data( | |||
3415 | dp += BBSIZE; | 3445 | dp += BBSIZE; |
3416 | } | 3446 | } |
3417 | 3447 | ||
3418 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3448 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
3419 | xhdr = (xlog_in_core_2_t *)rhead; | 3449 | xhdr = (xlog_in_core_2_t *)rhead; |
3420 | for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { | 3450 | for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { |
3421 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3451 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
@@ -3445,7 +3475,7 @@ xlog_valid_rec_header( | |||
3445 | (!rhead->h_version || | 3475 | (!rhead->h_version || |
3446 | (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { | 3476 | (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { |
3447 | xlog_warn("XFS: %s: unrecognised log version (%d).", | 3477 | xlog_warn("XFS: %s: unrecognised log version (%d).", |
3448 | __FUNCTION__, be32_to_cpu(rhead->h_version)); | 3478 | __func__, be32_to_cpu(rhead->h_version)); |
3449 | return XFS_ERROR(EIO); | 3479 | return XFS_ERROR(EIO); |
3450 | } | 3480 | } |
3451 | 3481 | ||
@@ -3494,7 +3524,7 @@ xlog_do_recovery_pass( | |||
3494 | * Read the header of the tail block and get the iclog buffer size from | 3524 | * Read the header of the tail block and get the iclog buffer size from |
3495 | * h_size. Use this to tell how many sectors make up the log header. | 3525 | * h_size. Use this to tell how many sectors make up the log header. |
3496 | */ | 3526 | */ |
3497 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3527 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
3498 | /* | 3528 | /* |
3499 | * When using variable length iclogs, read first sector of | 3529 | * When using variable length iclogs, read first sector of |
3500 | * iclog header and extract the header size from it. Get a | 3530 | * iclog header and extract the header size from it. Get a |
@@ -3604,15 +3634,19 @@ xlog_do_recovery_pass( | |||
3604 | * _first_, then the log start (LR header end) | 3634 | * _first_, then the log start (LR header end) |
3605 | * - order is important. | 3635 | * - order is important. |
3606 | */ | 3636 | */ |
3637 | wrapped_hblks = hblks - split_hblks; | ||
3607 | bufaddr = XFS_BUF_PTR(hbp); | 3638 | bufaddr = XFS_BUF_PTR(hbp); |
3608 | XFS_BUF_SET_PTR(hbp, | 3639 | error = XFS_BUF_SET_PTR(hbp, |
3609 | bufaddr + BBTOB(split_hblks), | 3640 | bufaddr + BBTOB(split_hblks), |
3610 | BBTOB(hblks - split_hblks)); | 3641 | BBTOB(hblks - split_hblks)); |
3611 | wrapped_hblks = hblks - split_hblks; | 3642 | if (!error) |
3612 | error = xlog_bread(log, 0, wrapped_hblks, hbp); | 3643 | error = xlog_bread(log, 0, |
3644 | wrapped_hblks, hbp); | ||
3645 | if (!error) | ||
3646 | error = XFS_BUF_SET_PTR(hbp, bufaddr, | ||
3647 | BBTOB(hblks)); | ||
3613 | if (error) | 3648 | if (error) |
3614 | goto bread_err2; | 3649 | goto bread_err2; |
3615 | XFS_BUF_SET_PTR(hbp, bufaddr, BBTOB(hblks)); | ||
3616 | if (!offset) | 3650 | if (!offset) |
3617 | offset = xlog_align(log, 0, | 3651 | offset = xlog_align(log, 0, |
3618 | wrapped_hblks, hbp); | 3652 | wrapped_hblks, hbp); |
@@ -3664,13 +3698,18 @@ xlog_do_recovery_pass( | |||
3664 | * - order is important. | 3698 | * - order is important. |
3665 | */ | 3699 | */ |
3666 | bufaddr = XFS_BUF_PTR(dbp); | 3700 | bufaddr = XFS_BUF_PTR(dbp); |
3667 | XFS_BUF_SET_PTR(dbp, | 3701 | error = XFS_BUF_SET_PTR(dbp, |
3668 | bufaddr + BBTOB(split_bblks), | 3702 | bufaddr + BBTOB(split_bblks), |
3669 | BBTOB(bblks - split_bblks)); | 3703 | BBTOB(bblks - split_bblks)); |
3670 | if ((error = xlog_bread(log, wrapped_hblks, | 3704 | if (!error) |
3671 | bblks - split_bblks, dbp))) | 3705 | error = xlog_bread(log, wrapped_hblks, |
3706 | bblks - split_bblks, | ||
3707 | dbp); | ||
3708 | if (!error) | ||
3709 | error = XFS_BUF_SET_PTR(dbp, bufaddr, | ||
3710 | h_size); | ||
3711 | if (error) | ||
3672 | goto bread_err2; | 3712 | goto bread_err2; |
3673 | XFS_BUF_SET_PTR(dbp, bufaddr, h_size); | ||
3674 | if (!offset) | 3713 | if (!offset) |
3675 | offset = xlog_align(log, wrapped_hblks, | 3714 | offset = xlog_align(log, wrapped_hblks, |
3676 | bblks - split_bblks, dbp); | 3715 | bblks - split_bblks, dbp); |
@@ -3826,7 +3865,8 @@ xlog_do_recover( | |||
3826 | XFS_BUF_READ(bp); | 3865 | XFS_BUF_READ(bp); |
3827 | XFS_BUF_UNASYNC(bp); | 3866 | XFS_BUF_UNASYNC(bp); |
3828 | xfsbdstrat(log->l_mp, bp); | 3867 | xfsbdstrat(log->l_mp, bp); |
3829 | if ((error = xfs_iowait(bp))) { | 3868 | error = xfs_iowait(bp); |
3869 | if (error) { | ||
3830 | xfs_ioerror_alert("xlog_do_recover", | 3870 | xfs_ioerror_alert("xlog_do_recover", |
3831 | log->l_mp, bp, XFS_BUF_ADDR(bp)); | 3871 | log->l_mp, bp, XFS_BUF_ADDR(bp)); |
3832 | ASSERT(0); | 3872 | ASSERT(0); |
@@ -3838,7 +3878,7 @@ xlog_do_recover( | |||
3838 | sbp = &log->l_mp->m_sb; | 3878 | sbp = &log->l_mp->m_sb; |
3839 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); | 3879 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); |
3840 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); | 3880 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); |
3841 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); | 3881 | ASSERT(xfs_sb_good_version(sbp)); |
3842 | xfs_buf_relse(bp); | 3882 | xfs_buf_relse(bp); |
3843 | 3883 | ||
3844 | /* We've re-read the superblock so re-initialize per-cpu counters */ | 3884 | /* We've re-read the superblock so re-initialize per-cpu counters */ |
@@ -3917,7 +3957,14 @@ xlog_recover_finish( | |||
3917 | * rather than accepting new requests. | 3957 | * rather than accepting new requests. |
3918 | */ | 3958 | */ |
3919 | if (log->l_flags & XLOG_RECOVERY_NEEDED) { | 3959 | if (log->l_flags & XLOG_RECOVERY_NEEDED) { |
3920 | xlog_recover_process_efis(log); | 3960 | int error; |
3961 | error = xlog_recover_process_efis(log); | ||
3962 | if (error) { | ||
3963 | cmn_err(CE_ALERT, | ||
3964 | "Failed to recover EFIs on filesystem: %s", | ||
3965 | log->l_mp->m_fsname); | ||
3966 | return error; | ||
3967 | } | ||
3921 | /* | 3968 | /* |
3922 | * Sync the log to get all the EFIs out of the AIL. | 3969 | * Sync the log to get all the EFIs out of the AIL. |
3923 | * This isn't absolutely necessary, but it helps in | 3970 | * This isn't absolutely necessary, but it helps in |