recovery.c (d2dd01de9924ae24afeba5aa5bc2e08287701df6) | recovery.c (654137dd46bc7e9f088a4a551a2b77a8541dfdb8) |
---|---|
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 --- 14 unchanged lines hidden (view full) --- 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" | 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 --- 14 unchanged lines hidden (view full) --- 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 "seglist.h" | |
32#include "segbuf.h" 33 34/* 35 * Segment check result 36 */ 37enum { 38 NILFS_SEG_VALID, 39 NILFS_SEG_NO_SUPER_ROOT, --- 350 unchanged lines hidden (view full) --- 390 struct nilfs_recovery_block *rb 391 = list_entry(head->next, 392 struct nilfs_recovery_block, list); 393 list_del(&rb->list); 394 kfree(rb); 395 } 396} 397 | 31#include "segbuf.h" 32 33/* 34 * Segment check result 35 */ 36enum { 37 NILFS_SEG_VALID, 38 NILFS_SEG_NO_SUPER_ROOT, --- 350 unchanged lines hidden (view full) --- 389 struct nilfs_recovery_block *rb 390 = list_entry(head->next, 391 struct nilfs_recovery_block, list); 392 list_del(&rb->list); 393 kfree(rb); 394 } 395} 396 |
397struct nilfs_segment_entry { 398 struct list_head list; 399 __u64 segnum; 400}; 401 402static int nilfs_segment_list_add(struct list_head *head, __u64 segnum) 403{ 404 struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS); 405 406 if (unlikely(!ent)) 407 return -ENOMEM; 408 409 ent->segnum = segnum; 410 INIT_LIST_HEAD(&ent->list); 411 list_add_tail(&ent->list, head); 412 return 0; 413} 414 |
|
398void nilfs_dispose_segment_list(struct list_head *head) 399{ 400 while (!list_empty(head)) { 401 struct nilfs_segment_entry *ent 402 = list_entry(head->next, 403 struct nilfs_segment_entry, list); 404 list_del(&ent->list); | 415void nilfs_dispose_segment_list(struct list_head *head) 416{ 417 while (!list_empty(head)) { 418 struct nilfs_segment_entry *ent 419 = list_entry(head->next, 420 struct nilfs_segment_entry, list); 421 list_del(&ent->list); |
405 nilfs_free_segment_entry(ent); | 422 kfree(ent); |
406 } 407} 408 409static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, 410 struct nilfs_sb_info *sbi, 411 struct nilfs_recovery_info *ri) 412{ 413 struct list_head *head = &ri->ri_used_segments; --- 12 unchanged lines hidden (view full) --- 426 /* 427 * Releasing the next segment of the latest super root. 428 * The next segment is invalidated by this recovery. 429 */ 430 err = nilfs_sufile_free(sufile, segnum[1]); 431 if (unlikely(err)) 432 goto failed; 433 | 423 } 424} 425 426static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, 427 struct nilfs_sb_info *sbi, 428 struct nilfs_recovery_info *ri) 429{ 430 struct list_head *head = &ri->ri_used_segments; --- 12 unchanged lines hidden (view full) --- 443 /* 444 * Releasing the next segment of the latest super root. 445 * The next segment is invalidated by this recovery. 446 */ 447 err = nilfs_sufile_free(sufile, segnum[1]); 448 if (unlikely(err)) 449 goto failed; 450 |
434 err = -ENOMEM; | |
435 for (i = 1; i < 4; i++) { | 451 for (i = 1; i < 4; i++) { |
436 ent = nilfs_alloc_segment_entry(segnum[i]); 437 if (unlikely(!ent)) | 452 err = nilfs_segment_list_add(head, segnum[i]); 453 if (unlikely(err)) |
438 goto failed; | 454 goto failed; |
439 list_add_tail(&ent->list, head); | |
440 } 441 442 /* 443 * Collecting segments written after the latest super root. 444 * These are marked dirty to avoid being reallocated in the next write. 445 */ 446 list_for_each_entry_safe(ent, n, head, list) { 447 if (ent->segnum != segnum[0]) { 448 err = nilfs_sufile_scrap(sufile, ent->segnum); 449 if (unlikely(err)) 450 goto failed; 451 } 452 list_del(&ent->list); | 455 } 456 457 /* 458 * Collecting segments written after the latest super root. 459 * These are marked dirty to avoid being reallocated in the next write. 460 */ 461 list_for_each_entry_safe(ent, n, head, list) { 462 if (ent->segnum != segnum[0]) { 463 err = nilfs_sufile_scrap(sufile, ent->segnum); 464 if (unlikely(err)) 465 goto failed; 466 } 467 list_del(&ent->list); |
453 nilfs_free_segment_entry(ent); | 468 kfree(ent); |
454 } 455 456 /* Allocate new segments for recovery */ 457 err = nilfs_sufile_alloc(sufile, &segnum[0]); 458 if (unlikely(err)) 459 goto failed; 460 461 nilfs->ns_pseg_offset = 0; --- 324 unchanged lines hidden (view full) --- 786 struct nilfs_recovery_info *ri) 787{ 788 struct nilfs_segsum_info ssi; 789 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 790 sector_t seg_start, seg_end; /* range of full segment (block number) */ 791 u64 seg_seq; 792 __u64 segnum, nextnum = 0; 793 __u64 cno; | 469 } 470 471 /* Allocate new segments for recovery */ 472 err = nilfs_sufile_alloc(sufile, &segnum[0]); 473 if (unlikely(err)) 474 goto failed; 475 476 nilfs->ns_pseg_offset = 0; --- 324 unchanged lines hidden (view full) --- 801 struct nilfs_recovery_info *ri) 802{ 803 struct nilfs_segsum_info ssi; 804 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 805 sector_t seg_start, seg_end; /* range of full segment (block number) */ 806 u64 seg_seq; 807 __u64 segnum, nextnum = 0; 808 __u64 cno; |
794 struct nilfs_segment_entry *ent; | |
795 LIST_HEAD(segments); 796 int empty_seg = 0, scan_newer = 0; 797 int ret; 798 799 pseg_start = nilfs->ns_last_pseg; 800 seg_seq = nilfs->ns_last_seq; 801 cno = nilfs->ns_last_cno; 802 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); --- 84 unchanged lines hidden (view full) --- 887 */ 888 goto failed; 889 890 feed_segment: 891 /* Looking to the next full segment */ 892 if (empty_seg++) 893 goto super_root_found; /* found a valid super root */ 894 | 809 LIST_HEAD(segments); 810 int empty_seg = 0, scan_newer = 0; 811 int ret; 812 813 pseg_start = nilfs->ns_last_pseg; 814 seg_seq = nilfs->ns_last_seq; 815 cno = nilfs->ns_last_cno; 816 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); --- 84 unchanged lines hidden (view full) --- 901 */ 902 goto failed; 903 904 feed_segment: 905 /* Looking to the next full segment */ 906 if (empty_seg++) 907 goto super_root_found; /* found a valid super root */ 908 |
895 ent = nilfs_alloc_segment_entry(segnum); 896 if (unlikely(!ent)) { 897 ret = -ENOMEM; | 909 ret = nilfs_segment_list_add(&segments, segnum); 910 if (unlikely(ret)) |
898 goto failed; | 911 goto failed; |
899 } 900 list_add_tail(&ent->list, &segments); | |
901 902 seg_seq++; 903 segnum = nextnum; 904 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 905 pseg_start = seg_start; 906 } 907 908 super_root_found: 909 /* Updating pointers relating to the latest checkpoint */ 910 list_splice(&segments, ri->ri_used_segments.prev); 911 nilfs->ns_last_pseg = sr_pseg_start; 912 nilfs->ns_last_seq = nilfs->ns_seg_seq; 913 nilfs->ns_last_cno = ri->ri_cno; 914 return 0; 915 916 failed: 917 nilfs_dispose_segment_list(&segments); 918 return (ret < 0) ? ret : nilfs_warn_segment_error(ret); 919} | 912 913 seg_seq++; 914 segnum = nextnum; 915 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 916 pseg_start = seg_start; 917 } 918 919 super_root_found: 920 /* Updating pointers relating to the latest checkpoint */ 921 list_splice(&segments, ri->ri_used_segments.prev); 922 nilfs->ns_last_pseg = sr_pseg_start; 923 nilfs->ns_last_seq = nilfs->ns_seg_seq; 924 nilfs->ns_last_cno = ri->ri_cno; 925 return 0; 926 927 failed: 928 nilfs_dispose_segment_list(&segments); 929 return (ret < 0) ? ret : nilfs_warn_segment_error(ret); 930} |