This source file includes following definitions.
- journal_brelse_array
- do_readahead
- jread
- jbd2_descriptor_block_csum_verify
- count_tags
- jbd2_journal_recover
- jbd2_journal_skip_recovery
- read_tag_block
- calc_chksums
- jbd2_commit_block_csum_verify
- jbd2_block_tag_csum_verify
- do_one_pass
- scan_revoke_records
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifndef __KERNEL__
14 #include "jfs_user.h"
15 #else
16 #include <linux/time.h>
17 #include <linux/fs.h>
18 #include <linux/jbd2.h>
19 #include <linux/errno.h>
20 #include <linux/crc32.h>
21 #include <linux/blkdev.h>
22 #endif
23
24
25
26
27
28 struct recovery_info
29 {
30 tid_t start_transaction;
31 tid_t end_transaction;
32
33 int nr_replays;
34 int nr_revokes;
35 int nr_revoke_hits;
36 };
37
38 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
39 static int do_one_pass(journal_t *journal,
40 struct recovery_info *info, enum passtype pass);
41 static int scan_revoke_records(journal_t *, struct buffer_head *,
42 tid_t, struct recovery_info *);
43
44 #ifdef __KERNEL__
45
46
47 static void journal_brelse_array(struct buffer_head *b[], int n)
48 {
49 while (--n >= 0)
50 brelse (b[n]);
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 #define MAXBUF 8
67 static int do_readahead(journal_t *journal, unsigned int start)
68 {
69 int err;
70 unsigned int max, nbufs, next;
71 unsigned long long blocknr;
72 struct buffer_head *bh;
73
74 struct buffer_head * bufs[MAXBUF];
75
76
77 max = start + (128 * 1024 / journal->j_blocksize);
78 if (max > journal->j_maxlen)
79 max = journal->j_maxlen;
80
81
82
83
84 nbufs = 0;
85
86 for (next = start; next < max; next++) {
87 err = jbd2_journal_bmap(journal, next, &blocknr);
88
89 if (err) {
90 printk(KERN_ERR "JBD2: bad block at offset %u\n",
91 next);
92 goto failed;
93 }
94
95 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
96 if (!bh) {
97 err = -ENOMEM;
98 goto failed;
99 }
100
101 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
102 bufs[nbufs++] = bh;
103 if (nbufs == MAXBUF) {
104 ll_rw_block(REQ_OP_READ, 0, nbufs, bufs);
105 journal_brelse_array(bufs, nbufs);
106 nbufs = 0;
107 }
108 } else
109 brelse(bh);
110 }
111
112 if (nbufs)
113 ll_rw_block(REQ_OP_READ, 0, nbufs, bufs);
114 err = 0;
115
116 failed:
117 if (nbufs)
118 journal_brelse_array(bufs, nbufs);
119 return err;
120 }
121
122 #endif
123
124
125
126
127
128
129 static int jread(struct buffer_head **bhp, journal_t *journal,
130 unsigned int offset)
131 {
132 int err;
133 unsigned long long blocknr;
134 struct buffer_head *bh;
135
136 *bhp = NULL;
137
138 if (offset >= journal->j_maxlen) {
139 printk(KERN_ERR "JBD2: corrupted journal superblock\n");
140 return -EFSCORRUPTED;
141 }
142
143 err = jbd2_journal_bmap(journal, offset, &blocknr);
144
145 if (err) {
146 printk(KERN_ERR "JBD2: bad block at offset %u\n",
147 offset);
148 return err;
149 }
150
151 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
152 if (!bh)
153 return -ENOMEM;
154
155 if (!buffer_uptodate(bh)) {
156
157
158 if (!buffer_req(bh))
159 do_readahead(journal, offset);
160 wait_on_buffer(bh);
161 }
162
163 if (!buffer_uptodate(bh)) {
164 printk(KERN_ERR "JBD2: Failed to read block at offset %u\n",
165 offset);
166 brelse(bh);
167 return -EIO;
168 }
169
170 *bhp = bh;
171 return 0;
172 }
173
174 static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf)
175 {
176 struct jbd2_journal_block_tail *tail;
177 __be32 provided;
178 __u32 calculated;
179
180 if (!jbd2_journal_has_csum_v2or3(j))
181 return 1;
182
183 tail = (struct jbd2_journal_block_tail *)(buf + j->j_blocksize -
184 sizeof(struct jbd2_journal_block_tail));
185 provided = tail->t_checksum;
186 tail->t_checksum = 0;
187 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
188 tail->t_checksum = provided;
189
190 return provided == cpu_to_be32(calculated);
191 }
192
193
194
195
196
197 static int count_tags(journal_t *journal, struct buffer_head *bh)
198 {
199 char * tagp;
200 journal_block_tag_t * tag;
201 int nr = 0, size = journal->j_blocksize;
202 int tag_bytes = journal_tag_bytes(journal);
203
204 if (jbd2_journal_has_csum_v2or3(journal))
205 size -= sizeof(struct jbd2_journal_block_tail);
206
207 tagp = &bh->b_data[sizeof(journal_header_t)];
208
209 while ((tagp - bh->b_data + tag_bytes) <= size) {
210 tag = (journal_block_tag_t *) tagp;
211
212 nr++;
213 tagp += tag_bytes;
214 if (!(tag->t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID)))
215 tagp += 16;
216
217 if (tag->t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG))
218 break;
219 }
220
221 return nr;
222 }
223
224
225
226 #define wrap(journal, var) \
227 do { \
228 if (var >= (journal)->j_last) \
229 var -= ((journal)->j_last - (journal)->j_first); \
230 } while (0)
231
232
233
234
235
236
237
238
239
240
241
242
243
244 int jbd2_journal_recover(journal_t *journal)
245 {
246 int err, err2;
247 journal_superblock_t * sb;
248
249 struct recovery_info info;
250
251 memset(&info, 0, sizeof(info));
252 sb = journal->j_superblock;
253
254
255
256
257
258
259
260 if (!sb->s_start) {
261 jbd_debug(1, "No recovery required, last transaction %d\n",
262 be32_to_cpu(sb->s_sequence));
263 journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1;
264 return 0;
265 }
266
267 err = do_one_pass(journal, &info, PASS_SCAN);
268 if (!err)
269 err = do_one_pass(journal, &info, PASS_REVOKE);
270 if (!err)
271 err = do_one_pass(journal, &info, PASS_REPLAY);
272
273 jbd_debug(1, "JBD2: recovery, exit status %d, "
274 "recovered transactions %u to %u\n",
275 err, info.start_transaction, info.end_transaction);
276 jbd_debug(1, "JBD2: Replayed %d and revoked %d/%d blocks\n",
277 info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
278
279
280
281 journal->j_transaction_sequence = ++info.end_transaction;
282
283 jbd2_journal_clear_revoke(journal);
284 err2 = sync_blockdev(journal->j_fs_dev);
285 if (!err)
286 err = err2;
287
288 if (journal->j_flags & JBD2_BARRIER) {
289 err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
290 if (!err)
291 err = err2;
292 }
293 return err;
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309 int jbd2_journal_skip_recovery(journal_t *journal)
310 {
311 int err;
312
313 struct recovery_info info;
314
315 memset (&info, 0, sizeof(info));
316
317 err = do_one_pass(journal, &info, PASS_SCAN);
318
319 if (err) {
320 printk(KERN_ERR "JBD2: error %d scanning journal\n", err);
321 ++journal->j_transaction_sequence;
322 } else {
323 #ifdef CONFIG_JBD2_DEBUG
324 int dropped = info.end_transaction -
325 be32_to_cpu(journal->j_superblock->s_sequence);
326 jbd_debug(1,
327 "JBD2: ignoring %d transaction%s from the journal.\n",
328 dropped, (dropped == 1) ? "" : "s");
329 #endif
330 journal->j_transaction_sequence = ++info.end_transaction;
331 }
332
333 journal->j_tail = 0;
334 return err;
335 }
336
337 static inline unsigned long long read_tag_block(journal_t *journal,
338 journal_block_tag_t *tag)
339 {
340 unsigned long long block = be32_to_cpu(tag->t_blocknr);
341 if (jbd2_has_feature_64bit(journal))
342 block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
343 return block;
344 }
345
346
347
348
349
350 static int calc_chksums(journal_t *journal, struct buffer_head *bh,
351 unsigned long *next_log_block, __u32 *crc32_sum)
352 {
353 int i, num_blks, err;
354 unsigned long io_block;
355 struct buffer_head *obh;
356
357 num_blks = count_tags(journal, bh);
358
359 *crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size);
360
361 for (i = 0; i < num_blks; i++) {
362 io_block = (*next_log_block)++;
363 wrap(journal, *next_log_block);
364 err = jread(&obh, journal, io_block);
365 if (err) {
366 printk(KERN_ERR "JBD2: IO error %d recovering block "
367 "%lu in log\n", err, io_block);
368 return 1;
369 } else {
370 *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
371 obh->b_size);
372 }
373 put_bh(obh);
374 }
375 return 0;
376 }
377
378 static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)
379 {
380 struct commit_header *h;
381 __be32 provided;
382 __u32 calculated;
383
384 if (!jbd2_journal_has_csum_v2or3(j))
385 return 1;
386
387 h = buf;
388 provided = h->h_chksum[0];
389 h->h_chksum[0] = 0;
390 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
391 h->h_chksum[0] = provided;
392
393 return provided == cpu_to_be32(calculated);
394 }
395
396 static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
397 void *buf, __u32 sequence)
398 {
399 journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag;
400 __u32 csum32;
401 __be32 seq;
402
403 if (!jbd2_journal_has_csum_v2or3(j))
404 return 1;
405
406 seq = cpu_to_be32(sequence);
407 csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq));
408 csum32 = jbd2_chksum(j, csum32, buf, j->j_blocksize);
409
410 if (jbd2_has_feature_csum3(j))
411 return tag3->t_checksum == cpu_to_be32(csum32);
412 else
413 return tag->t_checksum == cpu_to_be16(csum32);
414 }
415
416 static int do_one_pass(journal_t *journal,
417 struct recovery_info *info, enum passtype pass)
418 {
419 unsigned int first_commit_ID, next_commit_ID;
420 unsigned long next_log_block;
421 int err, success = 0;
422 journal_superblock_t * sb;
423 journal_header_t * tmp;
424 struct buffer_head * bh;
425 unsigned int sequence;
426 int blocktype;
427 int tag_bytes = journal_tag_bytes(journal);
428 __u32 crc32_sum = ~0;
429 int descr_csum_size = 0;
430 int block_error = 0;
431
432
433
434
435
436
437
438 sb = journal->j_superblock;
439 next_commit_ID = be32_to_cpu(sb->s_sequence);
440 next_log_block = be32_to_cpu(sb->s_start);
441
442 first_commit_ID = next_commit_ID;
443 if (pass == PASS_SCAN)
444 info->start_transaction = first_commit_ID;
445
446 jbd_debug(1, "Starting recovery pass %d\n", pass);
447
448
449
450
451
452
453
454
455 while (1) {
456 int flags;
457 char * tagp;
458 journal_block_tag_t * tag;
459 struct buffer_head * obh;
460 struct buffer_head * nbh;
461
462 cond_resched();
463
464
465
466
467
468 if (pass != PASS_SCAN)
469 if (tid_geq(next_commit_ID, info->end_transaction))
470 break;
471
472 jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
473 next_commit_ID, next_log_block, journal->j_last);
474
475
476
477
478
479 jbd_debug(3, "JBD2: checking block %ld\n", next_log_block);
480 err = jread(&bh, journal, next_log_block);
481 if (err)
482 goto failed;
483
484 next_log_block++;
485 wrap(journal, next_log_block);
486
487
488
489
490
491
492
493 tmp = (journal_header_t *)bh->b_data;
494
495 if (tmp->h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER)) {
496 brelse(bh);
497 break;
498 }
499
500 blocktype = be32_to_cpu(tmp->h_blocktype);
501 sequence = be32_to_cpu(tmp->h_sequence);
502 jbd_debug(3, "Found magic %d, sequence %d\n",
503 blocktype, sequence);
504
505 if (sequence != next_commit_ID) {
506 brelse(bh);
507 break;
508 }
509
510
511
512
513
514 switch(blocktype) {
515 case JBD2_DESCRIPTOR_BLOCK:
516
517 if (jbd2_journal_has_csum_v2or3(journal))
518 descr_csum_size =
519 sizeof(struct jbd2_journal_block_tail);
520 if (descr_csum_size > 0 &&
521 !jbd2_descriptor_block_csum_verify(journal,
522 bh->b_data)) {
523 printk(KERN_ERR "JBD2: Invalid checksum "
524 "recovering block %lu in log\n",
525 next_log_block);
526 err = -EFSBADCRC;
527 brelse(bh);
528 goto failed;
529 }
530
531
532
533
534
535 if (pass != PASS_REPLAY) {
536 if (pass == PASS_SCAN &&
537 jbd2_has_feature_checksum(journal) &&
538 !info->end_transaction) {
539 if (calc_chksums(journal, bh,
540 &next_log_block,
541 &crc32_sum)) {
542 put_bh(bh);
543 break;
544 }
545 put_bh(bh);
546 continue;
547 }
548 next_log_block += count_tags(journal, bh);
549 wrap(journal, next_log_block);
550 put_bh(bh);
551 continue;
552 }
553
554
555
556
557
558 tagp = &bh->b_data[sizeof(journal_header_t)];
559 while ((tagp - bh->b_data + tag_bytes)
560 <= journal->j_blocksize - descr_csum_size) {
561 unsigned long io_block;
562
563 tag = (journal_block_tag_t *) tagp;
564 flags = be16_to_cpu(tag->t_flags);
565
566 io_block = next_log_block++;
567 wrap(journal, next_log_block);
568 err = jread(&obh, journal, io_block);
569 if (err) {
570
571
572 success = err;
573 printk(KERN_ERR
574 "JBD2: IO error %d recovering "
575 "block %ld in log\n",
576 err, io_block);
577 } else {
578 unsigned long long blocknr;
579
580 J_ASSERT(obh != NULL);
581 blocknr = read_tag_block(journal,
582 tag);
583
584
585
586
587 if (jbd2_journal_test_revoke
588 (journal, blocknr,
589 next_commit_ID)) {
590 brelse(obh);
591 ++info->nr_revoke_hits;
592 goto skip_write;
593 }
594
595
596 if (!jbd2_block_tag_csum_verify(
597 journal, tag, obh->b_data,
598 be32_to_cpu(tmp->h_sequence))) {
599 brelse(obh);
600 success = -EFSBADCRC;
601 printk(KERN_ERR "JBD2: Invalid "
602 "checksum recovering "
603 "data block %llu in "
604 "log\n", blocknr);
605 block_error = 1;
606 goto skip_write;
607 }
608
609
610
611 nbh = __getblk(journal->j_fs_dev,
612 blocknr,
613 journal->j_blocksize);
614 if (nbh == NULL) {
615 printk(KERN_ERR
616 "JBD2: Out of memory "
617 "during recovery.\n");
618 err = -ENOMEM;
619 brelse(bh);
620 brelse(obh);
621 goto failed;
622 }
623
624 lock_buffer(nbh);
625 memcpy(nbh->b_data, obh->b_data,
626 journal->j_blocksize);
627 if (flags & JBD2_FLAG_ESCAPE) {
628 *((__be32 *)nbh->b_data) =
629 cpu_to_be32(JBD2_MAGIC_NUMBER);
630 }
631
632 BUFFER_TRACE(nbh, "marking dirty");
633 set_buffer_uptodate(nbh);
634 mark_buffer_dirty(nbh);
635 BUFFER_TRACE(nbh, "marking uptodate");
636 ++info->nr_replays;
637
638 unlock_buffer(nbh);
639 brelse(obh);
640 brelse(nbh);
641 }
642
643 skip_write:
644 tagp += tag_bytes;
645 if (!(flags & JBD2_FLAG_SAME_UUID))
646 tagp += 16;
647
648 if (flags & JBD2_FLAG_LAST_TAG)
649 break;
650 }
651
652 brelse(bh);
653 continue;
654
655 case JBD2_COMMIT_BLOCK:
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691 if (pass == PASS_SCAN &&
692 jbd2_has_feature_checksum(journal)) {
693 int chksum_err, chksum_seen;
694 struct commit_header *cbh =
695 (struct commit_header *)bh->b_data;
696 unsigned found_chksum =
697 be32_to_cpu(cbh->h_chksum[0]);
698
699 chksum_err = chksum_seen = 0;
700
701 if (info->end_transaction) {
702 journal->j_failed_commit =
703 info->end_transaction;
704 brelse(bh);
705 break;
706 }
707
708 if (crc32_sum == found_chksum &&
709 cbh->h_chksum_type == JBD2_CRC32_CHKSUM &&
710 cbh->h_chksum_size ==
711 JBD2_CRC32_CHKSUM_SIZE)
712 chksum_seen = 1;
713 else if (!(cbh->h_chksum_type == 0 &&
714 cbh->h_chksum_size == 0 &&
715 found_chksum == 0 &&
716 !chksum_seen))
717
718
719
720
721
722
723
724
725
726
727 chksum_err = 1;
728
729 if (chksum_err) {
730 info->end_transaction = next_commit_ID;
731
732 if (!jbd2_has_feature_async_commit(journal)) {
733 journal->j_failed_commit =
734 next_commit_ID;
735 brelse(bh);
736 break;
737 }
738 }
739 crc32_sum = ~0;
740 }
741 if (pass == PASS_SCAN &&
742 !jbd2_commit_block_csum_verify(journal,
743 bh->b_data)) {
744 info->end_transaction = next_commit_ID;
745
746 if (!jbd2_has_feature_async_commit(journal)) {
747 journal->j_failed_commit =
748 next_commit_ID;
749 brelse(bh);
750 break;
751 }
752 }
753 brelse(bh);
754 next_commit_ID++;
755 continue;
756
757 case JBD2_REVOKE_BLOCK:
758
759
760 if (pass != PASS_REVOKE) {
761 brelse(bh);
762 continue;
763 }
764
765 err = scan_revoke_records(journal, bh,
766 next_commit_ID, info);
767 brelse(bh);
768 if (err)
769 goto failed;
770 continue;
771
772 default:
773 jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
774 blocktype);
775 brelse(bh);
776 goto done;
777 }
778 }
779
780 done:
781
782
783
784
785
786
787
788 if (pass == PASS_SCAN) {
789 if (!info->end_transaction)
790 info->end_transaction = next_commit_ID;
791 } else {
792
793
794 if (info->end_transaction != next_commit_ID) {
795 printk(KERN_ERR "JBD2: recovery pass %d ended at "
796 "transaction %u, expected %u\n",
797 pass, next_commit_ID, info->end_transaction);
798 if (!success)
799 success = -EIO;
800 }
801 }
802 if (block_error && success == 0)
803 success = -EIO;
804 return success;
805
806 failed:
807 return err;
808 }
809
810
811
812 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
813 tid_t sequence, struct recovery_info *info)
814 {
815 jbd2_journal_revoke_header_t *header;
816 int offset, max;
817 int csum_size = 0;
818 __u32 rcount;
819 int record_len = 4;
820
821 header = (jbd2_journal_revoke_header_t *) bh->b_data;
822 offset = sizeof(jbd2_journal_revoke_header_t);
823 rcount = be32_to_cpu(header->r_count);
824
825 if (!jbd2_descriptor_block_csum_verify(journal, header))
826 return -EFSBADCRC;
827
828 if (jbd2_journal_has_csum_v2or3(journal))
829 csum_size = sizeof(struct jbd2_journal_block_tail);
830 if (rcount > journal->j_blocksize - csum_size)
831 return -EINVAL;
832 max = rcount;
833
834 if (jbd2_has_feature_64bit(journal))
835 record_len = 8;
836
837 while (offset + record_len <= max) {
838 unsigned long long blocknr;
839 int err;
840
841 if (record_len == 4)
842 blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset)));
843 else
844 blocknr = be64_to_cpu(* ((__be64 *) (bh->b_data+offset)));
845 offset += record_len;
846 err = jbd2_journal_set_revoke(journal, blocknr, sequence);
847 if (err)
848 return err;
849 ++info->nr_revokes;
850 }
851 return 0;
852 }