diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index 709f3b78..48307ebc 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -270,8 +270,7 @@ int scoutfs_alloc_dirty_ring(struct super_block *sb) kfree(pend); } - scoutfs_treap_dirty_ring(sal->treap); - scoutfs_treap_update_root(&super->alloc_treap_root, sal->treap); + scoutfs_treap_dirty_ring(sal->treap, &super->alloc_treap_root); ret = 0; out: up_write(&sal->rwsem); diff --git a/kmod/src/manifest.c b/kmod/src/manifest.c index e10d811e..01266a52 100644 --- a/kmod/src/manifest.c +++ b/kmod/src/manifest.c @@ -612,8 +612,7 @@ int scoutfs_manifest_dirty_ring(struct super_block *sb) struct scoutfs_super_block *super = &sbi->super; down_write(&mani->rwsem); - scoutfs_treap_dirty_ring(mani->treap); - scoutfs_treap_update_root(&super->manifest.root, mani->treap); + scoutfs_treap_dirty_ring(mani->treap, &super->manifest.root); up_write(&mani->rwsem); return 0; diff --git a/kmod/src/treap.c b/kmod/src/treap.c index 692b25a2..f458aa76 100644 --- a/kmod/src/treap.c +++ b/kmod/src/treap.c @@ -117,6 +117,7 @@ struct scoutfs_treap { struct scoutfs_super_block *super; struct scoutfs_treap_ops *ops; struct treap_ref root_ref; + bool dirty; u64 dirty_bytes; }; @@ -424,6 +425,7 @@ static bool mark_node_dirty(struct scoutfs_treap *treap, struct treap_ref *ref, return false; treap->dirty_bytes += node_ring_bytes(node); + treap->dirty = true; node->off = tinf->dirty_off; node->gen = tinf->dirty_gen; @@ -1030,7 +1032,7 @@ out: int scoutfs_treap_has_dirty(struct scoutfs_treap *treap) { - return !!(treap->root_ref.aug_bits & SCOUTFS_TREAP_AUG_DIRTY); + return treap->dirty; } static void *pages_off_ptr(struct treap_info *tinf) @@ -1135,7 +1137,8 @@ static void copy_node_to_ring(struct scoutfs_treap *treap, * * This is called for multiple treaps before the ring is written. */ -int scoutfs_treap_dirty_ring(struct scoutfs_treap *treap) +int scoutfs_treap_dirty_ring(struct scoutfs_treap *treap, + struct scoutfs_treap_root *root) { struct treap_node *node; unsigned bytes; @@ -1168,7 +1171,13 @@ int scoutfs_treap_dirty_ring(struct scoutfs_treap *treap) } } + /* point the persistent super root at the treap we wrote to the ring */ + root->ref.off = cpu_to_le64(treap->root_ref.off); + root->ref.gen = cpu_to_le64(treap->root_ref.gen); + root->ref.aug_bits = treap->root_ref.aug_bits; + treap->dirty_bytes = 0; + treap->dirty = false; ret = 0; out: return ret; @@ -1258,14 +1267,6 @@ struct scoutfs_treap *scoutfs_treap_alloc(struct super_block *sb, return treap; } -void scoutfs_treap_update_root(struct scoutfs_treap_root *root, - struct scoutfs_treap *treap) -{ - root->ref.off = cpu_to_le64(treap->root_ref.off); - root->ref.gen = cpu_to_le64(treap->root_ref.gen); - root->ref.aug_bits = treap->root_ref.aug_bits; -} - /* * Free all the allocated nodes in the treap and clear the root. */ diff --git a/kmod/src/treap.h b/kmod/src/treap.h index e69fbde1..497d742a 100644 --- a/kmod/src/treap.h +++ b/kmod/src/treap.h @@ -18,8 +18,6 @@ struct scoutfs_treap_ops { struct scoutfs_treap *scoutfs_treap_alloc(struct super_block *sb, struct scoutfs_treap_ops *ops, struct scoutfs_treap_root *root); -void scoutfs_treap_update_root(struct scoutfs_treap_root *root, - struct scoutfs_treap *treap); void scoutfs_treap_free(struct scoutfs_treap *treap); void *scoutfs_treap_insert(struct scoutfs_treap *treap, void *key, u16 bytes, @@ -38,7 +36,8 @@ void *scoutfs_treap_next(struct scoutfs_treap *treap, void *data); void *scoutfs_treap_prev(struct scoutfs_treap *treap, void *data); int scoutfs_treap_has_dirty(struct scoutfs_treap *treap); -int scoutfs_treap_dirty_ring(struct scoutfs_treap *treap); +int scoutfs_treap_dirty_ring(struct scoutfs_treap *treap, + struct scoutfs_treap_root *root); int scoutfs_treap_submit_write(struct super_block *sb, struct scoutfs_bio_completion *comp);