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