|
@@ -4239,10 +4239,12 @@ xlog_do_recovery_pass(
|
|
|
struct xlog *log,
|
|
|
xfs_daddr_t head_blk,
|
|
|
xfs_daddr_t tail_blk,
|
|
|
- int pass)
|
|
|
+ int pass,
|
|
|
+ xfs_daddr_t *first_bad) /* out: first bad log rec */
|
|
|
{
|
|
|
xlog_rec_header_t *rhead;
|
|
|
xfs_daddr_t blk_no;
|
|
|
+ xfs_daddr_t rhead_blk;
|
|
|
char *offset;
|
|
|
xfs_buf_t *hbp, *dbp;
|
|
|
int error = 0, h_size, h_len;
|
|
@@ -4251,6 +4253,7 @@ xlog_do_recovery_pass(
|
|
|
struct hlist_head rhash[XLOG_RHASH_SIZE];
|
|
|
|
|
|
ASSERT(head_blk != tail_blk);
|
|
|
+ rhead_blk = 0;
|
|
|
|
|
|
/*
|
|
|
* Read the header of the tail block and get the iclog buffer size from
|
|
@@ -4325,7 +4328,7 @@ xlog_do_recovery_pass(
|
|
|
}
|
|
|
|
|
|
memset(rhash, 0, sizeof(rhash));
|
|
|
- blk_no = tail_blk;
|
|
|
+ blk_no = rhead_blk = tail_blk;
|
|
|
if (tail_blk > head_blk) {
|
|
|
/*
|
|
|
* Perform recovery around the end of the physical log.
|
|
@@ -4436,11 +4439,14 @@ xlog_do_recovery_pass(
|
|
|
pass);
|
|
|
if (error)
|
|
|
goto bread_err2;
|
|
|
+
|
|
|
blk_no += bblks;
|
|
|
+ rhead_blk = blk_no;
|
|
|
}
|
|
|
|
|
|
ASSERT(blk_no >= log->l_logBBsize);
|
|
|
blk_no -= log->l_logBBsize;
|
|
|
+ rhead_blk = blk_no;
|
|
|
}
|
|
|
|
|
|
/* read first part of physical log */
|
|
@@ -4464,13 +4470,19 @@ xlog_do_recovery_pass(
|
|
|
error = xlog_recover_process(log, rhash, rhead, offset, pass);
|
|
|
if (error)
|
|
|
goto bread_err2;
|
|
|
+
|
|
|
blk_no += bblks + hblks;
|
|
|
+ rhead_blk = blk_no;
|
|
|
}
|
|
|
|
|
|
bread_err2:
|
|
|
xlog_put_bp(dbp);
|
|
|
bread_err1:
|
|
|
xlog_put_bp(hbp);
|
|
|
+
|
|
|
+ if (error && first_bad)
|
|
|
+ *first_bad = rhead_blk;
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -4508,7 +4520,7 @@ xlog_do_log_recovery(
|
|
|
INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
|
|
|
|
|
|
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
|
|
|
- XLOG_RECOVER_PASS1);
|
|
|
+ XLOG_RECOVER_PASS1, NULL);
|
|
|
if (error != 0) {
|
|
|
kmem_free(log->l_buf_cancel_table);
|
|
|
log->l_buf_cancel_table = NULL;
|
|
@@ -4519,7 +4531,7 @@ xlog_do_log_recovery(
|
|
|
* When it is complete free the table of buf cancel items.
|
|
|
*/
|
|
|
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
|
|
|
- XLOG_RECOVER_PASS2);
|
|
|
+ XLOG_RECOVER_PASS2, NULL);
|
|
|
#ifdef DEBUG
|
|
|
if (!error) {
|
|
|
int i;
|