1
2
3
4
5
6#include "xfs.h"
7#include "xfs_fs.h"
8#include "xfs_shared.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_trans_resv.h"
12#include "xfs_bit.h"
13#include "xfs_sb.h"
14#include "xfs_mount.h"
15#include "xfs_defer.h"
16#include "xfs_inode.h"
17#include "xfs_trans.h"
18#include "xfs_log.h"
19#include "xfs_log_priv.h"
20#include "xfs_log_recover.h"
21#include "xfs_trans_priv.h"
22#include "xfs_alloc.h"
23#include "xfs_ialloc.h"
24#include "xfs_trace.h"
25#include "xfs_icache.h"
26#include "xfs_error.h"
27#include "xfs_buf_item.h"
28
29#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
30
31STATIC int
32xlog_find_zeroed(
33 struct xlog *,
34 xfs_daddr_t *);
35STATIC int
36xlog_clear_stale_blocks(
37 struct xlog *,
38 xfs_lsn_t);
39#if defined(DEBUG)
40STATIC void
41xlog_recover_check_summary(
42 struct xlog *);
43#else
44#define xlog_recover_check_summary(log)
45#endif
46STATIC int
47xlog_do_recovery_pass(
48 struct xlog *, xfs_daddr_t, xfs_daddr_t, int, xfs_daddr_t *);
49
50
51
52
53
54
55
56
57
58
59static inline bool
60xlog_verify_bno(
61 struct xlog *log,
62 xfs_daddr_t blk_no,
63 int bbcount)
64{
65 if (blk_no < 0 || blk_no >= log->l_logBBsize)
66 return false;
67 if (bbcount <= 0 || (blk_no + bbcount) > log->l_logBBsize)
68 return false;
69 return true;
70}
71
72
73
74
75
76static char *
77xlog_alloc_buffer(
78 struct xlog *log,
79 int nbblks)
80{
81 int align_mask = xfs_buftarg_dma_alignment(log->l_targ);
82
83
84
85
86
87 if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, 0, nbblks))) {
88 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
89 nbblks);
90 return NULL;
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 if (nbblks > 1 && log->l_sectBBsize > 1)
108 nbblks += log->l_sectBBsize;
109 nbblks = round_up(nbblks, log->l_sectBBsize);
110 return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO);
111}
112
113
114
115
116
117static inline unsigned int
118xlog_align(
119 struct xlog *log,
120 xfs_daddr_t blk_no)
121{
122 return BBTOB(blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1));
123}
124
125static int
126xlog_do_io(
127 struct xlog *log,
128 xfs_daddr_t blk_no,
129 unsigned int nbblks,
130 char *data,
131 unsigned int op)
132{
133 int error;
134
135 if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, blk_no, nbblks))) {
136 xfs_warn(log->l_mp,
137 "Invalid log block/length (0x%llx, 0x%x) for buffer",
138 blk_no, nbblks);
139 return -EFSCORRUPTED;
140 }
141
142 blk_no = round_down(blk_no, log->l_sectBBsize);
143 nbblks = round_up(nbblks, log->l_sectBBsize);
144 ASSERT(nbblks > 0);
145
146 error = xfs_rw_bdev(log->l_targ->bt_bdev, log->l_logBBstart + blk_no,
147 BBTOB(nbblks), data, op);
148 if (error && !XFS_FORCED_SHUTDOWN(log->l_mp)) {
149 xfs_alert(log->l_mp,
150 "log recovery %s I/O error at daddr 0x%llx len %d error %d",
151 op == REQ_OP_WRITE ? "write" : "read",
152 blk_no, nbblks, error);
153 }
154 return error;
155}
156
157STATIC int
158xlog_bread_noalign(
159 struct xlog *log,
160 xfs_daddr_t blk_no,
161 int nbblks,
162 char *data)
163{
164 return xlog_do_io(log, blk_no, nbblks, data, REQ_OP_READ);
165}
166
167STATIC int
168xlog_bread(
169 struct xlog *log,
170 xfs_daddr_t blk_no,
171 int nbblks,
172 char *data,
173 char **offset)
174{
175 int error;
176
177 error = xlog_do_io(log, blk_no, nbblks, data, REQ_OP_READ);
178 if (!error)
179 *offset = data + xlog_align(log, blk_no);
180 return error;
181}
182
183STATIC int
184xlog_bwrite(
185 struct xlog *log,
186 xfs_daddr_t blk_no,
187 int nbblks,
188 char *data)
189{
190 return xlog_do_io(log, blk_no, nbblks, data, REQ_OP_WRITE);
191}
192
193#ifdef DEBUG
194
195
196
197STATIC void
198xlog_header_check_dump(
199 xfs_mount_t *mp,
200 xlog_rec_header_t *head)
201{
202 xfs_debug(mp, "%s: SB : uuid = %pU, fmt = %d",
203 __func__, &mp->m_sb.sb_uuid, XLOG_FMT);
204 xfs_debug(mp, " log : uuid = %pU, fmt = %d",
205 &head->h_fs_uuid, be32_to_cpu(head->h_fmt));
206}
207#else
208#define xlog_header_check_dump(mp, head)
209#endif
210
211
212
213
214STATIC int
215xlog_header_check_recover(
216 xfs_mount_t *mp,
217 xlog_rec_header_t *head)
218{
219 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
220
221
222
223
224
225
226 if (XFS_IS_CORRUPT(mp, head->h_fmt != cpu_to_be32(XLOG_FMT))) {
227 xfs_warn(mp,
228 "dirty log written in incompatible format - can't recover");
229 xlog_header_check_dump(mp, head);
230 return -EFSCORRUPTED;
231 }
232 if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid,
233 &head->h_fs_uuid))) {
234 xfs_warn(mp,
235 "dirty log entry has mismatched uuid - can't recover");
236 xlog_header_check_dump(mp, head);
237 return -EFSCORRUPTED;
238 }
239 return 0;
240}
241
242
243
244
245STATIC int
246xlog_header_check_mount(
247 xfs_mount_t *mp,
248 xlog_rec_header_t *head)
249{
250 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
251
252 if (uuid_is_null(&head->h_fs_uuid)) {
253
254
255
256
257
258 xfs_warn(mp, "null uuid in log - IRIX style log");
259 } else if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid,
260 &head->h_fs_uuid))) {
261 xfs_warn(mp, "log has mismatched uuid - can't recover");
262 xlog_header_check_dump(mp, head);
263 return -EFSCORRUPTED;
264 }
265 return 0;
266}
267
268
269
270
271
272
273
274STATIC int
275xlog_find_cycle_start(
276 struct xlog *log,
277 char *buffer,
278 xfs_daddr_t first_blk,
279 xfs_daddr_t *last_blk,
280 uint cycle)
281{
282 char *offset;
283 xfs_daddr_t mid_blk;
284 xfs_daddr_t end_blk;
285 uint mid_cycle;
286 int error;
287
288 end_blk = *last_blk;
289 mid_blk = BLK_AVG(first_blk, end_blk);
290 while (mid_blk != first_blk && mid_blk != end_blk) {
291 error = xlog_bread(log, mid_blk, 1, buffer, &offset);
292 if (error)
293 return error;
294 mid_cycle = xlog_get_cycle(offset);
295 if (mid_cycle == cycle)
296 end_blk = mid_blk;
297 else
298 first_blk = mid_blk;
299 mid_blk = BLK_AVG(first_blk, end_blk);
300 }
301 ASSERT((mid_blk == first_blk && mid_blk+1 == end_blk) ||
302 (mid_blk == end_blk && mid_blk-1 == first_blk));
303
304 *last_blk = end_blk;
305
306 return 0;
307}
308
309
310
311
312
313
314
315
316
317STATIC int
318xlog_find_verify_cycle(
319 struct xlog *log,
320 xfs_daddr_t start_blk,
321 int nbblks,
322 uint stop_on_cycle_no,
323 xfs_daddr_t *new_blk)
324{
325 xfs_daddr_t i, j;
326 uint cycle;
327 char *buffer;
328 xfs_daddr_t bufblks;
329 char *buf = NULL;
330 int error = 0;
331
332
333
334
335
336
337
338 bufblks = 1 << ffs(nbblks);
339 while (bufblks > log->l_logBBsize)
340 bufblks >>= 1;
341 while (!(buffer = xlog_alloc_buffer(log, bufblks))) {
342 bufblks >>= 1;
343 if (bufblks < log->l_sectBBsize)
344 return -ENOMEM;
345 }
346
347 for (i = start_blk; i < start_blk + nbblks; i += bufblks) {
348 int bcount;
349
350 bcount = min(bufblks, (start_blk + nbblks - i));
351
352 error = xlog_bread(log, i, bcount, buffer, &buf);
353 if (error)
354 goto out;
355
356 for (j = 0; j < bcount; j++) {
357 cycle = xlog_get_cycle(buf);
358 if (cycle == stop_on_cycle_no) {
359 *new_blk = i+j;
360 goto out;
361 }
362
363 buf += BBSIZE;
364 }
365 }
366
367 *new_blk = -1;
368
369out:
370 kmem_free(buffer);
371 return error;
372}
373
374static inline int
375xlog_logrec_hblks(struct xlog *log, struct xlog_rec_header *rh)
376{
377 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
378 int h_size = be32_to_cpu(rh->h_size);
379
380 if ((be32_to_cpu(rh->h_version) & XLOG_VERSION_2) &&
381 h_size > XLOG_HEADER_CYCLE_SIZE)
382 return DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
383 }
384 return 1;
385}
386
387
388
389
390
391
392
393
394
395
396
397
398
399STATIC int
400xlog_find_verify_log_record(
401 struct xlog *log,
402 xfs_daddr_t start_blk,
403 xfs_daddr_t *last_blk,
404 int extra_bblks)
405{
406 xfs_daddr_t i;
407 char *buffer;
408 char *offset = NULL;
409 xlog_rec_header_t *head = NULL;
410 int error = 0;
411 int smallmem = 0;
412 int num_blks = *last_blk - start_blk;
413 int xhdrs;
414
415 ASSERT(start_blk != 0 || *last_blk != start_blk);
416
417 buffer = xlog_alloc_buffer(log, num_blks);
418 if (!buffer) {
419 buffer = xlog_alloc_buffer(log, 1);
420 if (!buffer)
421 return -ENOMEM;
422 smallmem = 1;
423 } else {
424 error = xlog_bread(log, start_blk, num_blks, buffer, &offset);
425 if (error)
426 goto out;
427 offset += ((num_blks - 1) << BBSHIFT);
428 }
429
430 for (i = (*last_blk) - 1; i >= 0; i--) {
431 if (i < start_blk) {
432
433 xfs_warn(log->l_mp,
434 "Log inconsistent (didn't find previous header)");
435 ASSERT(0);
436 error = -EFSCORRUPTED;
437 goto out;
438 }
439
440 if (smallmem) {
441 error = xlog_bread(log, i, 1, buffer, &offset);
442 if (error)
443 goto out;
444 }
445
446 head = (xlog_rec_header_t *)offset;
447
448 if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
449 break;
450
451 if (!smallmem)
452 offset -= BBSIZE;
453 }
454
455
456
457
458
459
460 if (i == -1) {
461 error = 1;
462 goto out;
463 }
464
465
466
467
468
469 if ((error = xlog_header_check_mount(log->l_mp, head)))
470 goto out;
471
472
473
474
475
476
477
478
479 xhdrs = xlog_logrec_hblks(log, head);
480
481 if (*last_blk - i + extra_bblks !=
482 BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
483 *last_blk = i;
484
485out:
486 kmem_free(buffer);
487 return error;
488}
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503STATIC int
504xlog_find_head(
505 struct xlog *log,
506 xfs_daddr_t *return_head_blk)
507{
508 char *buffer;
509 char *offset;
510 xfs_daddr_t new_blk, first_blk, start_blk, last_blk, head_blk;
511 int num_scan_bblks;
512 uint first_half_cycle, last_half_cycle;
513 uint stop_on_cycle;
514 int error, log_bbnum = log->l_logBBsize;
515
516
517 error = xlog_find_zeroed(log, &first_blk);
518 if (error < 0) {
519 xfs_warn(log->l_mp, "empty log check failed");
520 return error;
521 }
522 if (error == 1) {
523 *return_head_blk = first_blk;
524
525
526 if (!first_blk) {
527
528
529
530
531 xfs_warn(log->l_mp, "totally zeroed log");
532 }
533
534 return 0;
535 }
536
537 first_blk = 0;
538 buffer = xlog_alloc_buffer(log, 1);
539 if (!buffer)
540 return -ENOMEM;
541
542 error = xlog_bread(log, 0, 1, buffer, &offset);
543 if (error)
544 goto out_free_buffer;
545
546 first_half_cycle = xlog_get_cycle(offset);
547
548 last_blk = head_blk = log_bbnum - 1;
549 error = xlog_bread(log, last_blk, 1, buffer, &offset);
550 if (error)
551 goto out_free_buffer;
552
553 last_half_cycle = xlog_get_cycle(offset);
554 ASSERT(last_half_cycle != 0);
555
556
557
558
559
560
561
562
563
564
565
566
567 if (first_half_cycle == last_half_cycle) {
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593 head_blk = log_bbnum;
594 stop_on_cycle = last_half_cycle - 1;
595 } else {
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618 stop_on_cycle = last_half_cycle;
619 error = xlog_find_cycle_start(log, buffer, first_blk, &head_blk,
620 last_half_cycle);
621 if (error)
622 goto out_free_buffer;
623 }
624
625
626
627
628
629
630
631
632 num_scan_bblks = min_t(int, log_bbnum, XLOG_TOTAL_REC_SHIFT(log));
633 if (head_blk >= num_scan_bblks) {
634
635
636
637
638 start_blk = head_blk - num_scan_bblks;
639 if ((error = xlog_find_verify_cycle(log,
640 start_blk, num_scan_bblks,
641 stop_on_cycle, &new_blk)))
642 goto out_free_buffer;
643 if (new_blk != -1)
644 head_blk = new_blk;
645 } else {
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673 ASSERT(head_blk <= INT_MAX &&
674 (xfs_daddr_t) num_scan_bblks >= head_blk);
675 start_blk = log_bbnum - (num_scan_bblks - head_blk);
676 if ((error = xlog_find_verify_cycle(log, start_blk,
677 num_scan_bblks - (int)head_blk,
678 (stop_on_cycle - 1), &new_blk)))
679 goto out_free_buffer;
680 if (new_blk != -1) {
681 head_blk = new_blk;
682 goto validate_head;
683 }
684
685
686
687
688
689
690 start_blk = 0;
691 ASSERT(head_blk <= INT_MAX);
692 if ((error = xlog_find_verify_cycle(log,
693 start_blk, (int)head_blk,
694 stop_on_cycle, &new_blk)))
695 goto out_free_buffer;
696 if (new_blk != -1)
697 head_blk = new_blk;
698 }
699
700validate_head:
701
702
703
704
705 num_scan_bblks = XLOG_REC_SHIFT(log);
706 if (head_blk >= num_scan_bblks) {
707 start_blk = head_blk - num_scan_bblks;
708
709
710 error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0);
711 if (error == 1)
712 error = -EIO;
713 if (error)
714 goto out_free_buffer;
715 } else {
716 start_blk = 0;
717 ASSERT(head_blk <= INT_MAX);
718 error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0);
719 if (error < 0)
720 goto out_free_buffer;
721 if (error == 1) {
722
723 start_blk = log_bbnum - (num_scan_bblks - head_blk);
724 new_blk = log_bbnum;
725 ASSERT(start_blk <= INT_MAX &&
726 (xfs_daddr_t) log_bbnum-start_blk >= 0);
727 ASSERT(head_blk <= INT_MAX);
728 error = xlog_find_verify_log_record(log, start_blk,
729 &new_blk, (int)head_blk);
730 if (error == 1)
731 error = -EIO;
732 if (error)
733 goto out_free_buffer;
734 if (new_blk != log_bbnum)
735 head_blk = new_blk;
736 } else if (error)
737 goto out_free_buffer;
738 }
739
740 kmem_free(buffer);
741 if (head_blk == log_bbnum)
742 *return_head_blk = 0;
743 else
744 *return_head_blk = head_blk;
745
746
747
748
749
750
751 return 0;
752
753out_free_buffer:
754 kmem_free(buffer);
755 if (error)
756 xfs_warn(log->l_mp, "failed to find log head");
757 return error;
758}
759
760
761
762
763
764
765
766
767
768STATIC int
769xlog_rseek_logrec_hdr(
770 struct xlog *log,
771 xfs_daddr_t head_blk,
772 xfs_daddr_t tail_blk,
773 int count,
774 char *buffer,
775 xfs_daddr_t *rblk,
776 struct xlog_rec_header **rhead,
777 bool *wrapped)
778{
779 int i;
780 int error;
781 int found = 0;
782 char *offset = NULL;
783 xfs_daddr_t end_blk;
784
785 *wrapped = false;
786
787
788
789
790
791 end_blk = head_blk > tail_blk ? tail_blk : 0;
792 for (i = (int) head_blk - 1; i >= end_blk; i--) {
793 error = xlog_bread(log, i, 1, buffer, &offset);
794 if (error)
795 goto out_error;
796
797 if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
798 *rblk = i;
799 *rhead = (struct xlog_rec_header *) offset;
800 if (++found == count)
801 break;
802 }
803 }
804
805
806
807
808
809
810 if (tail_blk >= head_blk && found != count) {
811 for (i = log->l_logBBsize - 1; i >= (int) tail_blk; i--) {
812 error = xlog_bread(log, i, 1, buffer, &offset);
813 if (error)
814 goto out_error;
815
816 if (*(__be32 *)offset ==
817 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
818 *wrapped = true;
819 *rblk = i;
820 *rhead = (struct xlog_rec_header *) offset;
821 if (++found == count)
822 break;
823 }
824 }
825 }
826
827 return found;
828
829out_error:
830 return error;
831}
832
833
834
835
836
837
838
839
840
841
842STATIC int
843xlog_seek_logrec_hdr(
844 struct xlog *log,
845 xfs_daddr_t head_blk,
846 xfs_daddr_t tail_blk,
847 int count,
848 char *buffer,
849 xfs_daddr_t *rblk,
850 struct xlog_rec_header **rhead,
851 bool *wrapped)
852{
853 int i;
854 int error;
855 int found = 0;
856 char *offset = NULL;
857 xfs_daddr_t end_blk;
858
859 *wrapped = false;
860
861
862
863
864
865 end_blk = head_blk > tail_blk ? head_blk : log->l_logBBsize - 1;
866 for (i = (int) tail_blk; i <= end_blk; i++) {
867 error = xlog_bread(log, i, 1, buffer, &offset);
868 if (error)
869 goto out_error;
870
871 if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
872 *rblk = i;
873 *rhead = (struct xlog_rec_header *) offset;
874 if (++found == count)
875 break;
876 }
877 }
878
879
880
881
882
883 if (tail_blk > head_blk && found != count) {
884 for (i = 0; i < (int) head_blk; i++) {
885 error = xlog_bread(log, i, 1, buffer, &offset);
886 if (error)
887 goto out_error;
888
889 if (*(__be32 *)offset ==
890 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
891 *wrapped = true;
892 *rblk = i;
893 *rhead = (struct xlog_rec_header *) offset;
894 if (++found == count)
895 break;
896 }
897 }
898 }
899
900 return found;
901
902out_error:
903 return error;
904}
905
906
907
908
909static inline int
910xlog_tail_distance(
911 struct xlog *log,
912 xfs_daddr_t head_blk,
913 xfs_daddr_t tail_blk)
914{
915 if (head_blk < tail_blk)
916 return tail_blk - head_blk;
917
918 return tail_blk + (log->l_logBBsize - head_blk);
919}
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940STATIC int
941xlog_verify_tail(
942 struct xlog *log,
943 xfs_daddr_t head_blk,
944 xfs_daddr_t *tail_blk,
945 int hsize)
946{
947 struct xlog_rec_header *thead;
948 char *buffer;
949 xfs_daddr_t first_bad;
950 int error = 0;
951 bool wrapped;
952 xfs_daddr_t tmp_tail;
953 xfs_daddr_t orig_tail = *tail_blk;
954
955 buffer = xlog_alloc_buffer(log, 1);
956 if (!buffer)
957 return -ENOMEM;
958
959
960
961
962
963 error = xlog_seek_logrec_hdr(log, head_blk, *tail_blk, 1, buffer,
964 &tmp_tail, &thead, &wrapped);
965 if (error < 0)
966 goto out;
967 if (*tail_blk != tmp_tail)
968 *tail_blk = tmp_tail;
969
970
971
972
973
974
975
976
977 first_bad = 0;
978 error = xlog_do_recovery_pass(log, head_blk, *tail_blk,
979 XLOG_RECOVER_CRCPASS, &first_bad);
980 while ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) {
981 int tail_distance;
982
983
984
985
986
987 tail_distance = xlog_tail_distance(log, head_blk, first_bad);
988 if (tail_distance > BTOBB(XLOG_MAX_ICLOGS * hsize))
989 break;
990
991
992 error = xlog_seek_logrec_hdr(log, head_blk, first_bad, 2,
993 buffer, &tmp_tail, &thead, &wrapped);
994 if (error < 0)
995 goto out;
996
997 *tail_blk = tmp_tail;
998 first_bad = 0;
999 error = xlog_do_recovery_pass(log, head_blk, *tail_blk,
1000 XLOG_RECOVER_CRCPASS, &first_bad);
1001 }
1002
1003 if (!error && *tail_blk != orig_tail)
1004 xfs_warn(log->l_mp,
1005 "Tail block (0x%llx) overwrite detected. Updated to 0x%llx",
1006 orig_tail, *tail_blk);
1007out:
1008 kmem_free(buffer);
1009 return error;
1010}
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025STATIC int
1026xlog_verify_head(
1027 struct xlog *log,
1028 xfs_daddr_t *head_blk,
1029 xfs_daddr_t *tail_blk,
1030 char *buffer,
1031 xfs_daddr_t *rhead_blk,
1032 struct xlog_rec_header **rhead,
1033 bool *wrapped)
1034{
1035 struct xlog_rec_header *tmp_rhead;
1036 char *tmp_buffer;
1037 xfs_daddr_t first_bad;
1038 xfs_daddr_t tmp_rhead_blk;
1039 int found;
1040 int error;
1041 bool tmp_wrapped;
1042
1043
1044
1045
1046
1047
1048
1049 tmp_buffer = xlog_alloc_buffer(log, 1);
1050 if (!tmp_buffer)
1051 return -ENOMEM;
1052 error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk,
1053 XLOG_MAX_ICLOGS, tmp_buffer,
1054 &tmp_rhead_blk, &tmp_rhead, &tmp_wrapped);
1055 kmem_free(tmp_buffer);
1056 if (error < 0)
1057 return error;
1058
1059
1060
1061
1062
1063
1064 error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk,
1065 XLOG_RECOVER_CRCPASS, &first_bad);
1066 if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) {
1067
1068
1069
1070
1071 error = 0;
1072 xfs_warn(log->l_mp,
1073"Torn write (CRC failure) detected at log block 0x%llx. Truncating head block from 0x%llx.",
1074 first_bad, *head_blk);
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1,
1085 buffer, rhead_blk, rhead, wrapped);
1086 if (found < 0)
1087 return found;
1088 if (found == 0)
1089 return -EIO;
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 *head_blk = first_bad;
1101 *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn));
1102 if (*head_blk == *tail_blk) {
1103 ASSERT(0);
1104 return 0;
1105 }
1106 }
1107 if (error)
1108 return error;
1109
1110 return xlog_verify_tail(log, *head_blk, tail_blk,
1111 be32_to_cpu((*rhead)->h_size));
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122static inline xfs_daddr_t
1123xlog_wrap_logbno(
1124 struct xlog *log,
1125 xfs_daddr_t bno)
1126{
1127 int mod;
1128
1129 div_s64_rem(bno, log->l_logBBsize, &mod);
1130 return mod;
1131}
1132
1133
1134
1135
1136
1137
1138static int
1139xlog_check_unmount_rec(
1140 struct xlog *log,
1141 xfs_daddr_t *head_blk,
1142 xfs_daddr_t *tail_blk,
1143 struct xlog_rec_header *rhead,
1144 xfs_daddr_t rhead_blk,
1145 char *buffer,
1146 bool *clean)
1147{
1148 struct xlog_op_header *op_head;
1149 xfs_daddr_t umount_data_blk;
1150 xfs_daddr_t after_umount_blk;
1151 int hblks;
1152 int error;
1153 char *offset;
1154
1155 *clean = false;
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166 hblks = xlog_logrec_hblks(log, rhead);
1167 after_umount_blk = xlog_wrap_logbno(log,
1168 rhead_blk + hblks + BTOBB(be32_to_cpu(rhead->h_len)));
1169
1170 if (*head_blk == after_umount_blk &&
1171 be32_to_cpu(rhead->h_num_logops) == 1) {
1172 umount_data_blk = xlog_wrap_logbno(log, rhead_blk + hblks);
1173 error = xlog_bread(log, umount_data_blk, 1, buffer, &offset);
1174 if (error)
1175 return error;
1176
1177 op_head = (struct xlog_op_header *)offset;
1178 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
1179
1180
1181
1182
1183
1184 xlog_assign_atomic_lsn(&log->l_tail_lsn,
1185 log->l_curr_cycle, after_umount_blk);
1186 xlog_assign_atomic_lsn(&log->l_last_sync_lsn,
1187 log->l_curr_cycle, after_umount_blk);
1188 *tail_blk = after_umount_blk;
1189
1190 *clean = true;
1191 }
1192 }
1193
1194 return 0;
1195}
1196
1197static void
1198xlog_set_state(
1199 struct xlog *log,
1200 xfs_daddr_t head_blk,
1201 struct xlog_rec_header *rhead,
1202 xfs_daddr_t rhead_blk,
1203 bool bump_cycle)
1204{
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 log->l_prev_block = rhead_blk;
1216 log->l_curr_block = (int)head_blk;
1217 log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
1218 if (bump_cycle)
1219 log->l_curr_cycle++;
1220 atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn));
1221 atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn));
1222 xlog_assign_grant_head(&log->l_reserve_head.grant, log->l_curr_cycle,
1223 BBTOB(log->l_curr_block));
1224 xlog_assign_grant_head(&log->l_write_head.grant, log->l_curr_cycle,
1225 BBTOB(log->l_curr_block));
1226}
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244STATIC int
1245xlog_find_tail(
1246 struct xlog *log,
1247 xfs_daddr_t *head_blk,
1248 xfs_daddr_t *tail_blk)
1249{
1250 xlog_rec_header_t *rhead;
1251 char *offset = NULL;
1252 char *buffer;
1253 int error;
1254 xfs_daddr_t rhead_blk;
1255 xfs_lsn_t tail_lsn;
1256 bool wrapped = false;
1257 bool clean = false;
1258
1259
1260
1261
1262 if ((error = xlog_find_head(log, head_blk)))
1263 return error;
1264 ASSERT(*head_blk < INT_MAX);
1265
1266 buffer = xlog_alloc_buffer(log, 1);
1267 if (!buffer)
1268 return -ENOMEM;
1269 if (*head_blk == 0) {
1270 error = xlog_bread(log, 0, 1, buffer, &offset);
1271 if (error)
1272 goto done;
1273
1274 if (xlog_get_cycle(offset) == 0) {
1275 *tail_blk = 0;
1276
1277 goto done;
1278 }
1279 }
1280
1281
1282
1283
1284
1285
1286 error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, buffer,
1287 &rhead_blk, &rhead, &wrapped);
1288 if (error < 0)
1289 goto done;
1290 if (!error) {
1291 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
1292 error = -EFSCORRUPTED;
1293 goto done;
1294 }
1295 *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
1296
1297
1298
1299
1300 xlog_set_state(log, *head_blk, rhead, rhead_blk, wrapped);
1301 tail_lsn = atomic64_read(&log->l_tail_lsn);
1302
1303
1304
1305
1306
1307 error = xlog_check_unmount_rec(log, head_blk, tail_blk, rhead,
1308 rhead_blk, buffer, &clean);
1309 if (error)
1310 goto done;
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 if (!clean) {
1323 xfs_daddr_t orig_head = *head_blk;
1324
1325 error = xlog_verify_head(log, head_blk, tail_blk, buffer,
1326 &rhead_blk, &rhead, &wrapped);
1327 if (error)
1328 goto done;
1329
1330
1331 if (*head_blk != orig_head) {
1332 xlog_set_state(log, *head_blk, rhead, rhead_blk,
1333 wrapped);
1334 tail_lsn = atomic64_read(&log->l_tail_lsn);
1335 error = xlog_check_unmount_rec(log, head_blk, tail_blk,
1336 rhead, rhead_blk, buffer,
1337 &clean);
1338 if (error)
1339 goto done;
1340 }
1341 }
1342
1343
1344
1345
1346
1347
1348 if (clean)
1349 log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN;
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370 if (!xfs_readonly_buftarg(log->l_targ))
1371 error = xlog_clear_stale_blocks(log, tail_lsn);
1372
1373done:
1374 kmem_free(buffer);
1375
1376 if (error)
1377 xfs_warn(log->l_mp, "failed to locate log tail");
1378 return error;
1379}
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397STATIC int
1398xlog_find_zeroed(
1399 struct xlog *log,
1400 xfs_daddr_t *blk_no)
1401{
1402 char *buffer;
1403 char *offset;
1404 uint first_cycle, last_cycle;
1405 xfs_daddr_t new_blk, last_blk, start_blk;
1406 xfs_daddr_t num_scan_bblks;
1407 int error, log_bbnum = log->l_logBBsize;
1408
1409 *blk_no = 0;
1410
1411
1412 buffer = xlog_alloc_buffer(log, 1);
1413 if (!buffer)
1414 return -ENOMEM;
1415 error = xlog_bread(log, 0, 1, buffer, &offset);
1416 if (error)
1417 goto out_free_buffer;
1418
1419 first_cycle = xlog_get_cycle(offset);
1420 if (first_cycle == 0) {
1421 *blk_no = 0;
1422 kmem_free(buffer);
1423 return 1;
1424 }
1425
1426
1427 error = xlog_bread(log, log_bbnum-1, 1, buffer, &offset);
1428 if (error)
1429 goto out_free_buffer;
1430
1431 last_cycle = xlog_get_cycle(offset);
1432 if (last_cycle != 0) {
1433 kmem_free(buffer);
1434 return 0;
1435 }
1436
1437
1438 last_blk = log_bbnum-1;
1439 error = xlog_find_cycle_start(log, buffer, 0, &last_blk, 0);
1440 if (error)
1441 goto out_free_buffer;
1442
1443
1444
1445
1446
1447
1448
1449 num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
1450 ASSERT(num_scan_bblks <= INT_MAX);
1451
1452 if (last_blk < num_scan_bblks)
1453 num_scan_bblks = last_blk;
1454 start_blk = last_blk - num_scan_bblks;
1455
1456
1457
1458
1459
1460
1461
1462 if ((error = xlog_find_verify_cycle(log, start_blk,
1463 (int)num_scan_bblks, 0, &new_blk)))
1464 goto out_free_buffer;
1465 if (new_blk != -1)
1466 last_blk = new_blk;
1467
1468
1469
1470
1471
1472 error = xlog_find_verify_log_record(log, start_blk, &last_blk, 0);
1473 if (error == 1)
1474 error = -EIO;
1475 if (error)
1476 goto out_free_buffer;
1477
1478 *blk_no = last_blk;
1479out_free_buffer:
1480 kmem_free(buffer);
1481 if (error)
1482 return error;
1483 return 1;
1484}
1485
1486
1487
1488
1489
1490
1491STATIC void
1492xlog_add_record(
1493 struct xlog *log,
1494 char *buf,
1495 int cycle,
1496 int block,
1497 int tail_cycle,
1498 int tail_block)
1499{
1500 xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
1501
1502 memset(buf, 0, BBSIZE);
1503 recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
1504 recp->h_cycle = cpu_to_be32(cycle);
1505 recp->h_version = cpu_to_be32(
1506 xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
1507 recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
1508 recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
1509 recp->h_fmt = cpu_to_be32(XLOG_FMT);
1510 memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
1511}
1512
1513STATIC int
1514xlog_write_log_records(
1515 struct xlog *log,
1516 int cycle,
1517 int start_block,
1518 int blocks,
1519 int tail_cycle,
1520 int tail_block)
1521{
1522 char *offset;
1523 char *buffer;
1524 int balign, ealign;
1525 int sectbb = log->l_sectBBsize;
1526 int end_block = start_block + blocks;
1527 int bufblks;
1528 int error = 0;
1529 int i, j = 0;
1530
1531
1532
1533
1534
1535
1536
1537 bufblks = 1 << ffs(blocks);
1538 while (bufblks > log->l_logBBsize)
1539 bufblks >>= 1;
1540 while (!(buffer = xlog_alloc_buffer(log, bufblks))) {
1541 bufblks >>= 1;
1542 if (bufblks < sectbb)
1543 return -ENOMEM;
1544 }
1545
1546
1547
1548
1549
1550 balign = round_down(start_block, sectbb);
1551 if (balign != start_block) {
1552 error = xlog_bread_noalign(log, start_block, 1, buffer);
1553 if (error)
1554 goto out_free_buffer;
1555
1556 j = start_block - balign;
1557 }
1558
1559 for (i = start_block; i < end_block; i += bufblks) {
1560 int bcount, endcount;
1561
1562 bcount = min(bufblks, end_block - start_block);
1563 endcount = bcount - j;
1564
1565
1566
1567
1568
1569 ealign = round_down(end_block, sectbb);
1570 if (j == 0 && (start_block + endcount > ealign)) {
1571 error = xlog_bread_noalign(log, ealign, sectbb,
1572 buffer + BBTOB(ealign - start_block));
1573 if (error)
1574 break;
1575
1576 }
1577
1578 offset = buffer + xlog_align(log, start_block);
1579 for (; j < endcount; j++) {
1580 xlog_add_record(log, offset, cycle, i+j,
1581 tail_cycle, tail_block);
1582 offset += BBSIZE;
1583 }
1584 error = xlog_bwrite(log, start_block, endcount, buffer);
1585 if (error)
1586 break;
1587 start_block += endcount;
1588 j = 0;
1589 }
1590
1591out_free_buffer:
1592 kmem_free(buffer);
1593 return error;
1594}
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612STATIC int
1613xlog_clear_stale_blocks(
1614 struct xlog *log,
1615 xfs_lsn_t tail_lsn)
1616{
1617 int tail_cycle, head_cycle;
1618 int tail_block, head_block;
1619 int tail_distance, max_distance;
1620 int distance;
1621 int error;
1622
1623 tail_cycle = CYCLE_LSN(tail_lsn);
1624 tail_block = BLOCK_LSN(tail_lsn);
1625 head_cycle = log->l_curr_cycle;
1626 head_block = log->l_curr_block;
1627
1628
1629
1630
1631
1632
1633
1634 if (head_cycle == tail_cycle) {
1635
1636
1637
1638
1639
1640
1641
1642 if (XFS_IS_CORRUPT(log->l_mp,
1643 head_block < tail_block ||
1644 head_block >= log->l_logBBsize))
1645 return -EFSCORRUPTED;
1646 tail_distance = tail_block + (log->l_logBBsize - head_block);
1647 } else {
1648
1649
1650
1651
1652
1653 if (XFS_IS_CORRUPT(log->l_mp,
1654 head_block >= tail_block ||
1655 head_cycle != tail_cycle + 1))
1656 return -EFSCORRUPTED;
1657 tail_distance = tail_block - head_block;
1658 }
1659
1660
1661
1662
1663
1664 if (tail_distance <= 0) {
1665 ASSERT(tail_distance == 0);
1666 return 0;
1667 }
1668
1669 max_distance = XLOG_TOTAL_REC_SHIFT(log);
1670
1671
1672
1673
1674
1675
1676
1677 max_distance = min(max_distance, tail_distance);
1678
1679 if ((head_block + max_distance) <= log->l_logBBsize) {
1680
1681
1682
1683
1684
1685
1686
1687 error = xlog_write_log_records(log, (head_cycle - 1),
1688 head_block, max_distance, tail_cycle,
1689 tail_block);
1690 if (error)
1691 return error;
1692 } else {
1693
1694
1695
1696
1697
1698
1699
1700 distance = log->l_logBBsize - head_block;
1701 error = xlog_write_log_records(log, (head_cycle - 1),
1702 head_block, distance, tail_cycle,
1703 tail_block);
1704
1705 if (error)
1706 return error;
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716 distance = max_distance - (log->l_logBBsize - head_block);
1717 error = xlog_write_log_records(log, head_cycle, 0, distance,
1718 tail_cycle, tail_block);
1719 if (error)
1720 return error;
1721 }
1722
1723 return 0;
1724}
1725
1726
1727
1728
1729
1730void
1731xlog_recover_release_intent(
1732 struct xlog *log,
1733 unsigned short intent_type,
1734 uint64_t intent_id)
1735{
1736 struct xfs_ail_cursor cur;
1737 struct xfs_log_item *lip;
1738 struct xfs_ail *ailp = log->l_ailp;
1739
1740 spin_lock(&ailp->ail_lock);
1741 for (lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); lip != NULL;
1742 lip = xfs_trans_ail_cursor_next(ailp, &cur)) {
1743 if (lip->li_type != intent_type)
1744 continue;
1745 if (!lip->li_ops->iop_match(lip, intent_id))
1746 continue;
1747
1748 spin_unlock(&ailp->ail_lock);
1749 lip->li_ops->iop_release(lip);
1750 spin_lock(&ailp->ail_lock);
1751 break;
1752 }
1753
1754 xfs_trans_ail_cursor_done(&cur);
1755 spin_unlock(&ailp->ail_lock);
1756}
1757
1758
1759
1760
1761
1762
1763
1764static const struct xlog_recover_item_ops *xlog_recover_item_ops[] = {
1765 &xlog_buf_item_ops,
1766 &xlog_inode_item_ops,
1767 &xlog_dquot_item_ops,
1768 &xlog_quotaoff_item_ops,
1769 &xlog_icreate_item_ops,
1770 &xlog_efi_item_ops,
1771 &xlog_efd_item_ops,
1772 &xlog_rui_item_ops,
1773 &xlog_rud_item_ops,
1774 &xlog_cui_item_ops,
1775 &xlog_cud_item_ops,
1776 &xlog_bui_item_ops,
1777 &xlog_bud_item_ops,
1778};
1779
1780static const struct xlog_recover_item_ops *
1781xlog_find_item_ops(
1782 struct xlog_recover_item *item)
1783{
1784 unsigned int i;
1785
1786 for (i = 0; i < ARRAY_SIZE(xlog_recover_item_ops); i++)
1787 if (ITEM_TYPE(item) == xlog_recover_item_ops[i]->item_type)
1788 return xlog_recover_item_ops[i];
1789
1790 return NULL;
1791}
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842STATIC int
1843xlog_recover_reorder_trans(
1844 struct xlog *log,
1845 struct xlog_recover *trans,
1846 int pass)
1847{
1848 struct xlog_recover_item *item, *n;
1849 int error = 0;
1850 LIST_HEAD(sort_list);
1851 LIST_HEAD(cancel_list);
1852 LIST_HEAD(buffer_list);
1853 LIST_HEAD(inode_buffer_list);
1854 LIST_HEAD(item_list);
1855
1856 list_splice_init(&trans->r_itemq, &sort_list);
1857 list_for_each_entry_safe(item, n, &sort_list, ri_list) {
1858 enum xlog_recover_reorder fate = XLOG_REORDER_ITEM_LIST;
1859
1860 item->ri_ops = xlog_find_item_ops(item);
1861 if (!item->ri_ops) {
1862 xfs_warn(log->l_mp,
1863 "%s: unrecognized type of log operation (%d)",
1864 __func__, ITEM_TYPE(item));
1865 ASSERT(0);
1866
1867
1868
1869
1870 if (!list_empty(&sort_list))
1871 list_splice_init(&sort_list, &trans->r_itemq);
1872 error = -EFSCORRUPTED;
1873 break;
1874 }
1875
1876 if (item->ri_ops->reorder)
1877 fate = item->ri_ops->reorder(item);
1878
1879 switch (fate) {
1880 case XLOG_REORDER_BUFFER_LIST:
1881 list_move_tail(&item->ri_list, &buffer_list);
1882 break;
1883 case XLOG_REORDER_CANCEL_LIST:
1884 trace_xfs_log_recover_item_reorder_head(log,
1885 trans, item, pass);
1886 list_move(&item->ri_list, &cancel_list);
1887 break;
1888 case XLOG_REORDER_INODE_BUFFER_LIST:
1889 list_move(&item->ri_list, &inode_buffer_list);
1890 break;
1891 case XLOG_REORDER_ITEM_LIST:
1892 trace_xfs_log_recover_item_reorder_tail(log,
1893 trans, item, pass);
1894 list_move_tail(&item->ri_list, &item_list);
1895 break;
1896 }
1897 }
1898
1899 ASSERT(list_empty(&sort_list));
1900 if (!list_empty(&buffer_list))
1901 list_splice(&buffer_list, &trans->r_itemq);
1902 if (!list_empty(&item_list))
1903 list_splice_tail(&item_list, &trans->r_itemq);
1904 if (!list_empty(&inode_buffer_list))
1905 list_splice_tail(&inode_buffer_list, &trans->r_itemq);
1906 if (!list_empty(&cancel_list))
1907 list_splice_tail(&cancel_list, &trans->r_itemq);
1908 return error;
1909}
1910
1911void
1912xlog_buf_readahead(
1913 struct xlog *log,
1914 xfs_daddr_t blkno,
1915 uint len,
1916 const struct xfs_buf_ops *ops)
1917{
1918 if (!xlog_is_buffer_cancelled(log, blkno, len))
1919 xfs_buf_readahead(log->l_mp->m_ddev_targp, blkno, len, ops);
1920}
1921
1922STATIC int
1923xlog_recover_items_pass2(
1924 struct xlog *log,
1925 struct xlog_recover *trans,
1926 struct list_head *buffer_list,
1927 struct list_head *item_list)
1928{
1929 struct xlog_recover_item *item;
1930 int error = 0;
1931
1932 list_for_each_entry(item, item_list, ri_list) {
1933 trace_xfs_log_recover_item_recover(log, trans, item,
1934 XLOG_RECOVER_PASS2);
1935
1936 if (item->ri_ops->commit_pass2)
1937 error = item->ri_ops->commit_pass2(log, buffer_list,
1938 item, trans->r_lsn);
1939 if (error)
1940 return error;
1941 }
1942
1943 return error;
1944}
1945
1946
1947
1948
1949
1950
1951
1952STATIC int
1953xlog_recover_commit_trans(
1954 struct xlog *log,
1955 struct xlog_recover *trans,
1956 int pass,
1957 struct list_head *buffer_list)
1958{
1959 int error = 0;
1960 int items_queued = 0;
1961 struct xlog_recover_item *item;
1962 struct xlog_recover_item *next;
1963 LIST_HEAD (ra_list);
1964 LIST_HEAD (done_list);
1965
1966 #define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
1967
1968 hlist_del_init(&trans->r_list);
1969
1970 error = xlog_recover_reorder_trans(log, trans, pass);
1971 if (error)
1972 return error;
1973
1974 list_for_each_entry_safe(item, next, &trans->r_itemq, ri_list) {
1975 trace_xfs_log_recover_item_recover(log, trans, item, pass);
1976
1977 switch (pass) {
1978 case XLOG_RECOVER_PASS1:
1979 if (item->ri_ops->commit_pass1)
1980 error = item->ri_ops->commit_pass1(log, item);
1981 break;
1982 case XLOG_RECOVER_PASS2:
1983 if (item->ri_ops->ra_pass2)
1984 item->ri_ops->ra_pass2(log, item);
1985 list_move_tail(&item->ri_list, &ra_list);
1986 items_queued++;
1987 if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) {
1988 error = xlog_recover_items_pass2(log, trans,
1989 buffer_list, &ra_list);
1990 list_splice_tail_init(&ra_list, &done_list);
1991 items_queued = 0;
1992 }
1993
1994 break;
1995 default:
1996 ASSERT(0);
1997 }
1998
1999 if (error)
2000 goto out;
2001 }
2002
2003out:
2004 if (!list_empty(&ra_list)) {
2005 if (!error)
2006 error = xlog_recover_items_pass2(log, trans,
2007 buffer_list, &ra_list);
2008 list_splice_tail_init(&ra_list, &done_list);
2009 }
2010
2011 if (!list_empty(&done_list))
2012 list_splice_init(&done_list, &trans->r_itemq);
2013
2014 return error;
2015}
2016
2017STATIC void
2018xlog_recover_add_item(
2019 struct list_head *head)
2020{
2021 struct xlog_recover_item *item;
2022
2023 item = kmem_zalloc(sizeof(struct xlog_recover_item), 0);
2024 INIT_LIST_HEAD(&item->ri_list);
2025 list_add_tail(&item->ri_list, head);
2026}
2027
2028STATIC int
2029xlog_recover_add_to_cont_trans(
2030 struct xlog *log,
2031 struct xlog_recover *trans,
2032 char *dp,
2033 int len)
2034{
2035 struct xlog_recover_item *item;
2036 char *ptr, *old_ptr;
2037 int old_len;
2038
2039
2040
2041
2042
2043 if (list_empty(&trans->r_itemq)) {
2044 ASSERT(len <= sizeof(struct xfs_trans_header));
2045 if (len > sizeof(struct xfs_trans_header)) {
2046 xfs_warn(log->l_mp, "%s: bad header length", __func__);
2047 return -EFSCORRUPTED;
2048 }
2049
2050 xlog_recover_add_item(&trans->r_itemq);
2051 ptr = (char *)&trans->r_theader +
2052 sizeof(struct xfs_trans_header) - len;
2053 memcpy(ptr, dp, len);
2054 return 0;
2055 }
2056
2057
2058 item = list_entry(trans->r_itemq.prev, struct xlog_recover_item,
2059 ri_list);
2060
2061 old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
2062 old_len = item->ri_buf[item->ri_cnt-1].i_len;
2063
2064 ptr = krealloc(old_ptr, len + old_len, GFP_KERNEL | __GFP_NOFAIL);
2065 memcpy(&ptr[old_len], dp, len);
2066 item->ri_buf[item->ri_cnt-1].i_len += len;
2067 item->ri_buf[item->ri_cnt-1].i_addr = ptr;
2068 trace_xfs_log_recover_item_add_cont(log, trans, item, 0);
2069 return 0;
2070}
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085STATIC int
2086xlog_recover_add_to_trans(
2087 struct xlog *log,
2088 struct xlog_recover *trans,
2089 char *dp,
2090 int len)
2091{
2092 struct xfs_inode_log_format *in_f;
2093 struct xlog_recover_item *item;
2094 char *ptr;
2095
2096 if (!len)
2097 return 0;
2098 if (list_empty(&trans->r_itemq)) {
2099
2100 if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) {
2101 xfs_warn(log->l_mp, "%s: bad header magic number",
2102 __func__);
2103 ASSERT(0);
2104 return -EFSCORRUPTED;
2105 }
2106
2107 if (len > sizeof(struct xfs_trans_header)) {
2108 xfs_warn(log->l_mp, "%s: bad header length", __func__);
2109 ASSERT(0);
2110 return -EFSCORRUPTED;
2111 }
2112
2113
2114
2115
2116
2117
2118 if (len == sizeof(struct xfs_trans_header))
2119 xlog_recover_add_item(&trans->r_itemq);
2120 memcpy(&trans->r_theader, dp, len);
2121 return 0;
2122 }
2123
2124 ptr = kmem_alloc(len, 0);
2125 memcpy(ptr, dp, len);
2126 in_f = (struct xfs_inode_log_format *)ptr;
2127
2128
2129 item = list_entry(trans->r_itemq.prev, struct xlog_recover_item,
2130 ri_list);
2131 if (item->ri_total != 0 &&
2132 item->ri_total == item->ri_cnt) {
2133
2134 xlog_recover_add_item(&trans->r_itemq);
2135 item = list_entry(trans->r_itemq.prev,
2136 struct xlog_recover_item, ri_list);
2137 }
2138
2139 if (item->ri_total == 0) {
2140 if (in_f->ilf_size == 0 ||
2141 in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) {
2142 xfs_warn(log->l_mp,
2143 "bad number of regions (%d) in inode log format",
2144 in_f->ilf_size);
2145 ASSERT(0);
2146 kmem_free(ptr);
2147 return -EFSCORRUPTED;
2148 }
2149
2150 item->ri_total = in_f->ilf_size;
2151 item->ri_buf =
2152 kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t),
2153 0);
2154 }
2155
2156 if (item->ri_total <= item->ri_cnt) {
2157 xfs_warn(log->l_mp,
2158 "log item region count (%d) overflowed size (%d)",
2159 item->ri_cnt, item->ri_total);
2160 ASSERT(0);
2161 kmem_free(ptr);
2162 return -EFSCORRUPTED;
2163 }
2164
2165
2166 item->ri_buf[item->ri_cnt].i_addr = ptr;
2167 item->ri_buf[item->ri_cnt].i_len = len;
2168 item->ri_cnt++;
2169 trace_xfs_log_recover_item_add(log, trans, item, 0);
2170 return 0;
2171}
2172
2173
2174
2175
2176
2177
2178STATIC void
2179xlog_recover_free_trans(
2180 struct xlog_recover *trans)
2181{
2182 struct xlog_recover_item *item, *n;
2183 int i;
2184
2185 hlist_del_init(&trans->r_list);
2186
2187 list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) {
2188
2189 list_del(&item->ri_list);
2190 for (i = 0; i < item->ri_cnt; i++)
2191 kmem_free(item->ri_buf[i].i_addr);
2192
2193 kmem_free(item->ri_buf);
2194 kmem_free(item);
2195 }
2196
2197 kmem_free(trans);
2198}
2199
2200
2201
2202
2203STATIC int
2204xlog_recovery_process_trans(
2205 struct xlog *log,
2206 struct xlog_recover *trans,
2207 char *dp,
2208 unsigned int len,
2209 unsigned int flags,
2210 int pass,
2211 struct list_head *buffer_list)
2212{
2213 int error = 0;
2214 bool freeit = false;
2215
2216
2217 flags &= ~XLOG_END_TRANS;
2218 if (flags & XLOG_WAS_CONT_TRANS)
2219 flags &= ~XLOG_CONTINUE_TRANS;
2220
2221
2222
2223
2224
2225 switch (flags) {
2226
2227 case 0:
2228 case XLOG_CONTINUE_TRANS:
2229 error = xlog_recover_add_to_trans(log, trans, dp, len);
2230 break;
2231 case XLOG_WAS_CONT_TRANS:
2232 error = xlog_recover_add_to_cont_trans(log, trans, dp, len);
2233 break;
2234 case XLOG_COMMIT_TRANS:
2235 error = xlog_recover_commit_trans(log, trans, pass,
2236 buffer_list);
2237
2238 freeit = true;
2239 break;
2240
2241
2242 case XLOG_UNMOUNT_TRANS:
2243
2244 xfs_warn(log->l_mp, "%s: Unmount LR", __func__);
2245 freeit = true;
2246 break;
2247 case XLOG_START_TRANS:
2248 default:
2249 xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags);
2250 ASSERT(0);
2251 error = -EFSCORRUPTED;
2252 break;
2253 }
2254 if (error || freeit)
2255 xlog_recover_free_trans(trans);
2256 return error;
2257}
2258
2259
2260
2261
2262
2263
2264
2265
2266STATIC struct xlog_recover *
2267xlog_recover_ophdr_to_trans(
2268 struct hlist_head rhash[],
2269 struct xlog_rec_header *rhead,
2270 struct xlog_op_header *ohead)
2271{
2272 struct xlog_recover *trans;
2273 xlog_tid_t tid;
2274 struct hlist_head *rhp;
2275
2276 tid = be32_to_cpu(ohead->oh_tid);
2277 rhp = &rhash[XLOG_RHASH(tid)];
2278 hlist_for_each_entry(trans, rhp, r_list) {
2279 if (trans->r_log_tid == tid)
2280 return trans;
2281 }
2282
2283
2284
2285
2286
2287 if (!(ohead->oh_flags & XLOG_START_TRANS))
2288 return NULL;
2289
2290 ASSERT(be32_to_cpu(ohead->oh_len) == 0);
2291
2292
2293
2294
2295
2296 trans = kmem_zalloc(sizeof(struct xlog_recover), 0);
2297 trans->r_log_tid = tid;
2298 trans->r_lsn = be64_to_cpu(rhead->h_lsn);
2299 INIT_LIST_HEAD(&trans->r_itemq);
2300 INIT_HLIST_NODE(&trans->r_list);
2301 hlist_add_head(&trans->r_list, rhp);
2302
2303
2304
2305
2306
2307 return NULL;
2308}
2309
2310STATIC int
2311xlog_recover_process_ophdr(
2312 struct xlog *log,
2313 struct hlist_head rhash[],
2314 struct xlog_rec_header *rhead,
2315 struct xlog_op_header *ohead,
2316 char *dp,
2317 char *end,
2318 int pass,
2319 struct list_head *buffer_list)
2320{
2321 struct xlog_recover *trans;
2322 unsigned int len;
2323 int error;
2324
2325
2326 if (ohead->oh_clientid != XFS_TRANSACTION &&
2327 ohead->oh_clientid != XFS_LOG) {
2328 xfs_warn(log->l_mp, "%s: bad clientid 0x%x",
2329 __func__, ohead->oh_clientid);
2330 ASSERT(0);
2331 return -EFSCORRUPTED;
2332 }
2333
2334
2335
2336
2337 len = be32_to_cpu(ohead->oh_len);
2338 if (dp + len > end) {
2339 xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len);
2340 WARN_ON(1);
2341 return -EFSCORRUPTED;
2342 }
2343
2344 trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead);
2345 if (!trans) {
2346
2347 return 0;
2348 }
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373 if (log->l_recovery_lsn != trans->r_lsn &&
2374 ohead->oh_flags & XLOG_COMMIT_TRANS) {
2375 error = xfs_buf_delwri_submit(buffer_list);
2376 if (error)
2377 return error;
2378 log->l_recovery_lsn = trans->r_lsn;
2379 }
2380
2381 return xlog_recovery_process_trans(log, trans, dp, len,
2382 ohead->oh_flags, pass, buffer_list);
2383}
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394STATIC int
2395xlog_recover_process_data(
2396 struct xlog *log,
2397 struct hlist_head rhash[],
2398 struct xlog_rec_header *rhead,
2399 char *dp,
2400 int pass,
2401 struct list_head *buffer_list)
2402{
2403 struct xlog_op_header *ohead;
2404 char *end;
2405 int num_logops;
2406 int error;
2407
2408 end = dp + be32_to_cpu(rhead->h_len);
2409 num_logops = be32_to_cpu(rhead->h_num_logops);
2410
2411
2412 if (xlog_header_check_recover(log->l_mp, rhead))
2413 return -EIO;
2414
2415 trace_xfs_log_recover_record(log, rhead, pass);
2416 while ((dp < end) && num_logops) {
2417
2418 ohead = (struct xlog_op_header *)dp;
2419 dp += sizeof(*ohead);
2420 ASSERT(dp <= end);
2421
2422
2423 error = xlog_recover_process_ophdr(log, rhash, rhead, ohead,
2424 dp, end, pass, buffer_list);
2425 if (error)
2426 return error;
2427
2428 dp += be32_to_cpu(ohead->oh_len);
2429 num_logops--;
2430 }
2431 return 0;
2432}
2433
2434
2435static int
2436xlog_finish_defer_ops(
2437 struct xfs_mount *mp,
2438 struct list_head *capture_list)
2439{
2440 struct xfs_defer_capture *dfc, *next;
2441 struct xfs_trans *tp;
2442 struct xfs_inode *ip;
2443 int error = 0;
2444
2445 list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
2446 struct xfs_trans_res resv;
2447
2448
2449
2450
2451
2452
2453
2454 resv.tr_logres = dfc->dfc_logres;
2455 resv.tr_logcount = 1;
2456 resv.tr_logflags = XFS_TRANS_PERM_LOG_RES;
2457
2458 error = xfs_trans_alloc(mp, &resv, dfc->dfc_blkres,
2459 dfc->dfc_rtxres, XFS_TRANS_RESERVE, &tp);
2460 if (error)
2461 return error;
2462
2463
2464
2465
2466
2467 list_del_init(&dfc->dfc_list);
2468 xfs_defer_ops_continue(dfc, tp, &ip);
2469
2470 error = xfs_trans_commit(tp);
2471 if (ip) {
2472 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2473 xfs_irele(ip);
2474 }
2475 if (error)
2476 return error;
2477 }
2478
2479 ASSERT(list_empty(capture_list));
2480 return 0;
2481}
2482
2483
2484static void
2485xlog_abort_defer_ops(
2486 struct xfs_mount *mp,
2487 struct list_head *capture_list)
2488{
2489 struct xfs_defer_capture *dfc;
2490 struct xfs_defer_capture *next;
2491
2492 list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
2493 list_del_init(&dfc->dfc_list);
2494 xfs_defer_ops_release(mp, dfc);
2495 }
2496}
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513STATIC int
2514xlog_recover_process_intents(
2515 struct xlog *log)
2516{
2517 LIST_HEAD(capture_list);
2518 struct xfs_ail_cursor cur;
2519 struct xfs_log_item *lip;
2520 struct xfs_ail *ailp;
2521 int error = 0;
2522#if defined(DEBUG) || defined(XFS_WARN)
2523 xfs_lsn_t last_lsn;
2524#endif
2525
2526 ailp = log->l_ailp;
2527 spin_lock(&ailp->ail_lock);
2528#if defined(DEBUG) || defined(XFS_WARN)
2529 last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block);
2530#endif
2531 for (lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
2532 lip != NULL;
2533 lip = xfs_trans_ail_cursor_next(ailp, &cur)) {
2534
2535
2536
2537
2538 if (!xlog_item_is_intent(lip)) {
2539#ifdef DEBUG
2540 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
2541 ASSERT(!xlog_item_is_intent(lip));
2542#endif
2543 break;
2544 }
2545
2546
2547
2548
2549
2550
2551 ASSERT(XFS_LSN_CMP(last_lsn, lip->li_lsn) >= 0);
2552
2553
2554
2555
2556
2557
2558
2559 spin_unlock(&ailp->ail_lock);
2560 error = lip->li_ops->iop_recover(lip, &capture_list);
2561 spin_lock(&ailp->ail_lock);
2562 if (error)
2563 break;
2564 }
2565
2566 xfs_trans_ail_cursor_done(&cur);
2567 spin_unlock(&ailp->ail_lock);
2568 if (error)
2569 goto err;
2570
2571 error = xlog_finish_defer_ops(log->l_mp, &capture_list);
2572 if (error)
2573 goto err;
2574
2575 return 0;
2576err:
2577 xlog_abort_defer_ops(log->l_mp, &capture_list);
2578 return error;
2579}
2580
2581
2582
2583
2584
2585STATIC void
2586xlog_recover_cancel_intents(
2587 struct xlog *log)
2588{
2589 struct xfs_log_item *lip;
2590 struct xfs_ail_cursor cur;
2591 struct xfs_ail *ailp;
2592
2593 ailp = log->l_ailp;
2594 spin_lock(&ailp->ail_lock);
2595 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
2596 while (lip != NULL) {
2597
2598
2599
2600
2601 if (!xlog_item_is_intent(lip)) {
2602#ifdef DEBUG
2603 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
2604 ASSERT(!xlog_item_is_intent(lip));
2605#endif
2606 break;
2607 }
2608
2609 spin_unlock(&ailp->ail_lock);
2610 lip->li_ops->iop_release(lip);
2611 spin_lock(&ailp->ail_lock);
2612 lip = xfs_trans_ail_cursor_next(ailp, &cur);
2613 }
2614
2615 xfs_trans_ail_cursor_done(&cur);
2616 spin_unlock(&ailp->ail_lock);
2617}
2618
2619
2620
2621
2622
2623STATIC void
2624xlog_recover_clear_agi_bucket(
2625 xfs_mount_t *mp,
2626 xfs_agnumber_t agno,
2627 int bucket)
2628{
2629 xfs_trans_t *tp;
2630 xfs_agi_t *agi;
2631 xfs_buf_t *agibp;
2632 int offset;
2633 int error;
2634
2635 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_clearagi, 0, 0, 0, &tp);
2636 if (error)
2637 goto out_error;
2638
2639 error = xfs_read_agi(mp, tp, agno, &agibp);
2640 if (error)
2641 goto out_abort;
2642
2643 agi = agibp->b_addr;
2644 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
2645 offset = offsetof(xfs_agi_t, agi_unlinked) +
2646 (sizeof(xfs_agino_t) * bucket);
2647 xfs_trans_log_buf(tp, agibp, offset,
2648 (offset + sizeof(xfs_agino_t) - 1));
2649
2650 error = xfs_trans_commit(tp);
2651 if (error)
2652 goto out_error;
2653 return;
2654
2655out_abort:
2656 xfs_trans_cancel(tp);
2657out_error:
2658 xfs_warn(mp, "%s: failed to clear agi %d. Continuing.", __func__, agno);
2659 return;
2660}
2661
2662STATIC xfs_agino_t
2663xlog_recover_process_one_iunlink(
2664 struct xfs_mount *mp,
2665 xfs_agnumber_t agno,
2666 xfs_agino_t agino,
2667 int bucket)
2668{
2669 struct xfs_buf *ibp;
2670 struct xfs_dinode *dip;
2671 struct xfs_inode *ip;
2672 xfs_ino_t ino;
2673 int error;
2674
2675 ino = XFS_AGINO_TO_INO(mp, agno, agino);
2676 error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
2677 if (error)
2678 goto fail;
2679
2680
2681
2682
2683 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &ibp, 0);
2684 if (error)
2685 goto fail_iput;
2686
2687 xfs_iflags_clear(ip, XFS_IRECOVERY);
2688 ASSERT(VFS_I(ip)->i_nlink == 0);
2689 ASSERT(VFS_I(ip)->i_mode != 0);
2690
2691
2692 agino = be32_to_cpu(dip->di_next_unlinked);
2693 xfs_buf_relse(ibp);
2694
2695
2696
2697
2698
2699 ip->i_d.di_dmevmask = 0;
2700
2701 xfs_irele(ip);
2702 return agino;
2703
2704 fail_iput:
2705 xfs_irele(ip);
2706 fail:
2707
2708
2709
2710
2711
2712
2713
2714
2715 xlog_recover_clear_agi_bucket(mp, agno, bucket);
2716 return NULLAGINO;
2717}
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742STATIC void
2743xlog_recover_process_iunlinks(
2744 struct xlog *log)
2745{
2746 xfs_mount_t *mp;
2747 xfs_agnumber_t agno;
2748 xfs_agi_t *agi;
2749 xfs_buf_t *agibp;
2750 xfs_agino_t agino;
2751 int bucket;
2752 int error;
2753
2754 mp = log->l_mp;
2755
2756 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
2757
2758
2759
2760 error = xfs_read_agi(mp, NULL, agno, &agibp);
2761 if (error) {
2762
2763
2764
2765
2766
2767
2768 continue;
2769 }
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779 agi = agibp->b_addr;
2780 xfs_buf_unlock(agibp);
2781
2782 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
2783 agino = be32_to_cpu(agi->agi_unlinked[bucket]);
2784 while (agino != NULLAGINO) {
2785 agino = xlog_recover_process_one_iunlink(mp,
2786 agno, agino, bucket);
2787 cond_resched();
2788 }
2789 }
2790 xfs_buf_rele(agibp);
2791 }
2792}
2793
2794STATIC void
2795xlog_unpack_data(
2796 struct xlog_rec_header *rhead,
2797 char *dp,
2798 struct xlog *log)
2799{
2800 int i, j, k;
2801
2802 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
2803 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
2804 *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
2805 dp += BBSIZE;
2806 }
2807
2808 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
2809 xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
2810 for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
2811 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
2812 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
2813 *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
2814 dp += BBSIZE;
2815 }
2816 }
2817}
2818
2819
2820
2821
2822STATIC int
2823xlog_recover_process(
2824 struct xlog *log,
2825 struct hlist_head rhash[],
2826 struct xlog_rec_header *rhead,
2827 char *dp,
2828 int pass,
2829 struct list_head *buffer_list)
2830{
2831 __le32 old_crc = rhead->h_crc;
2832 __le32 crc;
2833
2834 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
2835
2836
2837
2838
2839
2840
2841
2842
2843 if (pass == XLOG_RECOVER_CRCPASS) {
2844 if (old_crc && crc != old_crc)
2845 return -EFSBADCRC;
2846 return 0;
2847 }
2848
2849
2850
2851
2852
2853
2854
2855 if (crc != old_crc) {
2856 if (old_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
2857 xfs_alert(log->l_mp,
2858 "log record CRC mismatch: found 0x%x, expected 0x%x.",
2859 le32_to_cpu(old_crc),
2860 le32_to_cpu(crc));
2861 xfs_hex_dump(dp, 32);
2862 }
2863
2864
2865
2866
2867
2868 if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
2869 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
2870 return -EFSCORRUPTED;
2871 }
2872 }
2873
2874 xlog_unpack_data(rhead, dp, log);
2875
2876 return xlog_recover_process_data(log, rhash, rhead, dp, pass,
2877 buffer_list);
2878}
2879
2880STATIC int
2881xlog_valid_rec_header(
2882 struct xlog *log,
2883 struct xlog_rec_header *rhead,
2884 xfs_daddr_t blkno,
2885 int bufsize)
2886{
2887 int hlen;
2888
2889 if (XFS_IS_CORRUPT(log->l_mp,
2890 rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM)))
2891 return -EFSCORRUPTED;
2892 if (XFS_IS_CORRUPT(log->l_mp,
2893 (!rhead->h_version ||
2894 (be32_to_cpu(rhead->h_version) &
2895 (~XLOG_VERSION_OKBITS))))) {
2896 xfs_warn(log->l_mp, "%s: unrecognised log version (%d).",
2897 __func__, be32_to_cpu(rhead->h_version));
2898 return -EFSCORRUPTED;
2899 }
2900
2901
2902
2903
2904
2905 hlen = be32_to_cpu(rhead->h_len);
2906 if (XFS_IS_CORRUPT(log->l_mp, hlen <= 0 || hlen > bufsize))
2907 return -EFSCORRUPTED;
2908
2909 if (XFS_IS_CORRUPT(log->l_mp,
2910 blkno > log->l_logBBsize || blkno > INT_MAX))
2911 return -EFSCORRUPTED;
2912 return 0;
2913}
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923STATIC int
2924xlog_do_recovery_pass(
2925 struct xlog *log,
2926 xfs_daddr_t head_blk,
2927 xfs_daddr_t tail_blk,
2928 int pass,
2929 xfs_daddr_t *first_bad)
2930{
2931 xlog_rec_header_t *rhead;
2932 xfs_daddr_t blk_no, rblk_no;
2933 xfs_daddr_t rhead_blk;
2934 char *offset;
2935 char *hbp, *dbp;
2936 int error = 0, h_size, h_len;
2937 int error2 = 0;
2938 int bblks, split_bblks;
2939 int hblks, split_hblks, wrapped_hblks;
2940 int i;
2941 struct hlist_head rhash[XLOG_RHASH_SIZE];
2942 LIST_HEAD (buffer_list);
2943
2944 ASSERT(head_blk != tail_blk);
2945 blk_no = rhead_blk = tail_blk;
2946
2947 for (i = 0; i < XLOG_RHASH_SIZE; i++)
2948 INIT_HLIST_HEAD(&rhash[i]);
2949
2950
2951
2952
2953
2954 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
2955
2956
2957
2958
2959
2960 hbp = xlog_alloc_buffer(log, 1);
2961 if (!hbp)
2962 return -ENOMEM;
2963
2964 error = xlog_bread(log, tail_blk, 1, hbp, &offset);
2965 if (error)
2966 goto bread_err1;
2967
2968 rhead = (xlog_rec_header_t *)offset;
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981 h_size = be32_to_cpu(rhead->h_size);
2982 h_len = be32_to_cpu(rhead->h_len);
2983 if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
2984 rhead->h_num_logops == cpu_to_be32(1)) {
2985 xfs_warn(log->l_mp,
2986 "invalid iclog size (%d bytes), using lsunit (%d bytes)",
2987 h_size, log->l_mp->m_logbsize);
2988 h_size = log->l_mp->m_logbsize;
2989 }
2990
2991 error = xlog_valid_rec_header(log, rhead, tail_blk, h_size);
2992 if (error)
2993 goto bread_err1;
2994
2995 hblks = xlog_logrec_hblks(log, rhead);
2996 if (hblks != 1) {
2997 kmem_free(hbp);
2998 hbp = xlog_alloc_buffer(log, hblks);
2999 }
3000 } else {
3001 ASSERT(log->l_sectBBsize == 1);
3002 hblks = 1;
3003 hbp = xlog_alloc_buffer(log, 1);
3004 h_size = XLOG_BIG_RECORD_BSIZE;
3005 }
3006
3007 if (!hbp)
3008 return -ENOMEM;
3009 dbp = xlog_alloc_buffer(log, BTOBB(h_size));
3010 if (!dbp) {
3011 kmem_free(hbp);
3012 return -ENOMEM;
3013 }
3014
3015 memset(rhash, 0, sizeof(rhash));
3016 if (tail_blk > head_blk) {
3017
3018
3019
3020
3021
3022 while (blk_no < log->l_logBBsize) {
3023
3024
3025
3026 offset = hbp;
3027 split_hblks = 0;
3028 wrapped_hblks = 0;
3029 if (blk_no + hblks <= log->l_logBBsize) {
3030
3031 error = xlog_bread(log, blk_no, hblks, hbp,
3032 &offset);
3033 if (error)
3034 goto bread_err2;
3035 } else {
3036
3037 if (blk_no != log->l_logBBsize) {
3038
3039 ASSERT(blk_no <= INT_MAX);
3040 split_hblks = log->l_logBBsize - (int)blk_no;
3041 ASSERT(split_hblks > 0);
3042 error = xlog_bread(log, blk_no,
3043 split_hblks, hbp,
3044 &offset);
3045 if (error)
3046 goto bread_err2;
3047 }
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061 wrapped_hblks = hblks - split_hblks;
3062 error = xlog_bread_noalign(log, 0,
3063 wrapped_hblks,
3064 offset + BBTOB(split_hblks));
3065 if (error)
3066 goto bread_err2;
3067 }
3068 rhead = (xlog_rec_header_t *)offset;
3069 error = xlog_valid_rec_header(log, rhead,
3070 split_hblks ? blk_no : 0, h_size);
3071 if (error)
3072 goto bread_err2;
3073
3074 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
3075 blk_no += hblks;
3076
3077
3078
3079
3080
3081
3082
3083
3084 if (blk_no + bblks <= log->l_logBBsize ||
3085 blk_no >= log->l_logBBsize) {
3086 rblk_no = xlog_wrap_logbno(log, blk_no);
3087 error = xlog_bread(log, rblk_no, bblks, dbp,
3088 &offset);
3089 if (error)
3090 goto bread_err2;
3091 } else {
3092
3093
3094 offset = dbp;
3095 split_bblks = 0;
3096 if (blk_no != log->l_logBBsize) {
3097
3098
3099 ASSERT(!wrapped_hblks);
3100 ASSERT(blk_no <= INT_MAX);
3101 split_bblks =
3102 log->l_logBBsize - (int)blk_no;
3103 ASSERT(split_bblks > 0);
3104 error = xlog_bread(log, blk_no,
3105 split_bblks, dbp,
3106 &offset);
3107 if (error)
3108 goto bread_err2;
3109 }
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123 error = xlog_bread_noalign(log, 0,
3124 bblks - split_bblks,
3125 offset + BBTOB(split_bblks));
3126 if (error)
3127 goto bread_err2;
3128 }
3129
3130 error = xlog_recover_process(log, rhash, rhead, offset,
3131 pass, &buffer_list);
3132 if (error)
3133 goto bread_err2;
3134
3135 blk_no += bblks;
3136 rhead_blk = blk_no;
3137 }
3138
3139 ASSERT(blk_no >= log->l_logBBsize);
3140 blk_no -= log->l_logBBsize;
3141 rhead_blk = blk_no;
3142 }
3143
3144
3145 while (blk_no < head_blk) {
3146 error = xlog_bread(log, blk_no, hblks, hbp, &offset);
3147 if (error)
3148 goto bread_err2;
3149
3150 rhead = (xlog_rec_header_t *)offset;
3151 error = xlog_valid_rec_header(log, rhead, blk_no, h_size);
3152 if (error)
3153 goto bread_err2;
3154
3155
3156 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
3157 error = xlog_bread(log, blk_no+hblks, bblks, dbp,
3158 &offset);
3159 if (error)
3160 goto bread_err2;
3161
3162 error = xlog_recover_process(log, rhash, rhead, offset, pass,
3163 &buffer_list);
3164 if (error)
3165 goto bread_err2;
3166
3167 blk_no += bblks + hblks;
3168 rhead_blk = blk_no;
3169 }
3170
3171 bread_err2:
3172 kmem_free(dbp);
3173 bread_err1:
3174 kmem_free(hbp);
3175
3176
3177
3178
3179
3180 if (!list_empty(&buffer_list))
3181 error2 = xfs_buf_delwri_submit(&buffer_list);
3182
3183 if (error && first_bad)
3184 *first_bad = rhead_blk;
3185
3186
3187
3188
3189
3190
3191 for (i = 0; i < XLOG_RHASH_SIZE; i++) {
3192 struct hlist_node *tmp;
3193 struct xlog_recover *trans;
3194
3195 hlist_for_each_entry_safe(trans, tmp, &rhash[i], r_list)
3196 xlog_recover_free_trans(trans);
3197 }
3198
3199 return error ? error : error2;
3200}
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215STATIC int
3216xlog_do_log_recovery(
3217 struct xlog *log,
3218 xfs_daddr_t head_blk,
3219 xfs_daddr_t tail_blk)
3220{
3221 int error, i;
3222
3223 ASSERT(head_blk != tail_blk);
3224
3225
3226
3227
3228
3229 log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
3230 sizeof(struct list_head),
3231 0);
3232 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
3233 INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
3234
3235 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
3236 XLOG_RECOVER_PASS1, NULL);
3237 if (error != 0) {
3238 kmem_free(log->l_buf_cancel_table);
3239 log->l_buf_cancel_table = NULL;
3240 return error;
3241 }
3242
3243
3244
3245
3246 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
3247 XLOG_RECOVER_PASS2, NULL);
3248#ifdef DEBUG
3249 if (!error) {
3250 int i;
3251
3252 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
3253 ASSERT(list_empty(&log->l_buf_cancel_table[i]));
3254 }
3255#endif
3256
3257 kmem_free(log->l_buf_cancel_table);
3258 log->l_buf_cancel_table = NULL;
3259
3260 return error;
3261}
3262
3263
3264
3265
3266STATIC int
3267xlog_do_recover(
3268 struct xlog *log,
3269 xfs_daddr_t head_blk,
3270 xfs_daddr_t tail_blk)
3271{
3272 struct xfs_mount *mp = log->l_mp;
3273 struct xfs_buf *bp = mp->m_sb_bp;
3274 struct xfs_sb *sbp = &mp->m_sb;
3275 int error;
3276
3277 trace_xfs_log_recover(log, head_blk, tail_blk);
3278
3279
3280
3281
3282 error = xlog_do_log_recovery(log, head_blk, tail_blk);
3283 if (error)
3284 return error;
3285
3286
3287
3288
3289 if (XFS_FORCED_SHUTDOWN(mp))
3290 return -EIO;
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301 xlog_assign_tail_lsn(mp);
3302
3303
3304
3305
3306
3307 xfs_buf_lock(bp);
3308 xfs_buf_hold(bp);
3309 error = _xfs_buf_read(bp, XBF_READ);
3310 if (error) {
3311 if (!XFS_FORCED_SHUTDOWN(mp)) {
3312 xfs_buf_ioerror_alert(bp, __this_address);
3313 ASSERT(0);
3314 }
3315 xfs_buf_relse(bp);
3316 return error;
3317 }
3318
3319
3320 xfs_sb_from_disk(sbp, bp->b_addr);
3321 xfs_buf_relse(bp);
3322
3323
3324 xfs_reinit_percpu_counters(mp);
3325 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
3326 if (error) {
3327 xfs_warn(mp, "Failed post-recovery per-ag init: %d", error);
3328 return error;
3329 }
3330 mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
3331
3332 xlog_recover_check_summary(log);
3333
3334
3335 log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
3336 return 0;
3337}
3338
3339
3340
3341
3342
3343
3344int
3345xlog_recover(
3346 struct xlog *log)
3347{
3348 xfs_daddr_t head_blk, tail_blk;
3349 int error;
3350
3351
3352 error = xlog_find_tail(log, &head_blk, &tail_blk);
3353 if (error)
3354 return error;
3355
3356
3357
3358
3359
3360
3361 if (xfs_sb_version_hascrc(&log->l_mp->m_sb) &&
3362 !xfs_log_check_lsn(log->l_mp, log->l_mp->m_sb.sb_lsn))
3363 return -EINVAL;
3364
3365 if (tail_blk != head_blk) {
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377 if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
3378 return error;
3379 }
3380
3381
3382
3383
3384
3385
3386
3387
3388 if (XFS_SB_VERSION_NUM(&log->l_mp->m_sb) == XFS_SB_VERSION_5 &&
3389 xfs_sb_has_incompat_log_feature(&log->l_mp->m_sb,
3390 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) {
3391 xfs_warn(log->l_mp,
3392"Superblock has unknown incompatible log features (0x%x) enabled.",
3393 (log->l_mp->m_sb.sb_features_log_incompat &
3394 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN));
3395 xfs_warn(log->l_mp,
3396"The log can not be fully and/or safely recovered by this kernel.");
3397 xfs_warn(log->l_mp,
3398"Please recover the log on a kernel that supports the unknown features.");
3399 return -EINVAL;
3400 }
3401
3402
3403
3404
3405
3406
3407 if (xfs_globals.log_recovery_delay) {
3408 xfs_notice(log->l_mp,
3409 "Delaying log recovery for %d seconds.",
3410 xfs_globals.log_recovery_delay);
3411 msleep(xfs_globals.log_recovery_delay * 1000);
3412 }
3413
3414 xfs_notice(log->l_mp, "Starting recovery (logdev: %s)",
3415 log->l_mp->m_logname ? log->l_mp->m_logname
3416 : "internal");
3417
3418 error = xlog_do_recover(log, head_blk, tail_blk);
3419 log->l_flags |= XLOG_RECOVERY_NEEDED;
3420 }
3421 return error;
3422}
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433int
3434xlog_recover_finish(
3435 struct xlog *log)
3436{
3437
3438
3439
3440
3441
3442
3443
3444
3445 if (log->l_flags & XLOG_RECOVERY_NEEDED) {
3446 int error;
3447 error = xlog_recover_process_intents(log);
3448 if (error) {
3449
3450
3451
3452
3453
3454
3455
3456 xlog_recover_cancel_intents(log);
3457 xfs_alert(log->l_mp, "Failed to recover intents");
3458 return error;
3459 }
3460
3461
3462
3463
3464
3465
3466
3467 xfs_log_force(log->l_mp, XFS_LOG_SYNC);
3468
3469 xlog_recover_process_iunlinks(log);
3470
3471 xlog_recover_check_summary(log);
3472
3473 xfs_notice(log->l_mp, "Ending recovery (logdev: %s)",
3474 log->l_mp->m_logname ? log->l_mp->m_logname
3475 : "internal");
3476 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
3477 } else {
3478 xfs_info(log->l_mp, "Ending clean mount");
3479 }
3480 return 0;
3481}
3482
3483void
3484xlog_recover_cancel(
3485 struct xlog *log)
3486{
3487 if (log->l_flags & XLOG_RECOVERY_NEEDED)
3488 xlog_recover_cancel_intents(log);
3489}
3490
3491#if defined(DEBUG)
3492
3493
3494
3495
3496STATIC void
3497xlog_recover_check_summary(
3498 struct xlog *log)
3499{
3500 xfs_mount_t *mp;
3501 xfs_buf_t *agfbp;
3502 xfs_buf_t *agibp;
3503 xfs_agnumber_t agno;
3504 uint64_t freeblks;
3505 uint64_t itotal;
3506 uint64_t ifree;
3507 int error;
3508
3509 mp = log->l_mp;
3510
3511 freeblks = 0LL;
3512 itotal = 0LL;
3513 ifree = 0LL;
3514 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
3515 error = xfs_read_agf(mp, NULL, agno, 0, &agfbp);
3516 if (error) {
3517 xfs_alert(mp, "%s agf read failed agno %d error %d",
3518 __func__, agno, error);
3519 } else {
3520 struct xfs_agf *agfp = agfbp->b_addr;
3521
3522 freeblks += be32_to_cpu(agfp->agf_freeblks) +
3523 be32_to_cpu(agfp->agf_flcount);
3524 xfs_buf_relse(agfbp);
3525 }
3526
3527 error = xfs_read_agi(mp, NULL, agno, &agibp);
3528 if (error) {
3529 xfs_alert(mp, "%s agi read failed agno %d error %d",
3530 __func__, agno, error);
3531 } else {
3532 struct xfs_agi *agi = agibp->b_addr;
3533
3534 itotal += be32_to_cpu(agi->agi_count);
3535 ifree += be32_to_cpu(agi->agi_freecount);
3536 xfs_buf_relse(agibp);
3537 }
3538 }
3539}
3540#endif
3541