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