]> git.neil.brown.name Git - lafs-utils.git/blob - lib/lafs_checkpoint.c
Assorted changes to scheduling
[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 #include <stdio.h>
10 #include "internal.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                         trace(1, "checkpoint %p %d/%lld %s-%d %p\n", b, b->ino->inum,
24                               (long long)b->fileaddr,
25                               (b->flags & B_Index) ? "index":"data",
26                               (b->flags & B_Index) ? iblk(b)->sched_cnt:0,
27                               b->parent);
28                         list_del_init(&b->leafs);
29                         if (!(b->flags & B_Index)) {
30                                 struct lafs_dblk *db = dblk(b);
31                                 if (b->ino->type == TypeSegmentMap) {
32                                         /* Allow parents to be processed,
33                                          * but freeze this */
34                                         de_sched(b); b->flags |= B_Sched;
35                                         list_add(&b->leafs, &fs->account_leafs);
36                                         continue;
37                                 }
38                                 if (b->ino->type == TypeInodeFile &&
39                                     db->my_inode &&
40                                     db->my_inode->iblock &&
41                                     db->my_inode->iblock->sched_cnt)
42                                         /* Wait for InoIdx block to be ready */
43                                         continue;
44                         }
45
46                         if (b->flags & B_Index) {
47                                 struct lafs_iblk *ib = iblk(b);
48                                 if (ib->sched_cnt)
49                                         /* Not ready yet, leave it off the list */
50                                         continue;
51
52                                 if (ib->uninc) {
53                                         lafs_incorporate(ib);
54                                         if (list_empty(&ib->b.leafs))
55                                                 abort();
56                                         /* We'll pick it up next time 'round */
57                                         continue;
58                                 }
59                                 if (b->flags & B_InoIdx) {
60                                         /* InoIdx block is ready, so process
61                                          * the data block.
62                                          */
63                                         de_sched(b);
64                                         b->flags &= ~B_Dirty;
65                                         b = &b->ino->dblock->b;
66                                         b->flags |= B_Dirty;
67                                 }
68                         }
69                         if (b->flags & B_Dirty) {
70                                 trace(2, "...alloc\n");
71                                 lafs_cluster_allocate(b, 0);
72                         } else
73                                 de_sched(b);
74                 }
75                 lafs_cluster_flush(fs, 0);
76         }
77         fs->flags |= LAFS_DELAY_UPDATES;
78         while (!list_empty(&fs->account_leafs)) {
79                 b = list_first_entry(&fs->account_leafs,
80                                      struct lafs_blk, leafs);
81                 b->flags &= ~B_Sched;
82                 trace(1, "Account %d/%lld\n", b->ino->inum, (long long)b->fileaddr);
83                 list_del_init(&b->leafs);
84
85                 lafs_sched_blk(b);
86                 list_del_init(&b->leafs);
87
88                 lafs_cluster_allocate(b, 0);
89         }
90         fs->checkpointing |= CHECKPOINT_END;
91         lafs_cluster_flush(fs, 0);
92         fs->flags &= ~LAFS_DELAY_UPDATES;
93
94         lafs_write_state(fs);
95         return 0;
96 }