summaryrefslogtreecommitdiffstats
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.c93
1 files changed, 39 insertions, 54 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1fd5787add99..29e101fc32c5 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -4132,41 +4132,13 @@ xlog_do_recovery_pass(
}
memset(rhash, 0, sizeof(rhash));
- if (tail_blk <= head_blk) {
- for (blk_no = tail_blk; blk_no < head_blk; ) {
- error = xlog_bread(log, blk_no, hblks, hbp, &offset);
- if (error)
- goto bread_err2;
-
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead, blk_no);
- if (error)
- goto bread_err2;
-
- /* blocks in data section */
- bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- error = xlog_bread(log, blk_no + hblks, bblks, dbp,
- &offset);
- if (error)
- goto bread_err2;
-
- error = xlog_unpack_data(rhead, offset, log);
- if (error)
- goto bread_err2;
-
- error = xlog_recover_process_data(log,
- rhash, rhead, offset, pass);
- if (error)
- goto bread_err2;
- blk_no += bblks + hblks;
- }
- } else {
+ blk_no = tail_blk;
+ if (tail_blk > head_blk) {
/*
* Perform recovery around the end of the physical log.
* When the head is not on the same cycle number as the tail,
- * we can't do a sequential recovery as above.
+ * we can't do a sequential recovery.
*/
- blk_no = tail_blk;
while (blk_no < log->l_logBBsize) {
/*
* Check for header wrapping around physical end-of-log
@@ -4280,34 +4252,35 @@ xlog_do_recovery_pass(
ASSERT(blk_no >= log->l_logBBsize);
blk_no -= log->l_logBBsize;
+ }
- /* read first part of physical log */
- while (blk_no < head_blk) {
- error = xlog_bread(log, blk_no, hblks, hbp, &offset);
- if (error)
- goto bread_err2;
+ /* read first part of physical log */
+ while (blk_no < head_blk) {
+ error = xlog_bread(log, blk_no, hblks, hbp, &offset);
+ if (error)
+ goto bread_err2;
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead, blk_no);
- if (error)
- goto bread_err2;
+ rhead = (xlog_rec_header_t *)offset;
+ error = xlog_valid_rec_header(log, rhead, blk_no);
+ if (error)
+ goto bread_err2;
- bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- error = xlog_bread(log, blk_no+hblks, bblks, dbp,
- &offset);
- if (error)
- goto bread_err2;
+ /* blocks in data section */
+ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
+ error = xlog_bread(log, blk_no+hblks, bblks, dbp,
+ &offset);
+ if (error)
+ goto bread_err2;
- error = xlog_unpack_data(rhead, offset, log);
- if (error)
- goto bread_err2;
+ error = xlog_unpack_data(rhead, offset, log);
+ if (error)
+ goto bread_err2;
- error = xlog_recover_process_data(log, rhash,
- rhead, offset, pass);
- if (error)
- goto bread_err2;
- blk_no += bblks + hblks;
- }
+ error = xlog_recover_process_data(log, rhash,
+ rhead, offset, pass);
+ if (error)
+ goto bread_err2;
+ blk_no += bblks + hblks;
}
bread_err2:
@@ -4509,6 +4482,18 @@ xlog_recover(
return -EINVAL;
}
+ /*
+ * Delay log recovery if the debug hook is set. This is debug
+ * instrumention to coordinate simulation of I/O failures with
+ * log recovery.
+ */
+ if (xfs_globals.log_recovery_delay) {
+ xfs_notice(log->l_mp,
+ "Delaying log recovery for %d seconds.",
+ xfs_globals.log_recovery_delay);
+ msleep(xfs_globals.log_recovery_delay * 1000);
+ }
+
xfs_notice(log->l_mp, "Starting recovery (logdev: %s)",
log->l_mp->m_logname ? log->l_mp->m_logname
: "internal");