]> git.neil.brown.name Git - LaFS.git/commitdiff
make checkpointing more robust
authorNeilBrown <neilb@suse.de>
Sat, 15 Aug 2009 07:09:23 +0000 (17:09 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 15 Aug 2009 07:09:23 +0000 (17:09 +1000)
As long as the root inode hasn't changed phase, we keep
looking for things to do.
If things got confused, this could livelock, which would be bad...

checkpoint.c

index e0d5e93cb31483efdb355a69919560c181533e76..b6f9061c3c7eec88c5f3d0c92a7f489ae0bd8661 100644 (file)
@@ -353,7 +353,6 @@ static void do_checkpoint(void *data)
        struct fs *fs = data;
        int oldphase = !fs->phase; /*FIXME could there be a race getting this?*/
        struct block *b;
-       int cnt = 0;
 #ifdef DUMP
        dfs = fs;
 #endif
@@ -361,6 +360,7 @@ static void do_checkpoint(void *data)
        dprintk("Start Checkpoint\n");
        if (lafs_trace)
                lafs_dump_tree();
+ again:
        while ((b = lafs_get_flushable(fs, oldphase)) != NULL) {
                int unlock = 1;
                dprintk("Checkpoint Block %s\n", strblk(b));
@@ -402,38 +402,17 @@ static void do_checkpoint(void *data)
                        lafs_iounlock_block(b, 0);
 
                putref(b, MKREF(leaf));
-               if (list_empty(&fs->phase_leafs[oldphase])) {
-                       lafs_cluster_flush(fs, 0);
-                       lafs_cluster_wait_all(fs);
-                       lafs_clusters_done(fs);
-               }
-               cnt++;
        }
-       lafs_clusters_done(fs);
-
        if (test_bit(B_Pinned, &LAFSI(fs->ss[0].root)->iblock->b.flags) &&
            !!test_bit(B_Phase1, &LAFSI(fs->ss[0].root)->iblock->b.flags)
            != fs->phase) {
-               struct indexblock *ib = LAFSI(fs->ss[0].root)->iblock;
-               struct block *cb;
-               printk("ROOT has not changed phase!! \n");
-               lafs_dump_tree();
-               cb = &ib->b;
-               printk("Root %s Block still old: %s\n",
-                      test_bit(B_Index, &cb->flags) ? "Index" : "Data",
-                      strblk(cb));
-
-               list_for_each_entry(cb, &ib->children, siblings)
-                       if (test_bit(B_Pinned, &cb->flags)) {
-                               int pp = !!test_bit(B_Phase1, &cb->flags);
-                               if (pp != fs->phase)
-                                       printk("%s Block still old: %s\n",
-                                              test_bit(B_Index, &cb->flags)
-                                              ? "Index" : "Data",
-                                              strblk(cb));
-                       }
-               BUG();
+               BUG_ON(list_empty(&fs->wc[0].clhead));
+               lafs_cluster_flush(fs, 0);
+               lafs_cluster_wait_all(fs);
+               lafs_clusters_done(fs);
+               goto again;
        }
+       lafs_clusters_done(fs);
 }
 
 static void finish_checkpoint(struct fs *fs, int youth)