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