From: Stefan Metzmacher Date: Sun, 28 Aug 2022 09:41:46 +0000 (+0200) Subject: s3:g_lock: add g_lock_ctx->busy and assert it to false X-Git-Tag: talloc-2.4.0~853 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d19fa657d725e887ec0cd2f19b479e827230faa6;p=thirdparty%2Fsamba.git s3:g_lock: add g_lock_ctx->busy and assert it to false This prepares some helper functions in order to allow callers of g_lock_lock() to pass in a callback function that will run under the tdb chainlock when G_LOCK_WRITE was granted. The idea is that the callers callback function would run with g_lock_ctx->busy == true and all key based function are not be allowed during the execution of the callback function. Only the g_lock_lock_cb_state based helper function are allowed to be used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 28b1dd8382c..ec10e5b8514 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -37,6 +37,7 @@ struct g_lock_ctx { struct db_context *db; struct messaging_context *msg; enum dbwrap_lock_order lock_order; + bool busy; }; struct g_lock { @@ -198,7 +199,7 @@ struct g_lock_ctx *g_lock_ctx_init_backend( { struct g_lock_ctx *result; - result = talloc(mem_ctx, struct g_lock_ctx); + result = talloc_zero(mem_ctx, struct g_lock_ctx); if (result == NULL) { return NULL; } @@ -938,6 +939,8 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx, NTSTATUS status; bool ok; + SMB_ASSERT(!ctx->busy); + req = tevent_req_create(mem_ctx, &state, struct g_lock_lock_state); if (req == NULL) { return NULL; @@ -1134,6 +1137,8 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key, struct timeval end; NTSTATUS status; + SMB_ASSERT(!ctx->busy); + if ((type == G_LOCK_READ) || (type == G_LOCK_WRITE)) { /* * This is an abstraction violation: Normally we do @@ -1291,6 +1296,8 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, TDB_DATA key) }; NTSTATUS status; + SMB_ASSERT(!ctx->busy); + status = dbwrap_do_locked(ctx->db, key, g_lock_unlock_fn, &state); if (!NT_STATUS_IS_OK(status)) { DBG_WARNING("dbwrap_do_locked failed: %s\n", @@ -1390,6 +1397,8 @@ NTSTATUS g_lock_writev_data( }; NTSTATUS status; + SMB_ASSERT(!ctx->busy); + status = dbwrap_do_locked( ctx->db, key, g_lock_writev_data_fn, &state); if (!NT_STATUS_IS_OK(status)) { @@ -1438,6 +1447,8 @@ int g_lock_locks(struct g_lock_ctx *ctx, NTSTATUS status; int count; + SMB_ASSERT(!ctx->busy); + state.fn = fn; state.private_data = private_data; @@ -1522,6 +1533,8 @@ NTSTATUS g_lock_dump(struct g_lock_ctx *ctx, TDB_DATA key, }; NTSTATUS status; + SMB_ASSERT(!ctx->busy); + status = dbwrap_parse_record(ctx->db, key, g_lock_dump_fn, &state); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("dbwrap_parse_record returned %s\n", @@ -1554,6 +1567,8 @@ struct tevent_req *g_lock_dump_send( struct tevent_req *req = NULL, *subreq = NULL; struct g_lock_dump_state *state = NULL; + SMB_ASSERT(!ctx->busy); + req = tevent_req_create(mem_ctx, &state, struct g_lock_dump_state); if (req == NULL) { return NULL; @@ -1563,6 +1578,8 @@ struct tevent_req *g_lock_dump_send( state->fn = fn; state->private_data = private_data; + SMB_ASSERT(!ctx->busy); + subreq = dbwrap_parse_record_send( state, ev, @@ -1664,6 +1681,8 @@ struct tevent_req *g_lock_watch_data_send( struct g_lock_watch_data_state *state = NULL; NTSTATUS status; + SMB_ASSERT(!ctx->busy); + req = tevent_req_create( mem_ctx, &state, struct g_lock_watch_data_state); if (req == NULL) { @@ -1840,6 +1859,8 @@ void g_lock_wake_watchers(struct g_lock_ctx *ctx, TDB_DATA key) { NTSTATUS status; + SMB_ASSERT(!ctx->busy); + status = dbwrap_do_locked(ctx->db, key, g_lock_wake_watchers_fn, NULL); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("dbwrap_do_locked returned %s\n",