diff options
Diffstat (limited to 'fs/nilfs2/recovery.c')
-rw-r--r-- | fs/nilfs2/recovery.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index 877dc1ba23f3..a4253f34e138 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -416,6 +416,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
416 | struct nilfs_segment_entry *ent, *n; | 416 | struct nilfs_segment_entry *ent, *n; |
417 | struct inode *sufile = nilfs->ns_sufile; | 417 | struct inode *sufile = nilfs->ns_sufile; |
418 | __u64 segnum[4]; | 418 | __u64 segnum[4]; |
419 | time_t mtime; | ||
419 | int err; | 420 | int err; |
420 | int i; | 421 | int i; |
421 | 422 | ||
@@ -442,9 +443,9 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
442 | 443 | ||
443 | /* | 444 | /* |
444 | * Collecting segments written after the latest super root. | 445 | * Collecting segments written after the latest super root. |
445 | * These are marked volatile active, and won't be reallocated in | 446 | * These are marked dirty to avoid being reallocated in the next write. |
446 | * the next construction. | ||
447 | */ | 447 | */ |
448 | mtime = get_seconds(); | ||
448 | list_for_each_entry_safe(ent, n, head, list) { | 449 | list_for_each_entry_safe(ent, n, head, list) { |
449 | if (ent->segnum == segnum[0]) { | 450 | if (ent->segnum == segnum[0]) { |
450 | list_del(&ent->list); | 451 | list_del(&ent->list); |
@@ -454,17 +455,16 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
454 | err = nilfs_open_segment_entry(ent, sufile); | 455 | err = nilfs_open_segment_entry(ent, sufile); |
455 | if (unlikely(err)) | 456 | if (unlikely(err)) |
456 | goto failed; | 457 | goto failed; |
457 | if (nilfs_segment_usage_clean(ent->raw_su)) { | 458 | if (!nilfs_segment_usage_dirty(ent->raw_su)) { |
458 | nilfs_segment_usage_set_volatile_active(ent->raw_su); | 459 | /* make the segment garbage */ |
459 | /* Keep it open */ | 460 | ent->raw_su->su_nblocks = cpu_to_le32(0); |
460 | } else { | 461 | ent->raw_su->su_lastmod = cpu_to_le32(mtime); |
461 | /* Removing duplicated entries */ | 462 | nilfs_segment_usage_set_dirty(ent->raw_su); |
462 | list_del(&ent->list); | ||
463 | nilfs_close_segment_entry(ent, sufile); | ||
464 | nilfs_free_segment_entry(ent); | ||
465 | } | 463 | } |
464 | list_del(&ent->list); | ||
465 | nilfs_close_segment_entry(ent, sufile); | ||
466 | nilfs_free_segment_entry(ent); | ||
466 | } | 467 | } |
467 | list_splice_init(head, nilfs->ns_used_segments.prev); | ||
468 | 468 | ||
469 | /* | 469 | /* |
470 | * The segment having the latest super root is active, and | 470 | * The segment having the latest super root is active, and |
@@ -882,10 +882,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
882 | 882 | ||
883 | if (scan_newer) | 883 | if (scan_newer) |
884 | ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; | 884 | ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; |
885 | else if (nilfs->ns_mount_state & NILFS_VALID_FS) | 885 | else { |
886 | goto super_root_found; | 886 | nilfs->ns_prot_seq = ssi.seg_seq; |
887 | 887 | if (nilfs->ns_mount_state & NILFS_VALID_FS) | |
888 | scan_newer = 1; | 888 | goto super_root_found; |
889 | scan_newer = 1; | ||
890 | } | ||
889 | 891 | ||
890 | /* reset region for roll-forward */ | 892 | /* reset region for roll-forward */ |
891 | pseg_start += ssi.nblocks; | 893 | pseg_start += ssi.nblocks; |