]> git.neil.brown.name Git - lafs-utils.git/blob - lib/lafs_checkpoint.c
92d60c7f797a156be73882b6be4ad60adaaa1c7a
[lafs-utils.git] / lib / lafs_checkpoint.c
1
2 /* Force out a checkpoint
3  * All scheduled blocks get incorporated and/or written
4  * then we write out the new state blocks
5  */
6
7 #include <stdlib.h>
8 #include <lafs/lafs.h>
9
10 #include <stdio.h>
11
12 int lafs_checkpoint(struct lafs *fs)
13 {
14         struct lafs_blk *b;
15
16         fs->checkpointing = CHECKPOINTING | CHECKPOINT_START;
17
18         while (!list_empty(&fs->leafs)) {
19                 while (!list_empty(&fs->leafs)) {
20                         b = list_first_entry(&fs->leafs,
21                                              struct lafs_blk,
22                                              leafs);
23                         printf("checkpoint %p %d/%ld %s %p\n", b, b->ino->inum, b->fileaddr,
24                                (b->flags & B_Index) ? "index":"data", b->parent);
25                         list_del_init(&b->leafs);
26                         if (!(b->flags & B_Index)) {
27                                 struct lafs_dblk *db = dblk(b);
28                                 if (b->ino->type == TypeSegmentMap) {
29                                         /* Allow parents to be processed, but freeze this */
30                                         de_sched(b); b->flags |= B_Sched;
31                                         list_add(&b->leafs, &fs->account_leafs);
32                                         continue;
33                                 }
34                                 if (b->ino->type == TypeInodeFile &&
35                                     db->my_inode &&
36                                     db->my_inode->iblock &&
37                                     db->my_inode->iblock->sched_cnt) {
38                                         de_sched(b);
39                                         continue;
40                                 }
41                         }
42                         
43                         if (b->flags & B_Index) {
44                                 struct lafs_iblk *ib = iblk(b);
45                                 if (ib->sched_cnt) {
46                                         de_sched(b);
47                                         continue;
48                                 }
49                                 if (ib->uninc) {
50                                         de_sched(b);
51                                         lafs_incorporate(ib);
52                                         if (!(ib->b.flags & B_Sched))
53                                                 abort();
54                                         /* We'll pick it up next time 'round */
55                                         continue;
56                                 }
57                         }
58                         if (b->flags & B_Dirty) {
59                                 printf("...alloc\n");
60                                 lafs_cluster_allocate(b, 0);
61                         } else
62                                 de_sched(b);
63                 }
64                 lafs_cluster_flush(fs, 0);
65         }
66         fs->flags |= LAFS_DELAY_UPDATES;
67         while (!list_empty(&fs->account_leafs)) {
68                 b = list_first_entry(&fs->account_leafs,
69                                      struct lafs_blk, leafs);
70                 b->flags &= ~B_Sched;
71                 printf("Account %d/%ld\n", b->ino->inum, b->fileaddr);
72                 list_del_init(&b->leafs);
73
74                 lafs_sched_blk(b);
75                 list_del_init(&b->leafs);
76                 
77                 lafs_cluster_allocate(b, 0);
78         }
79         fs->checkpointing |= CHECKPOINT_END;
80         lafs_cluster_flush(fs, 0);
81         fs->flags &= ~LAFS_DELAY_UPDATES;
82
83         lafs_write_state(fs);
84         return 0;
85 }