aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_log_recover.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index da37beb76f6e..c2d04ff8876b 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1109,27 +1109,10 @@ xlog_verify_head(
1109 bool tmp_wrapped; 1109 bool tmp_wrapped;
1110 1110
1111 /* 1111 /*
1112 * Search backwards through the log looking for the log record header 1112 * Check the head of the log for torn writes. Search backwards from the
1113 * block. This wraps all the way back around to the head so something is 1113 * head until we hit the tail or the maximum number of log record I/Os
1114 * seriously wrong if we can't find it. 1114 * that could have been in flight at one time. Use a temporary buffer so
1115 */ 1115 * we don't trash the rhead/bp pointers from the caller.
1116 found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, rhead_blk,
1117 rhead, wrapped);
1118 if (found < 0)
1119 return found;
1120 if (!found) {
1121 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
1122 return -EIO;
1123 }
1124
1125 *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn));
1126
1127 /*
1128 * Now that we have a tail block, check the head of the log for torn
1129 * writes. Search again until we hit the tail or the maximum number of
1130 * log record I/Os that could have been in flight at one time. Use a
1131 * temporary buffer so we don't trash the rhead/bp pointer from the
1132 * call above.
1133 */ 1116 */
1134 tmp_bp = xlog_get_bp(log, 1); 1117 tmp_bp = xlog_get_bp(log, 1);
1135 if (!tmp_bp) 1118 if (!tmp_bp)
@@ -1254,6 +1237,7 @@ xlog_find_tail(
1254 */ 1237 */
1255 if ((error = xlog_find_head(log, head_blk))) 1238 if ((error = xlog_find_head(log, head_blk)))
1256 return error; 1239 return error;
1240 ASSERT(*head_blk < INT_MAX);
1257 1241
1258 bp = xlog_get_bp(log, 1); 1242 bp = xlog_get_bp(log, 1);
1259 if (!bp) 1243 if (!bp)
@@ -1271,12 +1255,26 @@ xlog_find_tail(
1271 } 1255 }
1272 1256
1273 /* 1257 /*
1258 * Search backwards through the log looking for the log record header
1259 * block. This wraps all the way back around to the head so something is
1260 * seriously wrong if we can't find it.
1261 */
1262 error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp,
1263 &rhead_blk, &rhead, &wrapped);
1264 if (error < 0)
1265 return error;
1266 if (!error) {
1267 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
1268 return -EIO;
1269 }
1270 *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
1271
1272 /*
1274 * Trim the head block back to skip over torn records. We can have 1273 * Trim the head block back to skip over torn records. We can have
1275 * multiple log I/Os in flight at any time, so we assume CRC failures 1274 * multiple log I/Os in flight at any time, so we assume CRC failures
1276 * back through the previous several records are torn writes and skip 1275 * back through the previous several records are torn writes and skip
1277 * them. 1276 * them.
1278 */ 1277 */
1279 ASSERT(*head_blk < INT_MAX);
1280 error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk, 1278 error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk,
1281 &rhead, &wrapped); 1279 &rhead, &wrapped);
1282 if (error) 1280 if (error)