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.c400
1 files changed, 190 insertions, 210 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 22e6efdc17ea..6f3f5fa37acf 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -24,15 +24,11 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_dmapi.h"
29#include "xfs_mount.h" 27#include "xfs_mount.h"
30#include "xfs_error.h" 28#include "xfs_error.h"
31#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h" 32#include "xfs_dinode.h"
37#include "xfs_inode.h" 33#include "xfs_inode.h"
38#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
@@ -56,33 +52,61 @@ STATIC void xlog_recover_check_summary(xlog_t *);
56#define xlog_recover_check_summary(log) 52#define xlog_recover_check_summary(log)
57#endif 53#endif
58 54
59
60/* 55/*
61 * Sector aligned buffer routines for buffer create/read/write/access 56 * Sector aligned buffer routines for buffer create/read/write/access
62 */ 57 */
63 58
64#define XLOG_SECTOR_ROUNDUP_BBCOUNT(log, bbs) \ 59/*
65 ( ((log)->l_sectbb_mask && (bbs & (log)->l_sectbb_mask)) ? \ 60 * Verify the given count of basic blocks is valid number of blocks
66 ((bbs + (log)->l_sectbb_mask + 1) & ~(log)->l_sectbb_mask) : (bbs) ) 61 * to specify for an operation involving the given XFS log buffer.
67#define XLOG_SECTOR_ROUNDDOWN_BLKNO(log, bno) ((bno) & ~(log)->l_sectbb_mask) 62 * Returns nonzero if the count is valid, 0 otherwise.
63 */
68 64
65static inline int
66xlog_buf_bbcount_valid(
67 xlog_t *log,
68 int bbcount)
69{
70 return bbcount > 0 && bbcount <= log->l_logBBsize;
71}
72
73/*
74 * Allocate a buffer to hold log data. The buffer needs to be able
75 * to map to a range of nbblks basic blocks at any valid (basic
76 * block) offset within the log.
77 */
69STATIC xfs_buf_t * 78STATIC xfs_buf_t *
70xlog_get_bp( 79xlog_get_bp(
71 xlog_t *log, 80 xlog_t *log,
72 int nbblks) 81 int nbblks)
73{ 82{
74 if (nbblks <= 0 || nbblks > log->l_logBBsize) { 83 if (!xlog_buf_bbcount_valid(log, nbblks)) {
75 xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); 84 xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
76 XFS_ERROR_REPORT("xlog_get_bp(1)", 85 nbblks);
77 XFS_ERRLEVEL_HIGH, log->l_mp); 86 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
78 return NULL; 87 return NULL;
79 } 88 }
80 89
81 if (log->l_sectbb_log) { 90 /*
82 if (nbblks > 1) 91 * We do log I/O in units of log sectors (a power-of-2
83 nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); 92 * multiple of the basic block size), so we round up the
84 nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); 93 * requested size to acommodate the basic blocks required
85 } 94 * for complete log sectors.
95 *
96 * In addition, the buffer may be used for a non-sector-
97 * aligned block offset, in which case an I/O of the
98 * requested size could extend beyond the end of the
99 * buffer. If the requested size is only 1 basic block it
100 * will never straddle a sector boundary, so this won't be
101 * an issue. Nor will this be a problem if the log I/O is
102 * done in basic blocks (sector size 1). But otherwise we
103 * extend the buffer by one extra log sector to ensure
104 * there's space to accomodate this possiblility.
105 */
106 if (nbblks > 1 && log->l_sectBBsize > 1)
107 nbblks += log->l_sectBBsize;
108 nbblks = round_up(nbblks, log->l_sectBBsize);
109
86 return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp); 110 return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
87} 111}
88 112
@@ -93,6 +117,10 @@ xlog_put_bp(
93 xfs_buf_free(bp); 117 xfs_buf_free(bp);
94} 118}
95 119
120/*
121 * Return the address of the start of the given block number's data
122 * in a log buffer. The buffer covers a log sector-aligned region.
123 */
96STATIC xfs_caddr_t 124STATIC xfs_caddr_t
97xlog_align( 125xlog_align(
98 xlog_t *log, 126 xlog_t *log,
@@ -100,15 +128,10 @@ xlog_align(
100 int nbblks, 128 int nbblks,
101 xfs_buf_t *bp) 129 xfs_buf_t *bp)
102{ 130{
103 xfs_caddr_t ptr; 131 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1);
104 132
105 if (!log->l_sectbb_log) 133 ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp));
106 return XFS_BUF_PTR(bp); 134 return XFS_BUF_PTR(bp) + BBTOB(offset);
107
108 ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
109 ASSERT(XFS_BUF_SIZE(bp) >=
110 BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
111 return ptr;
112} 135}
113 136
114 137
@@ -124,21 +147,18 @@ xlog_bread_noalign(
124{ 147{
125 int error; 148 int error;
126 149
127 if (nbblks <= 0 || nbblks > log->l_logBBsize) { 150 if (!xlog_buf_bbcount_valid(log, nbblks)) {
128 xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); 151 xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
129 XFS_ERROR_REPORT("xlog_bread(1)", 152 nbblks);
130 XFS_ERRLEVEL_HIGH, log->l_mp); 153 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
131 return EFSCORRUPTED; 154 return EFSCORRUPTED;
132 } 155 }
133 156
134 if (log->l_sectbb_log) { 157 blk_no = round_down(blk_no, log->l_sectBBsize);
135 blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); 158 nbblks = round_up(nbblks, log->l_sectBBsize);
136 nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
137 }
138 159
139 ASSERT(nbblks > 0); 160 ASSERT(nbblks > 0);
140 ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp)); 161 ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
141 ASSERT(bp);
142 162
143 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); 163 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
144 XFS_BUF_READ(bp); 164 XFS_BUF_READ(bp);
@@ -186,17 +206,15 @@ xlog_bwrite(
186{ 206{
187 int error; 207 int error;
188 208
189 if (nbblks <= 0 || nbblks > log->l_logBBsize) { 209 if (!xlog_buf_bbcount_valid(log, nbblks)) {
190 xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); 210 xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
191 XFS_ERROR_REPORT("xlog_bwrite(1)", 211 nbblks);
192 XFS_ERRLEVEL_HIGH, log->l_mp); 212 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
193 return EFSCORRUPTED; 213 return EFSCORRUPTED;
194 } 214 }
195 215
196 if (log->l_sectbb_log) { 216 blk_no = round_down(blk_no, log->l_sectBBsize);
197 blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); 217 nbblks = round_up(nbblks, log->l_sectBBsize);
198 nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
199 }
200 218
201 ASSERT(nbblks > 0); 219 ASSERT(nbblks > 0);
202 ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp)); 220 ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
@@ -327,39 +345,38 @@ xlog_find_cycle_start(
327{ 345{
328 xfs_caddr_t offset; 346 xfs_caddr_t offset;
329 xfs_daddr_t mid_blk; 347 xfs_daddr_t mid_blk;
348 xfs_daddr_t end_blk;
330 uint mid_cycle; 349 uint mid_cycle;
331 int error; 350 int error;
332 351
333 mid_blk = BLK_AVG(first_blk, *last_blk); 352 end_blk = *last_blk;
334 while (mid_blk != first_blk && mid_blk != *last_blk) { 353 mid_blk = BLK_AVG(first_blk, end_blk);
354 while (mid_blk != first_blk && mid_blk != end_blk) {
335 error = xlog_bread(log, mid_blk, 1, bp, &offset); 355 error = xlog_bread(log, mid_blk, 1, bp, &offset);
336 if (error) 356 if (error)
337 return error; 357 return error;
338 mid_cycle = xlog_get_cycle(offset); 358 mid_cycle = xlog_get_cycle(offset);
339 if (mid_cycle == cycle) { 359 if (mid_cycle == cycle)
340 *last_blk = mid_blk; 360 end_blk = mid_blk; /* last_half_cycle == mid_cycle */
341 /* last_half_cycle == mid_cycle */ 361 else
342 } else { 362 first_blk = mid_blk; /* first_half_cycle == mid_cycle */
343 first_blk = mid_blk; 363 mid_blk = BLK_AVG(first_blk, end_blk);
344 /* first_half_cycle == mid_cycle */
345 }
346 mid_blk = BLK_AVG(first_blk, *last_blk);
347 } 364 }
348 ASSERT((mid_blk == first_blk && mid_blk+1 == *last_blk) || 365 ASSERT((mid_blk == first_blk && mid_blk+1 == end_blk) ||
349 (mid_blk == *last_blk && mid_blk-1 == first_blk)); 366 (mid_blk == end_blk && mid_blk-1 == first_blk));
367
368 *last_blk = end_blk;
350 369
351 return 0; 370 return 0;
352} 371}
353 372
354/* 373/*
355 * Check that the range of blocks does not contain the cycle number 374 * Check that a range of blocks does not contain stop_on_cycle_no.
356 * given. The scan needs to occur from front to back and the ptr into the 375 * Fill in *new_blk with the block offset where such a block is
357 * region must be updated since a later routine will need to perform another 376 * found, or with -1 (an invalid block number) if there is no such
358 * test. If the region is completely good, we end up returning the same 377 * block in the range. The scan needs to occur from front to back
359 * last block number. 378 * and the pointer into the region must be updated since a later
360 * 379 * routine will need to perform another test.
361 * Set blkno to -1 if we encounter no errors. This is an invalid block number
362 * since we don't ever expect logs to get this large.
363 */ 380 */
364STATIC int 381STATIC int
365xlog_find_verify_cycle( 382xlog_find_verify_cycle(
@@ -376,12 +393,16 @@ xlog_find_verify_cycle(
376 xfs_caddr_t buf = NULL; 393 xfs_caddr_t buf = NULL;
377 int error = 0; 394 int error = 0;
378 395
396 /*
397 * Greedily allocate a buffer big enough to handle the full
398 * range of basic blocks we'll be examining. If that fails,
399 * try a smaller size. We need to be able to read at least
400 * a log sector, or we're out of luck.
401 */
379 bufblks = 1 << ffs(nbblks); 402 bufblks = 1 << ffs(nbblks);
380
381 while (!(bp = xlog_get_bp(log, bufblks))) { 403 while (!(bp = xlog_get_bp(log, bufblks))) {
382 /* can't get enough memory to do everything in one big buffer */
383 bufblks >>= 1; 404 bufblks >>= 1;
384 if (bufblks <= log->l_sectbb_log) 405 if (bufblks < log->l_sectBBsize)
385 return ENOMEM; 406 return ENOMEM;
386 } 407 }
387 408
@@ -629,7 +650,7 @@ xlog_find_head(
629 * In this case we want to find the first block with cycle 650 * In this case we want to find the first block with cycle
630 * number matching last_half_cycle. We expect the log to be 651 * number matching last_half_cycle. We expect the log to be
631 * some variation on 652 * some variation on
632 * x + 1 ... | x ... 653 * x + 1 ... | x ... | x
633 * The first block with cycle number x (last_half_cycle) will 654 * The first block with cycle number x (last_half_cycle) will
634 * be where the new head belongs. First we do a binary search 655 * be where the new head belongs. First we do a binary search
635 * for the first occurrence of last_half_cycle. The binary 656 * for the first occurrence of last_half_cycle. The binary
@@ -639,11 +660,13 @@ xlog_find_head(
639 * the log, then we look for occurrences of last_half_cycle - 1 660 * the log, then we look for occurrences of last_half_cycle - 1
640 * at the end of the log. The cases we're looking for look 661 * at the end of the log. The cases we're looking for look
641 * like 662 * like
642 * x + 1 ... | x | x + 1 | x ... 663 * v binary search stopped here
643 * ^ binary search stopped here 664 * x + 1 ... | x | x + 1 | x ... | x
665 * ^ but we want to locate this spot
644 * or 666 * or
645 * x + 1 ... | x ... | x - 1 | x
646 * <---------> less than scan distance 667 * <---------> less than scan distance
668 * x + 1 ... | x ... | x - 1 | x
669 * ^ we want to locate this spot
647 */ 670 */
648 stop_on_cycle = last_half_cycle; 671 stop_on_cycle = last_half_cycle;
649 if ((error = xlog_find_cycle_start(log, bp, first_blk, 672 if ((error = xlog_find_cycle_start(log, bp, first_blk,
@@ -699,16 +722,16 @@ xlog_find_head(
699 * certainly not the head of the log. By searching for 722 * certainly not the head of the log. By searching for
700 * last_half_cycle-1 we accomplish that. 723 * last_half_cycle-1 we accomplish that.
701 */ 724 */
702 start_blk = log_bbnum - num_scan_bblks + head_blk;
703 ASSERT(head_blk <= INT_MAX && 725 ASSERT(head_blk <= INT_MAX &&
704 (xfs_daddr_t) num_scan_bblks - head_blk >= 0); 726 (xfs_daddr_t) num_scan_bblks >= head_blk);
727 start_blk = log_bbnum - (num_scan_bblks - head_blk);
705 if ((error = xlog_find_verify_cycle(log, start_blk, 728 if ((error = xlog_find_verify_cycle(log, start_blk,
706 num_scan_bblks - (int)head_blk, 729 num_scan_bblks - (int)head_blk,
707 (stop_on_cycle - 1), &new_blk))) 730 (stop_on_cycle - 1), &new_blk)))
708 goto bp_err; 731 goto bp_err;
709 if (new_blk != -1) { 732 if (new_blk != -1) {
710 head_blk = new_blk; 733 head_blk = new_blk;
711 goto bad_blk; 734 goto validate_head;
712 } 735 }
713 736
714 /* 737 /*
@@ -726,7 +749,7 @@ xlog_find_head(
726 head_blk = new_blk; 749 head_blk = new_blk;
727 } 750 }
728 751
729 bad_blk: 752validate_head:
730 /* 753 /*
731 * Now we need to make sure head_blk is not pointing to a block in 754 * Now we need to make sure head_blk is not pointing to a block in
732 * the middle of a log record. 755 * the middle of a log record.
@@ -748,7 +771,7 @@ xlog_find_head(
748 if ((error = xlog_find_verify_log_record(log, start_blk, 771 if ((error = xlog_find_verify_log_record(log, start_blk,
749 &head_blk, 0)) == -1) { 772 &head_blk, 0)) == -1) {
750 /* We hit the beginning of the log during our search */ 773 /* We hit the beginning of the log during our search */
751 start_blk = log_bbnum - num_scan_bblks + head_blk; 774 start_blk = log_bbnum - (num_scan_bblks - head_blk);
752 new_blk = log_bbnum; 775 new_blk = log_bbnum;
753 ASSERT(start_blk <= INT_MAX && 776 ASSERT(start_blk <= INT_MAX &&
754 (xfs_daddr_t) log_bbnum-start_blk >= 0); 777 (xfs_daddr_t) log_bbnum-start_blk >= 0);
@@ -833,12 +856,12 @@ xlog_find_tail(
833 if (*head_blk == 0) { /* special case */ 856 if (*head_blk == 0) { /* special case */
834 error = xlog_bread(log, 0, 1, bp, &offset); 857 error = xlog_bread(log, 0, 1, bp, &offset);
835 if (error) 858 if (error)
836 goto bread_err; 859 goto done;
837 860
838 if (xlog_get_cycle(offset) == 0) { 861 if (xlog_get_cycle(offset) == 0) {
839 *tail_blk = 0; 862 *tail_blk = 0;
840 /* leave all other log inited values alone */ 863 /* leave all other log inited values alone */
841 goto exit; 864 goto done;
842 } 865 }
843 } 866 }
844 867
@@ -849,7 +872,7 @@ xlog_find_tail(
849 for (i = (int)(*head_blk) - 1; i >= 0; i--) { 872 for (i = (int)(*head_blk) - 1; i >= 0; i--) {
850 error = xlog_bread(log, i, 1, bp, &offset); 873 error = xlog_bread(log, i, 1, bp, &offset);
851 if (error) 874 if (error)
852 goto bread_err; 875 goto done;
853 876
854 if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { 877 if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
855 found = 1; 878 found = 1;
@@ -866,7 +889,7 @@ xlog_find_tail(
866 for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) { 889 for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) {
867 error = xlog_bread(log, i, 1, bp, &offset); 890 error = xlog_bread(log, i, 1, bp, &offset);
868 if (error) 891 if (error)
869 goto bread_err; 892 goto done;
870 893
871 if (XLOG_HEADER_MAGIC_NUM == 894 if (XLOG_HEADER_MAGIC_NUM ==
872 be32_to_cpu(*(__be32 *)offset)) { 895 be32_to_cpu(*(__be32 *)offset)) {
@@ -941,7 +964,7 @@ xlog_find_tail(
941 umount_data_blk = (i + hblks) % log->l_logBBsize; 964 umount_data_blk = (i + hblks) % log->l_logBBsize;
942 error = xlog_bread(log, umount_data_blk, 1, bp, &offset); 965 error = xlog_bread(log, umount_data_blk, 1, bp, &offset);
943 if (error) 966 if (error)
944 goto bread_err; 967 goto done;
945 968
946 op_head = (xlog_op_header_t *)offset; 969 op_head = (xlog_op_header_t *)offset;
947 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) { 970 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
@@ -987,12 +1010,10 @@ xlog_find_tail(
987 * But... if the -device- itself is readonly, just skip this. 1010 * But... if the -device- itself is readonly, just skip this.
988 * We can't recover this device anyway, so it won't matter. 1011 * We can't recover this device anyway, so it won't matter.
989 */ 1012 */
990 if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) { 1013 if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp))
991 error = xlog_clear_stale_blocks(log, tail_lsn); 1014 error = xlog_clear_stale_blocks(log, tail_lsn);
992 }
993 1015
994bread_err: 1016done:
995exit:
996 xlog_put_bp(bp); 1017 xlog_put_bp(bp);
997 1018
998 if (error) 1019 if (error)
@@ -1152,16 +1173,22 @@ xlog_write_log_records(
1152 xfs_caddr_t offset; 1173 xfs_caddr_t offset;
1153 xfs_buf_t *bp; 1174 xfs_buf_t *bp;
1154 int balign, ealign; 1175 int balign, ealign;
1155 int sectbb = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); 1176 int sectbb = log->l_sectBBsize;
1156 int end_block = start_block + blocks; 1177 int end_block = start_block + blocks;
1157 int bufblks; 1178 int bufblks;
1158 int error = 0; 1179 int error = 0;
1159 int i, j = 0; 1180 int i, j = 0;
1160 1181
1182 /*
1183 * Greedily allocate a buffer big enough to handle the full
1184 * range of basic blocks to be written. If that fails, try
1185 * a smaller size. We need to be able to write at least a
1186 * log sector, or we're out of luck.
1187 */
1161 bufblks = 1 << ffs(blocks); 1188 bufblks = 1 << ffs(blocks);
1162 while (!(bp = xlog_get_bp(log, bufblks))) { 1189 while (!(bp = xlog_get_bp(log, bufblks))) {
1163 bufblks >>= 1; 1190 bufblks >>= 1;
1164 if (bufblks <= log->l_sectbb_log) 1191 if (bufblks < sectbb)
1165 return ENOMEM; 1192 return ENOMEM;
1166 } 1193 }
1167 1194
@@ -1169,7 +1196,7 @@ xlog_write_log_records(
1169 * the buffer in the starting sector not covered by the first 1196 * the buffer in the starting sector not covered by the first
1170 * write below. 1197 * write below.
1171 */ 1198 */
1172 balign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, start_block); 1199 balign = round_down(start_block, sectbb);
1173 if (balign != start_block) { 1200 if (balign != start_block) {
1174 error = xlog_bread_noalign(log, start_block, 1, bp); 1201 error = xlog_bread_noalign(log, start_block, 1, bp);
1175 if (error) 1202 if (error)
@@ -1188,7 +1215,7 @@ xlog_write_log_records(
1188 * the buffer in the final sector not covered by the write. 1215 * the buffer in the final sector not covered by the write.
1189 * If this is the same sector as the above read, skip it. 1216 * If this is the same sector as the above read, skip it.
1190 */ 1217 */
1191 ealign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, end_block); 1218 ealign = round_down(end_block, sectbb);
1192 if (j == 0 && (start_block + endcount > ealign)) { 1219 if (j == 0 && (start_block + endcount > ealign)) {
1193 offset = XFS_BUF_PTR(bp); 1220 offset = XFS_BUF_PTR(bp);
1194 balign = BBTOB(ealign - start_block); 1221 balign = BBTOB(ealign - start_block);
@@ -1408,6 +1435,7 @@ xlog_recover_add_item(
1408 1435
1409STATIC int 1436STATIC int
1410xlog_recover_add_to_cont_trans( 1437xlog_recover_add_to_cont_trans(
1438 struct log *log,
1411 xlog_recover_t *trans, 1439 xlog_recover_t *trans,
1412 xfs_caddr_t dp, 1440 xfs_caddr_t dp,
1413 int len) 1441 int len)
@@ -1434,6 +1462,7 @@ xlog_recover_add_to_cont_trans(
1434 memcpy(&ptr[old_len], dp, len); /* d, s, l */ 1462 memcpy(&ptr[old_len], dp, len); /* d, s, l */
1435 item->ri_buf[item->ri_cnt-1].i_len += len; 1463 item->ri_buf[item->ri_cnt-1].i_len += len;
1436 item->ri_buf[item->ri_cnt-1].i_addr = ptr; 1464 item->ri_buf[item->ri_cnt-1].i_addr = ptr;
1465 trace_xfs_log_recover_item_add_cont(log, trans, item, 0);
1437 return 0; 1466 return 0;
1438} 1467}
1439 1468
@@ -1452,6 +1481,7 @@ xlog_recover_add_to_cont_trans(
1452 */ 1481 */
1453STATIC int 1482STATIC int
1454xlog_recover_add_to_trans( 1483xlog_recover_add_to_trans(
1484 struct log *log,
1455 xlog_recover_t *trans, 1485 xlog_recover_t *trans,
1456 xfs_caddr_t dp, 1486 xfs_caddr_t dp,
1457 int len) 1487 int len)
@@ -1510,6 +1540,7 @@ xlog_recover_add_to_trans(
1510 item->ri_buf[item->ri_cnt].i_addr = ptr; 1540 item->ri_buf[item->ri_cnt].i_addr = ptr;
1511 item->ri_buf[item->ri_cnt].i_len = len; 1541 item->ri_buf[item->ri_cnt].i_len = len;
1512 item->ri_cnt++; 1542 item->ri_cnt++;
1543 trace_xfs_log_recover_item_add(log, trans, item, 0);
1513 return 0; 1544 return 0;
1514} 1545}
1515 1546
@@ -1521,20 +1552,22 @@ xlog_recover_add_to_trans(
1521 */ 1552 */
1522STATIC int 1553STATIC int
1523xlog_recover_reorder_trans( 1554xlog_recover_reorder_trans(
1524 xlog_recover_t *trans) 1555 struct log *log,
1556 xlog_recover_t *trans,
1557 int pass)
1525{ 1558{
1526 xlog_recover_item_t *item, *n; 1559 xlog_recover_item_t *item, *n;
1527 LIST_HEAD(sort_list); 1560 LIST_HEAD(sort_list);
1528 1561
1529 list_splice_init(&trans->r_itemq, &sort_list); 1562 list_splice_init(&trans->r_itemq, &sort_list);
1530 list_for_each_entry_safe(item, n, &sort_list, ri_list) { 1563 list_for_each_entry_safe(item, n, &sort_list, ri_list) {
1531 xfs_buf_log_format_t *buf_f; 1564 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
1532
1533 buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
1534 1565
1535 switch (ITEM_TYPE(item)) { 1566 switch (ITEM_TYPE(item)) {
1536 case XFS_LI_BUF: 1567 case XFS_LI_BUF:
1537 if (!(buf_f->blf_flags & XFS_BLI_CANCEL)) { 1568 if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
1569 trace_xfs_log_recover_item_reorder_head(log,
1570 trans, item, pass);
1538 list_move(&item->ri_list, &trans->r_itemq); 1571 list_move(&item->ri_list, &trans->r_itemq);
1539 break; 1572 break;
1540 } 1573 }
@@ -1543,6 +1576,8 @@ xlog_recover_reorder_trans(
1543 case XFS_LI_QUOTAOFF: 1576 case XFS_LI_QUOTAOFF:
1544 case XFS_LI_EFD: 1577 case XFS_LI_EFD:
1545 case XFS_LI_EFI: 1578 case XFS_LI_EFI:
1579 trace_xfs_log_recover_item_reorder_tail(log,
1580 trans, item, pass);
1546 list_move_tail(&item->ri_list, &trans->r_itemq); 1581 list_move_tail(&item->ri_list, &trans->r_itemq);
1547 break; 1582 break;
1548 default: 1583 default:
@@ -1592,8 +1627,10 @@ xlog_recover_do_buffer_pass1(
1592 /* 1627 /*
1593 * If this isn't a cancel buffer item, then just return. 1628 * If this isn't a cancel buffer item, then just return.
1594 */ 1629 */
1595 if (!(flags & XFS_BLI_CANCEL)) 1630 if (!(flags & XFS_BLF_CANCEL)) {
1631 trace_xfs_log_recover_buf_not_cancel(log, buf_f);
1596 return; 1632 return;
1633 }
1597 1634
1598 /* 1635 /*
1599 * Insert an xfs_buf_cancel record into the hash table of 1636 * Insert an xfs_buf_cancel record into the hash table of
@@ -1627,6 +1664,7 @@ xlog_recover_do_buffer_pass1(
1627 while (nextp != NULL) { 1664 while (nextp != NULL) {
1628 if (nextp->bc_blkno == blkno && nextp->bc_len == len) { 1665 if (nextp->bc_blkno == blkno && nextp->bc_len == len) {
1629 nextp->bc_refcount++; 1666 nextp->bc_refcount++;
1667 trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f);
1630 return; 1668 return;
1631 } 1669 }
1632 prevp = nextp; 1670 prevp = nextp;
@@ -1640,13 +1678,14 @@ xlog_recover_do_buffer_pass1(
1640 bcp->bc_refcount = 1; 1678 bcp->bc_refcount = 1;
1641 bcp->bc_next = NULL; 1679 bcp->bc_next = NULL;
1642 prevp->bc_next = bcp; 1680 prevp->bc_next = bcp;
1681 trace_xfs_log_recover_buf_cancel_add(log, buf_f);
1643} 1682}
1644 1683
1645/* 1684/*
1646 * Check to see whether the buffer being recovered has a corresponding 1685 * Check to see whether the buffer being recovered has a corresponding
1647 * entry in the buffer cancel record table. If it does then return 1 1686 * entry in the buffer cancel record table. If it does then return 1
1648 * so that it will be cancelled, otherwise return 0. If the buffer is 1687 * so that it will be cancelled, otherwise return 0. If the buffer is
1649 * actually a buffer cancel item (XFS_BLI_CANCEL is set), then decrement 1688 * actually a buffer cancel item (XFS_BLF_CANCEL is set), then decrement
1650 * the refcount on the entry in the table and remove it from the table 1689 * the refcount on the entry in the table and remove it from the table
1651 * if this is the last reference. 1690 * if this is the last reference.
1652 * 1691 *
@@ -1671,7 +1710,7 @@ xlog_check_buffer_cancelled(
1671 * There is nothing in the table built in pass one, 1710 * There is nothing in the table built in pass one,
1672 * so this buffer must not be cancelled. 1711 * so this buffer must not be cancelled.
1673 */ 1712 */
1674 ASSERT(!(flags & XFS_BLI_CANCEL)); 1713 ASSERT(!(flags & XFS_BLF_CANCEL));
1675 return 0; 1714 return 0;
1676 } 1715 }
1677 1716
@@ -1683,7 +1722,7 @@ xlog_check_buffer_cancelled(
1683 * There is no corresponding entry in the table built 1722 * There is no corresponding entry in the table built
1684 * in pass one, so this buffer has not been cancelled. 1723 * in pass one, so this buffer has not been cancelled.
1685 */ 1724 */
1686 ASSERT(!(flags & XFS_BLI_CANCEL)); 1725 ASSERT(!(flags & XFS_BLF_CANCEL));
1687 return 0; 1726 return 0;
1688 } 1727 }
1689 1728
@@ -1702,7 +1741,7 @@ xlog_check_buffer_cancelled(
1702 * one in the table and remove it if this is the 1741 * one in the table and remove it if this is the
1703 * last reference. 1742 * last reference.
1704 */ 1743 */
1705 if (flags & XFS_BLI_CANCEL) { 1744 if (flags & XFS_BLF_CANCEL) {
1706 bcp->bc_refcount--; 1745 bcp->bc_refcount--;
1707 if (bcp->bc_refcount == 0) { 1746 if (bcp->bc_refcount == 0) {
1708 if (prevp == NULL) { 1747 if (prevp == NULL) {
@@ -1722,7 +1761,7 @@ xlog_check_buffer_cancelled(
1722 * We didn't find a corresponding entry in the table, so 1761 * We didn't find a corresponding entry in the table, so
1723 * return 0 so that the buffer is NOT cancelled. 1762 * return 0 so that the buffer is NOT cancelled.
1724 */ 1763 */
1725 ASSERT(!(flags & XFS_BLI_CANCEL)); 1764 ASSERT(!(flags & XFS_BLF_CANCEL));
1726 return 0; 1765 return 0;
1727} 1766}
1728 1767
@@ -1779,6 +1818,8 @@ xlog_recover_do_inode_buffer(
1779 unsigned int *data_map = NULL; 1818 unsigned int *data_map = NULL;
1780 unsigned int map_size = 0; 1819 unsigned int map_size = 0;
1781 1820
1821 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
1822
1782 switch (buf_f->blf_type) { 1823 switch (buf_f->blf_type) {
1783 case XFS_LI_BUF: 1824 case XFS_LI_BUF:
1784 data_map = buf_f->blf_data_map; 1825 data_map = buf_f->blf_data_map;
@@ -1822,8 +1863,8 @@ xlog_recover_do_inode_buffer(
1822 nbits = xfs_contig_bits(data_map, map_size, 1863 nbits = xfs_contig_bits(data_map, map_size,
1823 bit); 1864 bit);
1824 ASSERT(nbits > 0); 1865 ASSERT(nbits > 0);
1825 reg_buf_offset = bit << XFS_BLI_SHIFT; 1866 reg_buf_offset = bit << XFS_BLF_SHIFT;
1826 reg_buf_bytes = nbits << XFS_BLI_SHIFT; 1867 reg_buf_bytes = nbits << XFS_BLF_SHIFT;
1827 item_index++; 1868 item_index++;
1828 } 1869 }
1829 1870
@@ -1837,7 +1878,7 @@ xlog_recover_do_inode_buffer(
1837 } 1878 }
1838 1879
1839 ASSERT(item->ri_buf[item_index].i_addr != NULL); 1880 ASSERT(item->ri_buf[item_index].i_addr != NULL);
1840 ASSERT((item->ri_buf[item_index].i_len % XFS_BLI_CHUNK) == 0); 1881 ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
1841 ASSERT((reg_buf_offset + reg_buf_bytes) <= XFS_BUF_COUNT(bp)); 1882 ASSERT((reg_buf_offset + reg_buf_bytes) <= XFS_BUF_COUNT(bp));
1842 1883
1843 /* 1884 /*
@@ -1845,9 +1886,8 @@ xlog_recover_do_inode_buffer(
1845 * current di_next_unlinked field. Extract its value 1886 * current di_next_unlinked field. Extract its value
1846 * and copy it to the buffer copy. 1887 * and copy it to the buffer copy.
1847 */ 1888 */
1848 logged_nextp = (xfs_agino_t *) 1889 logged_nextp = item->ri_buf[item_index].i_addr +
1849 ((char *)(item->ri_buf[item_index].i_addr) + 1890 next_unlinked_offset - reg_buf_offset;
1850 (next_unlinked_offset - reg_buf_offset));
1851 if (unlikely(*logged_nextp == 0)) { 1891 if (unlikely(*logged_nextp == 0)) {
1852 xfs_fs_cmn_err(CE_ALERT, mp, 1892 xfs_fs_cmn_err(CE_ALERT, mp,
1853 "bad inode buffer log record (ptr = 0x%p, bp = 0x%p). XFS trying to replay bad (0) inode di_next_unlinked field", 1893 "bad inode buffer log record (ptr = 0x%p, bp = 0x%p). XFS trying to replay bad (0) inode di_next_unlinked field",
@@ -1874,6 +1914,7 @@ xlog_recover_do_inode_buffer(
1874/*ARGSUSED*/ 1914/*ARGSUSED*/
1875STATIC void 1915STATIC void
1876xlog_recover_do_reg_buffer( 1916xlog_recover_do_reg_buffer(
1917 struct xfs_mount *mp,
1877 xlog_recover_item_t *item, 1918 xlog_recover_item_t *item,
1878 xfs_buf_t *bp, 1919 xfs_buf_t *bp,
1879 xfs_buf_log_format_t *buf_f) 1920 xfs_buf_log_format_t *buf_f)
@@ -1885,6 +1926,8 @@ xlog_recover_do_reg_buffer(
1885 unsigned int map_size = 0; 1926 unsigned int map_size = 0;
1886 int error; 1927 int error;
1887 1928
1929 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
1930
1888 switch (buf_f->blf_type) { 1931 switch (buf_f->blf_type) {
1889 case XFS_LI_BUF: 1932 case XFS_LI_BUF:
1890 data_map = buf_f->blf_data_map; 1933 data_map = buf_f->blf_data_map;
@@ -1900,9 +1943,9 @@ xlog_recover_do_reg_buffer(
1900 nbits = xfs_contig_bits(data_map, map_size, bit); 1943 nbits = xfs_contig_bits(data_map, map_size, bit);
1901 ASSERT(nbits > 0); 1944 ASSERT(nbits > 0);
1902 ASSERT(item->ri_buf[i].i_addr != NULL); 1945 ASSERT(item->ri_buf[i].i_addr != NULL);
1903 ASSERT(item->ri_buf[i].i_len % XFS_BLI_CHUNK == 0); 1946 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
1904 ASSERT(XFS_BUF_COUNT(bp) >= 1947 ASSERT(XFS_BUF_COUNT(bp) >=
1905 ((uint)bit << XFS_BLI_SHIFT)+(nbits<<XFS_BLI_SHIFT)); 1948 ((uint)bit << XFS_BLF_SHIFT)+(nbits<<XFS_BLF_SHIFT));
1906 1949
1907 /* 1950 /*
1908 * Do a sanity check if this is a dquot buffer. Just checking 1951 * Do a sanity check if this is a dquot buffer. Just checking
@@ -1911,7 +1954,7 @@ xlog_recover_do_reg_buffer(
1911 */ 1954 */
1912 error = 0; 1955 error = 0;
1913 if (buf_f->blf_flags & 1956 if (buf_f->blf_flags &
1914 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { 1957 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
1915 if (item->ri_buf[i].i_addr == NULL) { 1958 if (item->ri_buf[i].i_addr == NULL) {
1916 cmn_err(CE_ALERT, 1959 cmn_err(CE_ALERT,
1917 "XFS: NULL dquot in %s.", __func__); 1960 "XFS: NULL dquot in %s.", __func__);
@@ -1923,8 +1966,7 @@ xlog_recover_do_reg_buffer(
1923 item->ri_buf[i].i_len, __func__); 1966 item->ri_buf[i].i_len, __func__);
1924 goto next; 1967 goto next;
1925 } 1968 }
1926 error = xfs_qm_dqcheck((xfs_disk_dquot_t *) 1969 error = xfs_qm_dqcheck(item->ri_buf[i].i_addr,
1927 item->ri_buf[i].i_addr,
1928 -1, 0, XFS_QMOPT_DOWARN, 1970 -1, 0, XFS_QMOPT_DOWARN,
1929 "dquot_buf_recover"); 1971 "dquot_buf_recover");
1930 if (error) 1972 if (error)
@@ -1932,9 +1974,9 @@ xlog_recover_do_reg_buffer(
1932 } 1974 }
1933 1975
1934 memcpy(xfs_buf_offset(bp, 1976 memcpy(xfs_buf_offset(bp,
1935 (uint)bit << XFS_BLI_SHIFT), /* dest */ 1977 (uint)bit << XFS_BLF_SHIFT), /* dest */
1936 item->ri_buf[i].i_addr, /* source */ 1978 item->ri_buf[i].i_addr, /* source */
1937 nbits<<XFS_BLI_SHIFT); /* length */ 1979 nbits<<XFS_BLF_SHIFT); /* length */
1938 next: 1980 next:
1939 i++; 1981 i++;
1940 bit += nbits; 1982 bit += nbits;
@@ -2083,6 +2125,8 @@ xlog_recover_do_dquot_buffer(
2083{ 2125{
2084 uint type; 2126 uint type;
2085 2127
2128 trace_xfs_log_recover_buf_dquot_buf(log, buf_f);
2129
2086 /* 2130 /*
2087 * Filesystems are required to send in quota flags at mount time. 2131 * Filesystems are required to send in quota flags at mount time.
2088 */ 2132 */
@@ -2091,11 +2135,11 @@ xlog_recover_do_dquot_buffer(
2091 } 2135 }
2092 2136
2093 type = 0; 2137 type = 0;
2094 if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) 2138 if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF)
2095 type |= XFS_DQ_USER; 2139 type |= XFS_DQ_USER;
2096 if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF) 2140 if (buf_f->blf_flags & XFS_BLF_PDQUOT_BUF)
2097 type |= XFS_DQ_PROJ; 2141 type |= XFS_DQ_PROJ;
2098 if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) 2142 if (buf_f->blf_flags & XFS_BLF_GDQUOT_BUF)
2099 type |= XFS_DQ_GROUP; 2143 type |= XFS_DQ_GROUP;
2100 /* 2144 /*
2101 * This type of quotas was turned off, so ignore this buffer 2145 * This type of quotas was turned off, so ignore this buffer
@@ -2103,7 +2147,7 @@ xlog_recover_do_dquot_buffer(
2103 if (log->l_quotaoffs_flag & type) 2147 if (log->l_quotaoffs_flag & type)
2104 return; 2148 return;
2105 2149
2106 xlog_recover_do_reg_buffer(item, bp, buf_f); 2150 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2107} 2151}
2108 2152
2109/* 2153/*
@@ -2116,7 +2160,7 @@ xlog_recover_do_dquot_buffer(
2116 * here which overlaps that may be stale. 2160 * here which overlaps that may be stale.
2117 * 2161 *
2118 * When meta-data buffers are freed at run time we log a buffer item 2162 * When meta-data buffers are freed at run time we log a buffer item
2119 * with the XFS_BLI_CANCEL bit set to indicate that previous copies 2163 * with the XFS_BLF_CANCEL bit set to indicate that previous copies
2120 * of the buffer in the log should not be replayed at recovery time. 2164 * of the buffer in the log should not be replayed at recovery time.
2121 * This is so that if the blocks covered by the buffer are reused for 2165 * This is so that if the blocks covered by the buffer are reused for
2122 * file data before we crash we don't end up replaying old, freed 2166 * file data before we crash we don't end up replaying old, freed
@@ -2135,7 +2179,7 @@ xlog_recover_do_buffer_trans(
2135 xlog_recover_item_t *item, 2179 xlog_recover_item_t *item,
2136 int pass) 2180 int pass)
2137{ 2181{
2138 xfs_buf_log_format_t *buf_f; 2182 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
2139 xfs_mount_t *mp; 2183 xfs_mount_t *mp;
2140 xfs_buf_t *bp; 2184 xfs_buf_t *bp;
2141 int error; 2185 int error;
@@ -2145,12 +2189,10 @@ xlog_recover_do_buffer_trans(
2145 ushort flags; 2189 ushort flags;
2146 uint buf_flags; 2190 uint buf_flags;
2147 2191
2148 buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
2149
2150 if (pass == XLOG_RECOVER_PASS1) { 2192 if (pass == XLOG_RECOVER_PASS1) {
2151 /* 2193 /*
2152 * In this pass we're only looking for buf items 2194 * In this pass we're only looking for buf items
2153 * with the XFS_BLI_CANCEL bit set. 2195 * with the XFS_BLF_CANCEL bit set.
2154 */ 2196 */
2155 xlog_recover_do_buffer_pass1(log, buf_f); 2197 xlog_recover_do_buffer_pass1(log, buf_f);
2156 return 0; 2198 return 0;
@@ -2164,9 +2206,11 @@ xlog_recover_do_buffer_trans(
2164 */ 2206 */
2165 cancel = xlog_recover_do_buffer_pass2(log, buf_f); 2207 cancel = xlog_recover_do_buffer_pass2(log, buf_f);
2166 if (cancel) { 2208 if (cancel) {
2209 trace_xfs_log_recover_buf_cancel(log, buf_f);
2167 return 0; 2210 return 0;
2168 } 2211 }
2169 } 2212 }
2213 trace_xfs_log_recover_buf_recover(log, buf_f);
2170 switch (buf_f->blf_type) { 2214 switch (buf_f->blf_type) {
2171 case XFS_LI_BUF: 2215 case XFS_LI_BUF:
2172 blkno = buf_f->blf_blkno; 2216 blkno = buf_f->blf_blkno;
@@ -2185,7 +2229,7 @@ xlog_recover_do_buffer_trans(
2185 2229
2186 mp = log->l_mp; 2230 mp = log->l_mp;
2187 buf_flags = XBF_LOCK; 2231 buf_flags = XBF_LOCK;
2188 if (!(flags & XFS_BLI_INODE_BUF)) 2232 if (!(flags & XFS_BLF_INODE_BUF))
2189 buf_flags |= XBF_MAPPED; 2233 buf_flags |= XBF_MAPPED;
2190 2234
2191 bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags); 2235 bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags);
@@ -2198,13 +2242,13 @@ xlog_recover_do_buffer_trans(
2198 } 2242 }
2199 2243
2200 error = 0; 2244 error = 0;
2201 if (flags & XFS_BLI_INODE_BUF) { 2245 if (flags & XFS_BLF_INODE_BUF) {
2202 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); 2246 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2203 } else if (flags & 2247 } else if (flags &
2204 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { 2248 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2205 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); 2249 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2206 } else { 2250 } else {
2207 xlog_recover_do_reg_buffer(item, bp, buf_f); 2251 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2208 } 2252 }
2209 if (error) 2253 if (error)
2210 return XFS_ERROR(error); 2254 return XFS_ERROR(error);
@@ -2265,10 +2309,9 @@ xlog_recover_do_inode_trans(
2265 } 2309 }
2266 2310
2267 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) { 2311 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2268 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; 2312 in_f = item->ri_buf[0].i_addr;
2269 } else { 2313 } else {
2270 in_f = (xfs_inode_log_format_t *)kmem_alloc( 2314 in_f = kmem_alloc(sizeof(xfs_inode_log_format_t), KM_SLEEP);
2271 sizeof(xfs_inode_log_format_t), KM_SLEEP);
2272 need_free = 1; 2315 need_free = 1;
2273 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f); 2316 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2274 if (error) 2317 if (error)
@@ -2284,8 +2327,10 @@ xlog_recover_do_inode_trans(
2284 if (xlog_check_buffer_cancelled(log, in_f->ilf_blkno, 2327 if (xlog_check_buffer_cancelled(log, in_f->ilf_blkno,
2285 in_f->ilf_len, 0)) { 2328 in_f->ilf_len, 0)) {
2286 error = 0; 2329 error = 0;
2330 trace_xfs_log_recover_inode_cancel(log, in_f);
2287 goto error; 2331 goto error;
2288 } 2332 }
2333 trace_xfs_log_recover_inode_recover(log, in_f);
2289 2334
2290 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 2335 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
2291 XBF_LOCK); 2336 XBF_LOCK);
@@ -2314,7 +2359,7 @@ xlog_recover_do_inode_trans(
2314 error = EFSCORRUPTED; 2359 error = EFSCORRUPTED;
2315 goto error; 2360 goto error;
2316 } 2361 }
2317 dicp = (xfs_icdinode_t *)(item->ri_buf[1].i_addr); 2362 dicp = item->ri_buf[1].i_addr;
2318 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2363 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
2319 xfs_buf_relse(bp); 2364 xfs_buf_relse(bp);
2320 xfs_fs_cmn_err(CE_ALERT, mp, 2365 xfs_fs_cmn_err(CE_ALERT, mp,
@@ -2337,6 +2382,7 @@ xlog_recover_do_inode_trans(
2337 /* do nothing */ 2382 /* do nothing */
2338 } else { 2383 } else {
2339 xfs_buf_relse(bp); 2384 xfs_buf_relse(bp);
2385 trace_xfs_log_recover_inode_skip(log, in_f);
2340 error = 0; 2386 error = 0;
2341 goto error; 2387 goto error;
2342 } 2388 }
@@ -2404,7 +2450,7 @@ xlog_recover_do_inode_trans(
2404 } 2450 }
2405 2451
2406 /* The core is in in-core format */ 2452 /* The core is in in-core format */
2407 xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr); 2453 xfs_dinode_to_disk(dip, item->ri_buf[1].i_addr);
2408 2454
2409 /* the rest is in on-disk format */ 2455 /* the rest is in on-disk format */
2410 if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) { 2456 if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) {
@@ -2521,7 +2567,7 @@ xlog_recover_do_quotaoff_trans(
2521 return (0); 2567 return (0);
2522 } 2568 }
2523 2569
2524 qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr; 2570 qoff_f = item->ri_buf[0].i_addr;
2525 ASSERT(qoff_f); 2571 ASSERT(qoff_f);
2526 2572
2527 /* 2573 /*
@@ -2565,9 +2611,8 @@ xlog_recover_do_dquot_trans(
2565 if (mp->m_qflags == 0) 2611 if (mp->m_qflags == 0)
2566 return (0); 2612 return (0);
2567 2613
2568 recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr; 2614 recddq = item->ri_buf[1].i_addr;
2569 2615 if (recddq == NULL) {
2570 if (item->ri_buf[1].i_addr == NULL) {
2571 cmn_err(CE_ALERT, 2616 cmn_err(CE_ALERT,
2572 "XFS: NULL dquot in %s.", __func__); 2617 "XFS: NULL dquot in %s.", __func__);
2573 return XFS_ERROR(EIO); 2618 return XFS_ERROR(EIO);
@@ -2597,7 +2642,7 @@ xlog_recover_do_dquot_trans(
2597 * The other possibility, of course, is that the quota subsystem was 2642 * The other possibility, of course, is that the quota subsystem was
2598 * removed since the last mount - ENOSYS. 2643 * removed since the last mount - ENOSYS.
2599 */ 2644 */
2600 dq_f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr; 2645 dq_f = item->ri_buf[0].i_addr;
2601 ASSERT(dq_f); 2646 ASSERT(dq_f);
2602 if ((error = xfs_qm_dqcheck(recddq, 2647 if ((error = xfs_qm_dqcheck(recddq,
2603 dq_f->qlf_id, 2648 dq_f->qlf_id,
@@ -2664,7 +2709,7 @@ xlog_recover_do_efi_trans(
2664 return 0; 2709 return 0;
2665 } 2710 }
2666 2711
2667 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; 2712 efi_formatp = item->ri_buf[0].i_addr;
2668 2713
2669 mp = log->l_mp; 2714 mp = log->l_mp;
2670 efip = xfs_efi_init(mp, efi_formatp->efi_nextents); 2715 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
@@ -2710,7 +2755,7 @@ xlog_recover_do_efd_trans(
2710 return; 2755 return;
2711 } 2756 }
2712 2757
2713 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; 2758 efd_formatp = item->ri_buf[0].i_addr;
2714 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) + 2759 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
2715 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) || 2760 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
2716 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) + 2761 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
@@ -2758,11 +2803,12 @@ xlog_recover_do_trans(
2758 int error = 0; 2803 int error = 0;
2759 xlog_recover_item_t *item; 2804 xlog_recover_item_t *item;
2760 2805
2761 error = xlog_recover_reorder_trans(trans); 2806 error = xlog_recover_reorder_trans(log, trans, pass);
2762 if (error) 2807 if (error)
2763 return error; 2808 return error;
2764 2809
2765 list_for_each_entry(item, &trans->r_itemq, ri_list) { 2810 list_for_each_entry(item, &trans->r_itemq, ri_list) {
2811 trace_xfs_log_recover_item_recover(log, trans, item, pass);
2766 switch (ITEM_TYPE(item)) { 2812 switch (ITEM_TYPE(item)) {
2767 case XFS_LI_BUF: 2813 case XFS_LI_BUF:
2768 error = xlog_recover_do_buffer_trans(log, item, pass); 2814 error = xlog_recover_do_buffer_trans(log, item, pass);
@@ -2919,8 +2965,9 @@ xlog_recover_process_data(
2919 error = xlog_recover_unmount_trans(trans); 2965 error = xlog_recover_unmount_trans(trans);
2920 break; 2966 break;
2921 case XLOG_WAS_CONT_TRANS: 2967 case XLOG_WAS_CONT_TRANS:
2922 error = xlog_recover_add_to_cont_trans(trans, 2968 error = xlog_recover_add_to_cont_trans(log,
2923 dp, be32_to_cpu(ohead->oh_len)); 2969 trans, dp,
2970 be32_to_cpu(ohead->oh_len));
2924 break; 2971 break;
2925 case XLOG_START_TRANS: 2972 case XLOG_START_TRANS:
2926 xlog_warn( 2973 xlog_warn(
@@ -2930,7 +2977,7 @@ xlog_recover_process_data(
2930 break; 2977 break;
2931 case 0: 2978 case 0:
2932 case XLOG_CONTINUE_TRANS: 2979 case XLOG_CONTINUE_TRANS:
2933 error = xlog_recover_add_to_trans(trans, 2980 error = xlog_recover_add_to_trans(log, trans,
2934 dp, be32_to_cpu(ohead->oh_len)); 2981 dp, be32_to_cpu(ohead->oh_len));
2935 break; 2982 break;
2936 default: 2983 default:
@@ -3139,7 +3186,7 @@ xlog_recover_process_one_iunlink(
3139 int error; 3186 int error;
3140 3187
3141 ino = XFS_AGINO_TO_INO(mp, agno, agino); 3188 ino = XFS_AGINO_TO_INO(mp, agno, agino);
3142 error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0); 3189 error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
3143 if (error) 3190 if (error)
3144 goto fail; 3191 goto fail;
3145 3192
@@ -3331,42 +3378,6 @@ xlog_pack_data(
3331 } 3378 }
3332} 3379}
3333 3380
3334#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
3335STATIC void
3336xlog_unpack_data_checksum(
3337 xlog_rec_header_t *rhead,
3338 xfs_caddr_t dp,
3339 xlog_t *log)
3340{
3341 __be32 *up = (__be32 *)dp;
3342 uint chksum = 0;
3343 int i;
3344
3345 /* divide length by 4 to get # words */
3346 for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) {
3347 chksum ^= be32_to_cpu(*up);
3348 up++;
3349 }
3350 if (chksum != be32_to_cpu(rhead->h_chksum)) {
3351 if (rhead->h_chksum ||
3352 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
3353 cmn_err(CE_DEBUG,
3354 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
3355 be32_to_cpu(rhead->h_chksum), chksum);
3356 cmn_err(CE_DEBUG,
3357"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
3358 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
3359 cmn_err(CE_DEBUG,
3360 "XFS: LogR this is a LogV2 filesystem\n");
3361 }
3362 log->l_flags |= XLOG_CHKSUM_MISMATCH;
3363 }
3364 }
3365}
3366#else
3367#define xlog_unpack_data_checksum(rhead, dp, log)
3368#endif
3369
3370STATIC void 3381STATIC void
3371xlog_unpack_data( 3382xlog_unpack_data(
3372 xlog_rec_header_t *rhead, 3383 xlog_rec_header_t *rhead,
@@ -3390,8 +3401,6 @@ xlog_unpack_data(
3390 dp += BBSIZE; 3401 dp += BBSIZE;
3391 } 3402 }
3392 } 3403 }
3393
3394 xlog_unpack_data_checksum(rhead, dp, log);
3395} 3404}
3396 3405
3397STATIC int 3406STATIC int
@@ -3490,7 +3499,7 @@ xlog_do_recovery_pass(
3490 hblks = 1; 3499 hblks = 1;
3491 } 3500 }
3492 } else { 3501 } else {
3493 ASSERT(log->l_sectbb_log == 0); 3502 ASSERT(log->l_sectBBsize == 1);
3494 hblks = 1; 3503 hblks = 1;
3495 hbp = xlog_get_bp(log, 1); 3504 hbp = xlog_get_bp(log, 1);
3496 h_size = XLOG_BIG_RECORD_BSIZE; 3505 h_size = XLOG_BIG_RECORD_BSIZE;
@@ -3946,10 +3955,6 @@ xlog_recover_check_summary(
3946 xfs_agf_t *agfp; 3955 xfs_agf_t *agfp;
3947 xfs_buf_t *agfbp; 3956 xfs_buf_t *agfbp;
3948 xfs_buf_t *agibp; 3957 xfs_buf_t *agibp;
3949 xfs_buf_t *sbbp;
3950#ifdef XFS_LOUD_RECOVERY
3951 xfs_sb_t *sbp;
3952#endif
3953 xfs_agnumber_t agno; 3958 xfs_agnumber_t agno;
3954 __uint64_t freeblks; 3959 __uint64_t freeblks;
3955 __uint64_t itotal; 3960 __uint64_t itotal;
@@ -3984,30 +3989,5 @@ xlog_recover_check_summary(
3984 xfs_buf_relse(agibp); 3989 xfs_buf_relse(agibp);
3985 } 3990 }
3986 } 3991 }
3987
3988 sbbp = xfs_getsb(mp, 0);
3989#ifdef XFS_LOUD_RECOVERY
3990 sbp = &mp->m_sb;
3991 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp));
3992 cmn_err(CE_NOTE,
3993 "xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
3994 sbp->sb_icount, itotal);
3995 cmn_err(CE_NOTE,
3996 "xlog_recover_check_summary: sb_ifree %Lu itotal %Lu",
3997 sbp->sb_ifree, ifree);
3998 cmn_err(CE_NOTE,
3999 "xlog_recover_check_summary: sb_fdblocks %Lu freeblks %Lu",
4000 sbp->sb_fdblocks, freeblks);
4001#if 0
4002 /*
4003 * This is turned off until I account for the allocation
4004 * btree blocks which live in free space.
4005 */
4006 ASSERT(sbp->sb_icount == itotal);
4007 ASSERT(sbp->sb_ifree == ifree);
4008 ASSERT(sbp->sb_fdblocks == freeblks);
4009#endif
4010#endif
4011 xfs_buf_relse(sbbp);
4012} 3992}
4013#endif /* DEBUG */ 3993#endif /* DEBUG */