1 /* 2 * recovery.c - NILFS recovery logic 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * Written by Ryusuke Konishi. 17 */ 18 19 #include <linux/buffer_head.h> 20 #include <linux/blkdev.h> 21 #include <linux/swap.h> 22 #include <linux/slab.h> 23 #include <linux/crc32.h> 24 #include "nilfs.h" 25 #include "segment.h" 26 #include "sufile.h" 27 #include "page.h" 28 #include "segbuf.h" 29 30 /* 31 * Segment check result 32 */ 33 enum { 34 NILFS_SEG_VALID, 35 NILFS_SEG_NO_SUPER_ROOT, 36 NILFS_SEG_FAIL_IO, 37 NILFS_SEG_FAIL_MAGIC, 38 NILFS_SEG_FAIL_SEQ, 39 NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT, 40 NILFS_SEG_FAIL_CHECKSUM_FULL, 41 NILFS_SEG_FAIL_CONSISTENCY, 42 }; 43 44 /* work structure for recovery */ 45 struct nilfs_recovery_block { 46 ino_t ino; /* 47 * Inode number of the file that this block 48 * belongs to 49 */ 50 sector_t blocknr; /* block number */ 51 __u64 vblocknr; /* virtual block number */ 52 unsigned long blkoff; /* File offset of the data block (per block) */ 53 struct list_head list; 54 }; 55 56 57 static int nilfs_warn_segment_error(struct super_block *sb, int err) 58 { 59 const char *msg = NULL; 60 61 switch (err) { 62 case NILFS_SEG_FAIL_IO: 63 nilfs_msg(sb, KERN_ERR, "I/O error reading segment"); 64 return -EIO; 65 case NILFS_SEG_FAIL_MAGIC: 66 msg = "Magic number mismatch"; 67 break; 68 case NILFS_SEG_FAIL_SEQ: 69 msg = "Sequence number mismatch"; 70 break; 71 case NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT: 72 msg = "Checksum error in super root"; 73 break; 74 case NILFS_SEG_FAIL_CHECKSUM_FULL: 75 msg = "Checksum error in segment payload"; 76 break; 77 case NILFS_SEG_FAIL_CONSISTENCY: 78 msg = "Inconsistency found"; 79 break; 80 case NILFS_SEG_NO_SUPER_ROOT: 81 msg = "No super root in the last segment"; 82 break; 83 default: 84 nilfs_msg(sb, KERN_ERR, "unrecognized segment error %d", err); 85 return -EINVAL; 86 } 87 nilfs_msg(sb, KERN_WARNING, "invalid segment: %s", msg); 88 return -EINVAL; 89 } 90 91 /** 92 * nilfs_compute_checksum - compute checksum of blocks continuously 93 * @nilfs: nilfs object 94 * @bhs: buffer head of start block 95 * @sum: place to store result 96 * @offset: offset bytes in the first block 97 * @check_bytes: number of bytes to be checked 98 * @start: DBN of start block 99 * @nblock: number of blocks to be checked 100 */ 101 static int nilfs_compute_checksum(struct the_nilfs *nilfs, 102 struct buffer_head *bhs, u32 *sum, 103 unsigned long offset, u64 check_bytes, 104 sector_t start, unsigned long nblock) 105 { 106 unsigned int blocksize = nilfs->ns_blocksize; 107 unsigned long size; 108 u32 crc; 109 110 BUG_ON(offset >= blocksize); 111 check_bytes -= offset; 112 size = min_t(u64, check_bytes, blocksize - offset); 113 crc = crc32_le(nilfs->ns_crc_seed, 114 (unsigned char *)bhs->b_data + offset, size); 115 if (--nblock > 0) { 116 do { 117 struct buffer_head *bh; 118 119 bh = __bread(nilfs->ns_bdev, ++start, blocksize); 120 if (!bh) 121 return -EIO; 122 check_bytes -= size; 123 size = min_t(u64, check_bytes, blocksize); 124 crc = crc32_le(crc, bh->b_data, size); 125 brelse(bh); 126 } while (--nblock > 0); 127 } 128 *sum = crc; 129 return 0; 130 } 131 132 /** 133 * nilfs_read_super_root_block - read super root block 134 * @nilfs: nilfs object 135 * @sr_block: disk block number of the super root block 136 * @pbh: address of a buffer_head pointer to return super root buffer 137 * @check: CRC check flag 138 */ 139 int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block, 140 struct buffer_head **pbh, int check) 141 { 142 struct buffer_head *bh_sr; 143 struct nilfs_super_root *sr; 144 u32 crc; 145 int ret; 146 147 *pbh = NULL; 148 bh_sr = __bread(nilfs->ns_bdev, sr_block, nilfs->ns_blocksize); 149 if (unlikely(!bh_sr)) { 150 ret = NILFS_SEG_FAIL_IO; 151 goto failed; 152 } 153 154 sr = (struct nilfs_super_root *)bh_sr->b_data; 155 if (check) { 156 unsigned int bytes = le16_to_cpu(sr->sr_bytes); 157 158 if (bytes == 0 || bytes > nilfs->ns_blocksize) { 159 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 160 goto failed_bh; 161 } 162 if (nilfs_compute_checksum( 163 nilfs, bh_sr, &crc, sizeof(sr->sr_sum), bytes, 164 sr_block, 1)) { 165 ret = NILFS_SEG_FAIL_IO; 166 goto failed_bh; 167 } 168 if (crc != le32_to_cpu(sr->sr_sum)) { 169 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 170 goto failed_bh; 171 } 172 } 173 *pbh = bh_sr; 174 return 0; 175 176 failed_bh: 177 brelse(bh_sr); 178 179 failed: 180 return nilfs_warn_segment_error(nilfs->ns_sb, ret); 181 } 182 183 /** 184 * nilfs_read_log_header - read summary header of the specified log 185 * @nilfs: nilfs object 186 * @start_blocknr: start block number of the log 187 * @sum: pointer to return segment summary structure 188 */ 189 static struct buffer_head * 190 nilfs_read_log_header(struct the_nilfs *nilfs, sector_t start_blocknr, 191 struct nilfs_segment_summary **sum) 192 { 193 struct buffer_head *bh_sum; 194 195 bh_sum = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); 196 if (bh_sum) 197 *sum = (struct nilfs_segment_summary *)bh_sum->b_data; 198 return bh_sum; 199 } 200 201 /** 202 * nilfs_validate_log - verify consistency of log 203 * @nilfs: nilfs object 204 * @seg_seq: sequence number of segment 205 * @bh_sum: buffer head of summary block 206 * @sum: segment summary struct 207 */ 208 static int nilfs_validate_log(struct the_nilfs *nilfs, u64 seg_seq, 209 struct buffer_head *bh_sum, 210 struct nilfs_segment_summary *sum) 211 { 212 unsigned long nblock; 213 u32 crc; 214 int ret; 215 216 ret = NILFS_SEG_FAIL_MAGIC; 217 if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) 218 goto out; 219 220 ret = NILFS_SEG_FAIL_SEQ; 221 if (le64_to_cpu(sum->ss_seq) != seg_seq) 222 goto out; 223 224 nblock = le32_to_cpu(sum->ss_nblocks); 225 ret = NILFS_SEG_FAIL_CONSISTENCY; 226 if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment)) 227 /* This limits the number of blocks read in the CRC check */ 228 goto out; 229 230 ret = NILFS_SEG_FAIL_IO; 231 if (nilfs_compute_checksum(nilfs, bh_sum, &crc, sizeof(sum->ss_datasum), 232 ((u64)nblock << nilfs->ns_blocksize_bits), 233 bh_sum->b_blocknr, nblock)) 234 goto out; 235 236 ret = NILFS_SEG_FAIL_CHECKSUM_FULL; 237 if (crc != le32_to_cpu(sum->ss_datasum)) 238 goto out; 239 ret = 0; 240 out: 241 return ret; 242 } 243 244 /** 245 * nilfs_read_summary_info - read an item on summary blocks of a log 246 * @nilfs: nilfs object 247 * @pbh: the current buffer head on summary blocks [in, out] 248 * @offset: the current byte offset on summary blocks [in, out] 249 * @bytes: byte size of the item to be read 250 */ 251 static void *nilfs_read_summary_info(struct the_nilfs *nilfs, 252 struct buffer_head **pbh, 253 unsigned int *offset, unsigned int bytes) 254 { 255 void *ptr; 256 sector_t blocknr; 257 258 BUG_ON((*pbh)->b_size < *offset); 259 if (bytes > (*pbh)->b_size - *offset) { 260 blocknr = (*pbh)->b_blocknr; 261 brelse(*pbh); 262 *pbh = __bread(nilfs->ns_bdev, blocknr + 1, 263 nilfs->ns_blocksize); 264 if (unlikely(!*pbh)) 265 return NULL; 266 *offset = 0; 267 } 268 ptr = (*pbh)->b_data + *offset; 269 *offset += bytes; 270 return ptr; 271 } 272 273 /** 274 * nilfs_skip_summary_info - skip items on summary blocks of a log 275 * @nilfs: nilfs object 276 * @pbh: the current buffer head on summary blocks [in, out] 277 * @offset: the current byte offset on summary blocks [in, out] 278 * @bytes: byte size of the item to be skipped 279 * @count: number of items to be skipped 280 */ 281 static void nilfs_skip_summary_info(struct the_nilfs *nilfs, 282 struct buffer_head **pbh, 283 unsigned int *offset, unsigned int bytes, 284 unsigned long count) 285 { 286 unsigned int rest_item_in_current_block 287 = ((*pbh)->b_size - *offset) / bytes; 288 289 if (count <= rest_item_in_current_block) { 290 *offset += bytes * count; 291 } else { 292 sector_t blocknr = (*pbh)->b_blocknr; 293 unsigned int nitem_per_block = (*pbh)->b_size / bytes; 294 unsigned int bcnt; 295 296 count -= rest_item_in_current_block; 297 bcnt = DIV_ROUND_UP(count, nitem_per_block); 298 *offset = bytes * (count - (bcnt - 1) * nitem_per_block); 299 300 brelse(*pbh); 301 *pbh = __bread(nilfs->ns_bdev, blocknr + bcnt, 302 nilfs->ns_blocksize); 303 } 304 } 305 306 /** 307 * nilfs_scan_dsync_log - get block information of a log written for data sync 308 * @nilfs: nilfs object 309 * @start_blocknr: start block number of the log 310 * @sum: log summary information 311 * @head: list head to add nilfs_recovery_block struct 312 */ 313 static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, 314 struct nilfs_segment_summary *sum, 315 struct list_head *head) 316 { 317 struct buffer_head *bh; 318 unsigned int offset; 319 u32 nfinfo, sumbytes; 320 sector_t blocknr; 321 ino_t ino; 322 int err = -EIO; 323 324 nfinfo = le32_to_cpu(sum->ss_nfinfo); 325 if (!nfinfo) 326 return 0; 327 328 sumbytes = le32_to_cpu(sum->ss_sumbytes); 329 blocknr = start_blocknr + DIV_ROUND_UP(sumbytes, nilfs->ns_blocksize); 330 bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); 331 if (unlikely(!bh)) 332 goto out; 333 334 offset = le16_to_cpu(sum->ss_bytes); 335 for (;;) { 336 unsigned long nblocks, ndatablk, nnodeblk; 337 struct nilfs_finfo *finfo; 338 339 finfo = nilfs_read_summary_info(nilfs, &bh, &offset, 340 sizeof(*finfo)); 341 if (unlikely(!finfo)) 342 goto out; 343 344 ino = le64_to_cpu(finfo->fi_ino); 345 nblocks = le32_to_cpu(finfo->fi_nblocks); 346 ndatablk = le32_to_cpu(finfo->fi_ndatablk); 347 nnodeblk = nblocks - ndatablk; 348 349 while (ndatablk-- > 0) { 350 struct nilfs_recovery_block *rb; 351 struct nilfs_binfo_v *binfo; 352 353 binfo = nilfs_read_summary_info(nilfs, &bh, &offset, 354 sizeof(*binfo)); 355 if (unlikely(!binfo)) 356 goto out; 357 358 rb = kmalloc(sizeof(*rb), GFP_NOFS); 359 if (unlikely(!rb)) { 360 err = -ENOMEM; 361 goto out; 362 } 363 rb->ino = ino; 364 rb->blocknr = blocknr++; 365 rb->vblocknr = le64_to_cpu(binfo->bi_vblocknr); 366 rb->blkoff = le64_to_cpu(binfo->bi_blkoff); 367 /* INIT_LIST_HEAD(&rb->list); */ 368 list_add_tail(&rb->list, head); 369 } 370 if (--nfinfo == 0) 371 break; 372 blocknr += nnodeblk; /* always 0 for data sync logs */ 373 nilfs_skip_summary_info(nilfs, &bh, &offset, sizeof(__le64), 374 nnodeblk); 375 if (unlikely(!bh)) 376 goto out; 377 } 378 err = 0; 379 out: 380 brelse(bh); /* brelse(NULL) is just ignored */ 381 return err; 382 } 383 384 static void dispose_recovery_list(struct list_head *head) 385 { 386 while (!list_empty(head)) { 387 struct nilfs_recovery_block *rb; 388 389 rb = list_first_entry(head, struct nilfs_recovery_block, list); 390 list_del(&rb->list); 391 kfree(rb); 392 } 393 } 394 395 struct nilfs_segment_entry { 396 struct list_head list; 397 __u64 segnum; 398 }; 399 400 static int nilfs_segment_list_add(struct list_head *head, __u64 segnum) 401 { 402 struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS); 403 404 if (unlikely(!ent)) 405 return -ENOMEM; 406 407 ent->segnum = segnum; 408 INIT_LIST_HEAD(&ent->list); 409 list_add_tail(&ent->list, head); 410 return 0; 411 } 412 413 void nilfs_dispose_segment_list(struct list_head *head) 414 { 415 while (!list_empty(head)) { 416 struct nilfs_segment_entry *ent; 417 418 ent = list_first_entry(head, struct nilfs_segment_entry, list); 419 list_del(&ent->list); 420 kfree(ent); 421 } 422 } 423 424 static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, 425 struct super_block *sb, 426 struct nilfs_recovery_info *ri) 427 { 428 struct list_head *head = &ri->ri_used_segments; 429 struct nilfs_segment_entry *ent, *n; 430 struct inode *sufile = nilfs->ns_sufile; 431 __u64 segnum[4]; 432 int err; 433 int i; 434 435 segnum[0] = nilfs->ns_segnum; 436 segnum[1] = nilfs->ns_nextnum; 437 segnum[2] = ri->ri_segnum; 438 segnum[3] = ri->ri_nextnum; 439 440 /* 441 * Releasing the next segment of the latest super root. 442 * The next segment is invalidated by this recovery. 443 */ 444 err = nilfs_sufile_free(sufile, segnum[1]); 445 if (unlikely(err)) 446 goto failed; 447 448 for (i = 1; i < 4; i++) { 449 err = nilfs_segment_list_add(head, segnum[i]); 450 if (unlikely(err)) 451 goto failed; 452 } 453 454 /* 455 * Collecting segments written after the latest super root. 456 * These are marked dirty to avoid being reallocated in the next write. 457 */ 458 list_for_each_entry_safe(ent, n, head, list) { 459 if (ent->segnum != segnum[0]) { 460 err = nilfs_sufile_scrap(sufile, ent->segnum); 461 if (unlikely(err)) 462 goto failed; 463 } 464 list_del(&ent->list); 465 kfree(ent); 466 } 467 468 /* Allocate new segments for recovery */ 469 err = nilfs_sufile_alloc(sufile, &segnum[0]); 470 if (unlikely(err)) 471 goto failed; 472 473 nilfs->ns_pseg_offset = 0; 474 nilfs->ns_seg_seq = ri->ri_seq + 2; 475 nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; 476 477 failed: 478 /* No need to recover sufile because it will be destroyed on error */ 479 return err; 480 } 481 482 static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, 483 struct nilfs_recovery_block *rb, 484 struct page *page) 485 { 486 struct buffer_head *bh_org; 487 void *kaddr; 488 489 bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize); 490 if (unlikely(!bh_org)) 491 return -EIO; 492 493 kaddr = kmap_atomic(page); 494 memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size); 495 kunmap_atomic(kaddr); 496 brelse(bh_org); 497 return 0; 498 } 499 500 static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, 501 struct super_block *sb, 502 struct nilfs_root *root, 503 struct list_head *head, 504 unsigned long *nr_salvaged_blocks) 505 { 506 struct inode *inode; 507 struct nilfs_recovery_block *rb, *n; 508 unsigned int blocksize = nilfs->ns_blocksize; 509 struct page *page; 510 loff_t pos; 511 int err = 0, err2 = 0; 512 513 list_for_each_entry_safe(rb, n, head, list) { 514 inode = nilfs_iget(sb, root, rb->ino); 515 if (IS_ERR(inode)) { 516 err = PTR_ERR(inode); 517 inode = NULL; 518 goto failed_inode; 519 } 520 521 pos = rb->blkoff << inode->i_blkbits; 522 err = block_write_begin(inode->i_mapping, pos, blocksize, 523 0, &page, nilfs_get_block); 524 if (unlikely(err)) { 525 loff_t isize = inode->i_size; 526 527 if (pos + blocksize > isize) 528 nilfs_write_failed(inode->i_mapping, 529 pos + blocksize); 530 goto failed_inode; 531 } 532 533 err = nilfs_recovery_copy_block(nilfs, rb, page); 534 if (unlikely(err)) 535 goto failed_page; 536 537 err = nilfs_set_file_dirty(inode, 1); 538 if (unlikely(err)) 539 goto failed_page; 540 541 block_write_end(NULL, inode->i_mapping, pos, blocksize, 542 blocksize, page, NULL); 543 544 unlock_page(page); 545 put_page(page); 546 547 (*nr_salvaged_blocks)++; 548 goto next; 549 550 failed_page: 551 unlock_page(page); 552 put_page(page); 553 554 failed_inode: 555 nilfs_msg(sb, KERN_WARNING, 556 "error %d recovering data block (ino=%lu, block-offset=%llu)", 557 err, (unsigned long)rb->ino, 558 (unsigned long long)rb->blkoff); 559 if (!err2) 560 err2 = err; 561 next: 562 iput(inode); /* iput(NULL) is just ignored */ 563 list_del_init(&rb->list); 564 kfree(rb); 565 } 566 return err2; 567 } 568 569 /** 570 * nilfs_do_roll_forward - salvage logical segments newer than the latest 571 * checkpoint 572 * @nilfs: nilfs object 573 * @sb: super block instance 574 * @ri: pointer to a nilfs_recovery_info 575 */ 576 static int nilfs_do_roll_forward(struct the_nilfs *nilfs, 577 struct super_block *sb, 578 struct nilfs_root *root, 579 struct nilfs_recovery_info *ri) 580 { 581 struct buffer_head *bh_sum = NULL; 582 struct nilfs_segment_summary *sum = NULL; 583 sector_t pseg_start; 584 sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */ 585 unsigned long nsalvaged_blocks = 0; 586 unsigned int flags; 587 u64 seg_seq; 588 __u64 segnum, nextnum = 0; 589 int empty_seg = 0; 590 int err = 0, ret; 591 LIST_HEAD(dsync_blocks); /* list of data blocks to be recovered */ 592 enum { 593 RF_INIT_ST, 594 RF_DSYNC_ST, /* scanning data-sync segments */ 595 }; 596 int state = RF_INIT_ST; 597 598 pseg_start = ri->ri_lsegs_start; 599 seg_seq = ri->ri_lsegs_start_seq; 600 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 601 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 602 603 while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) { 604 brelse(bh_sum); 605 bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); 606 if (!bh_sum) { 607 err = -EIO; 608 goto failed; 609 } 610 611 ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); 612 if (ret) { 613 if (ret == NILFS_SEG_FAIL_IO) { 614 err = -EIO; 615 goto failed; 616 } 617 goto strayed; 618 } 619 620 flags = le16_to_cpu(sum->ss_flags); 621 if (flags & NILFS_SS_SR) 622 goto confused; 623 624 /* Found a valid partial segment; do recovery actions */ 625 nextnum = nilfs_get_segnum_of_block(nilfs, 626 le64_to_cpu(sum->ss_next)); 627 empty_seg = 0; 628 nilfs->ns_ctime = le64_to_cpu(sum->ss_create); 629 if (!(flags & NILFS_SS_GC)) 630 nilfs->ns_nongc_ctime = nilfs->ns_ctime; 631 632 switch (state) { 633 case RF_INIT_ST: 634 if (!(flags & NILFS_SS_LOGBGN) || 635 !(flags & NILFS_SS_SYNDT)) 636 goto try_next_pseg; 637 state = RF_DSYNC_ST; 638 /* Fall through */ 639 case RF_DSYNC_ST: 640 if (!(flags & NILFS_SS_SYNDT)) 641 goto confused; 642 643 err = nilfs_scan_dsync_log(nilfs, pseg_start, sum, 644 &dsync_blocks); 645 if (unlikely(err)) 646 goto failed; 647 if (flags & NILFS_SS_LOGEND) { 648 err = nilfs_recover_dsync_blocks( 649 nilfs, sb, root, &dsync_blocks, 650 &nsalvaged_blocks); 651 if (unlikely(err)) 652 goto failed; 653 state = RF_INIT_ST; 654 } 655 break; /* Fall through to try_next_pseg */ 656 } 657 658 try_next_pseg: 659 if (pseg_start == ri->ri_lsegs_end) 660 break; 661 pseg_start += le32_to_cpu(sum->ss_nblocks); 662 if (pseg_start < seg_end) 663 continue; 664 goto feed_segment; 665 666 strayed: 667 if (pseg_start == ri->ri_lsegs_end) 668 break; 669 670 feed_segment: 671 /* Looking to the next full segment */ 672 if (empty_seg++) 673 break; 674 seg_seq++; 675 segnum = nextnum; 676 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 677 pseg_start = seg_start; 678 } 679 680 if (nsalvaged_blocks) { 681 nilfs_msg(sb, KERN_INFO, "salvaged %lu blocks", 682 nsalvaged_blocks); 683 ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE; 684 } 685 out: 686 brelse(bh_sum); 687 dispose_recovery_list(&dsync_blocks); 688 return err; 689 690 confused: 691 err = -EINVAL; 692 failed: 693 nilfs_msg(sb, KERN_ERR, 694 "error %d roll-forwarding partial segment at blocknr = %llu", 695 err, (unsigned long long)pseg_start); 696 goto out; 697 } 698 699 static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, 700 struct nilfs_recovery_info *ri) 701 { 702 struct buffer_head *bh; 703 int err; 704 705 if (nilfs_get_segnum_of_block(nilfs, ri->ri_lsegs_start) != 706 nilfs_get_segnum_of_block(nilfs, ri->ri_super_root)) 707 return; 708 709 bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize); 710 BUG_ON(!bh); 711 memset(bh->b_data, 0, bh->b_size); 712 set_buffer_dirty(bh); 713 err = sync_dirty_buffer(bh); 714 if (unlikely(err)) 715 nilfs_msg(nilfs->ns_sb, KERN_WARNING, 716 "buffer sync write failed during post-cleaning of recovery."); 717 brelse(bh); 718 } 719 720 /** 721 * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint 722 * @nilfs: nilfs object 723 * @sb: super block instance 724 * @ri: pointer to a nilfs_recovery_info struct to store search results. 725 * 726 * Return Value: On success, 0 is returned. On error, one of the following 727 * negative error code is returned. 728 * 729 * %-EINVAL - Inconsistent filesystem state. 730 * 731 * %-EIO - I/O error 732 * 733 * %-ENOSPC - No space left on device (only in a panic state). 734 * 735 * %-ERESTARTSYS - Interrupted. 736 * 737 * %-ENOMEM - Insufficient memory available. 738 */ 739 int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, 740 struct super_block *sb, 741 struct nilfs_recovery_info *ri) 742 { 743 struct nilfs_root *root; 744 int err; 745 746 if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0) 747 return 0; 748 749 err = nilfs_attach_checkpoint(sb, ri->ri_cno, true, &root); 750 if (unlikely(err)) { 751 nilfs_msg(sb, KERN_ERR, 752 "error %d loading the latest checkpoint", err); 753 return err; 754 } 755 756 err = nilfs_do_roll_forward(nilfs, sb, root, ri); 757 if (unlikely(err)) 758 goto failed; 759 760 if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { 761 err = nilfs_prepare_segment_for_recovery(nilfs, sb, ri); 762 if (unlikely(err)) { 763 nilfs_msg(sb, KERN_ERR, 764 "error %d preparing segment for recovery", 765 err); 766 goto failed; 767 } 768 769 err = nilfs_attach_log_writer(sb, root); 770 if (unlikely(err)) 771 goto failed; 772 773 set_nilfs_discontinued(nilfs); 774 err = nilfs_construct_segment(sb); 775 nilfs_detach_log_writer(sb); 776 777 if (unlikely(err)) { 778 nilfs_msg(sb, KERN_ERR, 779 "error %d writing segment for recovery", 780 err); 781 goto failed; 782 } 783 784 nilfs_finish_roll_forward(nilfs, ri); 785 } 786 787 failed: 788 nilfs_put_root(root); 789 return err; 790 } 791 792 /** 793 * nilfs_search_super_root - search the latest valid super root 794 * @nilfs: the_nilfs 795 * @ri: pointer to a nilfs_recovery_info struct to store search results. 796 * 797 * nilfs_search_super_root() looks for the latest super-root from a partial 798 * segment pointed by the superblock. It sets up struct the_nilfs through 799 * this search. It fills nilfs_recovery_info (ri) required for recovery. 800 * 801 * Return Value: On success, 0 is returned. On error, one of the following 802 * negative error code is returned. 803 * 804 * %-EINVAL - No valid segment found 805 * 806 * %-EIO - I/O error 807 * 808 * %-ENOMEM - Insufficient memory available. 809 */ 810 int nilfs_search_super_root(struct the_nilfs *nilfs, 811 struct nilfs_recovery_info *ri) 812 { 813 struct buffer_head *bh_sum = NULL; 814 struct nilfs_segment_summary *sum = NULL; 815 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 816 sector_t seg_start, seg_end; /* range of full segment (block number) */ 817 sector_t b, end; 818 unsigned long nblocks; 819 unsigned int flags; 820 u64 seg_seq; 821 __u64 segnum, nextnum = 0; 822 __u64 cno; 823 LIST_HEAD(segments); 824 int empty_seg = 0, scan_newer = 0; 825 int ret; 826 827 pseg_start = nilfs->ns_last_pseg; 828 seg_seq = nilfs->ns_last_seq; 829 cno = nilfs->ns_last_cno; 830 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 831 832 /* Calculate range of segment */ 833 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 834 835 /* Read ahead segment */ 836 b = seg_start; 837 while (b <= seg_end) 838 __breadahead(nilfs->ns_bdev, b++, nilfs->ns_blocksize); 839 840 for (;;) { 841 brelse(bh_sum); 842 ret = NILFS_SEG_FAIL_IO; 843 bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); 844 if (!bh_sum) 845 goto failed; 846 847 ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); 848 if (ret) { 849 if (ret == NILFS_SEG_FAIL_IO) 850 goto failed; 851 goto strayed; 852 } 853 854 nblocks = le32_to_cpu(sum->ss_nblocks); 855 pseg_end = pseg_start + nblocks - 1; 856 if (unlikely(pseg_end > seg_end)) { 857 ret = NILFS_SEG_FAIL_CONSISTENCY; 858 goto strayed; 859 } 860 861 /* A valid partial segment */ 862 ri->ri_pseg_start = pseg_start; 863 ri->ri_seq = seg_seq; 864 ri->ri_segnum = segnum; 865 nextnum = nilfs_get_segnum_of_block(nilfs, 866 le64_to_cpu(sum->ss_next)); 867 ri->ri_nextnum = nextnum; 868 empty_seg = 0; 869 870 flags = le16_to_cpu(sum->ss_flags); 871 if (!(flags & NILFS_SS_SR) && !scan_newer) { 872 /* 873 * This will never happen because a superblock 874 * (last_segment) always points to a pseg with 875 * a super root. 876 */ 877 ret = NILFS_SEG_FAIL_CONSISTENCY; 878 goto failed; 879 } 880 881 if (pseg_start == seg_start) { 882 nilfs_get_segment_range(nilfs, nextnum, &b, &end); 883 while (b <= end) 884 __breadahead(nilfs->ns_bdev, b++, 885 nilfs->ns_blocksize); 886 } 887 if (!(flags & NILFS_SS_SR)) { 888 if (!ri->ri_lsegs_start && (flags & NILFS_SS_LOGBGN)) { 889 ri->ri_lsegs_start = pseg_start; 890 ri->ri_lsegs_start_seq = seg_seq; 891 } 892 if (flags & NILFS_SS_LOGEND) 893 ri->ri_lsegs_end = pseg_start; 894 goto try_next_pseg; 895 } 896 897 /* A valid super root was found. */ 898 ri->ri_cno = cno++; 899 ri->ri_super_root = pseg_end; 900 ri->ri_lsegs_start = ri->ri_lsegs_end = 0; 901 902 nilfs_dispose_segment_list(&segments); 903 sr_pseg_start = pseg_start; 904 nilfs->ns_pseg_offset = pseg_start + nblocks - seg_start; 905 nilfs->ns_seg_seq = seg_seq; 906 nilfs->ns_segnum = segnum; 907 nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */ 908 nilfs->ns_ctime = le64_to_cpu(sum->ss_create); 909 nilfs->ns_nextnum = nextnum; 910 911 if (scan_newer) 912 ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; 913 else { 914 if (nilfs->ns_mount_state & NILFS_VALID_FS) 915 goto super_root_found; 916 scan_newer = 1; 917 } 918 919 try_next_pseg: 920 /* Standing on a course, or met an inconsistent state */ 921 pseg_start += nblocks; 922 if (pseg_start < seg_end) 923 continue; 924 goto feed_segment; 925 926 strayed: 927 /* Off the trail */ 928 if (!scan_newer) 929 /* 930 * This can happen if a checkpoint was written without 931 * barriers, or as a result of an I/O failure. 932 */ 933 goto failed; 934 935 feed_segment: 936 /* Looking to the next full segment */ 937 if (empty_seg++) 938 goto super_root_found; /* found a valid super root */ 939 940 ret = nilfs_segment_list_add(&segments, segnum); 941 if (unlikely(ret)) 942 goto failed; 943 944 seg_seq++; 945 segnum = nextnum; 946 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 947 pseg_start = seg_start; 948 } 949 950 super_root_found: 951 /* Updating pointers relating to the latest checkpoint */ 952 brelse(bh_sum); 953 list_splice_tail(&segments, &ri->ri_used_segments); 954 nilfs->ns_last_pseg = sr_pseg_start; 955 nilfs->ns_last_seq = nilfs->ns_seg_seq; 956 nilfs->ns_last_cno = ri->ri_cno; 957 return 0; 958 959 failed: 960 brelse(bh_sum); 961 nilfs_dispose_segment_list(&segments); 962 return ret < 0 ? ret : nilfs_warn_segment_error(nilfs->ns_sb, ret); 963 } 964