Hi all, Probably, this is the most essential "old sleeping" bug found for the latest 3 years. It could lead to data corruption (not proven). Details are in the changeset. It will go to reiser4-for-4.13.1 and higher. For other stuff please, apply (backport, etc) by yourself. Thanks, Edward.
commit 5e8518e0031c97e21830372721ee7a5fae78d610 Author: Edward Shishkin <edward.shishkin@xxxxxxxxx> Date: Wed Nov 8 21:27:44 2017 +0100 Fixed bug in reiser4_kill_root(): wrong function was called for reinitialization of the old root. As the result, cached number of items remained not updated (i.e. corruption of memory data structures). In practice problems could happen when removing file sets large enough to reduce storage tree height, i.e. when old root is killed and its single child becomes a new root. Signed-off-by: Edward Shishkin <edward.shishkin@xxxxxxxxx> diff --git a/jnode.c b/jnode.c index d8b2f8600..0f1594cd6 100644 --- a/jnode.c +++ b/jnode.c @@ -1310,7 +1310,7 @@ static int remove_znode(jnode * node, reiser4_tree * tree) } /* ->init() method for formatted nodes */ -static int init_znode(jnode * node) +int init_znode(jnode * node) { znode *z; diff --git a/tree_mod.c b/tree_mod.c index 26fff5f08..f9687df8f 100644 --- a/tree_mod.c +++ b/tree_mod.c @@ -317,7 +317,7 @@ static int reiser4_kill_root(reiser4_tree * tree /* tree from which root is write_unlock_tree(tree); /* reinitialise old root. */ - result = node_plugin_by_node(old_root)->init(old_root); + result = init_znode(ZJNODE(old_root)); znode_make_dirty(old_root); if (result == 0) { assert("nikita-1279", node_is_empty(old_root)); diff --git a/znode.h b/znode.h index 164fb985a..613377ef6 100644 --- a/znode.h +++ b/znode.h @@ -218,6 +218,7 @@ extern void znode_remove(znode *, reiser4_tree *); extern znode *znode_parent(const znode * node); extern znode *znode_parent_nolock(const znode * node); extern int znode_above_root(const znode * node); +extern int init_znode(jnode *node); extern int init_znodes(void); extern void done_znodes(void); extern int znodes_tree_init(reiser4_tree * ztree);