2 /* Force out a checkpoint
3 * All scheduled blocks get incorporated and/or written
4 * then we write out the new state blocks
12 int lafs_checkpoint(struct lafs *fs)
16 fs->checkpointing = CHECKPOINTING | CHECKPOINT_START;
18 while (!list_empty(&fs->leafs)) {
19 while (!list_empty(&fs->leafs)) {
20 b = list_first_entry(&fs->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,
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,
34 de_sched(b); b->flags |= B_Sched;
35 list_add(&b->leafs, &fs->account_leafs);
38 if (b->ino->type == TypeInodeFile &&
40 db->my_inode->iblock &&
41 db->my_inode->iblock->sched_cnt)
42 /* Wait for InoIdx block to be ready */
46 if (b->flags & B_Index) {
47 struct lafs_iblk *ib = iblk(b);
49 /* Not ready yet, leave it off the list */
54 if (list_empty(&ib->b.leafs))
56 /* We'll pick it up next time 'round */
59 if (b->flags & B_InoIdx) {
60 /* InoIdx block is ready, so process
65 b = &b->ino->dblock->b;
69 if (b->flags & B_Dirty) {
70 trace(2, "...alloc\n");
71 lafs_cluster_allocate(b, 0);
75 lafs_cluster_flush(fs, 0);
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);
82 trace(1, "Account %d/%lld\n", b->ino->inum, (long long)b->fileaddr);
83 list_del_init(&b->leafs);
86 list_del_init(&b->leafs);
88 lafs_cluster_allocate(b, 0);
90 fs->checkpointing |= CHECKPOINT_END;
91 lafs_cluster_flush(fs, 0);
92 fs->flags &= ~LAFS_DELAY_UPDATES;