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_inum.h"
26#include "xfs_sb.h"
27#include "xfs_ag.h"
28#include "xfs_mount.h"
29#include "xfs_da_format.h"
30#include "xfs_inode.h"
31#include "xfs_trans.h"
32#include "xfs_log.h"
33#include "xfs_log_priv.h"
34#include "xfs_log_recover.h"
35#include "xfs_inode_item.h"
36#include "xfs_extfree_item.h"
37#include "xfs_trans_priv.h"
38#include "xfs_alloc.h"
39#include "xfs_ialloc.h"
40#include "xfs_quota.h"
41#include "xfs_cksum.h"
42#include "xfs_trace.h"
43#include "xfs_icache.h"
44#include "xfs_bmap_btree.h"
45#include "xfs_dinode.h"
46#include "xfs_error.h"
47#include "xfs_dir2.h"
48
49#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
50
51STATIC int
52xlog_find_zeroed(
53 struct xlog *,
54 xfs_daddr_t *);
55STATIC int
56xlog_clear_stale_blocks(
57 struct xlog *,
58 xfs_lsn_t);
59#if defined(DEBUG)
60STATIC void
61xlog_recover_check_summary(
62 struct xlog *);
63#else
64#define xlog_recover_check_summary(log)
65#endif
66
67
68
69
70
71struct xfs_buf_cancel {
72 xfs_daddr_t bc_blkno;
73 uint bc_len;
74 int bc_refcount;
75 struct list_head bc_list;
76};
77
78
79
80
81
82
83
84
85
86
87
88static inline int
89xlog_buf_bbcount_valid(
90 struct xlog *log,
91 int bbcount)
92{
93 return bbcount > 0 && bbcount <= log->l_logBBsize;
94}
95
96
97
98
99
100
101STATIC xfs_buf_t *
102xlog_get_bp(
103 struct xlog *log,
104 int nbblks)
105{
106 struct xfs_buf *bp;
107
108 if (!xlog_buf_bbcount_valid(log, nbblks)) {
109 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
110 nbblks);
111 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
112 return NULL;
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 if (nbblks > 1 && log->l_sectBBsize > 1)
132 nbblks += log->l_sectBBsize;
133 nbblks = round_up(nbblks, log->l_sectBBsize);
134
135 bp = xfs_buf_get_uncached(log->l_mp->m_logdev_targp, nbblks, 0);
136 if (bp)
137 xfs_buf_unlock(bp);
138 return bp;
139}
140
141STATIC void
142xlog_put_bp(
143 xfs_buf_t *bp)
144{
145 xfs_buf_free(bp);
146}
147
148
149
150
151
152STATIC xfs_caddr_t
153xlog_align(
154 struct xlog *log,
155 xfs_daddr_t blk_no,
156 int nbblks,
157 struct xfs_buf *bp)
158{
159 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1);
160
161 ASSERT(offset + nbblks <= bp->b_length);
162 return bp->b_addr + BBTOB(offset);
163}
164
165
166
167
168
169STATIC int
170xlog_bread_noalign(
171 struct xlog *log,
172 xfs_daddr_t blk_no,
173 int nbblks,
174 struct xfs_buf *bp)
175{
176 int error;
177
178 if (!xlog_buf_bbcount_valid(log, nbblks)) {
179 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
180 nbblks);
181 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
182 return EFSCORRUPTED;
183 }
184
185 blk_no = round_down(blk_no, log->l_sectBBsize);
186 nbblks = round_up(nbblks, log->l_sectBBsize);
187
188 ASSERT(nbblks > 0);
189 ASSERT(nbblks <= bp->b_length);
190
191 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
192 XFS_BUF_READ(bp);
193 bp->b_io_length = nbblks;
194 bp->b_error = 0;
195
196 if (XFS_FORCED_SHUTDOWN(log->l_mp))
197 return XFS_ERROR(EIO);
198
199 xfs_buf_iorequest(bp);
200 error = xfs_buf_iowait(bp);
201 if (error)
202 xfs_buf_ioerror_alert(bp, __func__);
203 return error;
204}
205
206STATIC int
207xlog_bread(
208 struct xlog *log,
209 xfs_daddr_t blk_no,
210 int nbblks,
211 struct xfs_buf *bp,
212 xfs_caddr_t *offset)
213{
214 int error;
215
216 error = xlog_bread_noalign(log, blk_no, nbblks, bp);
217 if (error)
218 return error;
219
220 *offset = xlog_align(log, blk_no, nbblks, bp);
221 return 0;
222}
223
224
225
226
227
228STATIC int
229xlog_bread_offset(
230 struct xlog *log,
231 xfs_daddr_t blk_no,
232 int nbblks,
233 struct xfs_buf *bp,
234 xfs_caddr_t offset)
235{
236 xfs_caddr_t orig_offset = bp->b_addr;
237 int orig_len = BBTOB(bp->b_length);
238 int error, error2;
239
240 error = xfs_buf_associate_memory(bp, offset, BBTOB(nbblks));
241 if (error)
242 return error;
243
244 error = xlog_bread_noalign(log, blk_no, nbblks, bp);
245
246
247 error2 = xfs_buf_associate_memory(bp, orig_offset, orig_len);
248 if (error)
249 return error;
250 return error2;
251}
252
253
254
255
256
257
258STATIC int
259xlog_bwrite(
260 struct xlog *log,
261 xfs_daddr_t blk_no,
262 int nbblks,
263 struct xfs_buf *bp)
264{
265 int error;
266
267 if (!xlog_buf_bbcount_valid(log, nbblks)) {
268 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
269 nbblks);
270 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp);
271 return EFSCORRUPTED;
272 }
273
274 blk_no = round_down(blk_no, log->l_sectBBsize);
275 nbblks = round_up(nbblks, log->l_sectBBsize);
276
277 ASSERT(nbblks > 0);
278 ASSERT(nbblks <= bp->b_length);
279
280 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
281 XFS_BUF_ZEROFLAGS(bp);
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 XFS_ERROR(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 XFS_ERROR(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 XFS_ERROR(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 xfs_buf_ioerror_alert(bp, __func__);
382 xfs_force_shutdown(bp->b_target->bt_mount,
383 SHUTDOWN_META_IO_ERROR);
384 }
385 bp->b_iodone = NULL;
386 xfs_buf_ioend(bp, 0);
387}
388
389
390
391
392
393
394
395STATIC int
396xlog_find_cycle_start(
397 struct xlog *log,
398 struct xfs_buf *bp,
399 xfs_daddr_t first_blk,
400 xfs_daddr_t *last_blk,
401 uint cycle)
402{
403 xfs_caddr_t offset;
404 xfs_daddr_t mid_blk;
405 xfs_daddr_t end_blk;
406 uint mid_cycle;
407 int error;
408
409 end_blk = *last_blk;
410 mid_blk = BLK_AVG(first_blk, end_blk);
411 while (mid_blk != first_blk && mid_blk != end_blk) {
412 error = xlog_bread(log, mid_blk, 1, bp, &offset);
413 if (error)
414 return error;
415 mid_cycle = xlog_get_cycle(offset);
416 if (mid_cycle == cycle)
417 end_blk = mid_blk;
418 else
419 first_blk = mid_blk;
420 mid_blk = BLK_AVG(first_blk, end_blk);
421 }
422 ASSERT((mid_blk == first_blk && mid_blk+1 == end_blk) ||
423 (mid_blk == end_blk && mid_blk-1 == first_blk));
424
425 *last_blk = end_blk;
426
427 return 0;
428}
429
430
431
432
433
434
435
436
437
438STATIC int
439xlog_find_verify_cycle(
440 struct xlog *log,
441 xfs_daddr_t start_blk,
442 int nbblks,
443 uint stop_on_cycle_no,
444 xfs_daddr_t *new_blk)
445{
446 xfs_daddr_t i, j;
447 uint cycle;
448 xfs_buf_t *bp;
449 xfs_daddr_t bufblks;
450 xfs_caddr_t buf = NULL;
451 int error = 0;
452
453
454
455
456
457
458
459 bufblks = 1 << ffs(nbblks);
460 while (bufblks > log->l_logBBsize)
461 bufblks >>= 1;
462 while (!(bp = xlog_get_bp(log, bufblks))) {
463 bufblks >>= 1;
464 if (bufblks < log->l_sectBBsize)
465 return ENOMEM;
466 }
467
468 for (i = start_blk; i < start_blk + nbblks; i += bufblks) {
469 int bcount;
470
471 bcount = min(bufblks, (start_blk + nbblks - i));
472
473 error = xlog_bread(log, i, bcount, bp, &buf);
474 if (error)
475 goto out;
476
477 for (j = 0; j < bcount; j++) {
478 cycle = xlog_get_cycle(buf);
479 if (cycle == stop_on_cycle_no) {
480 *new_blk = i+j;
481 goto out;
482 }
483
484 buf += BBSIZE;
485 }
486 }
487
488 *new_blk = -1;
489
490out:
491 xlog_put_bp(bp);
492 return error;
493}
494
495
496
497
498
499
500
501
502
503
504
505
506
507STATIC int
508xlog_find_verify_log_record(
509 struct xlog *log,
510 xfs_daddr_t start_blk,
511 xfs_daddr_t *last_blk,
512 int extra_bblks)
513{
514 xfs_daddr_t i;
515 xfs_buf_t *bp;
516 xfs_caddr_t offset = NULL;
517 xlog_rec_header_t *head = NULL;
518 int error = 0;
519 int smallmem = 0;
520 int num_blks = *last_blk - start_blk;
521 int xhdrs;
522
523 ASSERT(start_blk != 0 || *last_blk != start_blk);
524
525 if (!(bp = xlog_get_bp(log, num_blks))) {
526 if (!(bp = xlog_get_bp(log, 1)))
527 return ENOMEM;
528 smallmem = 1;
529 } else {
530 error = xlog_bread(log, start_blk, num_blks, bp, &offset);
531 if (error)
532 goto out;
533 offset += ((num_blks - 1) << BBSHIFT);
534 }
535
536 for (i = (*last_blk) - 1; i >= 0; i--) {
537 if (i < start_blk) {
538
539 xfs_warn(log->l_mp,
540 "Log inconsistent (didn't find previous header)");
541 ASSERT(0);
542 error = XFS_ERROR(EIO);
543 goto out;
544 }
545
546 if (smallmem) {
547 error = xlog_bread(log, i, 1, bp, &offset);
548 if (error)
549 goto out;
550 }
551
552 head = (xlog_rec_header_t *)offset;
553
554 if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
555 break;
556
557 if (!smallmem)
558 offset -= BBSIZE;
559 }
560
561
562
563
564
565
566 if (i == -1) {
567 error = -1;
568 goto out;
569 }
570
571
572
573
574
575 if ((error = xlog_header_check_mount(log->l_mp, head)))
576 goto out;
577
578
579
580
581
582
583
584
585 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
586 uint h_size = be32_to_cpu(head->h_size);
587
588 xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
589 if (h_size % XLOG_HEADER_CYCLE_SIZE)
590 xhdrs++;
591 } else {
592 xhdrs = 1;
593 }
594
595 if (*last_blk - i + extra_bblks !=
596 BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
597 *last_blk = i;
598
599out:
600 xlog_put_bp(bp);
601 return error;
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617STATIC int
618xlog_find_head(
619 struct xlog *log,
620 xfs_daddr_t *return_head_blk)
621{
622 xfs_buf_t *bp;
623 xfs_caddr_t offset;
624 xfs_daddr_t new_blk, first_blk, start_blk, last_blk, head_blk;
625 int num_scan_bblks;
626 uint first_half_cycle, last_half_cycle;
627 uint stop_on_cycle;
628 int error, log_bbnum = log->l_logBBsize;
629
630
631 if ((error = xlog_find_zeroed(log, &first_blk)) == -1) {
632 *return_head_blk = first_blk;
633
634
635 if (!first_blk) {
636
637
638
639
640 xfs_warn(log->l_mp, "totally zeroed log");
641 }
642
643 return 0;
644 } else if (error) {
645 xfs_warn(log->l_mp, "empty log check failed");
646 return error;
647 }
648
649 first_blk = 0;
650 bp = xlog_get_bp(log, 1);
651 if (!bp)
652 return ENOMEM;
653
654 error = xlog_bread(log, 0, 1, bp, &offset);
655 if (error)
656 goto bp_err;
657
658 first_half_cycle = xlog_get_cycle(offset);
659
660 last_blk = head_blk = log_bbnum - 1;
661 error = xlog_bread(log, last_blk, 1, bp, &offset);
662 if (error)
663 goto bp_err;
664
665 last_half_cycle = xlog_get_cycle(offset);
666 ASSERT(last_half_cycle != 0);
667
668
669
670
671
672
673
674
675
676
677
678
679 if (first_half_cycle == last_half_cycle) {
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705 head_blk = log_bbnum;
706 stop_on_cycle = last_half_cycle - 1;
707 } else {
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730 stop_on_cycle = last_half_cycle;
731 if ((error = xlog_find_cycle_start(log, bp, first_blk,
732 &head_blk, last_half_cycle)))
733 goto bp_err;
734 }
735
736
737
738
739
740
741
742
743 num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
744 if (head_blk >= num_scan_bblks) {
745
746
747
748
749 start_blk = head_blk - num_scan_bblks;
750 if ((error = xlog_find_verify_cycle(log,
751 start_blk, num_scan_bblks,
752 stop_on_cycle, &new_blk)))
753 goto bp_err;
754 if (new_blk != -1)
755 head_blk = new_blk;
756 } else {
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784 ASSERT(head_blk <= INT_MAX &&
785 (xfs_daddr_t) num_scan_bblks >= head_blk);
786 start_blk = log_bbnum - (num_scan_bblks - head_blk);
787 if ((error = xlog_find_verify_cycle(log, start_blk,
788 num_scan_bblks - (int)head_blk,
789 (stop_on_cycle - 1), &new_blk)))
790 goto bp_err;
791 if (new_blk != -1) {
792 head_blk = new_blk;
793 goto validate_head;
794 }
795
796
797
798
799
800
801 start_blk = 0;
802 ASSERT(head_blk <= INT_MAX);
803 if ((error = xlog_find_verify_cycle(log,
804 start_blk, (int)head_blk,
805 stop_on_cycle, &new_blk)))
806 goto bp_err;
807 if (new_blk != -1)
808 head_blk = new_blk;
809 }
810
811validate_head:
812
813
814
815
816 num_scan_bblks = XLOG_REC_SHIFT(log);
817 if (head_blk >= num_scan_bblks) {
818 start_blk = head_blk - num_scan_bblks;
819
820
821 if ((error = xlog_find_verify_log_record(log, start_blk,
822 &head_blk, 0)) == -1) {
823 error = XFS_ERROR(EIO);
824 goto bp_err;
825 } else if (error)
826 goto bp_err;
827 } else {
828 start_blk = 0;
829 ASSERT(head_blk <= INT_MAX);
830 if ((error = xlog_find_verify_log_record(log, start_blk,
831 &head_blk, 0)) == -1) {
832
833 start_blk = log_bbnum - (num_scan_bblks - head_blk);
834 new_blk = log_bbnum;
835 ASSERT(start_blk <= INT_MAX &&
836 (xfs_daddr_t) log_bbnum-start_blk >= 0);
837 ASSERT(head_blk <= INT_MAX);
838 if ((error = xlog_find_verify_log_record(log,
839 start_blk, &new_blk,
840 (int)head_blk)) == -1) {
841 error = XFS_ERROR(EIO);
842 goto bp_err;
843 } else if (error)
844 goto bp_err;
845 if (new_blk != log_bbnum)
846 head_blk = new_blk;
847 } else if (error)
848 goto bp_err;
849 }
850
851 xlog_put_bp(bp);
852 if (head_blk == log_bbnum)
853 *return_head_blk = 0;
854 else
855 *return_head_blk = head_blk;
856
857
858
859
860
861
862 return 0;
863
864 bp_err:
865 xlog_put_bp(bp);
866
867 if (error)
868 xfs_warn(log->l_mp, "failed to find log head");
869 return error;
870}
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888STATIC int
889xlog_find_tail(
890 struct xlog *log,
891 xfs_daddr_t *head_blk,
892 xfs_daddr_t *tail_blk)
893{
894 xlog_rec_header_t *rhead;
895 xlog_op_header_t *op_head;
896 xfs_caddr_t offset = NULL;
897 xfs_buf_t *bp;
898 int error, i, found;
899 xfs_daddr_t umount_data_blk;
900 xfs_daddr_t after_umount_blk;
901 xfs_lsn_t tail_lsn;
902 int hblks;
903
904 found = 0;
905
906
907
908
909 if ((error = xlog_find_head(log, head_blk)))
910 return error;
911
912 bp = xlog_get_bp(log, 1);
913 if (!bp)
914 return ENOMEM;
915 if (*head_blk == 0) {
916 error = xlog_bread(log, 0, 1, bp, &offset);
917 if (error)
918 goto done;
919
920 if (xlog_get_cycle(offset) == 0) {
921 *tail_blk = 0;
922
923 goto done;
924 }
925 }
926
927
928
929
930 ASSERT(*head_blk < INT_MAX);
931 for (i = (int)(*head_blk) - 1; i >= 0; i--) {
932 error = xlog_bread(log, i, 1, bp, &offset);
933 if (error)
934 goto done;
935
936 if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
937 found = 1;
938 break;
939 }
940 }
941
942
943
944
945
946
947 if (!found) {
948 for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) {
949 error = xlog_bread(log, i, 1, bp, &offset);
950 if (error)
951 goto done;
952
953 if (*(__be32 *)offset ==
954 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
955 found = 2;
956 break;
957 }
958 }
959 }
960 if (!found) {
961 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
962 xlog_put_bp(bp);
963 ASSERT(0);
964 return XFS_ERROR(EIO);
965 }
966
967
968 rhead = (xlog_rec_header_t *)offset;
969 *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
970
971
972
973
974
975
976
977
978
979
980
981 log->l_prev_block = i;
982 log->l_curr_block = (int)*head_blk;
983 log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
984 if (found == 2)
985 log->l_curr_cycle++;
986 atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn));
987 atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn));
988 xlog_assign_grant_head(&log->l_reserve_head.grant, log->l_curr_cycle,
989 BBTOB(log->l_curr_block));
990 xlog_assign_grant_head(&log->l_write_head.grant, log->l_curr_cycle,
991 BBTOB(log->l_curr_block));
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
1005 int h_size = be32_to_cpu(rhead->h_size);
1006 int h_version = be32_to_cpu(rhead->h_version);
1007
1008 if ((h_version & XLOG_VERSION_2) &&
1009 (h_size > XLOG_HEADER_CYCLE_SIZE)) {
1010 hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
1011 if (h_size % XLOG_HEADER_CYCLE_SIZE)
1012 hblks++;
1013 } else {
1014 hblks = 1;
1015 }
1016 } else {
1017 hblks = 1;
1018 }
1019 after_umount_blk = (i + hblks + (int)
1020 BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize;
1021 tail_lsn = atomic64_read(&log->l_tail_lsn);
1022 if (*head_blk == after_umount_blk &&
1023 be32_to_cpu(rhead->h_num_logops) == 1) {
1024 umount_data_blk = (i + hblks) % log->l_logBBsize;
1025 error = xlog_bread(log, umount_data_blk, 1, bp, &offset);
1026 if (error)
1027 goto done;
1028
1029 op_head = (xlog_op_header_t *)offset;
1030 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
1031
1032
1033
1034
1035
1036 xlog_assign_atomic_lsn(&log->l_tail_lsn,
1037 log->l_curr_cycle, after_umount_blk);
1038 xlog_assign_atomic_lsn(&log->l_last_sync_lsn,
1039 log->l_curr_cycle, after_umount_blk);
1040 *tail_blk = after_umount_blk;
1041
1042
1043
1044
1045
1046
1047
1048 log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN;
1049 }
1050 }
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071 if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp))
1072 error = xlog_clear_stale_blocks(log, tail_lsn);
1073
1074done:
1075 xlog_put_bp(bp);
1076
1077 if (error)
1078 xfs_warn(log->l_mp, "failed to locate log tail");
1079 return error;
1080}
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098STATIC int
1099xlog_find_zeroed(
1100 struct xlog *log,
1101 xfs_daddr_t *blk_no)
1102{
1103 xfs_buf_t *bp;
1104 xfs_caddr_t offset;
1105 uint first_cycle, last_cycle;
1106 xfs_daddr_t new_blk, last_blk, start_blk;
1107 xfs_daddr_t num_scan_bblks;
1108 int error, log_bbnum = log->l_logBBsize;
1109
1110 *blk_no = 0;
1111
1112
1113 bp = xlog_get_bp(log, 1);
1114 if (!bp)
1115 return ENOMEM;
1116 error = xlog_bread(log, 0, 1, bp, &offset);
1117 if (error)
1118 goto bp_err;
1119
1120 first_cycle = xlog_get_cycle(offset);
1121 if (first_cycle == 0) {
1122 *blk_no = 0;
1123 xlog_put_bp(bp);
1124 return -1;
1125 }
1126
1127
1128 error = xlog_bread(log, log_bbnum-1, 1, bp, &offset);
1129 if (error)
1130 goto bp_err;
1131
1132 last_cycle = xlog_get_cycle(offset);
1133 if (last_cycle != 0) {
1134 xlog_put_bp(bp);
1135 return 0;
1136 } else if (first_cycle != 1) {
1137
1138
1139
1140
1141
1142 xfs_warn(log->l_mp,
1143 "Log inconsistent or not a log (last==0, first!=1)");
1144 error = XFS_ERROR(EINVAL);
1145 goto bp_err;
1146 }
1147
1148
1149 last_blk = log_bbnum-1;
1150 if ((error = xlog_find_cycle_start(log, bp, 0, &last_blk, 0)))
1151 goto bp_err;
1152
1153
1154
1155
1156
1157
1158
1159 num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
1160 ASSERT(num_scan_bblks <= INT_MAX);
1161
1162 if (last_blk < num_scan_bblks)
1163 num_scan_bblks = last_blk;
1164 start_blk = last_blk - num_scan_bblks;
1165
1166
1167
1168
1169
1170
1171
1172 if ((error = xlog_find_verify_cycle(log, start_blk,
1173 (int)num_scan_bblks, 0, &new_blk)))
1174 goto bp_err;
1175 if (new_blk != -1)
1176 last_blk = new_blk;
1177
1178
1179
1180
1181
1182 if ((error = xlog_find_verify_log_record(log, start_blk,
1183 &last_blk, 0)) == -1) {
1184 error = XFS_ERROR(EIO);
1185 goto bp_err;
1186 } else if (error)
1187 goto bp_err;
1188
1189 *blk_no = last_blk;
1190bp_err:
1191 xlog_put_bp(bp);
1192 if (error)
1193 return error;
1194 return -1;
1195}
1196
1197
1198
1199
1200
1201
1202STATIC void
1203xlog_add_record(
1204 struct xlog *log,
1205 xfs_caddr_t buf,
1206 int cycle,
1207 int block,
1208 int tail_cycle,
1209 int tail_block)
1210{
1211 xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
1212
1213 memset(buf, 0, BBSIZE);
1214 recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
1215 recp->h_cycle = cpu_to_be32(cycle);
1216 recp->h_version = cpu_to_be32(
1217 xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
1218 recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
1219 recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
1220 recp->h_fmt = cpu_to_be32(XLOG_FMT);
1221 memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
1222}
1223
1224STATIC int
1225xlog_write_log_records(
1226 struct xlog *log,
1227 int cycle,
1228 int start_block,
1229 int blocks,
1230 int tail_cycle,
1231 int tail_block)
1232{
1233 xfs_caddr_t offset;
1234 xfs_buf_t *bp;
1235 int balign, ealign;
1236 int sectbb = log->l_sectBBsize;
1237 int end_block = start_block + blocks;
1238 int bufblks;
1239 int error = 0;
1240 int i, j = 0;
1241
1242
1243
1244
1245
1246
1247
1248 bufblks = 1 << ffs(blocks);
1249 while (bufblks > log->l_logBBsize)
1250 bufblks >>= 1;
1251 while (!(bp = xlog_get_bp(log, bufblks))) {
1252 bufblks >>= 1;
1253 if (bufblks < sectbb)
1254 return ENOMEM;
1255 }
1256
1257
1258
1259
1260
1261 balign = round_down(start_block, sectbb);
1262 if (balign != start_block) {
1263 error = xlog_bread_noalign(log, start_block, 1, bp);
1264 if (error)
1265 goto out_put_bp;
1266
1267 j = start_block - balign;
1268 }
1269
1270 for (i = start_block; i < end_block; i += bufblks) {
1271 int bcount, endcount;
1272
1273 bcount = min(bufblks, end_block - start_block);
1274 endcount = bcount - j;
1275
1276
1277
1278
1279
1280 ealign = round_down(end_block, sectbb);
1281 if (j == 0 && (start_block + endcount > ealign)) {
1282 offset = bp->b_addr + BBTOB(ealign - start_block);
1283 error = xlog_bread_offset(log, ealign, sectbb,
1284 bp, offset);
1285 if (error)
1286 break;
1287
1288 }
1289
1290 offset = xlog_align(log, start_block, endcount, bp);
1291 for (; j < endcount; j++) {
1292 xlog_add_record(log, offset, cycle, i+j,
1293 tail_cycle, tail_block);
1294 offset += BBSIZE;
1295 }
1296 error = xlog_bwrite(log, start_block, endcount, bp);
1297 if (error)
1298 break;
1299 start_block += endcount;
1300 j = 0;
1301 }
1302
1303 out_put_bp:
1304 xlog_put_bp(bp);
1305 return error;
1306}
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324STATIC int
1325xlog_clear_stale_blocks(
1326 struct xlog *log,
1327 xfs_lsn_t tail_lsn)
1328{
1329 int tail_cycle, head_cycle;
1330 int tail_block, head_block;
1331 int tail_distance, max_distance;
1332 int distance;
1333 int error;
1334
1335 tail_cycle = CYCLE_LSN(tail_lsn);
1336 tail_block = BLOCK_LSN(tail_lsn);
1337 head_cycle = log->l_curr_cycle;
1338 head_block = log->l_curr_block;
1339
1340
1341
1342
1343
1344
1345
1346 if (head_cycle == tail_cycle) {
1347
1348
1349
1350
1351
1352
1353
1354 if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
1355 XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
1356 XFS_ERRLEVEL_LOW, log->l_mp);
1357 return XFS_ERROR(EFSCORRUPTED);
1358 }
1359 tail_distance = tail_block + (log->l_logBBsize - head_block);
1360 } else {
1361
1362
1363
1364
1365
1366 if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
1367 XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
1368 XFS_ERRLEVEL_LOW, log->l_mp);
1369 return XFS_ERROR(EFSCORRUPTED);
1370 }
1371 tail_distance = tail_block - head_block;
1372 }
1373
1374
1375
1376
1377
1378 if (tail_distance <= 0) {
1379 ASSERT(tail_distance == 0);
1380 return 0;
1381 }
1382
1383 max_distance = XLOG_TOTAL_REC_SHIFT(log);
1384
1385
1386
1387
1388
1389
1390
1391 max_distance = MIN(max_distance, tail_distance);
1392
1393 if ((head_block + max_distance) <= log->l_logBBsize) {
1394
1395
1396
1397
1398
1399
1400
1401 error = xlog_write_log_records(log, (head_cycle - 1),
1402 head_block, max_distance, tail_cycle,
1403 tail_block);
1404 if (error)
1405 return error;
1406 } else {
1407
1408
1409
1410
1411
1412
1413
1414 distance = log->l_logBBsize - head_block;
1415 error = xlog_write_log_records(log, (head_cycle - 1),
1416 head_block, distance, tail_cycle,
1417 tail_block);
1418
1419 if (error)
1420 return error;
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430 distance = max_distance - (log->l_logBBsize - head_block);
1431 error = xlog_write_log_records(log, head_cycle, 0, distance,
1432 tail_cycle, tail_block);
1433 if (error)
1434 return error;
1435 }
1436
1437 return 0;
1438}
1439
1440
1441
1442
1443
1444
1445
1446
1447STATIC xlog_recover_t *
1448xlog_recover_find_tid(
1449 struct hlist_head *head,
1450 xlog_tid_t tid)
1451{
1452 xlog_recover_t *trans;
1453
1454 hlist_for_each_entry(trans, head, r_list) {
1455 if (trans->r_log_tid == tid)
1456 return trans;
1457 }
1458 return NULL;
1459}
1460
1461STATIC void
1462xlog_recover_new_tid(
1463 struct hlist_head *head,
1464 xlog_tid_t tid,
1465 xfs_lsn_t lsn)
1466{
1467 xlog_recover_t *trans;
1468
1469 trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP);
1470 trans->r_log_tid = tid;
1471 trans->r_lsn = lsn;
1472 INIT_LIST_HEAD(&trans->r_itemq);
1473
1474 INIT_HLIST_NODE(&trans->r_list);
1475 hlist_add_head(&trans->r_list, head);
1476}
1477
1478STATIC void
1479xlog_recover_add_item(
1480 struct list_head *head)
1481{
1482 xlog_recover_item_t *item;
1483
1484 item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP);
1485 INIT_LIST_HEAD(&item->ri_list);
1486 list_add_tail(&item->ri_list, head);
1487}
1488
1489STATIC int
1490xlog_recover_add_to_cont_trans(
1491 struct xlog *log,
1492 struct xlog_recover *trans,
1493 xfs_caddr_t dp,
1494 int len)
1495{
1496 xlog_recover_item_t *item;
1497 xfs_caddr_t ptr, old_ptr;
1498 int old_len;
1499
1500 if (list_empty(&trans->r_itemq)) {
1501
1502 xlog_recover_add_item(&trans->r_itemq);
1503 ptr = (xfs_caddr_t) &trans->r_theader +
1504 sizeof(xfs_trans_header_t) - len;
1505 memcpy(ptr, dp, len);
1506 return 0;
1507 }
1508
1509 item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list);
1510
1511 old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
1512 old_len = item->ri_buf[item->ri_cnt-1].i_len;
1513
1514 ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP);
1515 memcpy(&ptr[old_len], dp, len);
1516 item->ri_buf[item->ri_cnt-1].i_len += len;
1517 item->ri_buf[item->ri_cnt-1].i_addr = ptr;
1518 trace_xfs_log_recover_item_add_cont(log, trans, item, 0);
1519 return 0;
1520}
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535STATIC int
1536xlog_recover_add_to_trans(
1537 struct xlog *log,
1538 struct xlog_recover *trans,
1539 xfs_caddr_t dp,
1540 int len)
1541{
1542 xfs_inode_log_format_t *in_f;
1543 xlog_recover_item_t *item;
1544 xfs_caddr_t ptr;
1545
1546 if (!len)
1547 return 0;
1548 if (list_empty(&trans->r_itemq)) {
1549
1550 if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) {
1551 xfs_warn(log->l_mp, "%s: bad header magic number",
1552 __func__);
1553 ASSERT(0);
1554 return XFS_ERROR(EIO);
1555 }
1556 if (len == sizeof(xfs_trans_header_t))
1557 xlog_recover_add_item(&trans->r_itemq);
1558 memcpy(&trans->r_theader, dp, len);
1559 return 0;
1560 }
1561
1562 ptr = kmem_alloc(len, KM_SLEEP);
1563 memcpy(ptr, dp, len);
1564 in_f = (xfs_inode_log_format_t *)ptr;
1565
1566
1567 item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list);
1568 if (item->ri_total != 0 &&
1569 item->ri_total == item->ri_cnt) {
1570
1571 xlog_recover_add_item(&trans->r_itemq);
1572 item = list_entry(trans->r_itemq.prev,
1573 xlog_recover_item_t, ri_list);
1574 }
1575
1576 if (item->ri_total == 0) {
1577 if (in_f->ilf_size == 0 ||
1578 in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) {
1579 xfs_warn(log->l_mp,
1580 "bad number of regions (%d) in inode log format",
1581 in_f->ilf_size);
1582 ASSERT(0);
1583 kmem_free(ptr);
1584 return XFS_ERROR(EIO);
1585 }
1586
1587 item->ri_total = in_f->ilf_size;
1588 item->ri_buf =
1589 kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t),
1590 KM_SLEEP);
1591 }
1592 ASSERT(item->ri_total > item->ri_cnt);
1593
1594 item->ri_buf[item->ri_cnt].i_addr = ptr;
1595 item->ri_buf[item->ri_cnt].i_len = len;
1596 item->ri_cnt++;
1597 trace_xfs_log_recover_item_add(log, trans, item, 0);
1598 return 0;
1599}
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650STATIC int
1651xlog_recover_reorder_trans(
1652 struct xlog *log,
1653 struct xlog_recover *trans,
1654 int pass)
1655{
1656 xlog_recover_item_t *item, *n;
1657 int error = 0;
1658 LIST_HEAD(sort_list);
1659 LIST_HEAD(cancel_list);
1660 LIST_HEAD(buffer_list);
1661 LIST_HEAD(inode_buffer_list);
1662 LIST_HEAD(inode_list);
1663
1664 list_splice_init(&trans->r_itemq, &sort_list);
1665 list_for_each_entry_safe(item, n, &sort_list, ri_list) {
1666 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
1667
1668 switch (ITEM_TYPE(item)) {
1669 case XFS_LI_ICREATE:
1670 list_move_tail(&item->ri_list, &buffer_list);
1671 break;
1672 case XFS_LI_BUF:
1673 if (buf_f->blf_flags & XFS_BLF_CANCEL) {
1674 trace_xfs_log_recover_item_reorder_head(log,
1675 trans, item, pass);
1676 list_move(&item->ri_list, &cancel_list);
1677 break;
1678 }
1679 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
1680 list_move(&item->ri_list, &inode_buffer_list);
1681 break;
1682 }
1683 list_move_tail(&item->ri_list, &buffer_list);
1684 break;
1685 case XFS_LI_INODE:
1686 case XFS_LI_DQUOT:
1687 case XFS_LI_QUOTAOFF:
1688 case XFS_LI_EFD:
1689 case XFS_LI_EFI:
1690 trace_xfs_log_recover_item_reorder_tail(log,
1691 trans, item, pass);
1692 list_move_tail(&item->ri_list, &inode_list);
1693 break;
1694 default:
1695 xfs_warn(log->l_mp,
1696 "%s: unrecognized type of log operation",
1697 __func__);
1698 ASSERT(0);
1699
1700
1701
1702
1703 if (!list_empty(&sort_list))
1704 list_splice_init(&sort_list, &trans->r_itemq);
1705 error = XFS_ERROR(EIO);
1706 goto out;
1707 }
1708 }
1709out:
1710 ASSERT(list_empty(&sort_list));
1711 if (!list_empty(&buffer_list))
1712 list_splice(&buffer_list, &trans->r_itemq);
1713 if (!list_empty(&inode_list))
1714 list_splice_tail(&inode_list, &trans->r_itemq);
1715 if (!list_empty(&inode_buffer_list))
1716 list_splice_tail(&inode_buffer_list, &trans->r_itemq);
1717 if (!list_empty(&cancel_list))
1718 list_splice_tail(&cancel_list, &trans->r_itemq);
1719 return error;
1720}
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734STATIC int
1735xlog_recover_buffer_pass1(
1736 struct xlog *log,
1737 struct xlog_recover_item *item)
1738{
1739 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
1740 struct list_head *bucket;
1741 struct xfs_buf_cancel *bcp;
1742
1743
1744
1745
1746 if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
1747 trace_xfs_log_recover_buf_not_cancel(log, buf_f);
1748 return 0;
1749 }
1750
1751
1752
1753
1754
1755 bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno);
1756 list_for_each_entry(bcp, bucket, bc_list) {
1757 if (bcp->bc_blkno == buf_f->blf_blkno &&
1758 bcp->bc_len == buf_f->blf_len) {
1759 bcp->bc_refcount++;
1760 trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f);
1761 return 0;
1762 }
1763 }
1764
1765 bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP);
1766 bcp->bc_blkno = buf_f->blf_blkno;
1767 bcp->bc_len = buf_f->blf_len;
1768 bcp->bc_refcount = 1;
1769 list_add_tail(&bcp->bc_list, bucket);
1770
1771 trace_xfs_log_recover_buf_cancel_add(log, buf_f);
1772 return 0;
1773}
1774
1775
1776
1777
1778
1779
1780STATIC struct xfs_buf_cancel *
1781xlog_peek_buffer_cancelled(
1782 struct xlog *log,
1783 xfs_daddr_t blkno,
1784 uint len,
1785 ushort flags)
1786{
1787 struct list_head *bucket;
1788 struct xfs_buf_cancel *bcp;
1789
1790 if (!log->l_buf_cancel_table) {
1791
1792 ASSERT(!(flags & XFS_BLF_CANCEL));
1793 return NULL;
1794 }
1795
1796 bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno);
1797 list_for_each_entry(bcp, bucket, bc_list) {
1798 if (bcp->bc_blkno == blkno && bcp->bc_len == len)
1799 return bcp;
1800 }
1801
1802
1803
1804
1805
1806 ASSERT(!(flags & XFS_BLF_CANCEL));
1807 return NULL;
1808}
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820STATIC int
1821xlog_check_buffer_cancelled(
1822 struct xlog *log,
1823 xfs_daddr_t blkno,
1824 uint len,
1825 ushort flags)
1826{
1827 struct xfs_buf_cancel *bcp;
1828
1829 bcp = xlog_peek_buffer_cancelled(log, blkno, len, flags);
1830 if (!bcp)
1831 return 0;
1832
1833
1834
1835
1836
1837
1838
1839 if (flags & XFS_BLF_CANCEL) {
1840 if (--bcp->bc_refcount == 0) {
1841 list_del(&bcp->bc_list);
1842 kmem_free(bcp);
1843 }
1844 }
1845 return 1;
1846}
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860STATIC int
1861xlog_recover_do_inode_buffer(
1862 struct xfs_mount *mp,
1863 xlog_recover_item_t *item,
1864 struct xfs_buf *bp,
1865 xfs_buf_log_format_t *buf_f)
1866{
1867 int i;
1868 int item_index = 0;
1869 int bit = 0;
1870 int nbits = 0;
1871 int reg_buf_offset = 0;
1872 int reg_buf_bytes = 0;
1873 int next_unlinked_offset;
1874 int inodes_per_buf;
1875 xfs_agino_t *logged_nextp;
1876 xfs_agino_t *buffer_nextp;
1877
1878 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
1879
1880
1881
1882
1883
1884 if (xfs_sb_version_hascrc(&mp->m_sb))
1885 bp->b_ops = &xfs_inode_buf_ops;
1886
1887 inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
1888 for (i = 0; i < inodes_per_buf; i++) {
1889 next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
1890 offsetof(xfs_dinode_t, di_next_unlinked);
1891
1892 while (next_unlinked_offset >=
1893 (reg_buf_offset + reg_buf_bytes)) {
1894
1895
1896
1897
1898
1899
1900 bit += nbits;
1901 bit = xfs_next_bit(buf_f->blf_data_map,
1902 buf_f->blf_map_size, bit);
1903
1904
1905
1906
1907
1908 if (bit == -1)
1909 return 0;
1910
1911 nbits = xfs_contig_bits(buf_f->blf_data_map,
1912 buf_f->blf_map_size, bit);
1913 ASSERT(nbits > 0);
1914 reg_buf_offset = bit << XFS_BLF_SHIFT;
1915 reg_buf_bytes = nbits << XFS_BLF_SHIFT;
1916 item_index++;
1917 }
1918
1919
1920
1921
1922
1923
1924 if (next_unlinked_offset < reg_buf_offset)
1925 continue;
1926
1927 ASSERT(item->ri_buf[item_index].i_addr != NULL);
1928 ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
1929 ASSERT((reg_buf_offset + reg_buf_bytes) <=
1930 BBTOB(bp->b_io_length));
1931
1932
1933
1934
1935
1936
1937 logged_nextp = item->ri_buf[item_index].i_addr +
1938 next_unlinked_offset - reg_buf_offset;
1939 if (unlikely(*logged_nextp == 0)) {
1940 xfs_alert(mp,
1941 "Bad inode buffer log record (ptr = 0x%p, bp = 0x%p). "
1942 "Trying to replay bad (0) inode di_next_unlinked field.",
1943 item, bp);
1944 XFS_ERROR_REPORT("xlog_recover_do_inode_buf",
1945 XFS_ERRLEVEL_LOW, mp);
1946 return XFS_ERROR(EFSCORRUPTED);
1947 }
1948
1949 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
1950 next_unlinked_offset);
1951 *buffer_nextp = *logged_nextp;
1952
1953
1954
1955
1956
1957
1958 xfs_dinode_calc_crc(mp, (struct xfs_dinode *)
1959 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
1960
1961 }
1962
1963 return 0;
1964}
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986static xfs_lsn_t
1987xlog_recover_get_buf_lsn(
1988 struct xfs_mount *mp,
1989 struct xfs_buf *bp)
1990{
1991 __uint32_t magic32;
1992 __uint16_t magic16;
1993 __uint16_t magicda;
1994 void *blk = bp->b_addr;
1995 uuid_t *uuid;
1996 xfs_lsn_t lsn = -1;
1997
1998
1999 if (!xfs_sb_version_hascrc(&mp->m_sb))
2000 goto recover_immediately;
2001
2002 magic32 = be32_to_cpu(*(__be32 *)blk);
2003 switch (magic32) {
2004 case XFS_ABTB_CRC_MAGIC:
2005 case XFS_ABTC_CRC_MAGIC:
2006 case XFS_ABTB_MAGIC:
2007 case XFS_ABTC_MAGIC:
2008 case XFS_IBT_CRC_MAGIC:
2009 case XFS_IBT_MAGIC: {
2010 struct xfs_btree_block *btb = blk;
2011
2012 lsn = be64_to_cpu(btb->bb_u.s.bb_lsn);
2013 uuid = &btb->bb_u.s.bb_uuid;
2014 break;
2015 }
2016 case XFS_BMAP_CRC_MAGIC:
2017 case XFS_BMAP_MAGIC: {
2018 struct xfs_btree_block *btb = blk;
2019
2020 lsn = be64_to_cpu(btb->bb_u.l.bb_lsn);
2021 uuid = &btb->bb_u.l.bb_uuid;
2022 break;
2023 }
2024 case XFS_AGF_MAGIC:
2025 lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn);
2026 uuid = &((struct xfs_agf *)blk)->agf_uuid;
2027 break;
2028 case XFS_AGFL_MAGIC:
2029 lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn);
2030 uuid = &((struct xfs_agfl *)blk)->agfl_uuid;
2031 break;
2032 case XFS_AGI_MAGIC:
2033 lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn);
2034 uuid = &((struct xfs_agi *)blk)->agi_uuid;
2035 break;
2036 case XFS_SYMLINK_MAGIC:
2037 lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn);
2038 uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid;
2039 break;
2040 case XFS_DIR3_BLOCK_MAGIC:
2041 case XFS_DIR3_DATA_MAGIC:
2042 case XFS_DIR3_FREE_MAGIC:
2043 lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn);
2044 uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid;
2045 break;
2046 case XFS_ATTR3_RMT_MAGIC:
2047 lsn = be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn);
2048 uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid;
2049 break;
2050 case XFS_SB_MAGIC:
2051 lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn);
2052 uuid = &((struct xfs_dsb *)blk)->sb_uuid;
2053 break;
2054 default:
2055 break;
2056 }
2057
2058 if (lsn != (xfs_lsn_t)-1) {
2059 if (!uuid_equal(&mp->m_sb.sb_uuid, uuid))
2060 goto recover_immediately;
2061 return lsn;
2062 }
2063
2064 magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic);
2065 switch (magicda) {
2066 case XFS_DIR3_LEAF1_MAGIC:
2067 case XFS_DIR3_LEAFN_MAGIC:
2068 case XFS_DA3_NODE_MAGIC:
2069 lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn);
2070 uuid = &((struct xfs_da3_blkinfo *)blk)->uuid;
2071 break;
2072 default:
2073 break;
2074 }
2075
2076 if (lsn != (xfs_lsn_t)-1) {
2077 if (!uuid_equal(&mp->m_sb.sb_uuid, uuid))
2078 goto recover_immediately;
2079 return lsn;
2080 }
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093 magic16 = be16_to_cpu(*(__be16 *)blk);
2094 switch (magic16) {
2095 case XFS_DQUOT_MAGIC:
2096 case XFS_DINODE_MAGIC:
2097 goto recover_immediately;
2098 default:
2099 break;
2100 }
2101
2102
2103
2104recover_immediately:
2105 return (xfs_lsn_t)-1;
2106
2107}
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117static void
2118xlog_recover_validate_buf_type(
2119 struct xfs_mount *mp,
2120 struct xfs_buf *bp,
2121 xfs_buf_log_format_t *buf_f)
2122{
2123 struct xfs_da_blkinfo *info = bp->b_addr;
2124 __uint32_t magic32;
2125 __uint16_t magic16;
2126 __uint16_t magicda;
2127
2128 magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
2129 magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
2130 magicda = be16_to_cpu(info->magic);
2131 switch (xfs_blft_from_flags(buf_f)) {
2132 case XFS_BLFT_BTREE_BUF:
2133 switch (magic32) {
2134 case XFS_ABTB_CRC_MAGIC:
2135 case XFS_ABTC_CRC_MAGIC:
2136 case XFS_ABTB_MAGIC:
2137 case XFS_ABTC_MAGIC:
2138 bp->b_ops = &xfs_allocbt_buf_ops;
2139 break;
2140 case XFS_IBT_CRC_MAGIC:
2141 case XFS_FIBT_CRC_MAGIC:
2142 case XFS_IBT_MAGIC:
2143 case XFS_FIBT_MAGIC:
2144 bp->b_ops = &xfs_inobt_buf_ops;
2145 break;
2146 case XFS_BMAP_CRC_MAGIC:
2147 case XFS_BMAP_MAGIC:
2148 bp->b_ops = &xfs_bmbt_buf_ops;
2149 break;
2150 default:
2151 xfs_warn(mp, "Bad btree block magic!");
2152 ASSERT(0);
2153 break;
2154 }
2155 break;
2156 case XFS_BLFT_AGF_BUF:
2157 if (magic32 != XFS_AGF_MAGIC) {
2158 xfs_warn(mp, "Bad AGF block magic!");
2159 ASSERT(0);
2160 break;
2161 }
2162 bp->b_ops = &xfs_agf_buf_ops;
2163 break;
2164 case XFS_BLFT_AGFL_BUF:
2165 if (!xfs_sb_version_hascrc(&mp->m_sb))
2166 break;
2167 if (magic32 != XFS_AGFL_MAGIC) {
2168 xfs_warn(mp, "Bad AGFL block magic!");
2169 ASSERT(0);
2170 break;
2171 }
2172 bp->b_ops = &xfs_agfl_buf_ops;
2173 break;
2174 case XFS_BLFT_AGI_BUF:
2175 if (magic32 != XFS_AGI_MAGIC) {
2176 xfs_warn(mp, "Bad AGI block magic!");
2177 ASSERT(0);
2178 break;
2179 }
2180 bp->b_ops = &xfs_agi_buf_ops;
2181 break;
2182 case XFS_BLFT_UDQUOT_BUF:
2183 case XFS_BLFT_PDQUOT_BUF:
2184 case XFS_BLFT_GDQUOT_BUF:
2185#ifdef CONFIG_XFS_QUOTA
2186 if (magic16 != XFS_DQUOT_MAGIC) {
2187 xfs_warn(mp, "Bad DQUOT block magic!");
2188 ASSERT(0);
2189 break;
2190 }
2191 bp->b_ops = &xfs_dquot_buf_ops;
2192#else
2193 xfs_alert(mp,
2194 "Trying to recover dquots without QUOTA support built in!");
2195 ASSERT(0);
2196#endif
2197 break;
2198 case XFS_BLFT_DINO_BUF:
2199
2200
2201
2202
2203 if (magic16 != XFS_DINODE_MAGIC) {
2204 xfs_warn(mp, "Bad INODE block magic!");
2205 ASSERT(0);
2206 break;
2207 }
2208 bp->b_ops = &xfs_inode_buf_ops;
2209 break;
2210 case XFS_BLFT_SYMLINK_BUF:
2211 if (magic32 != XFS_SYMLINK_MAGIC) {
2212 xfs_warn(mp, "Bad symlink block magic!");
2213 ASSERT(0);
2214 break;
2215 }
2216 bp->b_ops = &xfs_symlink_buf_ops;
2217 break;
2218 case XFS_BLFT_DIR_BLOCK_BUF:
2219 if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
2220 magic32 != XFS_DIR3_BLOCK_MAGIC) {
2221 xfs_warn(mp, "Bad dir block magic!");
2222 ASSERT(0);
2223 break;
2224 }
2225 bp->b_ops = &xfs_dir3_block_buf_ops;
2226 break;
2227 case XFS_BLFT_DIR_DATA_BUF:
2228 if (magic32 != XFS_DIR2_DATA_MAGIC &&
2229 magic32 != XFS_DIR3_DATA_MAGIC) {
2230 xfs_warn(mp, "Bad dir data magic!");
2231 ASSERT(0);
2232 break;
2233 }
2234 bp->b_ops = &xfs_dir3_data_buf_ops;
2235 break;
2236 case XFS_BLFT_DIR_FREE_BUF:
2237 if (magic32 != XFS_DIR2_FREE_MAGIC &&
2238 magic32 != XFS_DIR3_FREE_MAGIC) {
2239 xfs_warn(mp, "Bad dir3 free magic!");
2240 ASSERT(0);
2241 break;
2242 }
2243 bp->b_ops = &xfs_dir3_free_buf_ops;
2244 break;
2245 case XFS_BLFT_DIR_LEAF1_BUF:
2246 if (magicda != XFS_DIR2_LEAF1_MAGIC &&
2247 magicda != XFS_DIR3_LEAF1_MAGIC) {
2248 xfs_warn(mp, "Bad dir leaf1 magic!");
2249 ASSERT(0);
2250 break;
2251 }
2252 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
2253 break;
2254 case XFS_BLFT_DIR_LEAFN_BUF:
2255 if (magicda != XFS_DIR2_LEAFN_MAGIC &&
2256 magicda != XFS_DIR3_LEAFN_MAGIC) {
2257 xfs_warn(mp, "Bad dir leafn magic!");
2258 ASSERT(0);
2259 break;
2260 }
2261 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2262 break;
2263 case XFS_BLFT_DA_NODE_BUF:
2264 if (magicda != XFS_DA_NODE_MAGIC &&
2265 magicda != XFS_DA3_NODE_MAGIC) {
2266 xfs_warn(mp, "Bad da node magic!");
2267 ASSERT(0);
2268 break;
2269 }
2270 bp->b_ops = &xfs_da3_node_buf_ops;
2271 break;
2272 case XFS_BLFT_ATTR_LEAF_BUF:
2273 if (magicda != XFS_ATTR_LEAF_MAGIC &&
2274 magicda != XFS_ATTR3_LEAF_MAGIC) {
2275 xfs_warn(mp, "Bad attr leaf magic!");
2276 ASSERT(0);
2277 break;
2278 }
2279 bp->b_ops = &xfs_attr3_leaf_buf_ops;
2280 break;
2281 case XFS_BLFT_ATTR_RMT_BUF:
2282 if (!xfs_sb_version_hascrc(&mp->m_sb))
2283 break;
2284 if (magic32 != XFS_ATTR3_RMT_MAGIC) {
2285 xfs_warn(mp, "Bad attr remote magic!");
2286 ASSERT(0);
2287 break;
2288 }
2289 bp->b_ops = &xfs_attr3_rmt_buf_ops;
2290 break;
2291 case XFS_BLFT_SB_BUF:
2292 if (magic32 != XFS_SB_MAGIC) {
2293 xfs_warn(mp, "Bad SB block magic!");
2294 ASSERT(0);
2295 break;
2296 }
2297 bp->b_ops = &xfs_sb_buf_ops;
2298 break;
2299 default:
2300 xfs_warn(mp, "Unknown buffer type %d!",
2301 xfs_blft_from_flags(buf_f));
2302 break;
2303 }
2304}
2305
2306
2307
2308
2309
2310
2311
2312STATIC void
2313xlog_recover_do_reg_buffer(
2314 struct xfs_mount *mp,
2315 xlog_recover_item_t *item,
2316 struct xfs_buf *bp,
2317 xfs_buf_log_format_t *buf_f)
2318{
2319 int i;
2320 int bit;
2321 int nbits;
2322 int error;
2323
2324 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
2325
2326 bit = 0;
2327 i = 1;
2328 while (1) {
2329 bit = xfs_next_bit(buf_f->blf_data_map,
2330 buf_f->blf_map_size, bit);
2331 if (bit == -1)
2332 break;
2333 nbits = xfs_contig_bits(buf_f->blf_data_map,
2334 buf_f->blf_map_size, bit);
2335 ASSERT(nbits > 0);
2336 ASSERT(item->ri_buf[i].i_addr != NULL);
2337 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
2338 ASSERT(BBTOB(bp->b_io_length) >=
2339 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349 if (item->ri_buf[i].i_len < (nbits << XFS_BLF_SHIFT))
2350 nbits = item->ri_buf[i].i_len >> XFS_BLF_SHIFT;
2351
2352
2353
2354
2355
2356
2357 error = 0;
2358 if (buf_f->blf_flags &
2359 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2360 if (item->ri_buf[i].i_addr == NULL) {
2361 xfs_alert(mp,
2362 "XFS: NULL dquot in %s.", __func__);
2363 goto next;
2364 }
2365 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
2366 xfs_alert(mp,
2367 "XFS: dquot too small (%d) in %s.",
2368 item->ri_buf[i].i_len, __func__);
2369 goto next;
2370 }
2371 error = xfs_dqcheck(mp, item->ri_buf[i].i_addr,
2372 -1, 0, XFS_QMOPT_DOWARN,
2373 "dquot_buf_recover");
2374 if (error)
2375 goto next;
2376 }
2377
2378 memcpy(xfs_buf_offset(bp,
2379 (uint)bit << XFS_BLF_SHIFT),
2380 item->ri_buf[i].i_addr,
2381 nbits<<XFS_BLF_SHIFT);
2382 next:
2383 i++;
2384 bit += nbits;
2385 }
2386
2387
2388 ASSERT(i == item->ri_total);
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398 if (xfs_sb_version_hascrc(&mp->m_sb))
2399 xlog_recover_validate_buf_type(mp, bp, buf_f);
2400}
2401
2402
2403
2404
2405
2406
2407
2408STATIC void
2409xlog_recover_do_dquot_buffer(
2410 struct xfs_mount *mp,
2411 struct xlog *log,
2412 struct xlog_recover_item *item,
2413 struct xfs_buf *bp,
2414 struct xfs_buf_log_format *buf_f)
2415{
2416 uint type;
2417
2418 trace_xfs_log_recover_buf_dquot_buf(log, buf_f);
2419
2420
2421
2422
2423 if (mp->m_qflags == 0) {
2424 return;
2425 }
2426
2427 type = 0;
2428 if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF)
2429 type |= XFS_DQ_USER;
2430 if (buf_f->blf_flags & XFS_BLF_PDQUOT_BUF)
2431 type |= XFS_DQ_PROJ;
2432 if (buf_f->blf_flags & XFS_BLF_GDQUOT_BUF)
2433 type |= XFS_DQ_GROUP;
2434
2435
2436
2437 if (log->l_quotaoffs_flag & type)
2438 return;
2439
2440 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2441}
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466STATIC int
2467xlog_recover_buffer_pass2(
2468 struct xlog *log,
2469 struct list_head *buffer_list,
2470 struct xlog_recover_item *item,
2471 xfs_lsn_t current_lsn)
2472{
2473 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
2474 xfs_mount_t *mp = log->l_mp;
2475 xfs_buf_t *bp;
2476 int error;
2477 uint buf_flags;
2478 xfs_lsn_t lsn;
2479
2480
2481
2482
2483
2484 if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno,
2485 buf_f->blf_len, buf_f->blf_flags)) {
2486 trace_xfs_log_recover_buf_cancel(log, buf_f);
2487 return 0;
2488 }
2489
2490 trace_xfs_log_recover_buf_recover(log, buf_f);
2491
2492 buf_flags = 0;
2493 if (buf_f->blf_flags & XFS_BLF_INODE_BUF)
2494 buf_flags |= XBF_UNMAPPED;
2495
2496 bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
2497 buf_flags, NULL);
2498 if (!bp)
2499 return XFS_ERROR(ENOMEM);
2500 error = bp->b_error;
2501 if (error) {
2502 xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#1)");
2503 goto out_release;
2504 }
2505
2506
2507
2508
2509
2510 lsn = xlog_recover_get_buf_lsn(mp, bp);
2511 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0)
2512 goto out_release;
2513
2514 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
2515 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2516 } else if (buf_f->blf_flags &
2517 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2518 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2519 } else {
2520 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2521 }
2522 if (error)
2523 goto out_release;
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540 if (XFS_DINODE_MAGIC ==
2541 be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
2542 (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize,
2543 (__uint32_t)log->l_mp->m_inode_cluster_size))) {
2544 xfs_buf_stale(bp);
2545 error = xfs_bwrite(bp);
2546 } else {
2547 ASSERT(bp->b_target->bt_mount == mp);
2548 bp->b_iodone = xlog_recover_iodone;
2549 xfs_buf_delwri_queue(bp, buffer_list);
2550 }
2551
2552out_release:
2553 xfs_buf_relse(bp);
2554 return error;
2555}
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587STATIC int
2588xfs_recover_inode_owner_change(
2589 struct xfs_mount *mp,
2590 struct xfs_dinode *dip,
2591 struct xfs_inode_log_format *in_f,
2592 struct list_head *buffer_list)
2593{
2594 struct xfs_inode *ip;
2595 int error;
2596
2597 ASSERT(in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER));
2598
2599 ip = xfs_inode_alloc(mp, in_f->ilf_ino);
2600 if (!ip)
2601 return ENOMEM;
2602
2603
2604 xfs_dinode_from_disk(&ip->i_d, dip);
2605 ASSERT(ip->i_d.di_version >= 3);
2606
2607 error = xfs_iformat_fork(ip, dip);
2608 if (error)
2609 goto out_free_ip;
2610
2611
2612 if (in_f->ilf_fields & XFS_ILOG_DOWNER) {
2613 ASSERT(in_f->ilf_fields & XFS_ILOG_DBROOT);
2614 error = xfs_bmbt_change_owner(NULL, ip, XFS_DATA_FORK,
2615 ip->i_ino, buffer_list);
2616 if (error)
2617 goto out_free_ip;
2618 }
2619
2620 if (in_f->ilf_fields & XFS_ILOG_AOWNER) {
2621 ASSERT(in_f->ilf_fields & XFS_ILOG_ABROOT);
2622 error = xfs_bmbt_change_owner(NULL, ip, XFS_ATTR_FORK,
2623 ip->i_ino, buffer_list);
2624 if (error)
2625 goto out_free_ip;
2626 }
2627
2628out_free_ip:
2629 xfs_inode_free(ip);
2630 return error;
2631}
2632
2633STATIC int
2634xlog_recover_inode_pass2(
2635 struct xlog *log,
2636 struct list_head *buffer_list,
2637 struct xlog_recover_item *item,
2638 xfs_lsn_t current_lsn)
2639{
2640 xfs_inode_log_format_t *in_f;
2641 xfs_mount_t *mp = log->l_mp;
2642 xfs_buf_t *bp;
2643 xfs_dinode_t *dip;
2644 int len;
2645 xfs_caddr_t src;
2646 xfs_caddr_t dest;
2647 int error;
2648 int attr_index;
2649 uint fields;
2650 xfs_icdinode_t *dicp;
2651 uint isize;
2652 int need_free = 0;
2653
2654 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2655 in_f = item->ri_buf[0].i_addr;
2656 } else {
2657 in_f = kmem_alloc(sizeof(xfs_inode_log_format_t), KM_SLEEP);
2658 need_free = 1;
2659 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2660 if (error)
2661 goto error;
2662 }
2663
2664
2665
2666
2667
2668 if (xlog_check_buffer_cancelled(log, in_f->ilf_blkno,
2669 in_f->ilf_len, 0)) {
2670 error = 0;
2671 trace_xfs_log_recover_inode_cancel(log, in_f);
2672 goto error;
2673 }
2674 trace_xfs_log_recover_inode_recover(log, in_f);
2675
2676 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0,
2677 &xfs_inode_buf_ops);
2678 if (!bp) {
2679 error = ENOMEM;
2680 goto error;
2681 }
2682 error = bp->b_error;
2683 if (error) {
2684 xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#2)");
2685 goto out_release;
2686 }
2687 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
2688 dip = (xfs_dinode_t *)xfs_buf_offset(bp, in_f->ilf_boffset);
2689
2690
2691
2692
2693
2694 if (unlikely(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))) {
2695 xfs_alert(mp,
2696 "%s: Bad inode magic number, dip = 0x%p, dino bp = 0x%p, ino = %Ld",
2697 __func__, dip, bp, in_f->ilf_ino);
2698 XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)",
2699 XFS_ERRLEVEL_LOW, mp);
2700 error = EFSCORRUPTED;
2701 goto out_release;
2702 }
2703 dicp = item->ri_buf[1].i_addr;
2704 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
2705 xfs_alert(mp,
2706 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld",
2707 __func__, item, in_f->ilf_ino);
2708 XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)",
2709 XFS_ERRLEVEL_LOW, mp);
2710 error = EFSCORRUPTED;
2711 goto out_release;
2712 }
2713
2714
2715
2716
2717
2718
2719
2720
2721 if (dip->di_version >= 3) {
2722 xfs_lsn_t lsn = be64_to_cpu(dip->di_lsn);
2723
2724 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
2725 trace_xfs_log_recover_inode_skip(log, in_f);
2726 error = 0;
2727 goto out_owner_change;
2728 }
2729 }
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739 if (!xfs_sb_version_hascrc(&mp->m_sb) &&
2740 dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
2741
2742
2743
2744
2745 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
2746 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
2747
2748 } else {
2749 trace_xfs_log_recover_inode_skip(log, in_f);
2750 error = 0;
2751 goto out_release;
2752 }
2753 }
2754
2755
2756 dicp->di_flushiter = 0;
2757
2758 if (unlikely(S_ISREG(dicp->di_mode))) {
2759 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
2760 (dicp->di_format != XFS_DINODE_FMT_BTREE)) {
2761 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
2762 XFS_ERRLEVEL_LOW, mp, dicp);
2763 xfs_alert(mp,
2764 "%s: Bad regular inode log record, rec ptr 0x%p, "
2765 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2766 __func__, item, dip, bp, in_f->ilf_ino);
2767 error = EFSCORRUPTED;
2768 goto out_release;
2769 }
2770 } else if (unlikely(S_ISDIR(dicp->di_mode))) {
2771 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
2772 (dicp->di_format != XFS_DINODE_FMT_BTREE) &&
2773 (dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
2774 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
2775 XFS_ERRLEVEL_LOW, mp, dicp);
2776 xfs_alert(mp,
2777 "%s: Bad dir inode log record, rec ptr 0x%p, "
2778 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2779 __func__, item, dip, bp, in_f->ilf_ino);
2780 error = EFSCORRUPTED;
2781 goto out_release;
2782 }
2783 }
2784 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
2785 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
2786 XFS_ERRLEVEL_LOW, mp, dicp);
2787 xfs_alert(mp,
2788 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
2789 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
2790 __func__, item, dip, bp, in_f->ilf_ino,
2791 dicp->di_nextents + dicp->di_anextents,
2792 dicp->di_nblocks);
2793 error = EFSCORRUPTED;
2794 goto out_release;
2795 }
2796 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
2797 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
2798 XFS_ERRLEVEL_LOW, mp, dicp);
2799 xfs_alert(mp,
2800 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
2801 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__,
2802 item, dip, bp, in_f->ilf_ino, dicp->di_forkoff);
2803 error = EFSCORRUPTED;
2804 goto out_release;
2805 }
2806 isize = xfs_icdinode_size(dicp->di_version);
2807 if (unlikely(item->ri_buf[1].i_len > isize)) {
2808 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
2809 XFS_ERRLEVEL_LOW, mp, dicp);
2810 xfs_alert(mp,
2811 "%s: Bad inode log record length %d, rec ptr 0x%p",
2812 __func__, item->ri_buf[1].i_len, item);
2813 error = EFSCORRUPTED;
2814 goto out_release;
2815 }
2816
2817
2818 xfs_dinode_to_disk(dip, dicp);
2819
2820
2821 if (item->ri_buf[1].i_len > isize) {
2822 memcpy((char *)dip + isize,
2823 item->ri_buf[1].i_addr + isize,
2824 item->ri_buf[1].i_len - isize);
2825 }
2826
2827 fields = in_f->ilf_fields;
2828 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
2829 case XFS_ILOG_DEV:
2830 xfs_dinode_put_rdev(dip, in_f->ilf_u.ilfu_rdev);
2831 break;
2832 case XFS_ILOG_UUID:
2833 memcpy(XFS_DFORK_DPTR(dip),
2834 &in_f->ilf_u.ilfu_uuid,
2835 sizeof(uuid_t));
2836 break;
2837 }
2838
2839 if (in_f->ilf_size == 2)
2840 goto out_owner_change;
2841 len = item->ri_buf[2].i_len;
2842 src = item->ri_buf[2].i_addr;
2843 ASSERT(in_f->ilf_size <= 4);
2844 ASSERT((in_f->ilf_size == 3) || (fields & XFS_ILOG_AFORK));
2845 ASSERT(!(fields & XFS_ILOG_DFORK) ||
2846 (len == in_f->ilf_dsize));
2847
2848 switch (fields & XFS_ILOG_DFORK) {
2849 case XFS_ILOG_DDATA:
2850 case XFS_ILOG_DEXT:
2851 memcpy(XFS_DFORK_DPTR(dip), src, len);
2852 break;
2853
2854 case XFS_ILOG_DBROOT:
2855 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len,
2856 (xfs_bmdr_block_t *)XFS_DFORK_DPTR(dip),
2857 XFS_DFORK_DSIZE(dip, mp));
2858 break;
2859
2860 default:
2861
2862
2863
2864 ASSERT((fields & XFS_ILOG_DFORK) == 0);
2865 break;
2866 }
2867
2868
2869
2870
2871
2872
2873 if (in_f->ilf_fields & XFS_ILOG_AFORK) {
2874 if (in_f->ilf_fields & XFS_ILOG_DFORK) {
2875 attr_index = 3;
2876 } else {
2877 attr_index = 2;
2878 }
2879 len = item->ri_buf[attr_index].i_len;
2880 src = item->ri_buf[attr_index].i_addr;
2881 ASSERT(len == in_f->ilf_asize);
2882
2883 switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
2884 case XFS_ILOG_ADATA:
2885 case XFS_ILOG_AEXT:
2886 dest = XFS_DFORK_APTR(dip);
2887 ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
2888 memcpy(dest, src, len);
2889 break;
2890
2891 case XFS_ILOG_ABROOT:
2892 dest = XFS_DFORK_APTR(dip);
2893 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src,
2894 len, (xfs_bmdr_block_t*)dest,
2895 XFS_DFORK_ASIZE(dip, mp));
2896 break;
2897
2898 default:
2899 xfs_warn(log->l_mp, "%s: Invalid flag", __func__);
2900 ASSERT(0);
2901 error = EIO;
2902 goto out_release;
2903 }
2904 }
2905
2906out_owner_change:
2907 if (in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER))
2908 error = xfs_recover_inode_owner_change(mp, dip, in_f,
2909 buffer_list);
2910
2911 xfs_dinode_calc_crc(log->l_mp, dip);
2912
2913 ASSERT(bp->b_target->bt_mount == mp);
2914 bp->b_iodone = xlog_recover_iodone;
2915 xfs_buf_delwri_queue(bp, buffer_list);
2916
2917out_release:
2918 xfs_buf_relse(bp);
2919error:
2920 if (need_free)
2921 kmem_free(in_f);
2922 return XFS_ERROR(error);
2923}
2924
2925
2926
2927
2928
2929
2930STATIC int
2931xlog_recover_quotaoff_pass1(
2932 struct xlog *log,
2933 struct xlog_recover_item *item)
2934{
2935 xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr;
2936 ASSERT(qoff_f);
2937
2938
2939
2940
2941
2942 if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
2943 log->l_quotaoffs_flag |= XFS_DQ_USER;
2944 if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
2945 log->l_quotaoffs_flag |= XFS_DQ_PROJ;
2946 if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
2947 log->l_quotaoffs_flag |= XFS_DQ_GROUP;
2948
2949 return (0);
2950}
2951
2952
2953
2954
2955STATIC int
2956xlog_recover_dquot_pass2(
2957 struct xlog *log,
2958 struct list_head *buffer_list,
2959 struct xlog_recover_item *item,
2960 xfs_lsn_t current_lsn)
2961{
2962 xfs_mount_t *mp = log->l_mp;
2963 xfs_buf_t *bp;
2964 struct xfs_disk_dquot *ddq, *recddq;
2965 int error;
2966 xfs_dq_logformat_t *dq_f;
2967 uint type;
2968
2969
2970
2971
2972
2973 if (mp->m_qflags == 0)
2974 return (0);
2975
2976 recddq = item->ri_buf[1].i_addr;
2977 if (recddq == NULL) {
2978 xfs_alert(log->l_mp, "NULL dquot in %s.", __func__);
2979 return XFS_ERROR(EIO);
2980 }
2981 if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
2982 xfs_alert(log->l_mp, "dquot too small (%d) in %s.",
2983 item->ri_buf[1].i_len, __func__);
2984 return XFS_ERROR(EIO);
2985 }
2986
2987
2988
2989
2990 type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
2991 ASSERT(type);
2992 if (log->l_quotaoffs_flag & type)
2993 return (0);
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005 dq_f = item->ri_buf[0].i_addr;
3006 ASSERT(dq_f);
3007 error = xfs_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
3008 "xlog_recover_dquot_pass2 (log copy)");
3009 if (error)
3010 return XFS_ERROR(EIO);
3011 ASSERT(dq_f->qlf_len == 1);
3012
3013 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno,
3014 XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp,
3015 NULL);
3016 if (error)
3017 return error;
3018
3019 ASSERT(bp);
3020 ddq = (xfs_disk_dquot_t *)xfs_buf_offset(bp, dq_f->qlf_boffset);
3021
3022
3023
3024
3025
3026
3027 error = xfs_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
3028 "xlog_recover_dquot_pass2");
3029 if (error) {
3030 xfs_buf_relse(bp);
3031 return XFS_ERROR(EIO);
3032 }
3033
3034
3035
3036
3037
3038 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3039 struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddq;
3040 xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn);
3041
3042 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
3043 goto out_release;
3044 }
3045 }
3046
3047 memcpy(ddq, recddq, item->ri_buf[1].i_len);
3048 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3049 xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
3050 XFS_DQUOT_CRC_OFF);
3051 }
3052
3053 ASSERT(dq_f->qlf_size == 2);
3054 ASSERT(bp->b_target->bt_mount == mp);
3055 bp->b_iodone = xlog_recover_iodone;
3056 xfs_buf_delwri_queue(bp, buffer_list);
3057
3058out_release:
3059 xfs_buf_relse(bp);
3060 return 0;
3061}
3062
3063
3064
3065
3066
3067
3068
3069
3070STATIC int
3071xlog_recover_efi_pass2(
3072 struct xlog *log,
3073 struct xlog_recover_item *item,
3074 xfs_lsn_t lsn)
3075{
3076 int error;
3077 xfs_mount_t *mp = log->l_mp;
3078 xfs_efi_log_item_t *efip;
3079 xfs_efi_log_format_t *efi_formatp;
3080
3081 efi_formatp = item->ri_buf[0].i_addr;
3082
3083 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
3084 if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
3085 &(efip->efi_format)))) {
3086 xfs_efi_item_free(efip);
3087 return error;
3088 }
3089 atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
3090
3091 spin_lock(&log->l_ailp->xa_lock);
3092
3093
3094
3095 xfs_trans_ail_update(log->l_ailp, &efip->efi_item, lsn);
3096 return 0;
3097}
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108STATIC int
3109xlog_recover_efd_pass2(
3110 struct xlog *log,
3111 struct xlog_recover_item *item)
3112{
3113 xfs_efd_log_format_t *efd_formatp;
3114 xfs_efi_log_item_t *efip = NULL;
3115 xfs_log_item_t *lip;
3116 __uint64_t efi_id;
3117 struct xfs_ail_cursor cur;
3118 struct xfs_ail *ailp = log->l_ailp;
3119
3120 efd_formatp = item->ri_buf[0].i_addr;
3121 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
3122 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
3123 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
3124 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
3125 efi_id = efd_formatp->efd_efi_id;
3126
3127
3128
3129
3130
3131 spin_lock(&ailp->xa_lock);
3132 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3133 while (lip != NULL) {
3134 if (lip->li_type == XFS_LI_EFI) {
3135 efip = (xfs_efi_log_item_t *)lip;
3136 if (efip->efi_format.efi_id == efi_id) {
3137
3138
3139
3140
3141 xfs_trans_ail_delete(ailp, lip,
3142 SHUTDOWN_CORRUPT_INCORE);
3143 xfs_efi_item_free(efip);
3144 spin_lock(&ailp->xa_lock);
3145 break;
3146 }
3147 }
3148 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3149 }
3150 xfs_trans_ail_cursor_done(&cur);
3151 spin_unlock(&ailp->xa_lock);
3152
3153 return 0;
3154}
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164STATIC int
3165xlog_recover_do_icreate_pass2(
3166 struct xlog *log,
3167 struct list_head *buffer_list,
3168 xlog_recover_item_t *item)
3169{
3170 struct xfs_mount *mp = log->l_mp;
3171 struct xfs_icreate_log *icl;
3172 xfs_agnumber_t agno;
3173 xfs_agblock_t agbno;
3174 unsigned int count;
3175 unsigned int isize;
3176 xfs_agblock_t length;
3177
3178 icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
3179 if (icl->icl_type != XFS_LI_ICREATE) {
3180 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
3181 return EINVAL;
3182 }
3183
3184 if (icl->icl_size != 1) {
3185 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
3186 return EINVAL;
3187 }
3188
3189 agno = be32_to_cpu(icl->icl_ag);
3190 if (agno >= mp->m_sb.sb_agcount) {
3191 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
3192 return EINVAL;
3193 }
3194 agbno = be32_to_cpu(icl->icl_agbno);
3195 if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
3196 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
3197 return EINVAL;
3198 }
3199 isize = be32_to_cpu(icl->icl_isize);
3200 if (isize != mp->m_sb.sb_inodesize) {
3201 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
3202 return EINVAL;
3203 }
3204 count = be32_to_cpu(icl->icl_count);
3205 if (!count) {
3206 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
3207 return EINVAL;
3208 }
3209 length = be32_to_cpu(icl->icl_length);
3210 if (!length || length >= mp->m_sb.sb_agblocks) {
3211 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
3212 return EINVAL;
3213 }
3214
3215
3216 ASSERT(count == mp->m_ialloc_inos);
3217 ASSERT(length == mp->m_ialloc_blks);
3218 if (count != mp->m_ialloc_inos ||
3219 length != mp->m_ialloc_blks) {
3220 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2");
3221 return EINVAL;
3222 }
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234 if (xlog_check_buffer_cancelled(log,
3235 XFS_AGB_TO_DADDR(mp, agno, agbno), length, 0))
3236 return 0;
3237
3238 xfs_ialloc_inode_init(mp, NULL, buffer_list, agno, agbno, length,
3239 be32_to_cpu(icl->icl_gen));
3240 return 0;
3241}
3242
3243
3244
3245
3246
3247
3248STATIC void
3249xlog_recover_free_trans(
3250 struct xlog_recover *trans)
3251{
3252 xlog_recover_item_t *item, *n;
3253 int i;
3254
3255 list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) {
3256
3257 list_del(&item->ri_list);
3258 for (i = 0; i < item->ri_cnt; i++)
3259 kmem_free(item->ri_buf[i].i_addr);
3260
3261 kmem_free(item->ri_buf);
3262 kmem_free(item);
3263 }
3264
3265 kmem_free(trans);
3266}
3267
3268STATIC void
3269xlog_recover_buffer_ra_pass2(
3270 struct xlog *log,
3271 struct xlog_recover_item *item)
3272{
3273 struct xfs_buf_log_format *buf_f = item->ri_buf[0].i_addr;
3274 struct xfs_mount *mp = log->l_mp;
3275
3276 if (xlog_peek_buffer_cancelled(log, buf_f->blf_blkno,
3277 buf_f->blf_len, buf_f->blf_flags)) {
3278 return;
3279 }
3280
3281 xfs_buf_readahead(mp->m_ddev_targp, buf_f->blf_blkno,
3282 buf_f->blf_len, NULL);
3283}
3284
3285STATIC void
3286xlog_recover_inode_ra_pass2(
3287 struct xlog *log,
3288 struct xlog_recover_item *item)
3289{
3290 struct xfs_inode_log_format ilf_buf;
3291 struct xfs_inode_log_format *ilfp;
3292 struct xfs_mount *mp = log->l_mp;
3293 int error;
3294
3295 if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
3296 ilfp = item->ri_buf[0].i_addr;
3297 } else {
3298 ilfp = &ilf_buf;
3299 memset(ilfp, 0, sizeof(*ilfp));
3300 error = xfs_inode_item_format_convert(&item->ri_buf[0], ilfp);
3301 if (error)
3302 return;
3303 }
3304
3305 if (xlog_peek_buffer_cancelled(log, ilfp->ilf_blkno, ilfp->ilf_len, 0))
3306 return;
3307
3308 xfs_buf_readahead(mp->m_ddev_targp, ilfp->ilf_blkno,
3309 ilfp->ilf_len, &xfs_inode_buf_ra_ops);
3310}
3311
3312STATIC void
3313xlog_recover_dquot_ra_pass2(
3314 struct xlog *log,
3315 struct xlog_recover_item *item)
3316{
3317 struct xfs_mount *mp = log->l_mp;
3318 struct xfs_disk_dquot *recddq;
3319 struct xfs_dq_logformat *dq_f;
3320 uint type;
3321
3322
3323 if (mp->m_qflags == 0)
3324 return;
3325
3326 recddq = item->ri_buf[1].i_addr;
3327 if (recddq == NULL)
3328 return;
3329 if (item->ri_buf[1].i_len < sizeof(struct xfs_disk_dquot))
3330 return;
3331
3332 type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
3333 ASSERT(type);
3334 if (log->l_quotaoffs_flag & type)
3335 return;
3336
3337 dq_f = item->ri_buf[0].i_addr;
3338 ASSERT(dq_f);
3339 ASSERT(dq_f->qlf_len == 1);
3340
3341 xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno,
3342 XFS_FSB_TO_BB(mp, dq_f->qlf_len), NULL);
3343}
3344
3345STATIC void
3346xlog_recover_ra_pass2(
3347 struct xlog *log,
3348 struct xlog_recover_item *item)
3349{
3350 switch (ITEM_TYPE(item)) {
3351 case XFS_LI_BUF:
3352 xlog_recover_buffer_ra_pass2(log, item);
3353 break;
3354 case XFS_LI_INODE:
3355 xlog_recover_inode_ra_pass2(log, item);
3356 break;
3357 case XFS_LI_DQUOT:
3358 xlog_recover_dquot_ra_pass2(log, item);
3359 break;
3360 case XFS_LI_EFI:
3361 case XFS_LI_EFD:
3362 case XFS_LI_QUOTAOFF:
3363 default:
3364 break;
3365 }
3366}
3367
3368STATIC int
3369xlog_recover_commit_pass1(
3370 struct xlog *log,
3371 struct xlog_recover *trans,
3372 struct xlog_recover_item *item)
3373{
3374 trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1);
3375
3376 switch (ITEM_TYPE(item)) {
3377 case XFS_LI_BUF:
3378 return xlog_recover_buffer_pass1(log, item);
3379 case XFS_LI_QUOTAOFF:
3380 return xlog_recover_quotaoff_pass1(log, item);
3381 case XFS_LI_INODE:
3382 case XFS_LI_EFI:
3383 case XFS_LI_EFD:
3384 case XFS_LI_DQUOT:
3385 case XFS_LI_ICREATE:
3386
3387 return 0;
3388 default:
3389 xfs_warn(log->l_mp, "%s: invalid item type (%d)",
3390 __func__, ITEM_TYPE(item));
3391 ASSERT(0);
3392 return XFS_ERROR(EIO);
3393 }
3394}
3395
3396STATIC int
3397xlog_recover_commit_pass2(
3398 struct xlog *log,
3399 struct xlog_recover *trans,
3400 struct list_head *buffer_list,
3401 struct xlog_recover_item *item)
3402{
3403 trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2);
3404
3405 switch (ITEM_TYPE(item)) {
3406 case XFS_LI_BUF:
3407 return xlog_recover_buffer_pass2(log, buffer_list, item,
3408 trans->r_lsn);
3409 case XFS_LI_INODE:
3410 return xlog_recover_inode_pass2(log, buffer_list, item,
3411 trans->r_lsn);
3412 case XFS_LI_EFI:
3413 return xlog_recover_efi_pass2(log, item, trans->r_lsn);
3414 case XFS_LI_EFD:
3415 return xlog_recover_efd_pass2(log, item);
3416 case XFS_LI_DQUOT:
3417 return xlog_recover_dquot_pass2(log, buffer_list, item,
3418 trans->r_lsn);
3419 case XFS_LI_ICREATE:
3420 return xlog_recover_do_icreate_pass2(log, buffer_list, item);
3421 case XFS_LI_QUOTAOFF:
3422
3423 return 0;
3424 default:
3425 xfs_warn(log->l_mp, "%s: invalid item type (%d)",
3426 __func__, ITEM_TYPE(item));
3427 ASSERT(0);
3428 return XFS_ERROR(EIO);
3429 }
3430}
3431
3432STATIC int
3433xlog_recover_items_pass2(
3434 struct xlog *log,
3435 struct xlog_recover *trans,
3436 struct list_head *buffer_list,
3437 struct list_head *item_list)
3438{
3439 struct xlog_recover_item *item;
3440 int error = 0;
3441
3442 list_for_each_entry(item, item_list, ri_list) {
3443 error = xlog_recover_commit_pass2(log, trans,
3444 buffer_list, item);
3445 if (error)
3446 return error;
3447 }
3448
3449 return error;
3450}
3451
3452
3453
3454
3455
3456
3457
3458STATIC int
3459xlog_recover_commit_trans(
3460 struct xlog *log,
3461 struct xlog_recover *trans,
3462 int pass)
3463{
3464 int error = 0;
3465 int error2;
3466 int items_queued = 0;
3467 struct xlog_recover_item *item;
3468 struct xlog_recover_item *next;
3469 LIST_HEAD (buffer_list);
3470 LIST_HEAD (ra_list);
3471 LIST_HEAD (done_list);
3472
3473 #define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
3474
3475 hlist_del(&trans->r_list);
3476
3477 error = xlog_recover_reorder_trans(log, trans, pass);
3478 if (error)
3479 return error;
3480
3481 list_for_each_entry_safe(item, next, &trans->r_itemq, ri_list) {
3482 switch (pass) {
3483 case XLOG_RECOVER_PASS1:
3484 error = xlog_recover_commit_pass1(log, trans, item);
3485 break;
3486 case XLOG_RECOVER_PASS2:
3487 xlog_recover_ra_pass2(log, item);
3488 list_move_tail(&item->ri_list, &ra_list);
3489 items_queued++;
3490 if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) {
3491 error = xlog_recover_items_pass2(log, trans,
3492 &buffer_list, &ra_list);
3493 list_splice_tail_init(&ra_list, &done_list);
3494 items_queued = 0;
3495 }
3496
3497 break;
3498 default:
3499 ASSERT(0);
3500 }
3501
3502 if (error)
3503 goto out;
3504 }
3505
3506out:
3507 if (!list_empty(&ra_list)) {
3508 if (!error)
3509 error = xlog_recover_items_pass2(log, trans,
3510 &buffer_list, &ra_list);
3511 list_splice_tail_init(&ra_list, &done_list);
3512 }
3513
3514 if (!list_empty(&done_list))
3515 list_splice_init(&done_list, &trans->r_itemq);
3516
3517 xlog_recover_free_trans(trans);
3518
3519 error2 = xfs_buf_delwri_submit(&buffer_list);
3520 return error ? error : error2;
3521}
3522
3523STATIC int
3524xlog_recover_unmount_trans(
3525 struct xlog *log)
3526{
3527
3528 xfs_warn(log->l_mp, "%s: Unmount LR", __func__);
3529 return 0;
3530}
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541STATIC int
3542xlog_recover_process_data(
3543 struct xlog *log,
3544 struct hlist_head rhash[],
3545 struct xlog_rec_header *rhead,
3546 xfs_caddr_t dp,
3547 int pass)
3548{
3549 xfs_caddr_t lp;
3550 int num_logops;
3551 xlog_op_header_t *ohead;
3552 xlog_recover_t *trans;
3553 xlog_tid_t tid;
3554 int error;
3555 unsigned long hash;
3556 uint flags;
3557
3558 lp = dp + be32_to_cpu(rhead->h_len);
3559 num_logops = be32_to_cpu(rhead->h_num_logops);
3560
3561
3562 if (xlog_header_check_recover(log->l_mp, rhead))
3563 return (XFS_ERROR(EIO));
3564
3565 while ((dp < lp) && num_logops) {
3566 ASSERT(dp + sizeof(xlog_op_header_t) <= lp);
3567 ohead = (xlog_op_header_t *)dp;
3568 dp += sizeof(xlog_op_header_t);
3569 if (ohead->oh_clientid != XFS_TRANSACTION &&
3570 ohead->oh_clientid != XFS_LOG) {
3571 xfs_warn(log->l_mp, "%s: bad clientid 0x%x",
3572 __func__, ohead->oh_clientid);
3573 ASSERT(0);
3574 return (XFS_ERROR(EIO));
3575 }
3576 tid = be32_to_cpu(ohead->oh_tid);
3577 hash = XLOG_RHASH(tid);
3578 trans = xlog_recover_find_tid(&rhash[hash], tid);
3579 if (trans == NULL) {
3580 if (ohead->oh_flags & XLOG_START_TRANS)
3581 xlog_recover_new_tid(&rhash[hash], tid,
3582 be64_to_cpu(rhead->h_lsn));
3583 } else {
3584 if (dp + be32_to_cpu(ohead->oh_len) > lp) {
3585 xfs_warn(log->l_mp, "%s: bad length 0x%x",
3586 __func__, be32_to_cpu(ohead->oh_len));
3587 WARN_ON(1);
3588 return (XFS_ERROR(EIO));
3589 }
3590 flags = ohead->oh_flags & ~XLOG_END_TRANS;
3591 if (flags & XLOG_WAS_CONT_TRANS)
3592 flags &= ~XLOG_CONTINUE_TRANS;
3593 switch (flags) {
3594 case XLOG_COMMIT_TRANS:
3595 error = xlog_recover_commit_trans(log,
3596 trans, pass);
3597 break;
3598 case XLOG_UNMOUNT_TRANS:
3599 error = xlog_recover_unmount_trans(log);
3600 break;
3601 case XLOG_WAS_CONT_TRANS:
3602 error = xlog_recover_add_to_cont_trans(log,
3603 trans, dp,
3604 be32_to_cpu(ohead->oh_len));
3605 break;
3606 case XLOG_START_TRANS:
3607 xfs_warn(log->l_mp, "%s: bad transaction",
3608 __func__);
3609 ASSERT(0);
3610 error = XFS_ERROR(EIO);
3611 break;
3612 case 0:
3613 case XLOG_CONTINUE_TRANS:
3614 error = xlog_recover_add_to_trans(log, trans,
3615 dp, be32_to_cpu(ohead->oh_len));
3616 break;
3617 default:
3618 xfs_warn(log->l_mp, "%s: bad flag 0x%x",
3619 __func__, flags);
3620 ASSERT(0);
3621 error = XFS_ERROR(EIO);
3622 break;
3623 }
3624 if (error) {
3625 xlog_recover_free_trans(trans);
3626 return error;
3627 }
3628 }
3629 dp += be32_to_cpu(ohead->oh_len);
3630 num_logops--;
3631 }
3632 return 0;
3633}
3634
3635
3636
3637
3638
3639STATIC int
3640xlog_recover_process_efi(
3641 xfs_mount_t *mp,
3642 xfs_efi_log_item_t *efip)
3643{
3644 xfs_efd_log_item_t *efdp;
3645 xfs_trans_t *tp;
3646 int i;
3647 int error = 0;
3648 xfs_extent_t *extp;
3649 xfs_fsblock_t startblock_fsb;
3650
3651 ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags));
3652
3653
3654
3655
3656
3657
3658 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
3659 extp = &(efip->efi_format.efi_extents[i]);
3660 startblock_fsb = XFS_BB_TO_FSB(mp,
3661 XFS_FSB_TO_DADDR(mp, extp->ext_start));
3662 if ((startblock_fsb == 0) ||
3663 (extp->ext_len == 0) ||
3664 (startblock_fsb >= mp->m_sb.sb_dblocks) ||
3665 (extp->ext_len >= mp->m_sb.sb_agblocks)) {
3666
3667
3668
3669
3670 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
3671 xfs_efi_release(efip, efip->efi_format.efi_nextents);
3672 return XFS_ERROR(EIO);
3673 }
3674 }
3675
3676 tp = xfs_trans_alloc(mp, 0);
3677 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
3678 if (error)
3679 goto abort_error;
3680 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
3681
3682 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
3683 extp = &(efip->efi_format.efi_extents[i]);
3684 error = xfs_free_extent(tp, extp->ext_start, extp->ext_len);
3685 if (error)
3686 goto abort_error;
3687 xfs_trans_log_efd_extent(tp, efdp, extp->ext_start,
3688 extp->ext_len);
3689 }
3690
3691 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
3692 error = xfs_trans_commit(tp, 0);
3693 return error;
3694
3695abort_error:
3696 xfs_trans_cancel(tp, XFS_TRANS_ABORT);
3697 return error;
3698}
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718STATIC int
3719xlog_recover_process_efis(
3720 struct xlog *log)
3721{
3722 xfs_log_item_t *lip;
3723 xfs_efi_log_item_t *efip;
3724 int error = 0;
3725 struct xfs_ail_cursor cur;
3726 struct xfs_ail *ailp;
3727
3728 ailp = log->l_ailp;
3729 spin_lock(&ailp->xa_lock);
3730 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3731 while (lip != NULL) {
3732
3733
3734
3735
3736 if (lip->li_type != XFS_LI_EFI) {
3737#ifdef DEBUG
3738 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
3739 ASSERT(lip->li_type != XFS_LI_EFI);
3740#endif
3741 break;
3742 }
3743
3744
3745
3746
3747 efip = (xfs_efi_log_item_t *)lip;
3748 if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) {
3749 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3750 continue;
3751 }
3752
3753 spin_unlock(&ailp->xa_lock);
3754 error = xlog_recover_process_efi(log->l_mp, efip);
3755 spin_lock(&ailp->xa_lock);
3756 if (error)
3757 goto out;
3758 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3759 }
3760out:
3761 xfs_trans_ail_cursor_done(&cur);
3762 spin_unlock(&ailp->xa_lock);
3763 return error;
3764}
3765
3766
3767
3768
3769
3770STATIC void
3771xlog_recover_clear_agi_bucket(
3772 xfs_mount_t *mp,
3773 xfs_agnumber_t agno,
3774 int bucket)
3775{
3776 xfs_trans_t *tp;
3777 xfs_agi_t *agi;
3778 xfs_buf_t *agibp;
3779 int offset;
3780 int error;
3781
3782 tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
3783 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_clearagi, 0, 0);
3784 if (error)
3785 goto out_abort;
3786
3787 error = xfs_read_agi(mp, tp, agno, &agibp);
3788 if (error)
3789 goto out_abort;
3790
3791 agi = XFS_BUF_TO_AGI(agibp);
3792 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
3793 offset = offsetof(xfs_agi_t, agi_unlinked) +
3794 (sizeof(xfs_agino_t) * bucket);
3795 xfs_trans_log_buf(tp, agibp, offset,
3796 (offset + sizeof(xfs_agino_t) - 1));
3797
3798 error = xfs_trans_commit(tp, 0);
3799 if (error)
3800 goto out_error;
3801 return;
3802
3803out_abort:
3804 xfs_trans_cancel(tp, XFS_TRANS_ABORT);
3805out_error:
3806 xfs_warn(mp, "%s: failed to clear agi %d. Continuing.", __func__, agno);
3807 return;
3808}
3809
3810STATIC xfs_agino_t
3811xlog_recover_process_one_iunlink(
3812 struct xfs_mount *mp,
3813 xfs_agnumber_t agno,
3814 xfs_agino_t agino,
3815 int bucket)
3816{
3817 struct xfs_buf *ibp;
3818 struct xfs_dinode *dip;
3819 struct xfs_inode *ip;
3820 xfs_ino_t ino;
3821 int error;
3822
3823 ino = XFS_AGINO_TO_INO(mp, agno, agino);
3824 error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
3825 if (error)
3826 goto fail;
3827
3828
3829
3830
3831 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &ibp, 0, 0);
3832 if (error)
3833 goto fail_iput;
3834
3835 ASSERT(ip->i_d.di_nlink == 0);
3836 ASSERT(ip->i_d.di_mode != 0);
3837
3838
3839 agino = be32_to_cpu(dip->di_next_unlinked);
3840 xfs_buf_relse(ibp);
3841
3842
3843
3844
3845
3846 ip->i_d.di_dmevmask = 0;
3847
3848 IRELE(ip);
3849 return agino;
3850
3851 fail_iput:
3852 IRELE(ip);
3853 fail:
3854
3855
3856
3857
3858
3859
3860
3861
3862 xlog_recover_clear_agi_bucket(mp, agno, bucket);
3863 return NULLAGINO;
3864}
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878STATIC void
3879xlog_recover_process_iunlinks(
3880 struct xlog *log)
3881{
3882 xfs_mount_t *mp;
3883 xfs_agnumber_t agno;
3884 xfs_agi_t *agi;
3885 xfs_buf_t *agibp;
3886 xfs_agino_t agino;
3887 int bucket;
3888 int error;
3889 uint mp_dmevmask;
3890
3891 mp = log->l_mp;
3892
3893
3894
3895
3896 mp_dmevmask = mp->m_dmevmask;
3897 mp->m_dmevmask = 0;
3898
3899 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
3900
3901
3902
3903 error = xfs_read_agi(mp, NULL, agno, &agibp);
3904 if (error) {
3905
3906
3907
3908
3909
3910
3911 continue;
3912 }
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922 agi = XFS_BUF_TO_AGI(agibp);
3923 xfs_buf_unlock(agibp);
3924
3925 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
3926 agino = be32_to_cpu(agi->agi_unlinked[bucket]);
3927 while (agino != NULLAGINO) {
3928 agino = xlog_recover_process_one_iunlink(mp,
3929 agno, agino, bucket);
3930 }
3931 }
3932 xfs_buf_rele(agibp);
3933 }
3934
3935 mp->m_dmevmask = mp_dmevmask;
3936}
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948STATIC int
3949xlog_unpack_data_crc(
3950 struct xlog_rec_header *rhead,
3951 xfs_caddr_t dp,
3952 struct xlog *log)
3953{
3954 __le32 crc;
3955
3956 crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
3957 if (crc != rhead->h_crc) {
3958 if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
3959 xfs_alert(log->l_mp,
3960 "log record CRC mismatch: found 0x%x, expected 0x%x.",
3961 le32_to_cpu(rhead->h_crc),
3962 le32_to_cpu(crc));
3963 xfs_hex_dump(dp, 32);
3964 }
3965
3966
3967
3968
3969
3970
3971 if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
3972 return EFSCORRUPTED;
3973 }
3974
3975 return 0;
3976}
3977
3978STATIC int
3979xlog_unpack_data(
3980 struct xlog_rec_header *rhead,
3981 xfs_caddr_t dp,
3982 struct xlog *log)
3983{
3984 int i, j, k;
3985 int error;
3986
3987 error = xlog_unpack_data_crc(rhead, dp, log);
3988 if (error)
3989 return error;
3990
3991 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
3992 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
3993 *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
3994 dp += BBSIZE;
3995 }
3996
3997 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
3998 xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
3999 for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
4000 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
4001 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
4002 *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
4003 dp += BBSIZE;
4004 }
4005 }
4006
4007 return 0;
4008}
4009
4010STATIC int
4011xlog_valid_rec_header(
4012 struct xlog *log,
4013 struct xlog_rec_header *rhead,
4014 xfs_daddr_t blkno)
4015{
4016 int hlen;
4017
4018 if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) {
4019 XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
4020 XFS_ERRLEVEL_LOW, log->l_mp);
4021 return XFS_ERROR(EFSCORRUPTED);
4022 }
4023 if (unlikely(
4024 (!rhead->h_version ||
4025 (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
4026 xfs_warn(log->l_mp, "%s: unrecognised log version (%d).",
4027 __func__, be32_to_cpu(rhead->h_version));
4028 return XFS_ERROR(EIO);
4029 }
4030
4031
4032 hlen = be32_to_cpu(rhead->h_len);
4033 if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
4034 XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
4035 XFS_ERRLEVEL_LOW, log->l_mp);
4036 return XFS_ERROR(EFSCORRUPTED);
4037 }
4038 if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) {
4039 XFS_ERROR_REPORT("xlog_valid_rec_header(3)",
4040 XFS_ERRLEVEL_LOW, log->l_mp);
4041 return XFS_ERROR(EFSCORRUPTED);
4042 }
4043 return 0;
4044}
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054STATIC int
4055xlog_do_recovery_pass(
4056 struct xlog *log,
4057 xfs_daddr_t head_blk,
4058 xfs_daddr_t tail_blk,
4059 int pass)
4060{
4061 xlog_rec_header_t *rhead;
4062 xfs_daddr_t blk_no;
4063 xfs_caddr_t offset;
4064 xfs_buf_t *hbp, *dbp;
4065 int error = 0, h_size;
4066 int bblks, split_bblks;
4067 int hblks, split_hblks, wrapped_hblks;
4068 struct hlist_head rhash[XLOG_RHASH_SIZE];
4069
4070 ASSERT(head_blk != tail_blk);
4071
4072
4073
4074
4075
4076 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
4077
4078
4079
4080
4081
4082 hbp = xlog_get_bp(log, 1);
4083 if (!hbp)
4084 return ENOMEM;
4085
4086 error = xlog_bread(log, tail_blk, 1, hbp, &offset);
4087 if (error)
4088 goto bread_err1;
4089
4090 rhead = (xlog_rec_header_t *)offset;
4091 error = xlog_valid_rec_header(log, rhead, tail_blk);
4092 if (error)
4093 goto bread_err1;
4094 h_size = be32_to_cpu(rhead->h_size);
4095 if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
4096 (h_size > XLOG_HEADER_CYCLE_SIZE)) {
4097 hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
4098 if (h_size % XLOG_HEADER_CYCLE_SIZE)
4099 hblks++;
4100 xlog_put_bp(hbp);
4101 hbp = xlog_get_bp(log, hblks);
4102 } else {
4103 hblks = 1;
4104 }
4105 } else {
4106 ASSERT(log->l_sectBBsize == 1);
4107 hblks = 1;
4108 hbp = xlog_get_bp(log, 1);
4109 h_size = XLOG_BIG_RECORD_BSIZE;
4110 }
4111
4112 if (!hbp)
4113 return ENOMEM;
4114 dbp = xlog_get_bp(log, BTOBB(h_size));
4115 if (!dbp) {
4116 xlog_put_bp(hbp);
4117 return ENOMEM;
4118 }
4119
4120 memset(rhash, 0, sizeof(rhash));
4121 if (tail_blk <= head_blk) {
4122 for (blk_no = tail_blk; blk_no < head_blk; ) {
4123 error = xlog_bread(log, blk_no, hblks, hbp, &offset);
4124 if (error)
4125 goto bread_err2;
4126
4127 rhead = (xlog_rec_header_t *)offset;
4128 error = xlog_valid_rec_header(log, rhead, blk_no);
4129 if (error)
4130 goto bread_err2;
4131
4132
4133 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
4134 error = xlog_bread(log, blk_no + hblks, bblks, dbp,
4135 &offset);
4136 if (error)
4137 goto bread_err2;
4138
4139 error = xlog_unpack_data(rhead, offset, log);
4140 if (error)
4141 goto bread_err2;
4142
4143 error = xlog_recover_process_data(log,
4144 rhash, rhead, offset, pass);
4145 if (error)
4146 goto bread_err2;
4147 blk_no += bblks + hblks;
4148 }
4149 } else {
4150
4151
4152
4153
4154
4155 blk_no = tail_blk;
4156 while (blk_no < log->l_logBBsize) {
4157
4158
4159
4160 offset = hbp->b_addr;
4161 split_hblks = 0;
4162 wrapped_hblks = 0;
4163 if (blk_no + hblks <= log->l_logBBsize) {
4164
4165 error = xlog_bread(log, blk_no, hblks, hbp,
4166 &offset);
4167 if (error)
4168 goto bread_err2;
4169 } else {
4170
4171 if (blk_no != log->l_logBBsize) {
4172
4173 ASSERT(blk_no <= INT_MAX);
4174 split_hblks = log->l_logBBsize - (int)blk_no;
4175 ASSERT(split_hblks > 0);
4176 error = xlog_bread(log, blk_no,
4177 split_hblks, hbp,
4178 &offset);
4179 if (error)
4180 goto bread_err2;
4181 }
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195 wrapped_hblks = hblks - split_hblks;
4196 error = xlog_bread_offset(log, 0,
4197 wrapped_hblks, hbp,
4198 offset + BBTOB(split_hblks));
4199 if (error)
4200 goto bread_err2;
4201 }
4202 rhead = (xlog_rec_header_t *)offset;
4203 error = xlog_valid_rec_header(log, rhead,
4204 split_hblks ? blk_no : 0);
4205 if (error)
4206 goto bread_err2;
4207
4208 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
4209 blk_no += hblks;
4210
4211
4212 if (blk_no + bblks <= log->l_logBBsize) {
4213 error = xlog_bread(log, blk_no, bblks, dbp,
4214 &offset);
4215 if (error)
4216 goto bread_err2;
4217 } else {
4218
4219
4220 offset = dbp->b_addr;
4221 split_bblks = 0;
4222 if (blk_no != log->l_logBBsize) {
4223
4224
4225 ASSERT(!wrapped_hblks);
4226 ASSERT(blk_no <= INT_MAX);
4227 split_bblks =
4228 log->l_logBBsize - (int)blk_no;
4229 ASSERT(split_bblks > 0);
4230 error = xlog_bread(log, blk_no,
4231 split_bblks, dbp,
4232 &offset);
4233 if (error)
4234 goto bread_err2;
4235 }
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249 error = xlog_bread_offset(log, 0,
4250 bblks - split_bblks, dbp,
4251 offset + BBTOB(split_bblks));
4252 if (error)
4253 goto bread_err2;
4254 }
4255
4256 error = xlog_unpack_data(rhead, offset, log);
4257 if (error)
4258 goto bread_err2;
4259
4260 error = xlog_recover_process_data(log, rhash,
4261 rhead, offset, pass);
4262 if (error)
4263 goto bread_err2;
4264 blk_no += bblks;
4265 }
4266
4267 ASSERT(blk_no >= log->l_logBBsize);
4268 blk_no -= log->l_logBBsize;
4269
4270
4271 while (blk_no < head_blk) {
4272 error = xlog_bread(log, blk_no, hblks, hbp, &offset);
4273 if (error)
4274 goto bread_err2;
4275
4276 rhead = (xlog_rec_header_t *)offset;
4277 error = xlog_valid_rec_header(log, rhead, blk_no);
4278 if (error)
4279 goto bread_err2;
4280
4281 bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
4282 error = xlog_bread(log, blk_no+hblks, bblks, dbp,
4283 &offset);
4284 if (error)
4285 goto bread_err2;
4286
4287 error = xlog_unpack_data(rhead, offset, log);
4288 if (error)
4289 goto bread_err2;
4290
4291 error = xlog_recover_process_data(log, rhash,
4292 rhead, offset, pass);
4293 if (error)
4294 goto bread_err2;
4295 blk_no += bblks + hblks;
4296 }
4297 }
4298
4299 bread_err2:
4300 xlog_put_bp(dbp);
4301 bread_err1:
4302 xlog_put_bp(hbp);
4303 return error;
4304}
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319STATIC int
4320xlog_do_log_recovery(
4321 struct xlog *log,
4322 xfs_daddr_t head_blk,
4323 xfs_daddr_t tail_blk)
4324{
4325 int error, i;
4326
4327 ASSERT(head_blk != tail_blk);
4328
4329
4330
4331
4332
4333 log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
4334 sizeof(struct list_head),
4335 KM_SLEEP);
4336 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
4337 INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
4338
4339 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
4340 XLOG_RECOVER_PASS1);
4341 if (error != 0) {
4342 kmem_free(log->l_buf_cancel_table);
4343 log->l_buf_cancel_table = NULL;
4344 return error;
4345 }
4346
4347
4348
4349
4350 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
4351 XLOG_RECOVER_PASS2);
4352#ifdef DEBUG
4353 if (!error) {
4354 int i;
4355
4356 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
4357 ASSERT(list_empty(&log->l_buf_cancel_table[i]));
4358 }
4359#endif
4360
4361 kmem_free(log->l_buf_cancel_table);
4362 log->l_buf_cancel_table = NULL;
4363
4364 return error;
4365}
4366
4367
4368
4369
4370STATIC int
4371xlog_do_recover(
4372 struct xlog *log,
4373 xfs_daddr_t head_blk,
4374 xfs_daddr_t tail_blk)
4375{
4376 int error;
4377 xfs_buf_t *bp;
4378 xfs_sb_t *sbp;
4379
4380
4381
4382
4383 error = xlog_do_log_recovery(log, head_blk, tail_blk);
4384 if (error)
4385 return error;
4386
4387
4388
4389
4390 if (XFS_FORCED_SHUTDOWN(log->l_mp)) {
4391 return (EIO);
4392 }
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403 xlog_assign_tail_lsn(log->l_mp);
4404
4405
4406
4407
4408
4409 bp = xfs_getsb(log->l_mp, 0);
4410 XFS_BUF_UNDONE(bp);
4411 ASSERT(!(XFS_BUF_ISWRITE(bp)));
4412 XFS_BUF_READ(bp);
4413 XFS_BUF_UNASYNC(bp);
4414 bp->b_ops = &xfs_sb_buf_ops;
4415
4416 if (XFS_FORCED_SHUTDOWN(log->l_mp)) {
4417 xfs_buf_relse(bp);
4418 return XFS_ERROR(EIO);
4419 }
4420
4421 xfs_buf_iorequest(bp);
4422 error = xfs_buf_iowait(bp);
4423 if (error) {
4424 xfs_buf_ioerror_alert(bp, __func__);
4425 ASSERT(0);
4426 xfs_buf_relse(bp);
4427 return error;
4428 }
4429
4430
4431 sbp = &log->l_mp->m_sb;
4432 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
4433 ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
4434 ASSERT(xfs_sb_good_version(sbp));
4435 xfs_buf_relse(bp);
4436
4437
4438 xfs_icsb_reinit_counters(log->l_mp);
4439
4440 xlog_recover_check_summary(log);
4441
4442
4443 log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
4444 return 0;
4445}
4446
4447
4448
4449
4450
4451
4452int
4453xlog_recover(
4454 struct xlog *log)
4455{
4456 xfs_daddr_t head_blk, tail_blk;
4457 int error;
4458
4459
4460 if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
4461 return error;
4462
4463 if (tail_blk != head_blk) {
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475 if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
4476 return error;
4477 }
4478
4479
4480
4481
4482
4483
4484
4485
4486 if (XFS_SB_VERSION_NUM(&log->l_mp->m_sb) == XFS_SB_VERSION_5 &&
4487 xfs_sb_has_incompat_log_feature(&log->l_mp->m_sb,
4488 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) {
4489 xfs_warn(log->l_mp,
4490"Superblock has unknown incompatible log features (0x%x) enabled.\n"
4491"The log can not be fully and/or safely recovered by this kernel.\n"
4492"Please recover the log on a kernel that supports the unknown features.",
4493 (log->l_mp->m_sb.sb_features_log_incompat &
4494 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN));
4495 return EINVAL;
4496 }
4497
4498 xfs_notice(log->l_mp, "Starting recovery (logdev: %s)",
4499 log->l_mp->m_logname ? log->l_mp->m_logname
4500 : "internal");
4501
4502 error = xlog_do_recover(log, head_blk, tail_blk);
4503 log->l_flags |= XLOG_RECOVERY_NEEDED;
4504 }
4505 return error;
4506}
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517int
4518xlog_recover_finish(
4519 struct xlog *log)
4520{
4521
4522
4523
4524
4525
4526
4527
4528
4529 if (log->l_flags & XLOG_RECOVERY_NEEDED) {
4530 int error;
4531 error = xlog_recover_process_efis(log);
4532 if (error) {
4533 xfs_alert(log->l_mp, "Failed to recover EFIs");
4534 return error;
4535 }
4536
4537
4538
4539
4540
4541
4542 xfs_log_force(log->l_mp, XFS_LOG_SYNC);
4543
4544 xlog_recover_process_iunlinks(log);
4545
4546 xlog_recover_check_summary(log);
4547
4548 xfs_notice(log->l_mp, "Ending recovery (logdev: %s)",
4549 log->l_mp->m_logname ? log->l_mp->m_logname
4550 : "internal");
4551 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
4552 } else {
4553 xfs_info(log->l_mp, "Ending clean mount");
4554 }
4555 return 0;
4556}
4557
4558
4559#if defined(DEBUG)
4560
4561
4562
4563
4564void
4565xlog_recover_check_summary(
4566 struct xlog *log)
4567{
4568 xfs_mount_t *mp;
4569 xfs_agf_t *agfp;
4570 xfs_buf_t *agfbp;
4571 xfs_buf_t *agibp;
4572 xfs_agnumber_t agno;
4573 __uint64_t freeblks;
4574 __uint64_t itotal;
4575 __uint64_t ifree;
4576 int error;
4577
4578 mp = log->l_mp;
4579
4580 freeblks = 0LL;
4581 itotal = 0LL;
4582 ifree = 0LL;
4583 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
4584 error = xfs_read_agf(mp, NULL, agno, 0, &agfbp);
4585 if (error) {
4586 xfs_alert(mp, "%s agf read failed agno %d error %d",
4587 __func__, agno, error);
4588 } else {
4589 agfp = XFS_BUF_TO_AGF(agfbp);
4590 freeblks += be32_to_cpu(agfp->agf_freeblks) +
4591 be32_to_cpu(agfp->agf_flcount);
4592 xfs_buf_relse(agfbp);
4593 }
4594
4595 error = xfs_read_agi(mp, NULL, agno, &agibp);
4596 if (error) {
4597 xfs_alert(mp, "%s agi read failed agno %d error %d",
4598 __func__, agno, error);
4599 } else {
4600 struct xfs_agi *agi = XFS_BUF_TO_AGI(agibp);
4601
4602 itotal += be32_to_cpu(agi->agi_count);
4603 ifree += be32_to_cpu(agi->agi_freecount);
4604 xfs_buf_relse(agibp);
4605 }
4606 }
4607}
4608#endif
4609