aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r--fs/xfs/xfs_log_recover.c132
1 files changed, 63 insertions, 69 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 931e8e23f19..9c3651c9e75 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -41,6 +41,7 @@
41#include "xfs_trans_priv.h" 41#include "xfs_trans_priv.h"
42#include "xfs_quota.h" 42#include "xfs_quota.h"
43#include "xfs_utils.h" 43#include "xfs_utils.h"
44#include "xfs_cksum.h"
44#include "xfs_trace.h" 45#include "xfs_trace.h"
45#include "xfs_icache.h" 46#include "xfs_icache.h"
46 47
@@ -3216,80 +3217,58 @@ xlog_recover_process_iunlinks(
3216 mp->m_dmevmask = mp_dmevmask; 3217 mp->m_dmevmask = mp_dmevmask;
3217} 3218}
3218 3219
3219
3220#ifdef DEBUG
3221STATIC void
3222xlog_pack_data_checksum(
3223 struct xlog *log,
3224 struct xlog_in_core *iclog,
3225 int size)
3226{
3227 int i;
3228 __be32 *up;
3229 uint chksum = 0;
3230
3231 up = (__be32 *)iclog->ic_datap;
3232 /* divide length by 4 to get # words */
3233 for (i = 0; i < (size >> 2); i++) {
3234 chksum ^= be32_to_cpu(*up);
3235 up++;
3236 }
3237 iclog->ic_header.h_chksum = cpu_to_be32(chksum);
3238}
3239#else
3240#define xlog_pack_data_checksum(log, iclog, size)
3241#endif
3242
3243/* 3220/*
3244 * Stamp cycle number in every block 3221 * Upack the log buffer data and crc check it. If the check fails, issue a
3222 * warning if and only if the CRC in the header is non-zero. This makes the
3223 * check an advisory warning, and the zero CRC check will prevent failure
3224 * warnings from being emitted when upgrading the kernel from one that does not
3225 * add CRCs by default.
3226 *
3227 * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log
3228 * corruption failure
3245 */ 3229 */
3246void 3230STATIC int
3247xlog_pack_data( 3231xlog_unpack_data_crc(
3248 struct xlog *log, 3232 struct xlog_rec_header *rhead,
3249 struct xlog_in_core *iclog, 3233 xfs_caddr_t dp,
3250 int roundoff) 3234 struct xlog *log)
3251{ 3235{
3252 int i, j, k; 3236 __be32 crc;
3253 int size = iclog->ic_offset + roundoff; 3237
3254 __be32 cycle_lsn; 3238 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
3255 xfs_caddr_t dp; 3239 if (crc != rhead->h_crc) {
3256 3240 if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
3257 xlog_pack_data_checksum(log, iclog, size); 3241 xfs_alert(log->l_mp,
3258 3242 "log record CRC mismatch: found 0x%x, expected 0x%x.\n",
3259 cycle_lsn = CYCLE_LSN_DISK(iclog->ic_header.h_lsn); 3243 be32_to_cpu(rhead->h_crc),
3260 3244 be32_to_cpu(crc));
3261 dp = iclog->ic_datap; 3245 xfs_hex_dump(dp, 32);
3262 for (i = 0; i < BTOBB(size) &&
3263 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
3264 iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp;
3265 *(__be32 *)dp = cycle_lsn;
3266 dp += BBSIZE;
3267 }
3268
3269 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
3270 xlog_in_core_2_t *xhdr = iclog->ic_data;
3271
3272 for ( ; i < BTOBB(size); i++) {
3273 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3274 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3275 xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp;
3276 *(__be32 *)dp = cycle_lsn;
3277 dp += BBSIZE;
3278 } 3246 }
3279 3247
3280 for (i = 1; i < log->l_iclog_heads; i++) { 3248 /*
3281 xhdr[i].hic_xheader.xh_cycle = cycle_lsn; 3249 * If we've detected a log record corruption, then we can't
3282 } 3250 * recover past this point. Abort recovery if we are enforcing
3251 * CRC protection by punting an error back up the stack.
3252 */
3253 if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
3254 return EFSCORRUPTED;
3283 } 3255 }
3256
3257 return 0;
3284} 3258}
3285 3259
3286STATIC void 3260STATIC int
3287xlog_unpack_data( 3261xlog_unpack_data(
3288 struct xlog_rec_header *rhead, 3262 struct xlog_rec_header *rhead,
3289 xfs_caddr_t dp, 3263 xfs_caddr_t dp,
3290 struct xlog *log) 3264 struct xlog *log)
3291{ 3265{
3292 int i, j, k; 3266 int i, j, k;
3267 int error;
3268
3269 error = xlog_unpack_data_crc(rhead, dp, log);
3270 if (error)
3271 return error;
3293 3272
3294 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && 3273 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
3295 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { 3274 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
@@ -3306,6 +3285,8 @@ xlog_unpack_data(
3306 dp += BBSIZE; 3285 dp += BBSIZE;
3307 } 3286 }
3308 } 3287 }
3288
3289 return 0;
3309} 3290}
3310 3291
3311STATIC int 3292STATIC int
@@ -3437,9 +3418,13 @@ xlog_do_recovery_pass(
3437 if (error) 3418 if (error)
3438 goto bread_err2; 3419 goto bread_err2;
3439 3420
3440 xlog_unpack_data(rhead, offset, log); 3421 error = xlog_unpack_data(rhead, offset, log);
3441 if ((error = xlog_recover_process_data(log, 3422 if (error)
3442 rhash, rhead, offset, pass))) 3423 goto bread_err2;
3424
3425 error = xlog_recover_process_data(log,
3426 rhash, rhead, offset, pass);
3427 if (error)
3443 goto bread_err2; 3428 goto bread_err2;
3444 blk_no += bblks + hblks; 3429 blk_no += bblks + hblks;
3445 } 3430 }
@@ -3549,9 +3534,14 @@ xlog_do_recovery_pass(
3549 if (error) 3534 if (error)
3550 goto bread_err2; 3535 goto bread_err2;
3551 } 3536 }
3552 xlog_unpack_data(rhead, offset, log); 3537
3553 if ((error = xlog_recover_process_data(log, rhash, 3538 error = xlog_unpack_data(rhead, offset, log);
3554 rhead, offset, pass))) 3539 if (error)
3540 goto bread_err2;
3541
3542 error = xlog_recover_process_data(log, rhash,
3543 rhead, offset, pass);
3544 if (error)
3555 goto bread_err2; 3545 goto bread_err2;
3556 blk_no += bblks; 3546 blk_no += bblks;
3557 } 3547 }
@@ -3576,9 +3566,13 @@ xlog_do_recovery_pass(
3576 if (error) 3566 if (error)
3577 goto bread_err2; 3567 goto bread_err2;
3578 3568
3579 xlog_unpack_data(rhead, offset, log); 3569 error = xlog_unpack_data(rhead, offset, log);
3580 if ((error = xlog_recover_process_data(log, rhash, 3570 if (error)
3581 rhead, offset, pass))) 3571 goto bread_err2;
3572
3573 error = xlog_recover_process_data(log, rhash,
3574 rhead, offset, pass);
3575 if (error)
3582 goto bread_err2; 3576 goto bread_err2;
3583 blk_no += bblks + hblks; 3577 blk_no += bblks + hblks;
3584 } 3578 }