aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_log_recover.c72
1 files changed, 26 insertions, 46 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 236ebaf678f2..9ec4bbd28d55 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -4118,46 +4118,6 @@ xlog_recover_process_iunlinks(
4118 mp->m_dmevmask = mp_dmevmask; 4118 mp->m_dmevmask = mp_dmevmask;
4119} 4119}
4120 4120
4121/*
4122 * Upack the log buffer data and crc check it. If the check fails, issue a
4123 * warning if and only if the CRC in the header is non-zero. This makes the
4124 * check an advisory warning, and the zero CRC check will prevent failure
4125 * warnings from being emitted when upgrading the kernel from one that does not
4126 * add CRCs by default.
4127 *
4128 * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log
4129 * corruption failure
4130 */
4131STATIC int
4132xlog_unpack_data_crc(
4133 struct xlog_rec_header *rhead,
4134 char *dp,
4135 struct xlog *log)
4136{
4137 __le32 crc;
4138
4139 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
4140 if (crc != rhead->h_crc) {
4141 if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
4142 xfs_alert(log->l_mp,
4143 "log record CRC mismatch: found 0x%x, expected 0x%x.",
4144 le32_to_cpu(rhead->h_crc),
4145 le32_to_cpu(crc));
4146 xfs_hex_dump(dp, 32);
4147 }
4148
4149 /*
4150 * If we've detected a log record corruption, then we can't
4151 * recover past this point. Abort recovery if we are enforcing
4152 * CRC protection by punting an error back up the stack.
4153 */
4154 if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
4155 return -EFSCORRUPTED;
4156 }
4157
4158 return 0;
4159}
4160
4161STATIC int 4121STATIC int
4162xlog_unpack_data( 4122xlog_unpack_data(
4163 struct xlog_rec_header *rhead, 4123 struct xlog_rec_header *rhead,
@@ -4165,11 +4125,6 @@ xlog_unpack_data(
4165 struct xlog *log) 4125 struct xlog *log)
4166{ 4126{
4167 int i, j, k; 4127 int i, j, k;
4168 int error;
4169
4170 error = xlog_unpack_data_crc(rhead, dp, log);
4171 if (error)
4172 return error;
4173 4128
4174 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && 4129 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
4175 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { 4130 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
@@ -4191,7 +4146,7 @@ xlog_unpack_data(
4191} 4146}
4192 4147
4193/* 4148/*
4194 * Unpack and process a log record. 4149 * CRC check, unpack and process a log record.
4195 */ 4150 */
4196STATIC int 4151STATIC int
4197xlog_recover_process( 4152xlog_recover_process(
@@ -4202,6 +4157,31 @@ xlog_recover_process(
4202 int pass) 4157 int pass)
4203{ 4158{
4204 int error; 4159 int error;
4160 __le32 crc;
4161
4162 /*
4163 * Check the CRC and issue a warning if and only if the CRC in the
4164 * header is non-zero. This is an advisory warning and the zero CRC
4165 * check prevents warnings from being emitted when upgrading the kernel
4166 * from one that does not add CRCs by default.
4167 */
4168 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
4169 if (crc != le32_to_cpu(rhead->h_crc)) {
4170 if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
4171 xfs_alert(log->l_mp,
4172 "log record CRC mismatch: found 0x%x, expected 0x%x.",
4173 le32_to_cpu(rhead->h_crc),
4174 le32_to_cpu(crc));
4175 xfs_hex_dump(dp, 32);
4176 }
4177
4178 /*
4179 * If the filesystem is CRC enabled, this mismatch becomes a
4180 * fatal log corruption failure.
4181 */
4182 if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
4183 return -EFSCORRUPTED;
4184 }
4205 4185
4206 error = xlog_unpack_data(rhead, dp, log); 4186 error = xlog_unpack_data(rhead, dp, log);
4207 if (error) 4187 if (error)