summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViacheslav Dubeyko <slava@dubeyko.com>2026-04-04 02:05:54 +0300
committerViacheslav Dubeyko <slava@dubeyko.com>2026-04-09 00:23:29 +0300
commit63584d76765bb3e212f70c4c3951ea785fabef1b (patch)
tree3592fbcc35b7acc363fa9ff9ffb91a00873a55dc
parentcd3901f4c0348da84f33b6b6e3e8e9aa7e441d01 (diff)
downloadlinux-63584d76765bb3e212f70c4c3951ea785fabef1b.tar.xz
hfsplus: fix logic of alloc/free b-tree node
The hfs_bmap_alloc() and hfs_bmap_free() modify the b-tree's counters and nodes' bitmap of b-tree. However, hfs_btree_write() synchronizes the state of in-core b-tree's counters and node's bitmap with b-tree's descriptor in header node. Postponing this synchronization could result in inconsistent state of file system volume. This patch adds calling of hfs_btree_write() in hfs_bmap_alloc() and hfs_bmap_free() methods. cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> cc: Yangtao Li <frank.li@vivo.com> cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260403230556.614171-4-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
-rw-r--r--fs/hfsplus/btree.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index 80aa816ae1c0..761c74ccd653 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -564,6 +564,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
set_page_dirty(page);
kunmap_local(data);
tree->free_nodes--;
+ hfs_btree_write(tree);
mark_inode_dirty(tree->inode);
hfs_bnode_put(node);
return hfs_bnode_create(tree,
@@ -585,6 +586,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
if (!nidx) {
hfs_dbg("create new bmap node\n");
next_node = hfs_bmap_new_bmap(node, idx);
+ hfs_btree_write(tree);
} else
next_node = hfs_bnode_find(tree, nidx);
hfs_bnode_put(node);
@@ -655,6 +657,7 @@ void hfs_bmap_free(struct hfs_bnode *node)
nidx, node->type);
} else {
tree->free_nodes++;
+ hfs_btree_write(tree);
mark_inode_dirty(tree->inode);
}