From 83a6bbb640ddb302aa0f94b471e9a3f2f564a579 Mon Sep 17 00:00:00 2001 From: "Bryant G. Duffy-Ly" Date: Tue, 2 Nov 2021 16:49:26 -0500 Subject: [PATCH] Fix inconsistency in server_log_merge_free_work In order to safely free blocks we need to first dirty the work. This allows for resume later on without a double free. Signed-off-by: Bryant G. Duffy-Ly --- kmod/src/server.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/kmod/src/server.c b/kmod/src/server.c index 1b338775..157eebfc 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -2068,6 +2068,19 @@ static void server_log_merge_free_work(struct work_struct *work) break; } + /* Dirty the btree before freeing so that we can pin it + * so that later touches will succeed. + */ + init_log_merge_key(&key, SCOUTFS_LOG_MERGE_FREEING_ZONE, + le64_to_cpu(fr.seq), 0); + ret = scoutfs_btree_dirty(sb, &server->alloc, + &server->wri, &super->log_merge, + &key); + if (ret < 0) { + err_str = "dirtying log btree"; + break; + } + ret = scoutfs_btree_free_blocks(sb, &server->alloc, &server->wri, &fr.key, &fr.root, 10); @@ -2077,8 +2090,6 @@ static void server_log_merge_free_work(struct work_struct *work) } /* freed blocks are in allocator, we *have* to update key */ - init_log_merge_key(&key, SCOUTFS_LOG_MERGE_FREEING_ZONE, - le64_to_cpu(fr.seq), 0); if (scoutfs_key_is_ones(&fr.key)) ret = scoutfs_btree_delete(sb, &server->alloc, &server->wri,