]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nilfs2/recovery.c
nilfs2: introduce secondary super block
[linux-2.6-omap-h63xx.git] / fs / nilfs2 / recovery.c
index 877dc1ba23f3972aa42b32367c6a2e516261dc3b..6ade0963fc1d8a29459596db127d9c6797d7e4fa 100644 (file)
@@ -92,9 +92,6 @@ static int nilfs_warn_segment_error(int err)
                printk(KERN_WARNING
                       "NILFS warning: No super root in the last segment\n");
                break;
-       case NILFS_SEG_VALID:
-       default:
-               BUG();
        }
        return -EINVAL;
 }
@@ -416,6 +413,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
        struct nilfs_segment_entry *ent, *n;
        struct inode *sufile = nilfs->ns_sufile;
        __u64 segnum[4];
+       time_t mtime;
        int err;
        int i;
 
@@ -442,9 +440,9 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
 
        /*
         * 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);
@@ -454,27 +452,16 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
                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
-        * should be deactivated on the next construction for recovery.
-        */
-       err = -ENOMEM;
-       ent = nilfs_alloc_segment_entry(segnum[0]);
-       if (unlikely(!ent))
-               goto failed;
-       list_add_tail(&ent->list, &ri->ri_used_segments);
 
        /* Allocate new segments for recovery */
        err = nilfs_sufile_alloc(sufile, &segnum[0]);
@@ -760,7 +747,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
                        goto failed;
                }
 
-               err = nilfs_attach_segment_constructor(sbi, ri);
+               err = nilfs_attach_segment_constructor(sbi);
                if (unlikely(err))
                        goto failed;
 
@@ -882,10 +869,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
 
                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 {
+                       if (nilfs->ns_mount_state & NILFS_VALID_FS)
+                               goto super_root_found;
+                       scan_newer = 1;
+               }
 
                /* reset region for roll-forward */
                pseg_start += ssi.nblocks;