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