Ensure that writer_init and alloc_init are cleaned

In scoutfs_server_worker we do not properly handle the clean up
of _block_writer_init and alloc_init. On error paths we can clean
up the context if either of thoes are initialized we can call
alloc_prepare_commit or writer_forget_all to ensure we drop
the block references and clear the dirty status of all the blocks
in the writer.

Signed-off-by: Bryant G. Duffy-Ly <bduffyly@versity.com>
This commit is contained in:
Bryant G. Duffy-Ly
2021-11-02 19:27:25 -05:00
parent 83a6bbb640
commit 65429a9cc4

View File

@@ -3823,6 +3823,7 @@ static void scoutfs_server_worker(struct work_struct *work)
struct scoutfs_net_connection *conn = NULL;
DECLARE_WAIT_QUEUE_HEAD(waitq);
struct sockaddr_in sin;
bool alloc_init = false;
u64 max_seq;
int ret;
@@ -3831,6 +3832,8 @@ static void scoutfs_server_worker(struct work_struct *work)
scoutfs_quorum_slot_sin(super, opts->quorum_slot_nr, &sin);
scoutfs_info(sb, "server starting at "SIN_FMT, SIN_ARG(&sin));
scoutfs_block_writer_init(sb, &server->wri);
/* first make sure no other servers are still running */
ret = scoutfs_quorum_fence_leaders(sb, server->term);
if (ret < 0) {
@@ -3870,7 +3873,6 @@ static void scoutfs_server_worker(struct work_struct *work)
atomic64_set(&server->seq_atomic, le64_to_cpu(super->seq));
set_roots(server, &super->fs_root, &super->logs_root,
&super->srch_root);
scoutfs_block_writer_init(sb, &server->wri);
/* prepare server alloc for this transaction, larger first */
if (le64_to_cpu(super->server_meta_avail[0].total_nr) <
@@ -3881,6 +3883,7 @@ static void scoutfs_server_worker(struct work_struct *work)
scoutfs_alloc_init(&server->alloc,
&super->server_meta_avail[server->other_ind ^ 1],
&super->server_meta_freed[server->other_ind ^ 1]);
alloc_init = true;
server->other_avail = &super->server_meta_avail[server->other_ind];
server->other_freed = &super->server_meta_freed[server->other_ind];
@@ -3942,6 +3945,11 @@ shutdown:
/* wait for extra queues by requests, won't find waiters */
flush_work(&server->commit_work);
if (alloc_init)
scoutfs_alloc_prepare_commit(sb, &server->alloc, &server->wri);
scoutfs_block_writer_forget_all(sb, &server->wri);
scoutfs_lock_server_destroy(sb);
scoutfs_omap_server_shutdown(sb);