printk(KERN_WARNING
"NILFS warning: No super root in the last segment\n");
break;
- case NILFS_SEG_VALID:
- default:
- BUG();
}
return -EINVAL;
}
struct nilfs_segment_entry *ent, *n;
struct inode *sufile = nilfs->ns_sufile;
__u64 segnum[4];
+ time_t mtime;
int err;
int i;
/*
* Collecting segments written after the latest super root.
- * These are marked volatile active, and won't be reallocated in
- * the next construction.
+ * These are marked dirty to avoid being reallocated in the next write.
*/
+ mtime = get_seconds();
list_for_each_entry_safe(ent, n, head, list) {
if (ent->segnum == segnum[0]) {
list_del(&ent->list);
err = nilfs_open_segment_entry(ent, sufile);
if (unlikely(err))
goto failed;
- if (nilfs_segment_usage_clean(ent->raw_su)) {
- nilfs_segment_usage_set_volatile_active(ent->raw_su);
- /* Keep it open */
- } else {
- /* Removing duplicated entries */
- list_del(&ent->list);
- nilfs_close_segment_entry(ent, sufile);
- nilfs_free_segment_entry(ent);
+ if (!nilfs_segment_usage_dirty(ent->raw_su)) {
+ /* make the segment garbage */
+ ent->raw_su->su_nblocks = cpu_to_le32(0);
+ ent->raw_su->su_lastmod = cpu_to_le32(mtime);
+ nilfs_segment_usage_set_dirty(ent->raw_su);
}
+ list_del(&ent->list);
+ nilfs_close_segment_entry(ent, sufile);
+ nilfs_free_segment_entry(ent);
}
- list_splice_init(head, nilfs->ns_used_segments.prev);
/*
* The segment having the latest super root is active, and
if (scan_newer)
ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED;
- else if (nilfs->ns_mount_state & NILFS_VALID_FS)
- goto super_root_found;
-
- scan_newer = 1;
+ else {
+ nilfs->ns_prot_seq = ssi.seg_seq;
+ if (nilfs->ns_mount_state & NILFS_VALID_FS)
+ goto super_root_found;
+ scan_newer = 1;
+ }
/* reset region for roll-forward */
pseg_start += ssi.nblocks;