1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_shared.h"
21#include "xfs_format.h"
22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h"
24#include "xfs_bit.h"
25#include "xfs_sb.h"
26#include "xfs_mount.h"
27#include "xfs_da_format.h"
28#include "xfs_da_btree.h"
29#include "xfs_inode.h"
30#include "xfs_trans.h"
31#include "xfs_log.h"
32#include "xfs_log_priv.h"
33#include "xfs_log_recover.h"
34#include "xfs_inode_item.h"
35#include "xfs_extfree_item.h"
36#include "xfs_trans_priv.h"
37#include "xfs_alloc.h"
38#include "xfs_ialloc.h"
39#include "xfs_quota.h"
40#include "xfs_cksum.h"
41#include "xfs_trace.h"
42#include "xfs_icache.h"
43#include "xfs_bmap_btree.h"
44#include "xfs_error.h"
45#include "xfs_dir2.h"
46#include "xfs_rmap_item.h"
47#include "xfs_buf_item.h"
48#include "xfs_refcount_item.h"
49#include "xfs_bmap_item.h"
50
51#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
52
53STATIC int
54xlog_find_zeroed(
55 struct xlog *,
56 xfs_daddr_t *);
57STATIC int
58xlog_clear_stale_blocks(
59 struct xlog *,
60 xfs_lsn_t);
61#if defined(DEBUG)
62STATIC void
63xlog_recover_check_summary(
64 struct xlog *);
65#else
66#define xlog_recover_check_summary(log)
67#endif
68STATIC int
69xlog_do_recovery_pass(
70 struct xlog *, xfs_daddr_t, xfs_daddr_t, int, xfs_daddr_t *);
71
72
73
74
75
76struct xfs_buf_cancel {
77 xfs_daddr_t bc_blkno;
78 uint bc_len;
79 int bc_refcount;
80 struct list_head bc_list;
81};
82
83
84
85
86
87
88
89
90
91
92
93static inline int
94xlog_buf_bbcount_valid(
95 struct xlog *log,
96 int bbcount)
97{
98 return bbcount > 0 && bbcount <= log->l_logBBsize;
99}
100
101
102
103
104
105
106STATIC xfs_buf_t *
107xlog_get_bp(
108 struct xlog *log,
109 int nbblks)
110{
111 struct xfs_buf *bp;
112
113 if (!xlog_buf_bbcount_valid(log, nbblks)) {
114 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
115 nbblks);
116 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
117 return NULL;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 if (nbblks > 1 && log->l_sectBBsize > 1)
137 nbblks += log->l_sectBBsize;
138 nbblks = round_up(nbblks, log->l_sectBBsize);
139
140 bp = xfs_buf_get_uncached(log->l_mp->m_logdev_targp, nbblks, 0);
141 if (bp)
142 xfs_buf_unlock(bp);
143 return bp;
144}
145
146STATIC void
147xlog_put_bp(
148 xfs_buf_t *bp)
149{
150 xfs_buf_free(bp);
151}
152
153
154
155
156
157STATIC char *
158xlog_align(
159 struct xlog *log,
160 xfs_daddr_t blk_no,
161 int nbblks,
162 struct xfs_buf *bp)
163{
164 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1);
165
166 ASSERT(offset + nbblks <= bp->b_length);
167 return bp->b_addr + BBTOB(offset);
168}
169
170
171
172
173
174STATIC int
175xlog_bread_noalign(
176 struct xlog *log,
177 xfs_daddr_t blk_no,
178 int nbblks,
179 struct xfs_buf *bp)
180{
181 int error;
182
183 if (!xlog_buf_bbcount_valid(log, nbblks)) {
184 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
185 nbblks);
186 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
187 return -EFSCORRUPTED;
188 }
189
190 blk_no = round_down(blk_no, log->l_sectBBsize);
191 nbblks = round_up(nbblks, log->l_sectBBsize);
192
193 ASSERT(nbblks > 0);
194 ASSERT(nbblks <= bp->b_length);
195
196 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
197 bp->b_flags |= XBF_READ;
198 bp->b_io_length = nbblks;
199 bp->b_error = 0;
200
201 error = xfs_buf_submit_wait(bp);
202 if (error && !XFS_FORCED_SHUTDOWN(log->l_mp))
203 xfs_buf_ioerror_alert(bp, __func__);
204 return error;
205}
206
207STATIC int
208xlog_bread(
209 struct xlog *log,
210 xfs_daddr_t blk_no,
211 int nbblks,
212 struct xfs_buf *bp,
213 char **offset)
214{
215 int error;
216
217 error = xlog_bread_noalign(log, blk_no, nbblks, bp);
218 if (error)
219 return error;
220
221 *offset = xlog_align(log, blk_no, nbblks, bp);
222 return 0;
223}
224
225
226
227
228
229STATIC int
230xlog_bread_offset(
231 struct xlog *log,
232 xfs_daddr_t blk_no,
233 int nbblks,
234 struct xfs_buf *bp,
235 char *offset)
236{
237 char *orig_offset = bp->b_addr;
238 int orig_len = BBTOB(bp->b_length);
239 int error, error2;
240
241 error = xfs_buf_associate_memory(bp, offset, BBTOB(nbblks));
242 if (error)
243 return error;
244
245 error = xlog_bread_noalign(log, blk_no, nbblks, bp);
246
247
248 error2 = xfs_buf_associate_memory(bp, orig_offset, orig_len);
249 if (error)
250 return error;
251 return error2;
252}
253
254
255
256
257
258
259STATIC int
260xlog_bwrite(
261 struct xlog *log,
262 xfs_daddr_t blk_no,
263 int nbblks,
264 struct xfs_buf *bp)
265{
266 int error;
267
268 if (!xlog_buf_bbcount_valid(log, nbblks)) {
269 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
270 nbblks);
271 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
272 return -EFSCORRUPTED;
273 }
274
275 blk_no = round_down(blk_no, log->l_sectBBsize);
276 nbblks = round_up(nbblks, log->l_sectBBsize);
277
278 ASSERT(nbblks > 0);
279 ASSERT(nbblks <= bp->b_length);
280
281 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
282 xfs_buf_hold(bp);
283 xfs_buf_lock(bp);
284 bp->b_io_length = nbblks;
285 bp->b_error = 0;
286
287 error = xfs_bwrite(bp);
288 if (error)
289 xfs_buf_ioerror_alert(bp, __func__);
290 xfs_buf_relse(bp);
291 return error;
292}
293
294#ifdef DEBUG
295
296
297
298STATIC void
299xlog_header_check_dump(
300 xfs_mount_t *mp,
301 xlog_rec_header_t *head)
302{
303 xfs_debug(mp, "%s: SB : uuid = %pU, fmt = %d",
304 __func__, &mp->m_sb.sb_uuid, XLOG_FMT);
305 xfs_debug(mp, " log : uuid = %pU, fmt = %d",
306 &head->h_fs_uuid, be32_to_cpu(head->h_fmt));
307}
308#else
309#define xlog_header_check_dump(mp, head)
310#endif
311
312
313
314
315STATIC int
316xlog_header_check_recover(
317 xfs_mount_t *mp,
318 xlog_rec_header_t *head)
319{
320 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
321
322
323
324
325
326
327 if (unlikely(head->h_fmt != cpu_to_be32(XLOG_FMT))) {
328 xfs_warn(mp,
329 "dirty log written in incompatible format - can't recover");
330 xlog_header_check_dump(mp, head);
331 XFS_ERROR_REPORT("xlog_header_check_recover(1)",
332 XFS_ERRLEVEL_HIGH, mp);
333 return -EFSCORRUPTED;
334 } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
335 xfs_warn(mp,
336 "dirty log entry has mismatched uuid - can't recover");
337 xlog_header_check_dump(mp, head);
338 XFS_ERROR_REPORT("xlog_header_check_recover(2)",
339 XFS_ERRLEVEL_HIGH, mp);
340 return -EFSCORRUPTED;
341 }
342 return 0;
343}
344
345
346
347
348STATIC int
349xlog_header_check_mount(
350 xfs_mount_t *mp,
351 xlog_rec_header_t *head)
352{
353 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
354
355 if (uuid_is_nil(&head->h_fs_uuid)) {
356
357
358
359
360
361 xfs_warn(mp, "nil uuid in log - IRIX style log");
362 } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
363 xfs_warn(mp, "log has mismatched uuid - can't recover");
364 xlog_header_check_dump(mp, head);
365 XFS_ERROR_REPORT("xlog_header_check_mount",
366 XFS_ERRLEVEL_HIGH, mp);
367 return -EFSCORRUPTED;
368 }
369 return 0;
370}
371
372STATIC void
373xlog_recover_iodone(
374 struct xfs_buf *bp)
375{
376 if (bp->b_error) {
377
378
379
380
381 if (!XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
382 xfs_buf_ioerror_alert(bp, __func__);
383 xfs_force_shutdown(bp->b_target->bt_mount,
384 SHUTDOWN_META_IO_ERROR);
385 }
386 }
387
388
389
390
391
392 if (bp->b_fspriv)
393 xfs_buf_item_relse(bp);
394 ASSERT(bp->b_fspriv == NULL);
395
396 bp->b_iodone = NULL;
397 xfs_buf_ioend(bp);
398}
399
400
401
402
403
404
405
406STATIC int
407xlog_find_cycle_start(
408 struct xlog *log,
409 struct xfs_buf *bp,
410 xfs_daddr_t first_blk,
411 xfs_daddr_t *last_blk,
412 uint cycle)
413{
414 char *offset;
415 xfs_daddr_t mid_blk;
416 xfs_daddr_t end_blk;
417 uint mid_cycle;
418 int error;
419
420 end_blk = *last_blk;
421 mid_blk = BLK_AVG(first_blk, end_blk);
422 while (mid_blk != first_blk && mid_blk != end_blk) {
423 error = xlog_bread(log, mid_blk, 1, bp, &offset);
424 if (error)
425 return error;
426 mid_cycle = xlog_get_cycle(offset);
427 if (mid_cycle == cycle)
428 end_blk = mid_blk;
429 else
430 first_blk = mid_blk;
431 mid_blk = BLK_AVG(first_blk, end_blk);
432 }
433 ASSERT((mid_blk == first_blk && mid_blk+1 == end_blk) ||
434 (mid_blk == end_blk && mid_blk-1 == first_blk));
435
436 *last_blk = end_blk;
437
438 return 0;
439}
440
441
442
443
444
445
446
447
448
449STATIC int
450xlog_find_verify_cycle(
451 struct xlog *log,
452 xfs_daddr_t start_blk,
453 int nbblks,
454 uint stop_on_cycle_no,
455 xfs_daddr_t *new_blk)
456{
457 xfs_daddr_t i, j;
458 uint cycle;
459 xfs_buf_t *bp;
460 xfs_daddr_t bufblks;
461 char *buf = NULL;
462 int error = 0;
463
464
465
466
467
468
469
470 bufblks = 1 << ffs(nbblks);
471 while (bufblks > log->l_logBBsize)
472 bufblks >>= 1;
473 while (!(bp = xlog_get_bp(log, bufblks))) {
474 bufblks >>= 1;
475 if (bufblks < log->l_sectBBsize)
476 return -ENOMEM;
477 }
478
479 for (i = start_blk; i < start_blk + nbblks; i += bufblks) {
480 int bcount;
481
482 bcount = min(bufblks, (start_blk + nbblks - i));
483
484 error = xlog_bread(log, i, bcount, bp, &buf);
485 if (error)
486 goto out;
487
488 for (j = 0; j < bcount; j++) {
489 cycle = xlog_get_cycle(buf);
490 if (cycle == stop_on_cycle_no) {
491 *new_blk = i+j;
492 goto out;
493 }
494
495 buf += BBSIZE;
496 }
497 }
498
499 *new_blk = -1;
500
501out:
502 xlog_put_bp(bp);
503 return error;
504}
505
506
507
508
509
510
511
512
513
514
515
516
517
518STATIC int
519xlog_find_verify_log_record(
520 struct xlog *log,
521 xfs_daddr_t start_blk,
522 xfs_daddr_t *last_blk,
523 int extra_bblks)
524{
525 xfs_daddr_t i;
526 xfs_buf_t *bp;
527 char *offset = NULL;
528 xlog_rec_header_t *head = NULL;
529 int error = 0;
530 int smallmem = 0;
531 int num_blks = *last_blk - start_blk;
532 int xhdrs;
533
534 ASSERT(start_blk != 0 || *last_blk != start_blk);
535
536 if (!(bp = xlog_get_bp(log, num_blks))) {
537 if (!(bp = xlog_get_bp(log, 1)))
538 return -ENOMEM;
539 smallmem = 1;
540 } else {
541 error = xlog_bread(log, start_blk, num_blks, bp, &offset);
542 if (error)
543 goto out;
544 offset += ((num_blks - 1) << BBSHIFT);
545 }
546
547 for (i = (*last_blk) - 1; i >= 0; i--) {
548 if (i < start_blk) {
549
550 xfs_warn(log->l_mp,
551 "Log inconsistent (didn't find previous header)");
552 ASSERT(0);
553 error = -EIO;
554 goto out;
555 }
556
557 if (smallmem) {
558 error = xlog_bread(log, i, 1, bp, &offset);
559 if (error)
560 goto out;
561 }
562
563 head = (xlog_rec_header_t *)offset;
564
565 if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
566 break;
567
568 if (!smallmem)
569 offset -= BBSIZE;
570 }
571
572
573
574
575
576
577 if (i == -1) {
578 error = 1;
579 goto out;
580 }
581
582
583
584
585
586 if ((error = xlog_header_check_mount(log->l_mp, head)))
587 goto out;
588
589
590
591
592
593
594
595
596 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
597 uint h_size = be32_to_cpu(head->h_size);
598
599 xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
600 if (h_size % XLOG_HEADER_CYCLE_SIZE)
601 xhdrs++;
602 } else {
603 xhdrs = 1;
604 }
605
606 if (*last_blk - i + extra_bblks !=
607 BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
608 *last_blk = i;
609
610out:
611 xlog_put_bp(bp);
612 return error;
613}
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628STATIC int
629xlog_find_head(
630 struct xlog *log,
631 xfs_daddr_t *return_head_blk)
632{
633 xfs_buf_t *bp;
634 char *offset;
635 xfs_daddr_t new_blk, first_blk, start_blk, last_blk, head_blk;
636 int num_scan_bblks;
637 uint first_half_cycle, last_half_cycle;
638 uint stop_on_cycle;
639 int error, log_bbnum = log->l_logBBsize;
640
641
642 error = xlog_find_zeroed(log, &first_blk);
643 if (error < 0) {
644 xfs_warn(log->l_mp, "empty log check failed");
645 return error;
646 }
647 if (error == 1) {
648 *return_head_blk = first_blk;
649
650
651 if (!first_blk) {
652
653
654
655
656 xfs_warn(log->l_mp, "totally zeroed log");
657 }
658
659 return 0;
660 }
661
662 first_blk = 0;
663 bp = xlog_get_bp(log, 1);
664 if (!bp)
665 return -ENOMEM;
666
667 error = xlog_bread(log, 0, 1, bp, &offset);
668 if (error)
669 goto bp_err;
670
671 first_half_cycle = xlog_get_cycle(offset);
672
673 last_blk = head_blk = log_bbnum - 1;
674 error = xlog_bread(log, last_blk, 1, bp, &offset);
675 if (error)
676 goto bp_err;
677
678 last_half_cycle = xlog_get_cycle(offset);
679 ASSERT(last_half_cycle != 0);
680
681
682
683
684
685
686
687
688
689
690
691
692 if (first_half_cycle == last_half_cycle) {
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718 head_blk = log_bbnum;
719 stop_on_cycle = last_half_cycle - 1;
720 } else {
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 stop_on_cycle = last_half_cycle;
744 if ((error = xlog_find_cycle_start(log, bp, first_blk,
745 &head_blk, last_half_cycle)))
746 goto bp_err;
747 }
748
749
750
751
752
753
754
755
756 num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
757 if (head_blk >= num_scan_bblks) {
758
759
760
761
762 start_blk = head_blk - num_scan_bblks;
763 if ((error = xlog_find_verify_cycle(log,
764 start_blk, num_scan_bblks,
765 stop_on_cycle, &new_blk)))
766 goto bp_err;
767 if (new_blk != -1)
768 head_blk = new_blk;
769 } else {
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797 ASSERT(head_blk <= INT_MAX &&
798 (xfs_daddr_t) num_scan_bblks >= head_blk);
799 start_blk = log_bbnum - (num_scan_bblks - head_blk);
800 if ((error = xlog_find_verify_cycle(log, start_blk,
801 num_scan_bblks - (int)head_blk,
802 (stop_on_cycle - 1), &new_blk)))
803 goto bp_err;
804 if (new_blk != -1) {
805 head_blk = new_blk;
806 goto validate_head;
807 }
808
809
810
811
812
813
814 start_blk = 0;
815 ASSERT(head_blk <= INT_MAX);
816 if ((error = xlog_find_verify_cycle(log,
817 start_blk, (int)head_blk,
818 stop_on_cycle, &new_blk)))
819 goto bp_err;
820 if (new_blk != -1)
821 head_blk = new_blk;
822 }
823
824validate_head:
825
826
827
828
829 num_scan_bblks = XLOG_REC_SHIFT(log);
830 if (head_blk >= num_scan_bblks) {
831 start_blk = head_blk - num_scan_bblks;
832
833
834 error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0);
835 if (error == 1)
836 error = -EIO;
837 if (error)
838 goto bp_err;
839 } else {
840 start_blk = 0;
841 ASSERT(head_blk <= INT_MAX);
842 error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0);
843 if (error < 0)
844 goto bp_err;
845 if (error == 1) {
846
847 start_blk = log_bbnum - (num_scan_bblks - head_blk);
848 new_blk = log_bbnum;
849 ASSERT(start_blk <= INT_MAX &&
850 (xfs_daddr_t) log_bbnum-start_blk >= 0);
851 ASSERT(head_blk <= INT_MAX);
852 error = xlog_find_verify_log_record(log, start_blk,
853 &new_blk, (int)head_blk);
854 if (error == 1)
855 error = -EIO;
856 if (error)
857 goto bp_err;
858 if (new_blk != log_bbnum)
859 head_blk = new_blk;
860 } else if (error)
861 goto bp_err;
862 }
863
864 xlog_put_bp(bp);
865 if (head_blk == log_bbnum)
866 *return_head_blk = 0;
867 else
868 *return_head_blk = head_blk;
869
870
871
872
873
874
875 return 0;
876
877 bp_err:
878 xlog_put_bp(bp);
879
880 if (error)
881 xfs_warn(log->l_mp, "failed to find log head");
882 return error;
883}
884
885
886
887
888
889
890
891
892
893STATIC int
894xlog_rseek_logrec_hdr(
895 struct xlog *log,
896 xfs_daddr_t head_blk,
897 xfs_daddr_t tail_blk,
898 int count,
899 struct xfs_buf *bp,
900 xfs_daddr_t *rblk,
901 struct xlog_rec_header **rhead,
902 bool *wrapped)
903{
904 int i;
905 int error;
906 int found = 0;
907 char *offset = NULL;
908 xfs_daddr_t end_blk;
909
910 *wrapped = false;
911
912
913
914
915
916 end_blk = head_blk > tail_blk ? tail_blk : 0;
917 for (i = (int) head_blk - 1; i >= end_blk; i--) {
918 error = xlog_bread(log, i, 1, bp, &offset);
919 if (error)
920 goto out_error;
921
922 if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
923 *rblk = i;
924 *rhead = (struct xlog_rec_header *) offset;
925 if (++found == count)
926 break;
927 }
928 }
929
930
931
932
933
934
935 if (tail_blk >= head_blk && found != count) {
936 for (i = log->l_logBBsize - 1; i >= (int) tail_blk; i--) {
937 error = xlog_bread(log, i, 1, bp, &offset);
938 if (error)
939 goto out_error;
940
941 if (*(__be32 *)offset ==
942 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
943 *wrapped = true;
944 *rblk = i;
945 *rhead = (struct xlog_rec_header *) offset;
946 if (++found == count)
947 break;
948 }
949 }
950 }
951
952 return found;
953
954out_error:
955 return error;
956}
957
958
959
960
961
962
963
964
965
966
967STATIC int
968xlog_seek_logrec_hdr(
969 struct xlog *log,
970 xfs_daddr_t head_blk,
971 xfs_daddr_t tail_blk,
972 int count,
973 struct xfs_buf *bp,
974 xfs_daddr_t *rblk,
975 struct xlog_rec_header **rhead,
976 bool *wrapped)
977{
978 int i;
979 int error;
980 int found = 0;
981 char *offset = NULL;
982 xfs_daddr_t end_blk;
983
984 *wrapped = false;
985
986
987
988
989
990 end_blk = head_blk > tail_blk ? head_blk : log->l_logBBsize - 1;
991 for (i = (int) tail_blk; i <= end_blk; i++) {
992 error = xlog_bread(log, i, 1, bp, &offset);
993 if (error)
994 goto out_error;
995
996 if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
997 *rblk = i;
998 *rhead = (struct xlog_rec_header *) offset;
999 if (++found == count)
1000 break;
1001 }
1002 }
1003
1004
1005
1006
1007
1008 if (tail_blk > head_blk && found != count) {
1009 for (i = 0; i < (int) head_blk; i++) {
1010 error = xlog_bread(log, i, 1, bp, &offset);
1011 if (error)
1012 goto out_error;
1013
1014 if (*(__be32 *)offset ==
1015 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
1016 *wrapped = true;
1017 *rblk = i;
1018 *rhead = (struct xlog_rec_header *) offset;
1019 if (++found == count)
1020 break;
1021 }
1022 }
1023 }
1024
1025 return found;
1026
1027out_error:
1028 return error;
1029}
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039STATIC int
1040xlog_verify_tail(
1041 struct xlog *log,
1042 xfs_daddr_t head_blk,
1043 xfs_daddr_t tail_blk)
1044{
1045 struct xlog_rec_header *thead;
1046 struct xfs_buf *bp;
1047 xfs_daddr_t first_bad;
1048 int count;
1049 int error = 0;
1050 bool wrapped;
1051 xfs_daddr_t tmp_head;
1052
1053 bp = xlog_get_bp(log, 1);
1054 if (!bp)
1055 return -ENOMEM;
1056
1057
1058
1059
1060
1061
1062 count = xlog_seek_logrec_hdr(log, head_blk, tail_blk,
1063 XLOG_MAX_ICLOGS + 1, bp, &tmp_head, &thead,
1064 &wrapped);
1065 if (count < 0) {
1066 error = count;
1067 goto out;
1068 }
1069
1070
1071
1072
1073
1074
1075 if (count < XLOG_MAX_ICLOGS + 1)
1076 tmp_head = head_blk;
1077
1078
1079
1080
1081
1082
1083
1084 error = xlog_do_recovery_pass(log, tmp_head, tail_blk,
1085 XLOG_RECOVER_CRCPASS, &first_bad);
1086
1087out:
1088 xlog_put_bp(bp);
1089 return error;
1090}
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105STATIC int
1106xlog_verify_head(
1107 struct xlog *log,
1108 xfs_daddr_t *head_blk,
1109 xfs_daddr_t *tail_blk,
1110 struct xfs_buf *bp,
1111 xfs_daddr_t *rhead_blk,
1112 struct xlog_rec_header **rhead,
1113 bool *wrapped)
1114{
1115 struct xlog_rec_header *tmp_rhead;
1116 struct xfs_buf *tmp_bp;
1117 xfs_daddr_t first_bad;
1118 xfs_daddr_t tmp_rhead_blk;
1119 int found;
1120 int error;
1121 bool tmp_wrapped;
1122
1123
1124
1125
1126
1127
1128
1129 tmp_bp = xlog_get_bp(log, 1);
1130 if (!tmp_bp)
1131 return -ENOMEM;
1132 error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk,
1133 XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk,
1134 &tmp_rhead, &tmp_wrapped);
1135 xlog_put_bp(tmp_bp);
1136 if (error < 0)
1137 return error;
1138
1139
1140
1141
1142
1143
1144 error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk,
1145 XLOG_RECOVER_CRCPASS, &first_bad);
1146 if (error == -EFSBADCRC) {
1147
1148
1149
1150
1151 error = 0;
1152 xfs_warn(log->l_mp,
1153"Torn write (CRC failure) detected at log block 0x%llx. Truncating head block from 0x%llx.",
1154 first_bad, *head_blk);
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1, bp,
1165 rhead_blk, rhead, wrapped);
1166 if (found < 0)
1167 return found;
1168 if (found == 0)
1169 return -EIO;
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180 *head_blk = first_bad;
1181 *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn));
1182 if (*head_blk == *tail_blk) {
1183 ASSERT(0);
1184 return 0;
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207 error = xlog_verify_tail(log, *head_blk, *tail_blk);
1208 }
1209
1210 return error;
1211}
1212
1213
1214
1215
1216
1217
1218static int
1219xlog_check_unmount_rec(
1220 struct xlog *log,
1221 xfs_daddr_t *head_blk,
1222 xfs_daddr_t *tail_blk,
1223 struct xlog_rec_header *rhead,
1224 xfs_daddr_t rhead_blk,
1225 struct xfs_buf *bp,
1226 bool *clean)
1227{
1228 struct xlog_op_header *op_head;
1229 xfs_daddr_t umount_data_blk;
1230 xfs_daddr_t after_umount_blk;
1231 int hblks;
1232 int error;
1233 char *offset;
1234
1235 *clean = false;
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
1247 int h_size = be32_to_cpu(rhead->h_size);
1248 int h_version = be32_to_cpu(rhead->h_version);
1249
1250 if ((h_version & XLOG_VERSION_2) &&
1251 (h_size > XLOG_HEADER_CYCLE_SIZE)) {
1252 hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
1253 if (h_size % XLOG_HEADER_CYCLE_SIZE)
1254 hblks++;
1255 } else {
1256 hblks = 1;
1257 }
1258 } else {
1259 hblks = 1;
1260 }
1261 after_umount_blk = rhead_blk + hblks + BTOBB(be32_to_cpu(rhead->h_len));
1262 after_umount_blk = do_mod(after_umount_blk, log->l_logBBsize);
1263 if (*head_blk == after_umount_blk &&
1264 be32_to_cpu(rhead->h_num_logops) == 1) {
1265 umount_data_blk = rhead_blk + hblks;
1266 umount_data_blk = do_mod(umount_data_blk, log->l_logBBsize);
1267 error = xlog_bread(log, umount_data_blk, 1, bp, &offset);
1268 if (error)
1269 return error;
1270
1271 op_head = (struct xlog_op_header *)offset;
1272 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
1273
1274
1275
1276
1277
1278 xlog_assign_atomic_lsn(&log->l_tail_lsn,
1279 log->l_curr_cycle, after_umount_blk);
1280 xlog_assign_atomic_lsn(&log->l_last_sync_lsn,
1281 log->l_curr_cycle, after_umount_blk);
1282 *tail_blk = after_umount_blk;
1283
1284 *clean = true;
1285 }
1286 }
1287
1288 return 0;
1289}
1290
1291static void
1292xlog_set_state(
1293 struct xlog *log,
1294 xfs_daddr_t head_blk,
1295 struct xlog_rec_header *rhead,
1296 xfs_daddr_t rhead_blk,
1297 bool bump_cycle)
1298{
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309 log->l_prev_block = rhead_blk;
1310 log->l_curr_block = (int)head_blk;
1311 log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
1312 if (bump_cycle)
1313 log->l_curr_cycle++;
1314 atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn));
1315 atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn));
1316 xlog_assign_grant_head(&log->l_reserve_head.grant, log->l_curr_cycle,
1317 BBTOB(log->l_curr_block));
1318 xlog_assign_grant_head(&log->l_write_head.grant, log->l_curr_cycle,
1319 BBTOB(log->l_curr_block));
1320}
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338STATIC int
1339xlog_find_tail(
1340 struct xlog *log,
1341 xfs_daddr_t *head_blk,
1342 xfs_daddr_t *tail_blk)
1343{
1344 xlog_rec_header_t *rhead;
1345 char *offset = NULL;
1346 xfs_buf_t *bp;
1347 int error;
1348 xfs_daddr_t rhead_blk;
1349 xfs_lsn_t tail_lsn;
1350 bool wrapped = false;
1351 bool clean = false;
1352
1353
1354
1355
1356 if ((error = xlog_find_head(log, head_blk)))
1357 return error;
1358 ASSERT(*head_blk < INT_MAX);
1359
1360 bp = xlog_get_bp(log, 1);
1361 if (!bp)
1362 return -ENOMEM;
1363 if (*head_blk == 0) {
1364 error = xlog_bread(log, 0, 1, bp, &offset);
1365 if (error)
1366 goto done;
1367
1368 if (xlog_get_cycle(offset) == 0) {
1369 *tail_blk = 0;
1370
1371 goto done;
1372 }
1373 }
1374
1375
1376
1377
1378
1379
1380 error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp,
1381 &rhead_blk, &rhead, &wrapped);
1382 if (error < 0)
1383 return error;
1384 if (!error) {
1385 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
1386 return -EIO;
1387 }
1388 *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
1389
1390
1391
1392
1393 xlog_set_state(log, *head_blk, rhead, rhead_blk, wrapped);
1394 tail_lsn = atomic64_read(&log->l_tail_lsn);
1395
1396
1397
1398
1399
1400 error = xlog_check_unmount_rec(log, head_blk, tail_blk, rhead,
1401 rhead_blk, bp, &clean);
1402 if (error)
1403 goto done;
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415 if (!clean) {
1416 xfs_daddr_t orig_head = *head_blk;
1417
1418 error = xlog_verify_head(log, head_blk, tail_blk, bp,
1419 &rhead_blk, &rhead, &wrapped);
1420 if (error)
1421 goto done;
1422
1423
1424 if (*head_blk != orig_head) {
1425 xlog_set_state(log, *head_blk, rhead, rhead_blk,
1426 wrapped);
1427 tail_lsn = atomic64_read(&log->l_tail_lsn);
1428 error = xlog_check_unmount_rec(log, head_blk, tail_blk,
1429 rhead, rhead_blk, bp,
1430 &clean);
1431 if (error)
1432 goto done;
1433 }
1434 }
1435
1436
1437
1438
1439
1440
1441 if (clean)
1442 log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN;
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463 if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp))
1464 error = xlog_clear_stale_blocks(log, tail_lsn);
1465
1466done:
1467 xlog_put_bp(bp);
1468
1469 if (error)
1470 xfs_warn(log->l_mp, "failed to locate log tail");
1471 return error;
1472}
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490STATIC int
1491xlog_find_zeroed(
1492 struct xlog *log,
1493 xfs_daddr_t *blk_no)
1494{
1495 xfs_buf_t *bp;
1496 char *offset;
1497 uint first_cycle, last_cycle;
1498 xfs_daddr_t new_blk, last_blk, start_blk;
1499 xfs_daddr_t num_scan_bblks;
1500 int error, log_bbnum = log->l_logBBsize;
1501
1502 *blk_no = 0;
1503
1504
1505 bp = xlog_get_bp(log, 1);
1506 if (!bp)
1507 return -ENOMEM;
1508 error = xlog_bread(log, 0, 1, bp, &offset);
1509 if (error)
1510 goto bp_err;
1511
1512 first_cycle = xlog_get_cycle(offset);
1513 if (first_cycle == 0) {
1514 *blk_no = 0;
1515 xlog_put_bp(bp);
1516 return 1;
1517 }
1518
1519
1520 error = xlog_bread(log, log_bbnum-1, 1, bp, &offset);
1521 if (error)
1522 goto bp_err;
1523
1524 last_cycle = xlog_get_cycle(offset);
1525 if (last_cycle != 0) {
1526 xlog_put_bp(bp);
1527 return 0;
1528 } else if (first_cycle != 1) {
1529
1530
1531
1532
1533
1534 xfs_warn(log->l_mp,
1535 "Log inconsistent or not a log (last==0, first!=1)");
1536 error = -EINVAL;
1537 goto bp_err;
1538 }
1539
1540
1541 last_blk = log_bbnum-1;
1542 if ((error = xlog_find_cycle_start(log, bp, 0, &last_blk, 0)))
1543 goto bp_err;
1544
1545
1546
1547
1548
1549
1550
1551 num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
1552 ASSERT(num_scan_bblks <= INT_MAX);
1553
1554 if (last_blk < num_scan_bblks)
1555 num_scan_bblks = last_blk;
1556 start_blk = last_blk - num_scan_bblks;
1557
1558
1559
1560
1561
1562
1563
1564 if ((error = xlog_find_verify_cycle(log, start_blk,
1565 (int)num_scan_bblks, 0, &new_blk)))
1566 goto bp_err;
1567 if (new_blk != -1)
1568 last_blk = new_blk;
1569
1570
1571
1572
1573
1574 error = xlog_find_verify_log_record(log, start_blk, &last_blk, 0);
1575 if (error == 1)
1576 error = -EIO;
1577 if (error)
1578 goto bp_err;
1579
1580 *blk_no = last_blk;
1581bp_err:
1582 xlog_put_bp(bp);
1583 if (error)
1584 return error;
1585 return 1;
1586}
1587
1588
1589
1590
1591
1592
1593STATIC void
1594xlog_add_record(
1595 struct xlog *log,
1596 char *buf,
1597 int cycle,
1598 int block,
1599 int tail_cycle,
1600 int tail_block)
1601{
1602 xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
1603
1604 memset(buf, 0, BBSIZE);
1605 recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
1606 recp->h_cycle = cpu_to_be32(cycle);
1607 recp->h_version = cpu_to_be32(
1608 xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
1609 recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
1610 recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
1611 recp->h_fmt = cpu_to_be32(XLOG_FMT);
1612 memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
1613}
1614
1615STATIC int
1616xlog_write_log_records(
1617 struct xlog *log,
1618 int cycle,
1619 int start_block,
1620 int blocks,
1621 int tail_cycle,
1622 int tail_block)
1623{
1624 char *offset;
1625 xfs_buf_t *bp;
1626 int balign, ealign;
1627 int sectbb = log->l_sectBBsize;
1628 int end_block = start_block + blocks;
1629 int bufblks;
1630 int error = 0;
1631 int i, j = 0;
1632
1633
1634
1635
1636
1637
1638
1639 bufblks = 1 << ffs(blocks);
1640 while (bufblks > log->l_logBBsize)
1641 bufblks >>= 1;
1642 while (!(bp = xlog_get_bp(log, bufblks))) {
1643 bufblks >>= 1;
1644 if (bufblks < sectbb)
1645 return -ENOMEM;
1646 }
1647
1648
1649
1650
1651
1652 balign = round_down(start_block, sectbb);
1653 if (balign != start_block) {
1654 error = xlog_bread_noalign(log, start_block, 1, bp);
1655 if (error)
1656 goto out_put_bp;
1657
1658 j = start_block - balign;
1659 }
1660
1661 for (i = start_block; i < end_block; i += bufblks) {
1662 int bcount, endcount;
1663
1664 bcount = min(bufblks, end_block - start_block);
1665 endcount = bcount - j;
1666
1667
1668
1669
1670
1671 ealign = round_down(end_block, sectbb);
1672 if (j == 0 && (start_block + endcount > ealign)) {
1673 offset = bp->b_addr + BBTOB(ealign - start_block);
1674 error = xlog_bread_offset(log, ealign, sectbb,
1675 bp, offset);
1676 if (error)
1677 break;
1678
1679 }
1680
1681 offset = xlog_align(log, start_block, endcount, bp);
1682 for (; j < endcount; j++) {
1683 xlog_add_record(log, offset, cycle, i+j,
1684 tail_cycle, tail_block);
1685 offset += BBSIZE;
1686 }
1687 error = xlog_bwrite(log, start_block, endcount, bp);
1688 if (error)
1689 break;
1690 start_block += endcount;
1691 j = 0;
1692 }
1693
1694 out_put_bp:
1695 xlog_put_bp(bp);
1696 return error;
1697}
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715STATIC int
1716xlog_clear_stale_blocks(
1717 struct xlog *log,
1718 xfs_lsn_t tail_lsn)
1719{
1720 int tail_cycle, head_cycle;
1721 int tail_block, head_block;
1722 int tail_distance, max_distance;
1723 int distance;
1724 int error;
1725
1726 tail_cycle = CYCLE_LSN(tail_lsn);
1727 tail_block = BLOCK_LSN(tail_lsn);
1728 head_cycle = log->l_curr_cycle;
1729 head_block = log->l_curr_block;
1730
1731
1732
1733
1734
1735
1736
1737 if (head_cycle == tail_cycle) {
1738
1739
1740
1741
1742
1743
1744
1745 if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
1746 XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
1747 XFS_ERRLEVEL_LOW, log->l_mp);
1748 return -EFSCORRUPTED;
1749 }
1750 tail_distance = tail_block + (log->l_logBBsize - head_block);
1751 } else {
1752
1753
1754
1755
1756
1757 if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
1758 XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
1759 XFS_ERRLEVEL_LOW, log->l_mp);
1760 return -EFSCORRUPTED;
1761 }
1762 tail_distance = tail_block - head_block;
1763 }
1764
1765
1766
1767
1768
1769 if (tail_distance <= 0) {
1770 ASSERT(tail_distance == 0);
1771 return 0;
1772 }
1773
1774 max_distance = XLOG_TOTAL_REC_SHIFT(log);
1775
1776
1777
1778
1779
1780
1781
1782 max_distance = MIN(max_distance, tail_distance);
1783
1784 if ((head_block + max_distance) <= log->l_logBBsize) {
1785
1786
1787
1788
1789
1790
1791
1792 error = xlog_write_log_records(log, (head_cycle - 1),
1793 head_block, max_distance, tail_cycle,
1794 tail_block);
1795 if (error)
1796 return error;
1797 } else {
1798
1799
1800
1801
1802
1803
1804
1805 distance = log->l_logBBsize - head_block;
1806 error = xlog_write_log_records(log, (head_cycle - 1),
1807 head_block, distance, tail_cycle,
1808 tail_block);
1809
1810 if (error)
1811 return error;
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821 distance = max_distance - (log->l_logBBsize - head_block);
1822 error = xlog_write_log_records(log, head_cycle, 0, distance,
1823 tail_cycle, tail_block);
1824 if (error)
1825 return error;
1826 }
1827
1828 return 0;
1829}
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887STATIC int
1888xlog_recover_reorder_trans(
1889 struct xlog *log,
1890 struct xlog_recover *trans,
1891 int pass)
1892{
1893 xlog_recover_item_t *item, *n;
1894 int error = 0;
1895 LIST_HEAD(sort_list);
1896 LIST_HEAD(cancel_list);
1897 LIST_HEAD(buffer_list);
1898 LIST_HEAD(inode_buffer_list);
1899 LIST_HEAD(inode_list);
1900
1901 list_splice_init(&trans->r_itemq, &sort_list);
1902 list_for_each_entry_safe(item, n, &sort_list, ri_list) {
1903 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
1904
1905 switch (ITEM_TYPE(item)) {
1906 case XFS_LI_ICREATE:
1907 list_move_tail(&item->ri_list, &buffer_list);
1908 break;
1909 case XFS_LI_BUF:
1910 if (buf_f->blf_flags & XFS_BLF_CANCEL) {
1911 trace_xfs_log_recover_item_reorder_head(log,
1912 trans, item, pass);
1913 list_move(&item->ri_list, &cancel_list);
1914 break;
1915 }
1916 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
1917 list_move(&item->ri_list, &inode_buffer_list);
1918 break;
1919 }
1920 list_move_tail(&item->ri_list, &buffer_list);
1921 break;
1922 case XFS_LI_INODE:
1923 case XFS_LI_DQUOT:
1924 case XFS_LI_QUOTAOFF:
1925 case XFS_LI_EFD:
1926 case XFS_LI_EFI:
1927 case XFS_LI_RUI:
1928 case XFS_LI_RUD:
1929 case XFS_LI_CUI:
1930 case XFS_LI_CUD:
1931 case XFS_LI_BUI:
1932 case XFS_LI_BUD:
1933 trace_xfs_log_recover_item_reorder_tail(log,
1934 trans, item, pass);
1935 list_move_tail(&item->ri_list, &inode_list);
1936 break;
1937 default:
1938 xfs_warn(log->l_mp,
1939 "%s: unrecognized type of log operation",
1940 __func__);
1941 ASSERT(0);
1942
1943
1944
1945
1946 if (!list_empty(&sort_list))
1947 list_splice_init(&sort_list, &trans->r_itemq);
1948 error = -EIO;
1949 goto out;
1950 }
1951 }
1952out:
1953 ASSERT(list_empty(&sort_list));
1954 if (!list_empty(&buffer_list))
1955 list_splice(&buffer_list, &trans->r_itemq);
1956 if (!list_empty(&inode_list))
1957 list_splice_tail(&inode_list, &trans->r_itemq);
1958 if (!list_empty(&inode_buffer_list))
1959 list_splice_tail(&inode_buffer_list, &trans->r_itemq);
1960 if (!list_empty(&cancel_list))
1961 list_splice_tail(&cancel_list, &trans->r_itemq);
1962 return error;
1963}
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977STATIC int
1978xlog_recover_buffer_pass1(
1979 struct xlog *log,
1980 struct xlog_recover_item *item)
1981{
1982 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
1983 struct list_head *bucket;
1984 struct xfs_buf_cancel *bcp;
1985
1986
1987
1988
1989 if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
1990 trace_xfs_log_recover_buf_not_cancel(log, buf_f);
1991 return 0;
1992 }
1993
1994
1995
1996
1997
1998 bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno);
1999 list_for_each_entry(bcp, bucket, bc_list) {
2000 if (bcp->bc_blkno == buf_f->blf_blkno &&
2001 bcp->bc_len == buf_f->blf_len) {
2002 bcp->bc_refcount++;
2003 trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f);
2004 return 0;
2005 }
2006 }
2007
2008 bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP);
2009 bcp->bc_blkno = buf_f->blf_blkno;
2010 bcp->bc_len = buf_f->blf_len;
2011 bcp->bc_refcount = 1;
2012 list_add_tail(&bcp->bc_list, bucket);
2013
2014 trace_xfs_log_recover_buf_cancel_add(log, buf_f);
2015 return 0;
2016}
2017
2018
2019
2020
2021
2022
2023STATIC struct xfs_buf_cancel *
2024xlog_peek_buffer_cancelled(
2025 struct xlog *log,
2026 xfs_daddr_t blkno,
2027 uint len,
2028 unsigned short flags)
2029{
2030 struct list_head *bucket;
2031 struct xfs_buf_cancel *bcp;
2032
2033 if (!log->l_buf_cancel_table) {
2034
2035 ASSERT(!(flags & XFS_BLF_CANCEL));
2036 return NULL;
2037 }
2038
2039 bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno);
2040 list_for_each_entry(bcp, bucket, bc_list) {
2041 if (bcp->bc_blkno == blkno && bcp->bc_len == len)
2042 return bcp;
2043 }
2044
2045
2046
2047
2048
2049 ASSERT(!(flags & XFS_BLF_CANCEL));
2050 return NULL;
2051}
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063STATIC int
2064xlog_check_buffer_cancelled(
2065 struct xlog *log,
2066 xfs_daddr_t blkno,
2067 uint len,
2068 unsigned short flags)
2069{
2070 struct xfs_buf_cancel *bcp;
2071
2072 bcp = xlog_peek_buffer_cancelled(log, blkno, len, flags);
2073 if (!bcp)
2074 return 0;
2075
2076
2077
2078
2079
2080
2081
2082 if (flags & XFS_BLF_CANCEL) {
2083 if (--bcp->bc_refcount == 0) {
2084 list_del(&bcp->bc_list);
2085 kmem_free(bcp);
2086 }
2087 }
2088 return 1;
2089}
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103STATIC int
2104xlog_recover_do_inode_buffer(
2105 struct xfs_mount *mp,
2106 xlog_recover_item_t *item,
2107 struct xfs_buf *bp,
2108 xfs_buf_log_format_t *buf_f)
2109{
2110 int i;
2111 int item_index = 0;
2112 int bit = 0;
2113 int nbits = 0;
2114 int reg_buf_offset = 0;
2115 int reg_buf_bytes = 0;
2116 int next_unlinked_offset;
2117 int inodes_per_buf;
2118 xfs_agino_t *logged_nextp;
2119 xfs_agino_t *buffer_nextp;
2120
2121 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
2122
2123
2124
2125
2126
2127 if (xfs_sb_version_hascrc(&mp->m_sb))
2128 bp->b_ops = &xfs_inode_buf_ops;
2129
2130 inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
2131 for (i = 0; i < inodes_per_buf; i++) {
2132 next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
2133 offsetof(xfs_dinode_t, di_next_unlinked);
2134
2135 while (next_unlinked_offset >=
2136 (reg_buf_offset + reg_buf_bytes)) {
2137
2138
2139
2140
2141
2142
2143 bit += nbits;
2144 bit = xfs_next_bit(buf_f->blf_data_map,
2145 buf_f->blf_map_size, bit);
2146
2147
2148
2149
2150
2151 if (bit == -1)
2152 return 0;
2153
2154 nbits = xfs_contig_bits(buf_f->blf_data_map,
2155 buf_f->blf_map_size, bit);
2156 ASSERT(nbits > 0);
2157 reg_buf_offset = bit << XFS_BLF_SHIFT;
2158 reg_buf_bytes = nbits << XFS_BLF_SHIFT;
2159 item_index++;
2160 }
2161
2162
2163
2164
2165
2166
2167 if (next_unlinked_offset < reg_buf_offset)
2168 continue;
2169
2170 ASSERT(item->ri_buf[item_index].i_addr != NULL);
2171 ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
2172 ASSERT((reg_buf_offset + reg_buf_bytes) <=
2173 BBTOB(bp->b_io_length));
2174
2175
2176
2177
2178
2179
2180 logged_nextp = item->ri_buf[item_index].i_addr +
2181 next_unlinked_offset - reg_buf_offset;
2182 if (unlikely(*logged_nextp == 0)) {
2183 xfs_alert(mp,
2184 "Bad inode buffer log record (ptr = 0x%p, bp = 0x%p). "
2185 "Trying to replay bad (0) inode di_next_unlinked field.",
2186 item, bp);
2187 XFS_ERROR_REPORT("xlog_recover_do_inode_buf",
2188 XFS_ERRLEVEL_LOW, mp);
2189 return -EFSCORRUPTED;
2190 }
2191
2192 buffer_nextp = xfs_buf_offset(bp, next_unlinked_offset);
2193 *buffer_nextp = *logged_nextp;
2194
2195
2196
2197
2198
2199
2200 xfs_dinode_calc_crc(mp,
2201 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
2202
2203 }
2204
2205 return 0;
2206}
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228static xfs_lsn_t
2229xlog_recover_get_buf_lsn(
2230 struct xfs_mount *mp,
2231 struct xfs_buf *bp)
2232{
2233 __uint32_t magic32;
2234 __uint16_t magic16;
2235 __uint16_t magicda;
2236 void *blk = bp->b_addr;
2237 uuid_t *uuid;
2238 xfs_lsn_t lsn = -1;
2239
2240
2241 if (!xfs_sb_version_hascrc(&mp->m_sb))
2242 goto recover_immediately;
2243
2244 magic32 = be32_to_cpu(*(__be32 *)blk);
2245 switch (magic32) {
2246 case XFS_ABTB_CRC_MAGIC:
2247 case XFS_ABTC_CRC_MAGIC:
2248 case XFS_ABTB_MAGIC:
2249 case XFS_ABTC_MAGIC:
2250 case XFS_RMAP_CRC_MAGIC:
2251 case XFS_REFC_CRC_MAGIC:
2252 case XFS_IBT_CRC_MAGIC:
2253 case XFS_IBT_MAGIC: {
2254 struct xfs_btree_block *btb = blk;
2255
2256 lsn = be64_to_cpu(btb->bb_u.s.bb_lsn);
2257 uuid = &btb->bb_u.s.bb_uuid;
2258 break;
2259 }
2260 case XFS_BMAP_CRC_MAGIC:
2261 case XFS_BMAP_MAGIC: {
2262 struct xfs_btree_block *btb = blk;
2263
2264 lsn = be64_to_cpu(btb->bb_u.l.bb_lsn);
2265 uuid = &btb->bb_u.l.bb_uuid;
2266 break;
2267 }
2268 case XFS_AGF_MAGIC:
2269 lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn);
2270 uuid = &((struct xfs_agf *)blk)->agf_uuid;
2271 break;
2272 case XFS_AGFL_MAGIC:
2273 lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn);
2274 uuid = &((struct xfs_agfl *)blk)->agfl_uuid;
2275 break;
2276 case XFS_AGI_MAGIC:
2277 lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn);
2278 uuid = &((struct xfs_agi *)blk)->agi_uuid;
2279 break;
2280 case XFS_SYMLINK_MAGIC:
2281 lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn);
2282 uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid;
2283 break;
2284 case XFS_DIR3_BLOCK_MAGIC:
2285 case XFS_DIR3_DATA_MAGIC:
2286 case XFS_DIR3_FREE_MAGIC:
2287 lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn);
2288 uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid;
2289 break;
2290 case XFS_ATTR3_RMT_MAGIC:
2291
2292
2293
2294
2295
2296
2297
2298 goto recover_immediately;
2299 case XFS_SB_MAGIC:
2300
2301
2302
2303
2304
2305
2306
2307 lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn);
2308 if (xfs_sb_version_hasmetauuid(&mp->m_sb))
2309 uuid = &((struct xfs_dsb *)blk)->sb_meta_uuid;
2310 else
2311 uuid = &((struct xfs_dsb *)blk)->sb_uuid;
2312 break;
2313 default:
2314 break;
2315 }
2316
2317 if (lsn != (xfs_lsn_t)-1) {
2318 if (!uuid_equal(&mp->m_sb.sb_meta_uuid, uuid))
2319 goto recover_immediately;
2320 return lsn;
2321 }
2322
2323 magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic);
2324 switch (magicda) {
2325 case XFS_DIR3_LEAF1_MAGIC:
2326 case XFS_DIR3_LEAFN_MAGIC:
2327 case XFS_DA3_NODE_MAGIC:
2328 lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn);
2329 uuid = &((struct xfs_da3_blkinfo *)blk)->uuid;
2330 break;
2331 default:
2332 break;
2333 }
2334
2335 if (lsn != (xfs_lsn_t)-1) {
2336 if (!uuid_equal(&mp->m_sb.sb_uuid, uuid))
2337 goto recover_immediately;
2338 return lsn;
2339 }
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352 magic16 = be16_to_cpu(*(__be16 *)blk);
2353 switch (magic16) {
2354 case XFS_DQUOT_MAGIC:
2355 case XFS_DINODE_MAGIC:
2356 goto recover_immediately;
2357 default:
2358 break;
2359 }
2360
2361
2362
2363recover_immediately:
2364 return (xfs_lsn_t)-1;
2365
2366}
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376static void
2377xlog_recover_validate_buf_type(
2378 struct xfs_mount *mp,
2379 struct xfs_buf *bp,
2380 xfs_buf_log_format_t *buf_f,
2381 xfs_lsn_t current_lsn)
2382{
2383 struct xfs_da_blkinfo *info = bp->b_addr;
2384 __uint32_t magic32;
2385 __uint16_t magic16;
2386 __uint16_t magicda;
2387 char *warnmsg = NULL;
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397 if (!xfs_sb_version_hascrc(&mp->m_sb))
2398 return;
2399
2400 magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
2401 magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
2402 magicda = be16_to_cpu(info->magic);
2403 switch (xfs_blft_from_flags(buf_f)) {
2404 case XFS_BLFT_BTREE_BUF:
2405 switch (magic32) {
2406 case XFS_ABTB_CRC_MAGIC:
2407 case XFS_ABTC_CRC_MAGIC:
2408 case XFS_ABTB_MAGIC:
2409 case XFS_ABTC_MAGIC:
2410 bp->b_ops = &xfs_allocbt_buf_ops;
2411 break;
2412 case XFS_IBT_CRC_MAGIC:
2413 case XFS_FIBT_CRC_MAGIC:
2414 case XFS_IBT_MAGIC:
2415 case XFS_FIBT_MAGIC:
2416 bp->b_ops = &xfs_inobt_buf_ops;
2417 break;
2418 case XFS_BMAP_CRC_MAGIC:
2419 case XFS_BMAP_MAGIC:
2420 bp->b_ops = &xfs_bmbt_buf_ops;
2421 break;
2422 case XFS_RMAP_CRC_MAGIC:
2423 bp->b_ops = &xfs_rmapbt_buf_ops;
2424 break;
2425 case XFS_REFC_CRC_MAGIC:
2426 bp->b_ops = &xfs_refcountbt_buf_ops;
2427 break;
2428 default:
2429 warnmsg = "Bad btree block magic!";
2430 break;
2431 }
2432 break;
2433 case XFS_BLFT_AGF_BUF:
2434 if (magic32 != XFS_AGF_MAGIC) {
2435 warnmsg = "Bad AGF block magic!";
2436 break;
2437 }
2438 bp->b_ops = &xfs_agf_buf_ops;
2439 break;
2440 case XFS_BLFT_AGFL_BUF:
2441 if (magic32 != XFS_AGFL_MAGIC) {
2442 warnmsg = "Bad AGFL block magic!";
2443 break;
2444 }
2445 bp->b_ops = &xfs_agfl_buf_ops;
2446 break;
2447 case XFS_BLFT_AGI_BUF:
2448 if (magic32 != XFS_AGI_MAGIC) {
2449 warnmsg = "Bad AGI block magic!";
2450 break;
2451 }
2452 bp->b_ops = &xfs_agi_buf_ops;
2453 break;
2454 case XFS_BLFT_UDQUOT_BUF:
2455 case XFS_BLFT_PDQUOT_BUF:
2456 case XFS_BLFT_GDQUOT_BUF:
2457#ifdef CONFIG_XFS_QUOTA
2458 if (magic16 != XFS_DQUOT_MAGIC) {
2459 warnmsg = "Bad DQUOT block magic!";
2460 break;
2461 }
2462 bp->b_ops = &xfs_dquot_buf_ops;
2463#else
2464 xfs_alert(mp,
2465 "Trying to recover dquots without QUOTA support built in!");
2466 ASSERT(0);
2467#endif
2468 break;
2469 case XFS_BLFT_DINO_BUF:
2470 if (magic16 != XFS_DINODE_MAGIC) {
2471 warnmsg = "Bad INODE block magic!";
2472 break;
2473 }
2474 bp->b_ops = &xfs_inode_buf_ops;
2475 break;
2476 case XFS_BLFT_SYMLINK_BUF:
2477 if (magic32 != XFS_SYMLINK_MAGIC) {
2478 warnmsg = "Bad symlink block magic!";
2479 break;
2480 }
2481 bp->b_ops = &xfs_symlink_buf_ops;
2482 break;
2483 case XFS_BLFT_DIR_BLOCK_BUF:
2484 if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
2485 magic32 != XFS_DIR3_BLOCK_MAGIC) {
2486 warnmsg = "Bad dir block magic!";
2487 break;
2488 }
2489 bp->b_ops = &xfs_dir3_block_buf_ops;
2490 break;
2491 case XFS_BLFT_DIR_DATA_BUF:
2492 if (magic32 != XFS_DIR2_DATA_MAGIC &&
2493 magic32 != XFS_DIR3_DATA_MAGIC) {
2494 warnmsg = "Bad dir data magic!";
2495 break;
2496 }
2497 bp->b_ops = &xfs_dir3_data_buf_ops;
2498 break;
2499 case XFS_BLFT_DIR_FREE_BUF:
2500 if (magic32 != XFS_DIR2_FREE_MAGIC &&
2501 magic32 != XFS_DIR3_FREE_MAGIC) {
2502 warnmsg = "Bad dir3 free magic!";
2503 break;
2504 }
2505 bp->b_ops = &xfs_dir3_free_buf_ops;
2506 break;
2507 case XFS_BLFT_DIR_LEAF1_BUF:
2508 if (magicda != XFS_DIR2_LEAF1_MAGIC &&
2509 magicda != XFS_DIR3_LEAF1_MAGIC) {
2510 warnmsg = "Bad dir leaf1 magic!";
2511 break;
2512 }
2513 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
2514 break;
2515 case XFS_BLFT_DIR_LEAFN_BUF:
2516 if (magicda != XFS_DIR2_LEAFN_MAGIC &&
2517 magicda != XFS_DIR3_LEAFN_MAGIC) {
2518 warnmsg = "Bad dir leafn magic!";
2519 break;
2520 }
2521 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2522 break;
2523 case XFS_BLFT_DA_NODE_BUF:
2524 if (magicda != XFS_DA_NODE_MAGIC &&
2525 magicda != XFS_DA3_NODE_MAGIC) {
2526 warnmsg = "Bad da node magic!";
2527 break;
2528 }
2529 bp->b_ops = &xfs_da3_node_buf_ops;
2530 break;
2531 case XFS_BLFT_ATTR_LEAF_BUF:
2532 if (magicda != XFS_ATTR_LEAF_MAGIC &&
2533 magicda != XFS_ATTR3_LEAF_MAGIC) {
2534 warnmsg = "Bad attr leaf magic!";
2535 break;
2536 }
2537 bp->b_ops = &xfs_attr3_leaf_buf_ops;
2538 break;
2539 case XFS_BLFT_ATTR_RMT_BUF:
2540 if (magic32 != XFS_ATTR3_RMT_MAGIC) {
2541 warnmsg = "Bad attr remote magic!";
2542 break;
2543 }
2544 bp->b_ops = &xfs_attr3_rmt_buf_ops;
2545 break;
2546 case XFS_BLFT_SB_BUF:
2547 if (magic32 != XFS_SB_MAGIC) {
2548 warnmsg = "Bad SB block magic!";
2549 break;
2550 }
2551 bp->b_ops = &xfs_sb_buf_ops;
2552 break;
2553#ifdef CONFIG_XFS_RT
2554 case XFS_BLFT_RTBITMAP_BUF:
2555 case XFS_BLFT_RTSUMMARY_BUF:
2556
2557 bp->b_ops = &xfs_rtbuf_ops;
2558 break;
2559#endif
2560 default:
2561 xfs_warn(mp, "Unknown buffer type %d!",
2562 xfs_blft_from_flags(buf_f));
2563 break;
2564 }
2565
2566
2567
2568
2569
2570
2571 if (current_lsn == NULLCOMMITLSN)
2572 return;
2573
2574 if (warnmsg) {
2575 xfs_warn(mp, warnmsg);
2576 ASSERT(0);
2577 }
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590 if (bp->b_ops) {
2591 struct xfs_buf_log_item *bip;
2592
2593 ASSERT(!bp->b_iodone || bp->b_iodone == xlog_recover_iodone);
2594 bp->b_iodone = xlog_recover_iodone;
2595 xfs_buf_item_init(bp, mp);
2596 bip = bp->b_fspriv;
2597 bip->bli_item.li_lsn = current_lsn;
2598 }
2599}
2600
2601
2602
2603
2604
2605
2606
2607STATIC void
2608xlog_recover_do_reg_buffer(
2609 struct xfs_mount *mp,
2610 xlog_recover_item_t *item,
2611 struct xfs_buf *bp,
2612 xfs_buf_log_format_t *buf_f,
2613 xfs_lsn_t current_lsn)
2614{
2615 int i;
2616 int bit;
2617 int nbits;
2618 int error;
2619
2620 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
2621
2622 bit = 0;
2623 i = 1;
2624 while (1) {
2625 bit = xfs_next_bit(buf_f->blf_data_map,
2626 buf_f->blf_map_size, bit);
2627 if (bit == -1)
2628 break;
2629 nbits = xfs_contig_bits(buf_f->blf_data_map,
2630 buf_f->blf_map_size, bit);
2631 ASSERT(nbits > 0);
2632 ASSERT(item->ri_buf[i].i_addr != NULL);
2633 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
2634 ASSERT(BBTOB(bp->b_io_length) >=
2635 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645 if (item->ri_buf[i].i_len < (nbits << XFS_BLF_SHIFT))
2646 nbits = item->ri_buf[i].i_len >> XFS_BLF_SHIFT;
2647
2648
2649
2650
2651
2652
2653 error = 0;
2654 if (buf_f->blf_flags &
2655 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2656 if (item->ri_buf[i].i_addr == NULL) {
2657 xfs_alert(mp,
2658 "XFS: NULL dquot in %s.", __func__);
2659 goto next;
2660 }
2661 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
2662 xfs_alert(mp,
2663 "XFS: dquot too small (%d) in %s.",
2664 item->ri_buf[i].i_len, __func__);
2665 goto next;
2666 }
2667 error = xfs_dqcheck(mp, item->ri_buf[i].i_addr,
2668 -1, 0, XFS_QMOPT_DOWARN,
2669 "dquot_buf_recover");
2670 if (error)
2671 goto next;
2672 }
2673
2674 memcpy(xfs_buf_offset(bp,
2675 (uint)bit << XFS_BLF_SHIFT),
2676 item->ri_buf[i].i_addr,
2677 nbits<<XFS_BLF_SHIFT);
2678 next:
2679 i++;
2680 bit += nbits;
2681 }
2682
2683
2684 ASSERT(i == item->ri_total);
2685
2686 xlog_recover_validate_buf_type(mp, bp, buf_f, current_lsn);
2687}
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698STATIC bool
2699xlog_recover_do_dquot_buffer(
2700 struct xfs_mount *mp,
2701 struct xlog *log,
2702 struct xlog_recover_item *item,
2703 struct xfs_buf *bp,
2704 struct xfs_buf_log_format *buf_f)
2705{
2706 uint type;
2707
2708 trace_xfs_log_recover_buf_dquot_buf(log, buf_f);
2709
2710
2711
2712
2713 if (!mp->m_qflags)
2714 return false;
2715
2716 type = 0;
2717 if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF)
2718 type |= XFS_DQ_USER;
2719 if (buf_f->blf_flags & XFS_BLF_PDQUOT_BUF)
2720 type |= XFS_DQ_PROJ;
2721 if (buf_f->blf_flags & XFS_BLF_GDQUOT_BUF)
2722 type |= XFS_DQ_GROUP;
2723
2724
2725
2726 if (log->l_quotaoffs_flag & type)
2727 return false;
2728
2729 xlog_recover_do_reg_buffer(mp, item, bp, buf_f, NULLCOMMITLSN);
2730 return true;
2731}
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756STATIC int
2757xlog_recover_buffer_pass2(
2758 struct xlog *log,
2759 struct list_head *buffer_list,
2760 struct xlog_recover_item *item,
2761 xfs_lsn_t current_lsn)
2762{
2763 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
2764 xfs_mount_t *mp = log->l_mp;
2765 xfs_buf_t *bp;
2766 int error;
2767 uint buf_flags;
2768 xfs_lsn_t lsn;
2769
2770
2771
2772
2773
2774 if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno,
2775 buf_f->blf_len, buf_f->blf_flags)) {
2776 trace_xfs_log_recover_buf_cancel(log, buf_f);
2777 return 0;
2778 }
2779
2780 trace_xfs_log_recover_buf_recover(log, buf_f);
2781
2782 buf_flags = 0;
2783 if (buf_f->blf_flags & XFS_BLF_INODE_BUF)
2784 buf_flags |= XBF_UNMAPPED;
2785
2786 bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
2787 buf_flags, NULL);
2788 if (!bp)
2789 return -ENOMEM;
2790 error = bp->b_error;
2791 if (error) {
2792 xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#1)");
2793 goto out_release;
2794 }
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815 lsn = xlog_recover_get_buf_lsn(mp, bp);
2816 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
2817 trace_xfs_log_recover_buf_skip(log, buf_f);
2818 xlog_recover_validate_buf_type(mp, bp, buf_f, NULLCOMMITLSN);
2819 goto out_release;
2820 }
2821
2822 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
2823 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2824 if (error)
2825 goto out_release;
2826 } else if (buf_f->blf_flags &
2827 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2828 bool dirty;
2829
2830 dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2831 if (!dirty)
2832 goto out_release;
2833 } else {
2834 xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
2835 }
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852 if (XFS_DINODE_MAGIC ==
2853 be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
2854 (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize,
2855 (__uint32_t)log->l_mp->m_inode_cluster_size))) {
2856 xfs_buf_stale(bp);
2857 error = xfs_bwrite(bp);
2858 } else {
2859 ASSERT(bp->b_target->bt_mount == mp);
2860 bp->b_iodone = xlog_recover_iodone;
2861 xfs_buf_delwri_queue(bp, buffer_list);
2862 }
2863
2864out_release:
2865 xfs_buf_relse(bp);
2866 return error;
2867}
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899STATIC int
2900xfs_recover_inode_owner_change(
2901 struct xfs_mount *mp,
2902 struct xfs_dinode *dip,
2903 struct xfs_inode_log_format *in_f,
2904 struct list_head *buffer_list)
2905{
2906 struct xfs_inode *ip;
2907 int error;
2908
2909 ASSERT(in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER));
2910
2911 ip = xfs_inode_alloc(mp, in_f->ilf_ino);
2912 if (!ip)
2913 return -ENOMEM;
2914
2915
2916 xfs_inode_from_disk(ip, dip);
2917 ASSERT(ip->i_d.di_version >= 3);
2918
2919 error = xfs_iformat_fork(ip, dip);
2920 if (error)
2921 goto out_free_ip;
2922
2923
2924 if (in_f->ilf_fields & XFS_ILOG_DOWNER) {
2925 ASSERT(in_f->ilf_fields & XFS_ILOG_DBROOT);
2926 error = xfs_bmbt_change_owner(NULL, ip, XFS_DATA_FORK,
2927 ip->i_ino, buffer_list);
2928 if (error)
2929 goto out_free_ip;
2930 }
2931
2932 if (in_f->ilf_fields & XFS_ILOG_AOWNER) {
2933 ASSERT(in_f->ilf_fields & XFS_ILOG_ABROOT);
2934 error = xfs_bmbt_change_owner(NULL, ip, XFS_ATTR_FORK,
2935 ip->i_ino, buffer_list);
2936 if (error)
2937 goto out_free_ip;
2938 }
2939
2940out_free_ip:
2941 xfs_inode_free(ip);
2942 return error;
2943}
2944
2945STATIC int
2946xlog_recover_inode_pass2(
2947 struct xlog *log,
2948 struct list_head *buffer_list,
2949 struct xlog_recover_item *item,
2950 xfs_lsn_t current_lsn)
2951{
2952 xfs_inode_log_format_t *in_f;
2953 xfs_mount_t *mp = log->l_mp;
2954 xfs_buf_t *bp;
2955 xfs_dinode_t *dip;
2956 int len;
2957 char *src;
2958 char *dest;
2959 int error;
2960 int attr_index;
2961 uint fields;
2962 struct xfs_log_dinode *ldip;
2963 uint isize;
2964 int need_free = 0;
2965
2966 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2967 in_f = item->ri_buf[0].i_addr;
2968 } else {
2969 in_f = kmem_alloc(sizeof(xfs_inode_log_format_t), KM_SLEEP);
2970 need_free = 1;
2971 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2972 if (error)
2973 goto error;
2974 }
2975
2976
2977
2978
2979
2980 if (xlog_check_buffer_cancelled(log, in_f->ilf_blkno,
2981 in_f->ilf_len, 0)) {
2982 error = 0;
2983 trace_xfs_log_recover_inode_cancel(log, in_f);
2984 goto error;
2985 }
2986 trace_xfs_log_recover_inode_recover(log, in_f);
2987
2988 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0,
2989 &xfs_inode_buf_ops);
2990 if (!bp) {
2991 error = -ENOMEM;
2992 goto error;
2993 }
2994 error = bp->b_error;
2995 if (error) {
2996 xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#2)");
2997 goto out_release;
2998 }
2999 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
3000 dip = xfs_buf_offset(bp, in_f->ilf_boffset);
3001
3002
3003
3004
3005
3006 if (unlikely(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))) {
3007 xfs_alert(mp,
3008 "%s: Bad inode magic number, dip = 0x%p, dino bp = 0x%p, ino = %Ld",
3009 __func__, dip, bp, in_f->ilf_ino);
3010 XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)",
3011 XFS_ERRLEVEL_LOW, mp);
3012 error = -EFSCORRUPTED;
3013 goto out_release;
3014 }
3015 ldip = item->ri_buf[1].i_addr;
3016 if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) {
3017 xfs_alert(mp,
3018 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld",
3019 __func__, item, in_f->ilf_ino);
3020 XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)",
3021 XFS_ERRLEVEL_LOW, mp);
3022 error = -EFSCORRUPTED;
3023 goto out_release;
3024 }
3025
3026
3027
3028
3029
3030
3031
3032
3033 if (dip->di_version >= 3) {
3034 xfs_lsn_t lsn = be64_to_cpu(dip->di_lsn);
3035
3036 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
3037 trace_xfs_log_recover_inode_skip(log, in_f);
3038 error = 0;
3039 goto out_owner_change;
3040 }
3041 }
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051 if (!xfs_sb_version_hascrc(&mp->m_sb) &&
3052 ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
3053
3054
3055
3056
3057 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
3058 ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) {
3059
3060 } else {
3061 trace_xfs_log_recover_inode_skip(log, in_f);
3062 error = 0;
3063 goto out_release;
3064 }
3065 }
3066
3067
3068 ldip->di_flushiter = 0;
3069
3070 if (unlikely(S_ISREG(ldip->di_mode))) {
3071 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
3072 (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
3073 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
3074 XFS_ERRLEVEL_LOW, mp, ldip);
3075 xfs_alert(mp,
3076 "%s: Bad regular inode log record, rec ptr 0x%p, "
3077 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
3078 __func__, item, dip, bp, in_f->ilf_ino);
3079 error = -EFSCORRUPTED;
3080 goto out_release;
3081 }
3082 } else if (unlikely(S_ISDIR(ldip->di_mode))) {
3083 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
3084 (ldip->di_format != XFS_DINODE_FMT_BTREE) &&
3085 (ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
3086 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
3087 XFS_ERRLEVEL_LOW, mp, ldip);
3088 xfs_alert(mp,
3089 "%s: Bad dir inode log record, rec ptr 0x%p, "
3090 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
3091 __func__, item, dip, bp, in_f->ilf_ino);
3092 error = -EFSCORRUPTED;
3093 goto out_release;
3094 }
3095 }
3096 if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
3097 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
3098 XFS_ERRLEVEL_LOW, mp, ldip);
3099 xfs_alert(mp,
3100 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
3101 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
3102 __func__, item, dip, bp, in_f->ilf_ino,
3103 ldip->di_nextents + ldip->di_anextents,
3104 ldip->di_nblocks);
3105 error = -EFSCORRUPTED;
3106 goto out_release;
3107 }
3108 if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
3109 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
3110 XFS_ERRLEVEL_LOW, mp, ldip);
3111 xfs_alert(mp,
3112 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
3113 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__,
3114 item, dip, bp, in_f->ilf_ino, ldip->di_forkoff);
3115 error = -EFSCORRUPTED;
3116 goto out_release;
3117 }
3118 isize = xfs_log_dinode_size(ldip->di_version);
3119 if (unlikely(item->ri_buf[1].i_len > isize)) {
3120 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
3121 XFS_ERRLEVEL_LOW, mp, ldip);
3122 xfs_alert(mp,
3123 "%s: Bad inode log record length %d, rec ptr 0x%p",
3124 __func__, item->ri_buf[1].i_len, item);
3125 error = -EFSCORRUPTED;
3126 goto out_release;
3127 }
3128
3129
3130 xfs_log_dinode_to_disk(ldip, dip);
3131
3132
3133 if (item->ri_buf[1].i_len > isize) {
3134 memcpy((char *)dip + isize,
3135 item->ri_buf[1].i_addr + isize,
3136 item->ri_buf[1].i_len - isize);
3137 }
3138
3139 fields = in_f->ilf_fields;
3140 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
3141 case XFS_ILOG_DEV:
3142 xfs_dinode_put_rdev(dip, in_f->ilf_u.ilfu_rdev);
3143 break;
3144 case XFS_ILOG_UUID:
3145 memcpy(XFS_DFORK_DPTR(dip),
3146 &in_f->ilf_u.ilfu_uuid,
3147 sizeof(uuid_t));
3148 break;
3149 }
3150
3151 if (in_f->ilf_size == 2)
3152 goto out_owner_change;
3153 len = item->ri_buf[2].i_len;
3154 src = item->ri_buf[2].i_addr;
3155 ASSERT(in_f->ilf_size <= 4);
3156 ASSERT((in_f->ilf_size == 3) || (fields & XFS_ILOG_AFORK));
3157 ASSERT(!(fields & XFS_ILOG_DFORK) ||
3158 (len == in_f->ilf_dsize));
3159
3160 switch (fields & XFS_ILOG_DFORK) {
3161 case XFS_ILOG_DDATA:
3162 case XFS_ILOG_DEXT:
3163 memcpy(XFS_DFORK_DPTR(dip), src, len);
3164 break;
3165
3166 case XFS_ILOG_DBROOT:
3167 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len,
3168 (xfs_bmdr_block_t *)XFS_DFORK_DPTR(dip),
3169 XFS_DFORK_DSIZE(dip, mp));
3170 break;
3171
3172 default:
3173
3174
3175
3176 ASSERT((fields & XFS_ILOG_DFORK) == 0);
3177 break;
3178 }
3179
3180
3181
3182
3183
3184
3185 if (in_f->ilf_fields & XFS_ILOG_AFORK) {
3186 if (in_f->ilf_fields & XFS_ILOG_DFORK) {
3187 attr_index = 3;
3188 } else {
3189 attr_index = 2;
3190 }
3191 len = item->ri_buf[attr_index].i_len;
3192 src = item->ri_buf[attr_index].i_addr;
3193 ASSERT(len == in_f->ilf_asize);
3194
3195 switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
3196 case XFS_ILOG_ADATA:
3197 case XFS_ILOG_AEXT:
3198 dest = XFS_DFORK_APTR(dip);
3199 ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
3200 memcpy(dest, src, len);
3201 break;
3202
3203 case XFS_ILOG_ABROOT:
3204 dest = XFS_DFORK_APTR(dip);
3205 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src,
3206 len, (xfs_bmdr_block_t*)dest,
3207 XFS_DFORK_ASIZE(dip, mp));
3208 break;
3209
3210 default:
3211 xfs_warn(log->l_mp, "%s: Invalid flag", __func__);
3212 ASSERT(0);
3213 error = -EIO;
3214 goto out_release;
3215 }
3216 }
3217
3218out_owner_change:
3219 if (in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER))
3220 error = xfs_recover_inode_owner_change(mp, dip, in_f,
3221 buffer_list);
3222
3223 xfs_dinode_calc_crc(log->l_mp, dip);
3224
3225 ASSERT(bp->b_target->bt_mount == mp);
3226 bp->b_iodone = xlog_recover_iodone;
3227 xfs_buf_delwri_queue(bp, buffer_list);
3228
3229out_release:
3230 xfs_buf_relse(bp);
3231error:
3232 if (need_free)
3233 kmem_free(in_f);
3234 return error;
3235}
3236
3237
3238
3239
3240
3241
3242STATIC int
3243xlog_recover_quotaoff_pass1(
3244 struct xlog *log,
3245 struct xlog_recover_item *item)
3246{
3247 xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr;
3248 ASSERT(qoff_f);
3249
3250
3251
3252
3253
3254 if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
3255 log->l_quotaoffs_flag |= XFS_DQ_USER;
3256 if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
3257 log->l_quotaoffs_flag |= XFS_DQ_PROJ;
3258 if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
3259 log->l_quotaoffs_flag |= XFS_DQ_GROUP;
3260
3261 return 0;
3262}
3263
3264
3265
3266
3267STATIC int
3268xlog_recover_dquot_pass2(
3269 struct xlog *log,
3270 struct list_head *buffer_list,
3271 struct xlog_recover_item *item,
3272 xfs_lsn_t current_lsn)
3273{
3274 xfs_mount_t *mp = log->l_mp;
3275 xfs_buf_t *bp;
3276 struct xfs_disk_dquot *ddq, *recddq;
3277 int error;
3278 xfs_dq_logformat_t *dq_f;
3279 uint type;
3280
3281
3282
3283
3284
3285 if (mp->m_qflags == 0)
3286 return 0;
3287
3288 recddq = item->ri_buf[1].i_addr;
3289 if (recddq == NULL) {
3290 xfs_alert(log->l_mp, "NULL dquot in %s.", __func__);
3291 return -EIO;
3292 }
3293 if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
3294 xfs_alert(log->l_mp, "dquot too small (%d) in %s.",
3295 item->ri_buf[1].i_len, __func__);
3296 return -EIO;
3297 }
3298
3299
3300
3301
3302 type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
3303 ASSERT(type);
3304 if (log->l_quotaoffs_flag & type)
3305 return 0;
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317 dq_f = item->ri_buf[0].i_addr;
3318 ASSERT(dq_f);
3319 error = xfs_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
3320 "xlog_recover_dquot_pass2 (log copy)");
3321 if (error)
3322 return -EIO;
3323 ASSERT(dq_f->qlf_len == 1);
3324
3325
3326
3327
3328
3329
3330
3331
3332 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno,
3333 XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp,
3334 &xfs_dquot_buf_ops);
3335 if (error)
3336 return error;
3337
3338 ASSERT(bp);
3339 ddq = xfs_buf_offset(bp, dq_f->qlf_boffset);
3340
3341
3342
3343
3344
3345 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3346 struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddq;
3347 xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn);
3348
3349 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
3350 goto out_release;
3351 }
3352 }
3353
3354 memcpy(ddq, recddq, item->ri_buf[1].i_len);
3355 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3356 xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
3357 XFS_DQUOT_CRC_OFF);
3358 }
3359
3360 ASSERT(dq_f->qlf_size == 2);
3361 ASSERT(bp->b_target->bt_mount == mp);
3362 bp->b_iodone = xlog_recover_iodone;
3363 xfs_buf_delwri_queue(bp, buffer_list);
3364
3365out_release:
3366 xfs_buf_relse(bp);
3367 return 0;
3368}
3369
3370
3371
3372
3373
3374
3375
3376
3377STATIC int
3378xlog_recover_efi_pass2(
3379 struct xlog *log,
3380 struct xlog_recover_item *item,
3381 xfs_lsn_t lsn)
3382{
3383 int error;
3384 struct xfs_mount *mp = log->l_mp;
3385 struct xfs_efi_log_item *efip;
3386 struct xfs_efi_log_format *efi_formatp;
3387
3388 efi_formatp = item->ri_buf[0].i_addr;
3389
3390 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
3391 error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
3392 if (error) {
3393 xfs_efi_item_free(efip);
3394 return error;
3395 }
3396 atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
3397
3398 spin_lock(&log->l_ailp->xa_lock);
3399
3400
3401
3402
3403
3404
3405 xfs_trans_ail_update(log->l_ailp, &efip->efi_item, lsn);
3406 xfs_efi_release(efip);
3407 return 0;
3408}
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418STATIC int
3419xlog_recover_efd_pass2(
3420 struct xlog *log,
3421 struct xlog_recover_item *item)
3422{
3423 xfs_efd_log_format_t *efd_formatp;
3424 xfs_efi_log_item_t *efip = NULL;
3425 xfs_log_item_t *lip;
3426 __uint64_t efi_id;
3427 struct xfs_ail_cursor cur;
3428 struct xfs_ail *ailp = log->l_ailp;
3429
3430 efd_formatp = item->ri_buf[0].i_addr;
3431 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
3432 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
3433 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
3434 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
3435 efi_id = efd_formatp->efd_efi_id;
3436
3437
3438
3439
3440
3441 spin_lock(&ailp->xa_lock);
3442 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3443 while (lip != NULL) {
3444 if (lip->li_type == XFS_LI_EFI) {
3445 efip = (xfs_efi_log_item_t *)lip;
3446 if (efip->efi_format.efi_id == efi_id) {
3447
3448
3449
3450
3451 spin_unlock(&ailp->xa_lock);
3452 xfs_efi_release(efip);
3453 spin_lock(&ailp->xa_lock);
3454 break;
3455 }
3456 }
3457 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3458 }
3459
3460 xfs_trans_ail_cursor_done(&cur);
3461 spin_unlock(&ailp->xa_lock);
3462
3463 return 0;
3464}
3465
3466
3467
3468
3469
3470
3471
3472
3473STATIC int
3474xlog_recover_rui_pass2(
3475 struct xlog *log,
3476 struct xlog_recover_item *item,
3477 xfs_lsn_t lsn)
3478{
3479 int error;
3480 struct xfs_mount *mp = log->l_mp;
3481 struct xfs_rui_log_item *ruip;
3482 struct xfs_rui_log_format *rui_formatp;
3483
3484 rui_formatp = item->ri_buf[0].i_addr;
3485
3486 ruip = xfs_rui_init(mp, rui_formatp->rui_nextents);
3487 error = xfs_rui_copy_format(&item->ri_buf[0], &ruip->rui_format);
3488 if (error) {
3489 xfs_rui_item_free(ruip);
3490 return error;
3491 }
3492 atomic_set(&ruip->rui_next_extent, rui_formatp->rui_nextents);
3493
3494 spin_lock(&log->l_ailp->xa_lock);
3495
3496
3497
3498
3499
3500
3501 xfs_trans_ail_update(log->l_ailp, &ruip->rui_item, lsn);
3502 xfs_rui_release(ruip);
3503 return 0;
3504}
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514STATIC int
3515xlog_recover_rud_pass2(
3516 struct xlog *log,
3517 struct xlog_recover_item *item)
3518{
3519 struct xfs_rud_log_format *rud_formatp;
3520 struct xfs_rui_log_item *ruip = NULL;
3521 struct xfs_log_item *lip;
3522 __uint64_t rui_id;
3523 struct xfs_ail_cursor cur;
3524 struct xfs_ail *ailp = log->l_ailp;
3525
3526 rud_formatp = item->ri_buf[0].i_addr;
3527 ASSERT(item->ri_buf[0].i_len == sizeof(struct xfs_rud_log_format));
3528 rui_id = rud_formatp->rud_rui_id;
3529
3530
3531
3532
3533
3534 spin_lock(&ailp->xa_lock);
3535 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3536 while (lip != NULL) {
3537 if (lip->li_type == XFS_LI_RUI) {
3538 ruip = (struct xfs_rui_log_item *)lip;
3539 if (ruip->rui_format.rui_id == rui_id) {
3540
3541
3542
3543
3544 spin_unlock(&ailp->xa_lock);
3545 xfs_rui_release(ruip);
3546 spin_lock(&ailp->xa_lock);
3547 break;
3548 }
3549 }
3550 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3551 }
3552
3553 xfs_trans_ail_cursor_done(&cur);
3554 spin_unlock(&ailp->xa_lock);
3555
3556 return 0;
3557}
3558
3559
3560
3561
3562
3563
3564static int
3565xfs_cui_copy_format(
3566 struct xfs_log_iovec *buf,
3567 struct xfs_cui_log_format *dst_cui_fmt)
3568{
3569 struct xfs_cui_log_format *src_cui_fmt;
3570 uint len;
3571
3572 src_cui_fmt = buf->i_addr;
3573 len = xfs_cui_log_format_sizeof(src_cui_fmt->cui_nextents);
3574
3575 if (buf->i_len == len) {
3576 memcpy(dst_cui_fmt, src_cui_fmt, len);
3577 return 0;
3578 }
3579 return -EFSCORRUPTED;
3580}
3581
3582
3583
3584
3585
3586
3587
3588
3589STATIC int
3590xlog_recover_cui_pass2(
3591 struct xlog *log,
3592 struct xlog_recover_item *item,
3593 xfs_lsn_t lsn)
3594{
3595 int error;
3596 struct xfs_mount *mp = log->l_mp;
3597 struct xfs_cui_log_item *cuip;
3598 struct xfs_cui_log_format *cui_formatp;
3599
3600 cui_formatp = item->ri_buf[0].i_addr;
3601
3602 cuip = xfs_cui_init(mp, cui_formatp->cui_nextents);
3603 error = xfs_cui_copy_format(&item->ri_buf[0], &cuip->cui_format);
3604 if (error) {
3605 xfs_cui_item_free(cuip);
3606 return error;
3607 }
3608 atomic_set(&cuip->cui_next_extent, cui_formatp->cui_nextents);
3609
3610 spin_lock(&log->l_ailp->xa_lock);
3611
3612
3613
3614
3615
3616
3617 xfs_trans_ail_update(log->l_ailp, &cuip->cui_item, lsn);
3618 xfs_cui_release(cuip);
3619 return 0;
3620}
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630STATIC int
3631xlog_recover_cud_pass2(
3632 struct xlog *log,
3633 struct xlog_recover_item *item)
3634{
3635 struct xfs_cud_log_format *cud_formatp;
3636 struct xfs_cui_log_item *cuip = NULL;
3637 struct xfs_log_item *lip;
3638 __uint64_t cui_id;
3639 struct xfs_ail_cursor cur;
3640 struct xfs_ail *ailp = log->l_ailp;
3641
3642 cud_formatp = item->ri_buf[0].i_addr;
3643 if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format))
3644 return -EFSCORRUPTED;
3645 cui_id = cud_formatp->cud_cui_id;
3646
3647
3648
3649
3650
3651 spin_lock(&ailp->xa_lock);
3652 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3653 while (lip != NULL) {
3654 if (lip->li_type == XFS_LI_CUI) {
3655 cuip = (struct xfs_cui_log_item *)lip;
3656 if (cuip->cui_format.cui_id == cui_id) {
3657
3658
3659
3660
3661 spin_unlock(&ailp->xa_lock);
3662 xfs_cui_release(cuip);
3663 spin_lock(&ailp->xa_lock);
3664 break;
3665 }
3666 }
3667 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3668 }
3669
3670 xfs_trans_ail_cursor_done(&cur);
3671 spin_unlock(&ailp->xa_lock);
3672
3673 return 0;
3674}
3675
3676
3677
3678
3679
3680
3681static int
3682xfs_bui_copy_format(
3683 struct xfs_log_iovec *buf,
3684 struct xfs_bui_log_format *dst_bui_fmt)
3685{
3686 struct xfs_bui_log_format *src_bui_fmt;
3687 uint len;
3688
3689 src_bui_fmt = buf->i_addr;
3690 len = xfs_bui_log_format_sizeof(src_bui_fmt->bui_nextents);
3691
3692 if (buf->i_len == len) {
3693 memcpy(dst_bui_fmt, src_bui_fmt, len);
3694 return 0;
3695 }
3696 return -EFSCORRUPTED;
3697}
3698
3699
3700
3701
3702
3703
3704
3705
3706STATIC int
3707xlog_recover_bui_pass2(
3708 struct xlog *log,
3709 struct xlog_recover_item *item,
3710 xfs_lsn_t lsn)
3711{
3712 int error;
3713 struct xfs_mount *mp = log->l_mp;
3714 struct xfs_bui_log_item *buip;
3715 struct xfs_bui_log_format *bui_formatp;
3716
3717 bui_formatp = item->ri_buf[0].i_addr;
3718
3719 if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
3720 return -EFSCORRUPTED;
3721 buip = xfs_bui_init(mp);
3722 error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format);
3723 if (error) {
3724 xfs_bui_item_free(buip);
3725 return error;
3726 }
3727 atomic_set(&buip->bui_next_extent, bui_formatp->bui_nextents);
3728
3729 spin_lock(&log->l_ailp->xa_lock);
3730
3731
3732
3733
3734
3735
3736 xfs_trans_ail_update(log->l_ailp, &buip->bui_item, lsn);
3737 xfs_bui_release(buip);
3738 return 0;
3739}
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749STATIC int
3750xlog_recover_bud_pass2(
3751 struct xlog *log,
3752 struct xlog_recover_item *item)
3753{
3754 struct xfs_bud_log_format *bud_formatp;
3755 struct xfs_bui_log_item *buip = NULL;
3756 struct xfs_log_item *lip;
3757 __uint64_t bui_id;
3758 struct xfs_ail_cursor cur;
3759 struct xfs_ail *ailp = log->l_ailp;
3760
3761 bud_formatp = item->ri_buf[0].i_addr;
3762 if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format))
3763 return -EFSCORRUPTED;
3764 bui_id = bud_formatp->bud_bui_id;
3765
3766
3767
3768
3769
3770 spin_lock(&ailp->xa_lock);
3771 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3772 while (lip != NULL) {
3773 if (lip->li_type == XFS_LI_BUI) {
3774 buip = (struct xfs_bui_log_item *)lip;
3775 if (buip->bui_format.bui_id == bui_id) {
3776
3777
3778
3779
3780 spin_unlock(&ailp->xa_lock);
3781 xfs_bui_release(buip);
3782 spin_lock(&ailp->xa_lock);
3783 break;
3784 }
3785 }
3786 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3787 }
3788
3789 xfs_trans_ail_cursor_done(&cur);
3790 spin_unlock(&ailp->xa_lock);
3791
3792 return 0;
3793}
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803STATIC int
3804xlog_recover_do_icreate_pass2(
3805 struct xlog *log,
3806 struct list_head *buffer_list,
3807 xlog_recover_item_t *item)
3808{
3809 struct xfs_mount *mp = log->l_mp;
3810 struct xfs_icreate_log *icl;
3811 xfs_agnumber_t agno;
3812 xfs_agblock_t agbno;
3813 unsigned int count;
3814 unsigned int isize;
3815 xfs_agblock_t length;
3816 int blks_per_cluster;
3817 int bb_per_cluster;
3818 int cancel_count;
3819 int nbufs;
3820 int i;
3821
3822 icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
3823 if (icl->icl_type != XFS_LI_ICREATE) {
3824 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
3825 return -EINVAL;
3826 }
3827
3828 if (icl->icl_size != 1) {
3829 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
3830 return -EINVAL;
3831 }
3832
3833 agno = be32_to_cpu(icl->icl_ag);
3834 if (agno >= mp->m_sb.sb_agcount) {
3835 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
3836 return -EINVAL;
3837 }
3838 agbno = be32_to_cpu(icl->icl_agbno);
3839 if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
3840 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
3841 return -EINVAL;
3842 }
3843 isize = be32_to_cpu(icl->icl_isize);
3844 if (isize != mp->m_sb.sb_inodesize) {
3845 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
3846 return -EINVAL;
3847 }
3848 count = be32_to_cpu(icl->icl_count);
3849 if (!count) {
3850 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
3851 return -EINVAL;
3852 }
3853 length = be32_to_cpu(icl->icl_length);
3854 if (!length || length >= mp->m_sb.sb_agblocks) {
3855 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
3856 return -EINVAL;
3857 }
3858
3859
3860
3861
3862
3863 if (length != mp->m_ialloc_blks &&
3864 length != mp->m_ialloc_min_blks) {
3865 xfs_warn(log->l_mp,
3866 "%s: unsupported chunk length", __FUNCTION__);
3867 return -EINVAL;
3868 }
3869
3870
3871 if ((count >> mp->m_sb.sb_inopblog) != length) {
3872 xfs_warn(log->l_mp,
3873 "%s: inconsistent inode count and chunk length",
3874 __FUNCTION__);
3875 return -EINVAL;
3876 }
3877
3878
3879
3880
3881
3882
3883
3884 blks_per_cluster = xfs_icluster_size_fsb(mp);
3885 bb_per_cluster = XFS_FSB_TO_BB(mp, blks_per_cluster);
3886 nbufs = length / blks_per_cluster;
3887 for (i = 0, cancel_count = 0; i < nbufs; i++) {
3888 xfs_daddr_t daddr;
3889
3890 daddr = XFS_AGB_TO_DADDR(mp, agno,
3891 agbno + i * blks_per_cluster);
3892 if (xlog_check_buffer_cancelled(log, daddr, bb_per_cluster, 0))
3893 cancel_count++;
3894 }
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906 ASSERT(!cancel_count || cancel_count == nbufs);
3907 if (cancel_count) {
3908 if (cancel_count != nbufs)
3909 xfs_warn(mp,
3910 "WARNING: partial inode chunk cancellation, skipped icreate.");
3911 trace_xfs_log_recover_icreate_cancel(log, icl);
3912 return 0;
3913 }
3914
3915 trace_xfs_log_recover_icreate_recover(log, icl);
3916 return xfs_ialloc_inode_init(mp, NULL, buffer_list, count, agno, agbno,
3917 length, be32_to_cpu(icl->icl_gen));
3918}
3919
3920STATIC void
3921xlog_recover_buffer_ra_pass2(
3922 struct xlog *log,
3923 struct xlog_recover_item *item)
3924{
3925 struct xfs_buf_log_format *buf_f = item->ri_buf[0].i_addr;
3926 struct xfs_mount *mp = log->l_mp;
3927
3928 if (xlog_peek_buffer_cancelled(log, buf_f->blf_blkno,
3929 buf_f->blf_len, buf_f->blf_flags)) {
3930 return;
3931 }
3932
3933 xfs_buf_readahead(mp->m_ddev_targp, buf_f->blf_blkno,
3934 buf_f->blf_len, NULL);
3935}
3936
3937STATIC void
3938xlog_recover_inode_ra_pass2(
3939 struct xlog *log,
3940 struct xlog_recover_item *item)
3941{
3942 struct xfs_inode_log_format ilf_buf;
3943 struct xfs_inode_log_format *ilfp;
3944 struct xfs_mount *mp = log->l_mp;
3945 int error;
3946
3947 if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
3948 ilfp = item->ri_buf[0].i_addr;
3949 } else {
3950 ilfp = &ilf_buf;
3951 memset(ilfp, 0, sizeof(*ilfp));
3952 error = xfs_inode_item_format_convert(&item->ri_buf[0], ilfp);
3953 if (error)
3954 return;
3955 }
3956
3957 if (xlog_peek_buffer_cancelled(log, ilfp->ilf_blkno, ilfp->ilf_len, 0))
3958 return;
3959
3960 xfs_buf_readahead(mp->m_ddev_targp, ilfp->ilf_blkno,
3961 ilfp->ilf_len, &xfs_inode_buf_ra_ops);
3962}
3963
3964STATIC void
3965xlog_recover_dquot_ra_pass2(
3966 struct xlog *log,
3967 struct xlog_recover_item *item)
3968{
3969 struct xfs_mount *mp = log->l_mp;
3970 struct xfs_disk_dquot *recddq;
3971 struct xfs_dq_logformat *dq_f;
3972 uint type;
3973 int len;
3974
3975
3976 if (mp->m_qflags == 0)
3977 return;
3978
3979 recddq = item->ri_buf[1].i_addr;
3980 if (recddq == NULL)
3981 return;
3982 if (item->ri_buf[1].i_len < sizeof(struct xfs_disk_dquot))
3983 return;
3984
3985 type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
3986 ASSERT(type);
3987 if (log->l_quotaoffs_flag & type)
3988 return;
3989
3990 dq_f = item->ri_buf[0].i_addr;
3991 ASSERT(dq_f);
3992 ASSERT(dq_f->qlf_len == 1);
3993
3994 len = XFS_FSB_TO_BB(mp, dq_f->qlf_len);
3995 if (xlog_peek_buffer_cancelled(log, dq_f->qlf_blkno, len, 0))
3996 return;
3997
3998 xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno, len,
3999 &xfs_dquot_buf_ra_ops);
4000}
4001
4002STATIC void
4003xlog_recover_ra_pass2(
4004 struct xlog *log,
4005 struct xlog_recover_item *item)
4006{
4007 switch (ITEM_TYPE(item)) {
4008 case XFS_LI_BUF:
4009 xlog_recover_buffer_ra_pass2(log, item);
4010 break;
4011 case XFS_LI_INODE:
4012 xlog_recover_inode_ra_pass2(log, item);
4013 break;
4014 case XFS_LI_DQUOT:
4015 xlog_recover_dquot_ra_pass2(log, item);
4016 break;
4017 case XFS_LI_EFI:
4018 case XFS_LI_EFD:
4019 case XFS_LI_QUOTAOFF:
4020 case XFS_LI_RUI:
4021 case XFS_LI_RUD:
4022 case XFS_LI_CUI:
4023 case XFS_LI_CUD:
4024 case XFS_LI_BUI:
4025 case XFS_LI_BUD:
4026 default:
4027 break;
4028 }
4029}
4030
4031STATIC int
4032xlog_recover_commit_pass1(
4033 struct xlog *log,
4034 struct xlog_recover *trans,
4035 struct xlog_recover_item *item)
4036{
4037 trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1);
4038
4039 switch (ITEM_TYPE(item)) {
4040 case XFS_LI_BUF:
4041 return xlog_recover_buffer_pass1(log, item);
4042 case XFS_LI_QUOTAOFF:
4043 return xlog_recover_quotaoff_pass1(log, item);
4044 case XFS_LI_INODE:
4045 case XFS_LI_EFI:
4046 case XFS_LI_EFD:
4047 case XFS_LI_DQUOT:
4048 case XFS_LI_ICREATE:
4049 case XFS_LI_RUI:
4050 case XFS_LI_RUD:
4051 case XFS_LI_CUI:
4052 case XFS_LI_CUD:
4053 case XFS_LI_BUI:
4054 case XFS_LI_BUD:
4055
4056 return 0;
4057 default:
4058 xfs_warn(log->l_mp, "%s: invalid item type (%d)",
4059 __func__, ITEM_TYPE(item));
4060 ASSERT(0);
4061 return -EIO;
4062 }
4063}
4064
4065STATIC int
4066xlog_recover_commit_pass2(
4067 struct xlog *log,
4068 struct xlog_recover *trans,
4069 struct list_head *buffer_list,
4070 struct xlog_recover_item *item)
4071{
4072 trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2);
4073
4074 switch (ITEM_TYPE(item)) {
4075 case XFS_LI_BUF:
4076 return xlog_recover_buffer_pass2(log, buffer_list, item,
4077 trans->r_lsn);
4078 case XFS_LI_INODE:
4079 return xlog_recover_inode_pass2(log, buffer_list, item,
4080 trans->r_lsn);
4081 case XFS_LI_EFI:
4082 return xlog_recover_efi_pass2(log, item, trans->r_lsn);
4083 case XFS_LI_EFD:
4084 return xlog_recover_efd_pass2(log, item);
4085 case XFS_LI_RUI:
4086 return xlog_recover_rui_pass2(log, item, trans->r_lsn);
4087 case XFS_LI_RUD:
4088 return xlog_recover_rud_pass2(log, item);
4089 case XFS_LI_CUI:
4090 return xlog_recover_cui_pass2(log, item, trans->r_lsn);
4091 case XFS_LI_CUD:
4092 return xlog_recover_cud_pass2(log, item);
4093 case XFS_LI_BUI:
4094 return xlog_recover_bui_pass2(log, item, trans->r_lsn);
4095 case XFS_LI_BUD:
4096 return xlog_recover_bud_pass2(log, item);
4097 case XFS_LI_DQUOT:
4098 return xlog_recover_dquot_pass2(log, buffer_list, item,
4099 trans->r_lsn);
4100 case XFS_LI_ICREATE:
4101 return xlog_recover_do_icreate_pass2(log, buffer_list, item);
4102 case XFS_LI_QUOTAOFF:
4103
4104 return 0;
4105 default:
4106 xfs_warn(log->l_mp, "%s: invalid item type (%d)",
4107 __func__, ITEM_TYPE(item));
4108 ASSERT(0);
4109 return -EIO;
4110 }
4111}
4112
4113STATIC int
4114xlog_recover_items_pass2(
4115 struct xlog *log,
4116 struct xlog_recover *trans,
4117 struct list_head *buffer_list,
4118 struct list_head *item_list)
4119{
4120 struct xlog_recover_item *item;
4121 int error = 0;
4122
4123 list_for_each_entry(item, item_list, ri_list) {
4124 error = xlog_recover_commit_pass2(log, trans,
4125 buffer_list, item);
4126 if (error)
4127 return error;
4128 }
4129
4130 return error;
4131}
4132
4133
4134
4135
4136
4137
4138
4139STATIC int
4140xlog_recover_commit_trans(
4141 struct xlog *log,
4142 struct xlog_recover *trans,
4143 int pass,
4144 struct list_head *buffer_list)
4145{
4146 int error = 0;
4147 int items_queued = 0;
4148 struct xlog_recover_item *item;
4149 struct xlog_recover_item *next;
4150 LIST_HEAD (ra_list);
4151 LIST_HEAD (done_list);
4152
4153 #define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
4154
4155 hlist_del(&trans->r_list);
4156
4157 error = xlog_recover_reorder_trans(log, trans, pass);
4158 if (error)
4159 return error;
4160
4161 list_for_each_entry_safe(item, next, &trans->r_itemq, ri_list) {
4162 switch (pass) {
4163 case XLOG_RECOVER_PASS1:
4164 error = xlog_recover_commit_pass1(log, trans, item);
4165 break;
4166 case XLOG_RECOVER_PASS2:
4167 xlog_recover_ra_pass2(log, item);
4168 list_move_tail(&item->ri_list, &ra_list);
4169 items_queued++;
4170 if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) {
4171 error = xlog_recover_items_pass2(log, trans,
4172 buffer_list, &ra_list);
4173 list_splice_tail_init(&ra_list, &done_list);
4174 items_queued = 0;
4175 }
4176
4177 break;
4178 default:
4179 ASSERT(0);
4180 }
4181
4182 if (error)
4183 goto out;
4184 }
4185
4186out:
4187 if (!list_empty(&ra_list)) {
4188 if (!error)
4189 error = xlog_recover_items_pass2(log, trans,
4190 buffer_list, &ra_list);
4191 list_splice_tail_init(&ra_list, &done_list);
4192 }
4193
4194 if (!list_empty(&done_list))
4195 list_splice_init(&done_list, &trans->r_itemq);
4196
4197 return error;
4198}
4199
4200STATIC void
4201xlog_recover_add_item(
4202 struct list_head *head)
4203{
4204 xlog_recover_item_t *item;
4205
4206 item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP);
4207 INIT_LIST_HEAD(&item->ri_list);
4208 list_add_tail(&item->ri_list, head);
4209}
4210
4211STATIC int
4212xlog_recover_add_to_cont_trans(
4213 struct xlog *log,
4214 struct xlog_recover *trans,
4215 char *dp,
4216 int len)
4217{
4218 xlog_recover_item_t *item;
4219 char *ptr, *old_ptr;
4220 int old_len;
4221
4222
4223
4224
4225
4226 if (list_empty(&trans->r_itemq)) {
4227 ASSERT(len <= sizeof(struct xfs_trans_header));
4228 if (len > sizeof(struct xfs_trans_header)) {
4229 xfs_warn(log->l_mp, "%s: bad header length", __func__);
4230 return -EIO;
4231 }
4232
4233 xlog_recover_add_item(&trans->r_itemq);
4234 ptr = (char *)&trans->r_theader +
4235 sizeof(struct xfs_trans_header) - len;
4236 memcpy(ptr, dp, len);
4237 return 0;
4238 }
4239
4240
4241 item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list);
4242
4243 old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
4244 old_len = item->ri_buf[item->ri_cnt-1].i_len;
4245
4246 ptr = kmem_realloc(old_ptr, len + old_len, KM_SLEEP);
4247 memcpy(&ptr[old_len], dp, len);
4248 item->ri_buf[item->ri_cnt-1].i_len += len;
4249 item->ri_buf[item->ri_cnt-1].i_addr = ptr;
4250 trace_xfs_log_recover_item_add_cont(log, trans, item, 0);
4251 return 0;
4252}
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267STATIC int
4268xlog_recover_add_to_trans(
4269 struct xlog *log,
4270 struct xlog_recover *trans,
4271 char *dp,
4272 int len)
4273{
4274 xfs_inode_log_format_t *in_f;
4275 xlog_recover_item_t *item;
4276 char *ptr;
4277
4278 if (!len)
4279 return 0;
4280 if (list_empty(&trans->r_itemq)) {
4281
4282 if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) {
4283 xfs_warn(log->l_mp, "%s: bad header magic number",
4284 __func__);
4285 ASSERT(0);
4286 return -EIO;
4287 }
4288
4289 if (len > sizeof(struct xfs_trans_header)) {
4290 xfs_warn(log->l_mp, "%s: bad header length", __func__);
4291 ASSERT(0);
4292 return -EIO;
4293 }
4294
4295
4296
4297
4298
4299
4300 if (len == sizeof(struct xfs_trans_header))
4301 xlog_recover_add_item(&trans->r_itemq);
4302 memcpy(&trans->r_theader, dp, len);
4303 return 0;
4304 }
4305
4306 ptr = kmem_alloc(len, KM_SLEEP);
4307 memcpy(ptr, dp, len);
4308 in_f = (xfs_inode_log_format_t *)ptr;
4309
4310
4311 item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list);
4312 if (item->ri_total != 0 &&
4313 item->ri_total == item->ri_cnt) {
4314
4315 xlog_recover_add_item(&trans->r_itemq);
4316 item = list_entry(trans->r_itemq.prev,
4317 xlog_recover_item_t, ri_list);
4318 }
4319
4320 if (item->ri_total == 0) {
4321 if (in_f->ilf_size == 0 ||
4322 in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) {
4323 xfs_warn(log->l_mp,
4324 "bad number of regions (%d) in inode log format",
4325 in_f->ilf_size);
4326 ASSERT(0);
4327 kmem_free(ptr);
4328 return -EIO;
4329 }
4330
4331 item->ri_total = in_f->ilf_size;
4332 item->ri_buf =
4333 kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t),
4334 KM_SLEEP);
4335 }
4336 ASSERT(item->ri_total > item->ri_cnt);
4337
4338 item->ri_buf[item->ri_cnt].i_addr = ptr;
4339 item->ri_buf[item->ri_cnt].i_len = len;
4340 item->ri_cnt++;
4341 trace_xfs_log_recover_item_add(log, trans, item, 0);
4342 return 0;
4343}
4344
4345
4346
4347
4348
4349
4350STATIC void
4351xlog_recover_free_trans(
4352 struct xlog_recover *trans)
4353{
4354 xlog_recover_item_t *item, *n;
4355 int i;
4356
4357 list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) {
4358
4359 list_del(&item->ri_list);
4360 for (i = 0; i < item->ri_cnt; i++)
4361 kmem_free(item->ri_buf[i].i_addr);
4362
4363 kmem_free(item->ri_buf);
4364 kmem_free(item);
4365 }
4366
4367 kmem_free(trans);
4368}
4369
4370
4371
4372
4373STATIC int
4374xlog_recovery_process_trans(
4375 struct xlog *log,
4376 struct xlog_recover *trans,
4377 char *dp,
4378 unsigned int len,
4379 unsigned int flags,
4380 int pass,
4381 struct list_head *buffer_list)
4382{
4383 int error = 0;
4384 bool freeit = false;
4385
4386
4387 flags &= ~XLOG_END_TRANS;
4388 if (flags & XLOG_WAS_CONT_TRANS)
4389 flags &= ~XLOG_CONTINUE_TRANS;
4390
4391
4392
4393
4394
4395 switch (flags) {
4396
4397 case 0:
4398 case XLOG_CONTINUE_TRANS:
4399 error = xlog_recover_add_to_trans(log, trans, dp, len);
4400 break;
4401 case XLOG_WAS_CONT_TRANS:
4402 error = xlog_recover_add_to_cont_trans(log, trans, dp, len);
4403 break;
4404 case XLOG_COMMIT_TRANS:
4405 error = xlog_recover_commit_trans(log, trans, pass,
4406 buffer_list);
4407
4408 freeit = true;
4409 break;
4410
4411
4412 case XLOG_UNMOUNT_TRANS:
4413
4414 xfs_warn(log->l_mp, "%s: Unmount LR", __func__);
4415 freeit = true;
4416 break;
4417 case XLOG_START_TRANS:
4418 default:
4419 xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags);
4420 ASSERT(0);
4421 error = -EIO;
4422 break;
4423 }
4424 if (error || freeit)
4425 xlog_recover_free_trans(trans);
4426 return error;
4427}
4428
4429
4430
4431
4432
4433
4434
4435
4436STATIC struct xlog_recover *
4437xlog_recover_ophdr_to_trans(
4438 struct hlist_head rhash[],
4439 struct xlog_rec_header *rhead,
4440 struct xlog_op_header *ohead)
4441{
4442 struct xlog_recover *trans;
4443 xlog_tid_t tid;
4444 struct hlist_head *rhp;
4445
4446 tid = be32_to_cpu(ohead->oh_tid);
4447 rhp = &rhash[XLOG_RHASH(tid)];
4448 hlist_for_each_entry(trans, rhp, r_list) {
4449 if (trans->r_log_tid == tid)
4450 return trans;
4451 }
4452
4453
4454
4455
4456
4457 if (!(ohead->oh_flags & XLOG_START_TRANS))
4458 return NULL;
4459
4460 ASSERT(be32_to_cpu(ohead->oh_len) == 0);
4461
4462
4463
4464
4465
4466 trans = kmem_zalloc(sizeof(struct xlog_recover), KM_SLEEP);
4467 trans->r_log_tid = tid;
4468 trans->r_lsn = be64_to_cpu(rhead->h_lsn);
4469 INIT_LIST_HEAD(&trans->r_itemq);
4470 INIT_HLIST_NODE(&trans->r_list);
4471 hlist_add_head(&trans->r_list, rhp);
4472
4473
4474
4475
4476
4477 return NULL;
4478}
4479
4480STATIC int
4481xlog_recover_process_ophdr(
4482 struct xlog *log,
4483 struct hlist_head rhash[],
4484 struct xlog_rec_header *rhead,
4485 struct xlog_op_header *ohead,
4486 char *dp,
4487 char *end,
4488 int pass,
4489 struct list_head *buffer_list)
4490{
4491 struct xlog_recover *trans;
4492 unsigned int len;
4493 int error;
4494
4495
4496 if (ohead->oh_clientid != XFS_TRANSACTION &&
4497 ohead->oh_clientid != XFS_LOG) {
4498 xfs_warn(log->l_mp, "%s: bad clientid 0x%x",
4499 __func__, ohead->oh_clientid);
4500 ASSERT(0);
4501 return -EIO;
4502 }
4503
4504
4505
4506
4507 len = be32_to_cpu(ohead->oh_len);
4508 if (dp + len > end) {
4509 xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len);
4510 WARN_ON(1);
4511 return -EIO;
4512 }
4513
4514 trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead);
4515 if (!trans) {
4516
4517 return 0;
4518 }
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543 if (log->l_recovery_lsn != trans->r_lsn &&
4544 ohead->oh_flags & XLOG_COMMIT_TRANS) {
4545 error = xfs_buf_delwri_submit(buffer_list);
4546 if (error)
4547 return error;
4548 log->l_recovery_lsn = trans->r_lsn;
4549 }
4550
4551 return xlog_recovery_process_trans(log, trans, dp, len,
4552 ohead->oh_flags, pass, buffer_list);
4553}
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564STATIC int
4565xlog_recover_process_data(
4566 struct xlog *log,
4567 struct hlist_head rhash[],
4568 struct xlog_rec_header *rhead,
4569 char *dp,
4570 int pass,
4571 struct list_head *buffer_list)
4572{
4573 struct xlog_op_header *ohead;
4574 char *end;
4575 int num_logops;
4576 int error;
4577
4578 end = dp + be32_to_cpu(rhead->h_len);
4579 num_logops = be32_to_cpu(rhead->h_num_logops);
4580
4581
4582 if (xlog_header_check_recover(log->l_mp, rhead))
4583 return -EIO;
4584
4585 trace_xfs_log_recover_record(log, rhead, pass);
4586 while ((dp < end) && num_logops) {
4587
4588 ohead = (struct xlog_op_header *)dp;
4589 dp += sizeof(*ohead);
4590 ASSERT(dp <= end);
4591
4592
4593 error = xlog_recover_process_ophdr(log, rhash, rhead, ohead,
4594 dp, end, pass, buffer_list);
4595 if (error)
4596 return error;
4597
4598 dp += be32_to_cpu(ohead->oh_len);
4599 num_logops--;
4600 }
4601 return 0;
4602}
4603
4604
4605STATIC int
4606xlog_recover_process_efi(
4607 struct xfs_mount *mp,
4608 struct xfs_ail *ailp,
4609 struct xfs_log_item *lip)
4610{
4611 struct xfs_efi_log_item *efip;
4612 int error;
4613
4614
4615
4616
4617 efip = container_of(lip, struct xfs_efi_log_item, efi_item);
4618 if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
4619 return 0;
4620
4621 spin_unlock(&ailp->xa_lock);
4622 error = xfs_efi_recover(mp, efip);
4623 spin_lock(&ailp->xa_lock);
4624
4625 return error;
4626}
4627
4628
4629STATIC void
4630xlog_recover_cancel_efi(
4631 struct xfs_mount *mp,
4632 struct xfs_ail *ailp,
4633 struct xfs_log_item *lip)
4634{
4635 struct xfs_efi_log_item *efip;
4636
4637 efip = container_of(lip, struct xfs_efi_log_item, efi_item);
4638
4639 spin_unlock(&ailp->xa_lock);
4640 xfs_efi_release(efip);
4641 spin_lock(&ailp->xa_lock);
4642}
4643
4644
4645STATIC int
4646xlog_recover_process_rui(
4647 struct xfs_mount *mp,
4648 struct xfs_ail *ailp,
4649 struct xfs_log_item *lip)
4650{
4651 struct xfs_rui_log_item *ruip;
4652 int error;
4653
4654
4655
4656
4657 ruip = container_of(lip, struct xfs_rui_log_item, rui_item);
4658 if (test_bit(XFS_RUI_RECOVERED, &ruip->rui_flags))
4659 return 0;
4660
4661 spin_unlock(&ailp->xa_lock);
4662 error = xfs_rui_recover(mp, ruip);
4663 spin_lock(&ailp->xa_lock);
4664
4665 return error;
4666}
4667
4668
4669STATIC void
4670xlog_recover_cancel_rui(
4671 struct xfs_mount *mp,
4672 struct xfs_ail *ailp,
4673 struct xfs_log_item *lip)
4674{
4675 struct xfs_rui_log_item *ruip;
4676
4677 ruip = container_of(lip, struct xfs_rui_log_item, rui_item);
4678
4679 spin_unlock(&ailp->xa_lock);
4680 xfs_rui_release(ruip);
4681 spin_lock(&ailp->xa_lock);
4682}
4683
4684
4685STATIC int
4686xlog_recover_process_cui(
4687 struct xfs_mount *mp,
4688 struct xfs_ail *ailp,
4689 struct xfs_log_item *lip)
4690{
4691 struct xfs_cui_log_item *cuip;
4692 int error;
4693
4694
4695
4696
4697 cuip = container_of(lip, struct xfs_cui_log_item, cui_item);
4698 if (test_bit(XFS_CUI_RECOVERED, &cuip->cui_flags))
4699 return 0;
4700
4701 spin_unlock(&ailp->xa_lock);
4702 error = xfs_cui_recover(mp, cuip);
4703 spin_lock(&ailp->xa_lock);
4704
4705 return error;
4706}
4707
4708
4709STATIC void
4710xlog_recover_cancel_cui(
4711 struct xfs_mount *mp,
4712 struct xfs_ail *ailp,
4713 struct xfs_log_item *lip)
4714{
4715 struct xfs_cui_log_item *cuip;
4716
4717 cuip = container_of(lip, struct xfs_cui_log_item, cui_item);
4718
4719 spin_unlock(&ailp->xa_lock);
4720 xfs_cui_release(cuip);
4721 spin_lock(&ailp->xa_lock);
4722}
4723
4724
4725STATIC int
4726xlog_recover_process_bui(
4727 struct xfs_mount *mp,
4728 struct xfs_ail *ailp,
4729 struct xfs_log_item *lip)
4730{
4731 struct xfs_bui_log_item *buip;
4732 int error;
4733
4734
4735
4736
4737 buip = container_of(lip, struct xfs_bui_log_item, bui_item);
4738 if (test_bit(XFS_BUI_RECOVERED, &buip->bui_flags))
4739 return 0;
4740
4741 spin_unlock(&ailp->xa_lock);
4742 error = xfs_bui_recover(mp, buip);
4743 spin_lock(&ailp->xa_lock);
4744
4745 return error;
4746}
4747
4748
4749STATIC void
4750xlog_recover_cancel_bui(
4751 struct xfs_mount *mp,
4752 struct xfs_ail *ailp,
4753 struct xfs_log_item *lip)
4754{
4755 struct xfs_bui_log_item *buip;
4756
4757 buip = container_of(lip, struct xfs_bui_log_item, bui_item);
4758
4759 spin_unlock(&ailp->xa_lock);
4760 xfs_bui_release(buip);
4761 spin_lock(&ailp->xa_lock);
4762}
4763
4764
4765static inline bool xlog_item_is_intent(struct xfs_log_item *lip)
4766{
4767 switch (lip->li_type) {
4768 case XFS_LI_EFI:
4769 case XFS_LI_RUI:
4770 case XFS_LI_CUI:
4771 case XFS_LI_BUI:
4772 return true;
4773 default:
4774 return false;
4775 }
4776}
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794STATIC int
4795xlog_recover_process_intents(
4796 struct xlog *log)
4797{
4798 struct xfs_log_item *lip;
4799 int error = 0;
4800 struct xfs_ail_cursor cur;
4801 struct xfs_ail *ailp;
4802 xfs_lsn_t last_lsn;
4803
4804 ailp = log->l_ailp;
4805 spin_lock(&ailp->xa_lock);
4806 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
4807 last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block);
4808 while (lip != NULL) {
4809
4810
4811
4812
4813 if (!xlog_item_is_intent(lip)) {
4814#ifdef DEBUG
4815 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
4816 ASSERT(!xlog_item_is_intent(lip));
4817#endif
4818 break;
4819 }
4820
4821
4822
4823
4824
4825
4826 ASSERT(XFS_LSN_CMP(last_lsn, lip->li_lsn) >= 0);
4827
4828 switch (lip->li_type) {
4829 case XFS_LI_EFI:
4830 error = xlog_recover_process_efi(log->l_mp, ailp, lip);
4831 break;
4832 case XFS_LI_RUI:
4833 error = xlog_recover_process_rui(log->l_mp, ailp, lip);
4834 break;
4835 case XFS_LI_CUI:
4836 error = xlog_recover_process_cui(log->l_mp, ailp, lip);
4837 break;
4838 case XFS_LI_BUI:
4839 error = xlog_recover_process_bui(log->l_mp, ailp, lip);
4840 break;
4841 }
4842 if (error)
4843 goto out;
4844 lip = xfs_trans_ail_cursor_next(ailp, &cur);
4845 }
4846out:
4847 xfs_trans_ail_cursor_done(&cur);
4848 spin_unlock(&ailp->xa_lock);
4849 return error;
4850}
4851
4852
4853
4854
4855
4856STATIC int
4857xlog_recover_cancel_intents(
4858 struct xlog *log)
4859{
4860 struct xfs_log_item *lip;
4861 int error = 0;
4862 struct xfs_ail_cursor cur;
4863 struct xfs_ail *ailp;
4864
4865 ailp = log->l_ailp;
4866 spin_lock(&ailp->xa_lock);
4867 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
4868 while (lip != NULL) {
4869
4870
4871
4872
4873 if (!xlog_item_is_intent(lip)) {
4874#ifdef DEBUG
4875 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
4876 ASSERT(!xlog_item_is_intent(lip));
4877#endif
4878 break;
4879 }
4880
4881 switch (lip->li_type) {
4882 case XFS_LI_EFI:
4883 xlog_recover_cancel_efi(log->l_mp, ailp, lip);
4884 break;
4885 case XFS_LI_RUI:
4886 xlog_recover_cancel_rui(log->l_mp, ailp, lip);
4887 break;
4888 case XFS_LI_CUI:
4889 xlog_recover_cancel_cui(log->l_mp, ailp, lip);
4890 break;
4891 case XFS_LI_BUI:
4892 xlog_recover_cancel_bui(log->l_mp, ailp, lip);
4893 break;
4894 }
4895
4896 lip = xfs_trans_ail_cursor_next(ailp, &cur);
4897 }
4898
4899 xfs_trans_ail_cursor_done(&cur);
4900 spin_unlock(&ailp->xa_lock);
4901 return error;
4902}
4903
4904
4905
4906
4907
4908STATIC void
4909xlog_recover_clear_agi_bucket(
4910 xfs_mount_t *mp,
4911 xfs_agnumber_t agno,
4912 int bucket)
4913{
4914 xfs_trans_t *tp;
4915 xfs_agi_t *agi;
4916 xfs_buf_t *agibp;
4917 int offset;
4918 int error;
4919
4920 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_clearagi, 0, 0, 0, &tp);
4921 if (error)
4922 goto out_error;
4923
4924 error = xfs_read_agi(mp, tp, agno, &agibp);
4925 if (error)
4926 goto out_abort;
4927
4928 agi = XFS_BUF_TO_AGI(agibp);
4929 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
4930 offset = offsetof(xfs_agi_t, agi_unlinked) +
4931 (sizeof(xfs_agino_t) * bucket);
4932 xfs_trans_log_buf(tp, agibp, offset,
4933 (offset + sizeof(xfs_agino_t) - 1));
4934
4935 error = xfs_trans_commit(tp);
4936 if (error)
4937 goto out_error;
4938 return;
4939
4940out_abort:
4941 xfs_trans_cancel(tp);
4942out_error:
4943 xfs_warn(mp, "%s: failed to clear agi %d. Continuing.", __func__, agno);
4944 return;
4945}
4946
4947STATIC xfs_agino_t
4948xlog_recover_process_one_iunlink(
4949 struct xfs_mount *mp,
4950 xfs_agnumber_t agno,
4951 xfs_agino_t agino,
4952 int bucket)
4953{
4954 struct xfs_buf *ibp;
4955 struct xfs_dinode *dip;
4956 struct xfs_inode *ip;
4957 xfs_ino_t ino;
4958 int error;
4959
4960 ino = XFS_AGINO_TO_INO(mp, agno, agino);
4961 error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
4962 if (error)
4963 goto fail;
4964
4965
4966
4967
4968 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &ibp, 0, 0);
4969 if (error)
4970 goto fail_iput;
4971
4972 xfs_iflags_clear(ip, XFS_IRECOVERY);
4973 ASSERT(VFS_I(ip)->i_nlink == 0);
4974 ASSERT(VFS_I(ip)->i_mode != 0);
4975
4976
4977 agino = be32_to_cpu(dip->di_next_unlinked);
4978 xfs_buf_relse(ibp);
4979
4980
4981
4982
4983
4984 ip->i_d.di_dmevmask = 0;
4985
4986 IRELE(ip);
4987 return agino;
4988
4989 fail_iput:
4990 IRELE(ip);
4991 fail:
4992
4993
4994
4995
4996
4997
4998
4999
5000 xlog_recover_clear_agi_bucket(mp, agno, bucket);
5001 return NULLAGINO;
5002}
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016STATIC void
5017xlog_recover_process_iunlinks(
5018 struct xlog *log)
5019{
5020 xfs_mount_t *mp;
5021 xfs_agnumber_t agno;
5022 xfs_agi_t *agi;
5023 xfs_buf_t *agibp;
5024 xfs_agino_t agino;
5025 int bucket;
5026 int error;
5027 uint mp_dmevmask;
5028
5029 mp = log->l_mp;
5030
5031
5032
5033
5034 mp_dmevmask = mp->m_dmevmask;
5035 mp->m_dmevmask = 0;
5036
5037 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
5038
5039
5040
5041 error = xfs_read_agi(mp, NULL, agno, &agibp);
5042 if (error) {
5043
5044
5045
5046
5047
5048
5049 continue;
5050 }
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060 agi = XFS_BUF_TO_AGI(agibp);
5061 xfs_buf_unlock(agibp);
5062
5063 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
5064 agino = be32_to_cpu(agi->agi_unlinked[bucket]);
5065 while (agino != NULLAGINO) {
5066 agino = xlog_recover_process_one_iunlink(mp,
5067 agno, agino, bucket);
5068 }
5069 }
5070 xfs_buf_rele(agibp);
5071 }
5072
5073 mp->m_dmevmask = mp_dmevmask;
5074}
5075
5076STATIC int
5077xlog_unpack_data(
5078 struct xlog_rec_header *rhead,
5079 char *dp,
5080 struct xlog *log)
5081{
5082 int i, j, k;
5083
5084 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
5085 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
5086 *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
5087 dp += BBSIZE;
5088 }
5089
5090 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
5091 xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
5092 for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
5093 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
5094 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
5095 *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
5096 dp += BBSIZE;
5097 }
5098 }
5099
5100 return 0;
5101}
5102
5103
5104
5105
5106STATIC int
5107xlog_recover_process(
5108 struct xlog *log,
5109 struct hlist_head rhash[],
5110 struct xlog_rec_header *rhead,
5111 char *dp,
5112 int pass,
5113 struct list_head *buffer_list)
5114{
5115 int error;
5116 __le32 old_crc = rhead->h_crc;
5117 __le32 crc;
5118
5119
5120 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
5121
5122
5123
5124
5125
5126
5127
5128
5129 if (pass == XLOG_RECOVER_CRCPASS) {
5130 if (old_crc && crc != old_crc)
5131 return -EFSBADCRC;
5132 return 0;
5133 }
5134
5135
5136
5137
5138
5139
5140
5141 if (crc != old_crc) {
5142 if (old_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
5143 xfs_alert(log->l_mp,
5144 "log record CRC mismatch: found 0x%x, expected 0x%x.",
5145 le32_to_cpu(old_crc),
5146 le32_to_cpu(crc));
5147 xfs_hex_dump(dp, 32);
5148 }
5149
5150
5151
5152
5153
5154 if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
5155 return -EFSCORRUPTED;
5156 }
5157
5158 error = xlog_unpack_data(rhead, dp, log);
5159 if (error)
5160 return error;
5161
5162 return xlog_recover_process_data(log, rhash, rhead, dp, pass,
5163 buffer_list);
5164}
5165
5166STATIC int
5167xlog_valid_rec_header(
5168 struct xlog *log,
5169 struct xlog_rec_header *rhead,
5170 xfs_daddr_t blkno)
5171{
5172 int hlen;
5173
5174 if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) {
5175 XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
5176 XFS_ERRLEVEL_LOW, log->l_mp);
5177 return -EFSCORRUPTED;
5178 }
5179 if (unlikely(
5180 (!rhead->h_version ||
5181 (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
5182 xfs_warn(log->l_mp, "%s: unrecognised log version (%d).",
5183 __func__, be32_to_cpu(rhead->h_version));
5184 return -EIO;
5185 }
5186
5187
5188 hlen = be32_to_cpu(rhead->h_len);
5189 if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
5190 XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
5191 XFS_ERRLEVEL_LOW, log->l_mp);
5192 return -EFSCORRUPTED;
5193 }
5194 if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) {
5195 XFS_ERROR_REPORT("xlog_valid_rec_header(3)",
5196 XFS_ERRLEVEL_LOW, log->l_mp);
5197 return -EFSCORRUPTED;
5198 }
5199 return 0;
5200}
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210STATIC int
5211xlog_do_recovery_pass(
5212 struct xlog *log,
5213 xfs_daddr_t head_blk,
5214 xfs_daddr_t tail_blk,
5215 int pass,
5216 xfs_daddr_t *first_bad)
5217{
5218 xlog_rec_header_t *rhead;
5219 xfs_daddr_t blk_no;
5220 xfs_daddr_t rhead_blk;
5221 char *offset;
5222 xfs_buf_t *hbp, *dbp;
5223 int error = 0, h_size, h_len;
5224 int error2 = 0;
5225 int bblks, split_bblks;
5226 int hblks, split_hblks, wrapped_hblks;
5227 struct hlist_head rhash[XLOG_RHASH_SIZE];
5228 LIST_HEAD (buffer_list);
5229
5230 ASSERT(head_blk != tail_blk);
5231 rhead_blk = 0;
5232
5233
5234
5235
5236
5237 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
5238
5239
5240
5241
5242
5243 hbp = xlog_get_bp(log, 1);
5244 if (!hbp)
5245 return -ENOMEM;
5246
5247 error = xlog_bread(log, tail_blk, 1, hbp, &offset);
5248 if (error)
5249 goto bread_err1;
5250
5251 rhead = (xlog_rec_header_t *)offset;
5252 error = xlog_valid_rec_header(log, rhead, tail_blk);
5253 if (error)
5254 goto bread_err1;
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267 h_size = be32_to_cpu(rhead->h_size);
5268 h_len = be32_to_cpu(rhead->h_len);
5269 if (h_len > h_size) {
5270 if (h_len <= log->l_mp->m_logbsize &&
5271 be32_to_cpu(rhead->h_num_logops) == 1) {
5272 xfs_warn(log->l_mp,
5273 "invalid iclog size (%d bytes), using lsunit (%d bytes)",
5274 h_size, log->l_mp->m_logbsize);
5275 h_size = log->l_mp->m_logbsize;
5276 } else
5277 return -EFSCORRUPTED;
5278 }
5279
5280 if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
5281 (h_size > XLOG_HEADER_CYCLE_SIZE)) {
5282 hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
5283 if (h_size % XLOG_HEADER_CYCLE_SIZE)
5284 hblks++;
5285 xlog_put_bp(hbp);
5286 hbp = xlog_get_bp(log, hblks);
5287 } else {
5288 hblks = 1;
5289 }
5290 } else {
5291 ASSERT(log->l_sectBBsize == 1);
5292 hblks = 1;
5293 hbp = xlog_get_bp(log, 1);
5294 h_size = XLOG_BIG_RECORD_BSIZE;
5295 }
5296
5297 if (!hbp)
5298 return -ENOMEM;
5299 dbp = xlog_get_bp(log, BTOBB(h_size));
5300 if (!dbp) {
5301 xlog_put_bp(hbp);
5302 return -ENOMEM;
5303 }
5304
5305 memset(rhash, 0, sizeof(rhash));
5306 blk_no = rhead_blk = tail_blk;
5307 if (tail_blk > head_blk) {
5308
5309
5310
5311
5312
5313 while (blk_no < log->l_logBBsize) {
5314
5315
5316
5317 offset = hbp->b_addr;
5318 split_hblks = 0;
5319 wrapped_hblks = 0;
5320 if (blk_no + hblks <= log->l_logBBsize) {
5321
5322 error = xlog_bread(log, blk_no, hblks, hbp,
5323 &offset);
5324 if (error)
5325 goto bread_err2;
5326 } else {
5327
5328 if (blk_no != log->l_logBBsize) {
5329
5330 ASSERT(blk_no <= INT_MAX);
5331 split_hblks = log->l_logBBsize - (int)blk_no;
5332 ASSERT(split_hblks > 0);
5333 error = xlog_bread(log, blk_no,
5334 split_hblks, hbp,
5335 &offset);
5336 if (error)
5337 goto bread_err2;
5338 }
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352 wrapped_hblks = hblks - split_hblks;
5353 error = xlog_bread_offset(log, 0,
5354 wrapped_hblks, hbp,
5355 offset + BBTOB(split_hblks));
5356 if (error)
5357 goto bread_err2;
5358 }
5359 rhead = (xlog_rec_header_t *)offset;
5360 error = xlog_valid_rec_header(log, rhead,
5361 split_hblks ? blk_no : 0);
5362 if (error)
5363 goto bread_err2;
5364
5365 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
5366 blk_no += hblks;
5367
5368
5369 if (blk_no + bblks <= log->l_logBBsize) {
5370 error = xlog_bread(log, blk_no, bblks, dbp,
5371 &offset);
5372 if (error)
5373 goto bread_err2;
5374 } else {
5375
5376
5377 offset = dbp->b_addr;
5378 split_bblks = 0;
5379 if (blk_no != log->l_logBBsize) {
5380
5381
5382 ASSERT(!wrapped_hblks);
5383 ASSERT(blk_no <= INT_MAX);
5384 split_bblks =
5385 log->l_logBBsize - (int)blk_no;
5386 ASSERT(split_bblks > 0);
5387 error = xlog_bread(log, blk_no,
5388 split_bblks, dbp,
5389 &offset);
5390 if (error)
5391 goto bread_err2;
5392 }
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406 error = xlog_bread_offset(log, 0,
5407 bblks - split_bblks, dbp,
5408 offset + BBTOB(split_bblks));
5409 if (error)
5410 goto bread_err2;
5411 }
5412
5413 error = xlog_recover_process(log, rhash, rhead, offset,
5414 pass, &buffer_list);
5415 if (error)
5416 goto bread_err2;
5417
5418 blk_no += bblks;
5419 rhead_blk = blk_no;
5420 }
5421
5422 ASSERT(blk_no >= log->l_logBBsize);
5423 blk_no -= log->l_logBBsize;
5424 rhead_blk = blk_no;
5425 }
5426
5427
5428 while (blk_no < head_blk) {
5429 error = xlog_bread(log, blk_no, hblks, hbp, &offset);
5430 if (error)
5431 goto bread_err2;
5432
5433 rhead = (xlog_rec_header_t *)offset;
5434 error = xlog_valid_rec_header(log, rhead, blk_no);
5435 if (error)
5436 goto bread_err2;
5437
5438
5439 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
5440 error = xlog_bread(log, blk_no+hblks, bblks, dbp,
5441 &offset);
5442 if (error)
5443 goto bread_err2;
5444
5445 error = xlog_recover_process(log, rhash, rhead, offset, pass,
5446 &buffer_list);
5447 if (error)
5448 goto bread_err2;
5449
5450 blk_no += bblks + hblks;
5451 rhead_blk = blk_no;
5452 }
5453
5454 bread_err2:
5455 xlog_put_bp(dbp);
5456 bread_err1:
5457 xlog_put_bp(hbp);
5458
5459
5460
5461
5462
5463 if (!list_empty(&buffer_list))
5464 error2 = xfs_buf_delwri_submit(&buffer_list);
5465
5466 if (error && first_bad)
5467 *first_bad = rhead_blk;
5468
5469 return error ? error : error2;
5470}
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485STATIC int
5486xlog_do_log_recovery(
5487 struct xlog *log,
5488 xfs_daddr_t head_blk,
5489 xfs_daddr_t tail_blk)
5490{
5491 int error, i;
5492
5493 ASSERT(head_blk != tail_blk);
5494
5495
5496
5497
5498
5499 log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
5500 sizeof(struct list_head),
5501 KM_SLEEP);
5502 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
5503 INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
5504
5505 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
5506 XLOG_RECOVER_PASS1, NULL);
5507 if (error != 0) {
5508 kmem_free(log->l_buf_cancel_table);
5509 log->l_buf_cancel_table = NULL;
5510 return error;
5511 }
5512
5513
5514
5515
5516 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
5517 XLOG_RECOVER_PASS2, NULL);
5518#ifdef DEBUG
5519 if (!error) {
5520 int i;
5521
5522 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
5523 ASSERT(list_empty(&log->l_buf_cancel_table[i]));
5524 }
5525#endif
5526
5527 kmem_free(log->l_buf_cancel_table);
5528 log->l_buf_cancel_table = NULL;
5529
5530 return error;
5531}
5532
5533
5534
5535
5536STATIC int
5537xlog_do_recover(
5538 struct xlog *log,
5539 xfs_daddr_t head_blk,
5540 xfs_daddr_t tail_blk)
5541{
5542 struct xfs_mount *mp = log->l_mp;
5543 int error;
5544 xfs_buf_t *bp;
5545 xfs_sb_t *sbp;
5546
5547
5548
5549
5550 error = xlog_do_log_recovery(log, head_blk, tail_blk);
5551 if (error)
5552 return error;
5553
5554
5555
5556
5557 if (XFS_FORCED_SHUTDOWN(mp)) {
5558 return -EIO;
5559 }
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570 xlog_assign_tail_lsn(mp);
5571
5572
5573
5574
5575
5576 bp = xfs_getsb(mp, 0);
5577 bp->b_flags &= ~(XBF_DONE | XBF_ASYNC);
5578 ASSERT(!(bp->b_flags & XBF_WRITE));
5579 bp->b_flags |= XBF_READ;
5580 bp->b_ops = &xfs_sb_buf_ops;
5581
5582 error = xfs_buf_submit_wait(bp);
5583 if (error) {
5584 if (!XFS_FORCED_SHUTDOWN(mp)) {
5585 xfs_buf_ioerror_alert(bp, __func__);
5586 ASSERT(0);
5587 }
5588 xfs_buf_relse(bp);
5589 return error;
5590 }
5591
5592
5593 sbp = &mp->m_sb;
5594 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
5595 xfs_buf_relse(bp);
5596
5597
5598 xfs_reinit_percpu_counters(mp);
5599 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
5600 if (error) {
5601 xfs_warn(mp, "Failed post-recovery per-ag init: %d", error);
5602 return error;
5603 }
5604 mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
5605
5606 xlog_recover_check_summary(log);
5607
5608
5609 log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
5610 return 0;
5611}
5612
5613
5614
5615
5616
5617
5618int
5619xlog_recover(
5620 struct xlog *log)
5621{
5622 xfs_daddr_t head_blk, tail_blk;
5623 int error;
5624
5625
5626 error = xlog_find_tail(log, &head_blk, &tail_blk);
5627 if (error)
5628 return error;
5629
5630
5631
5632
5633
5634
5635 if (xfs_sb_version_hascrc(&log->l_mp->m_sb) &&
5636 !xfs_log_check_lsn(log->l_mp, log->l_mp->m_sb.sb_lsn))
5637 return -EINVAL;
5638
5639 if (tail_blk != head_blk) {
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651 if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
5652 return error;
5653 }
5654
5655
5656
5657
5658
5659
5660
5661
5662 if (XFS_SB_VERSION_NUM(&log->l_mp->m_sb) == XFS_SB_VERSION_5 &&
5663 xfs_sb_has_incompat_log_feature(&log->l_mp->m_sb,
5664 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) {
5665 xfs_warn(log->l_mp,
5666"Superblock has unknown incompatible log features (0x%x) enabled.",
5667 (log->l_mp->m_sb.sb_features_log_incompat &
5668 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN));
5669 xfs_warn(log->l_mp,
5670"The log can not be fully and/or safely recovered by this kernel.");
5671 xfs_warn(log->l_mp,
5672"Please recover the log on a kernel that supports the unknown features.");
5673 return -EINVAL;
5674 }
5675
5676
5677
5678
5679
5680
5681 if (xfs_globals.log_recovery_delay) {
5682 xfs_notice(log->l_mp,
5683 "Delaying log recovery for %d seconds.",
5684 xfs_globals.log_recovery_delay);
5685 msleep(xfs_globals.log_recovery_delay * 1000);
5686 }
5687
5688 xfs_notice(log->l_mp, "Starting recovery (logdev: %s)",
5689 log->l_mp->m_logname ? log->l_mp->m_logname
5690 : "internal");
5691
5692 error = xlog_do_recover(log, head_blk, tail_blk);
5693 log->l_flags |= XLOG_RECOVERY_NEEDED;
5694 }
5695 return error;
5696}
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707int
5708xlog_recover_finish(
5709 struct xlog *log)
5710{
5711
5712
5713
5714
5715
5716
5717
5718
5719 if (log->l_flags & XLOG_RECOVERY_NEEDED) {
5720 int error;
5721 error = xlog_recover_process_intents(log);
5722 if (error) {
5723 xfs_alert(log->l_mp, "Failed to recover intents");
5724 return error;
5725 }
5726
5727
5728
5729
5730
5731
5732
5733 xfs_log_force(log->l_mp, XFS_LOG_SYNC);
5734
5735 xlog_recover_process_iunlinks(log);
5736
5737 xlog_recover_check_summary(log);
5738
5739 xfs_notice(log->l_mp, "Ending recovery (logdev: %s)",
5740 log->l_mp->m_logname ? log->l_mp->m_logname
5741 : "internal");
5742 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
5743 } else {
5744 xfs_info(log->l_mp, "Ending clean mount");
5745 }
5746 return 0;
5747}
5748
5749int
5750xlog_recover_cancel(
5751 struct xlog *log)
5752{
5753 int error = 0;
5754
5755 if (log->l_flags & XLOG_RECOVERY_NEEDED)
5756 error = xlog_recover_cancel_intents(log);
5757
5758 return error;
5759}
5760
5761#if defined(DEBUG)
5762
5763
5764
5765
5766void
5767xlog_recover_check_summary(
5768 struct xlog *log)
5769{
5770 xfs_mount_t *mp;
5771 xfs_agf_t *agfp;
5772 xfs_buf_t *agfbp;
5773 xfs_buf_t *agibp;
5774 xfs_agnumber_t agno;
5775 __uint64_t freeblks;
5776 __uint64_t itotal;
5777 __uint64_t ifree;
5778 int error;
5779
5780 mp = log->l_mp;
5781
5782 freeblks = 0LL;
5783 itotal = 0LL;
5784 ifree = 0LL;
5785 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
5786 error = xfs_read_agf(mp, NULL, agno, 0, &agfbp);
5787 if (error) {
5788 xfs_alert(mp, "%s agf read failed agno %d error %d",
5789 __func__, agno, error);
5790 } else {
5791 agfp = XFS_BUF_TO_AGF(agfbp);
5792 freeblks += be32_to_cpu(agfp->agf_freeblks) +
5793 be32_to_cpu(agfp->agf_flcount);
5794 xfs_buf_relse(agfbp);
5795 }
5796
5797 error = xfs_read_agi(mp, NULL, agno, &agibp);
5798 if (error) {
5799 xfs_alert(mp, "%s agi read failed agno %d error %d",
5800 __func__, agno, error);
5801 } else {
5802 struct xfs_agi *agi = XFS_BUF_TO_AGI(agibp);
5803
5804 itotal += be32_to_cpu(agi->agi_count);
5805 ifree += be32_to_cpu(agi->agi_freecount);
5806 xfs_buf_relse(agibp);
5807 }
5808 }
5809}
5810#endif
5811