The branch, master has been updated via 49951b283d9 smbd: Store share_entries in locking.tdb again via 7bdd5ad4b5e smbd: Move share mode entry parsing up in the file via 8020f013084 smbd: Base locking.tdb on g_lock.c via 3bf576bb2a8 lib: Add g_lock_dump_send/recv via 0a043e64b63 lib: Add g_lock_set_lock_order() via 6fb6a6992d9 lib: Add g_lock_writev_data via 4f2117d6870 lib: Allow additional dbufs in g_lock_store() via 3d0cfb82ec6 lib: Add g_lock_seqnum() via c38f37147d1 lib: Add g_lock_wake_watchers() via 90dcfa4e592 torture: Test g_lock_watch_data_send()/recv() via 46e8e0cd7eb lib: Add g_lock_watch_data_send/recv() via 66d62ed7978 lib: Allow DBWRAP_LOCK_ORDER_NONE in db_open() via 5ae58cd0db3 dbwrap: Make dbwrap_lock_order_[un]lock() public via 38a80a30052 dbwrap: Simplify dbwrap_lock_order_[un]lock() from 01db877c776 srvsvc: Move brl_get_locks() out of enum_file_fn()
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 49951b283d98d81a2201341624b4bcdd3eba9ec4 Author: Volker Lendecke <v...@samba.org> Date: Tue Apr 14 16:51:15 2020 +0200 smbd: Store share_entries in locking.tdb again The "base on g_lock" patch is a slowdown because we do more tdb operations. Getting share_entries.tdb back into locking.tdb tries to speed things up again. Now that we're based on g_lock we'll most likely use a different method in order to spread the entries across multiple records. It still maintains the sorted array of share modes within locking.tdb, but not as part of the expensive ndr marshalling of the complete array. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Fri May 15 02:27:49 UTC 2020 on sn-devel-184 commit 7bdd5ad4b5e73937ffbbb9b7365639e360733d95 Author: Volker Lendecke <v...@samba.org> Date: Thu Mar 26 19:45:10 2020 +0100 smbd: Move share mode entry parsing up in the file Will be used by parsing code soon Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 8020f013084e4424e761b405634b03aa6466bd88 Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 5 12:01:52 2019 +0100 smbd: Base locking.tdb on g_lock.c This means we don't hold locking.tdb mutexes anymore while we do filesystem-level operations. This has hurt ctdb quite a bit: A smbd hanging in an unlink() syscall prevents ctdb from recovering locking.tdb. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3bf576bb2a8eaf1ede44b6327e2eb9272b73c5f9 Author: Volker Lendecke <v...@samba.org> Date: Tue Mar 24 09:54:26 2020 +0100 lib: Add g_lock_dump_send/recv Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0a043e64b639ff2d29eb052abcd894c5ee185936 Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 21 15:20:07 2019 +0100 lib: Add g_lock_set_lock_order() Optionally allow a database with g_lock format to participate in the dbwarp lock order check. Will be used once locking.tdb is based upon g_lock.c Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6fb6a6992d959d2904baf3448a09bb3575ca91f1 Author: Volker Lendecke <v...@samba.org> Date: Wed Apr 29 15:35:39 2020 +0200 lib: Add g_lock_writev_data Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 4f2117d68706d9e723b582f29623dfd7177d9251 Author: Volker Lendecke <v...@samba.org> Date: Wed Apr 29 15:28:03 2020 +0200 lib: Allow additional dbufs in g_lock_store() Preparation for g_lock_writev_data() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3d0cfb82ec6aa1accba27040c17880a43c3f155c Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 5 16:36:59 2019 +0100 lib: Add g_lock_seqnum() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c38f37147d127672398a4a05fc731d4bb9726947 Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 4 16:03:52 2019 +0100 lib: Add g_lock_wake_watchers() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 90dcfa4e59276467b89d07c1fc6fc14ed4c225ff Author: Volker Lendecke <v...@samba.org> Date: Thu Oct 31 11:45:36 2019 +0100 torture: Test g_lock_watch_data_send()/recv() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 46e8e0cd7eb69e2c8ee9b65491e198134fab1b61 Author: Volker Lendecke <v...@samba.org> Date: Wed Oct 30 16:12:11 2019 +0100 lib: Add g_lock_watch_data_send/recv() Same concept as dbwrap_watched_watch_send/recv: Get informed if the underlying data of a record changes. This utilizes the watched database that g_lock is based upon anyway. To avoid spurious wakeups by pure g_lock operations this patch adds a sequence number for the data that is stored in the g_lock data field. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 66d62ed7978cc0bc1d7bb6c495e32738802f4420 Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 21 15:20:33 2019 +0100 lib: Allow DBWRAP_LOCK_ORDER_NONE in db_open() locking.tdb will not have a LOCK_ORDER anymore, this will be done by the code in g_lock.c. We need to allow opening a database with dbwrap without having a lock order. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 5ae58cd0db34d6c406794fa2301df81d835c2ea8 Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 21 15:19:16 2019 +0100 dbwrap: Make dbwrap_lock_order_[un]lock() public Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 38a80a300529719934bba135334506346a7a4a6f Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 21 13:23:39 2019 +0100 dbwrap: Simplify dbwrap_lock_order_[un]lock() Directly pass the database name and lock order to the core functions, avoid passing struct db_context. In the next steps these functions will become public: locking.tdb will be based on g_lock.c to avoid holding a tdb-level locking.tdb mutex while doing complex file system operations like unlink() which can take ages on FAT for example. This means that g_lock.c will participate in the dbwrap lock order protection and needs access to dbwrap_lock_order_[un]lock() without providing a direct db_context. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/dbwrap/dbwrap.c | 83 +- lib/dbwrap/dbwrap.h | 5 + source3/include/g_lock.h | 33 + source3/lib/dbwrap/dbwrap_open.c | 3 +- source3/lib/g_lock.c | 451 ++++++++++- source3/locking/share_mode_lock.c | 1589 ++++++++++++++++++++----------------- source3/selftest/tests.py | 1 + source3/torture/proto.h | 1 + source3/torture/test_g_lock.c | 76 ++ source3/torture/torture.c | 4 + 10 files changed, 1461 insertions(+), 785 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/dbwrap/dbwrap.c b/lib/dbwrap/dbwrap.c index baab0338088..735ed169690 100644 --- a/lib/dbwrap/dbwrap.c +++ b/lib/dbwrap/dbwrap.c @@ -123,79 +123,96 @@ NTSTATUS dbwrap_record_delete(struct db_record *rec) return NT_STATUS_OK; } -static void debug_lock_order(int level, struct db_context *dbs[]) +const char *locked_dbs[DBWRAP_LOCK_ORDER_MAX]; + +static void debug_lock_order(int level) { int i; DEBUG(level, ("lock order: ")); for (i=0; i<DBWRAP_LOCK_ORDER_MAX; i++) { - DEBUGADD(level, (" %d:%s", i + 1, dbs[i] ? dbs[i]->name : "<none>")); + DEBUGADD(level, + (" %d:%s", + i + 1, + locked_dbs[i] ? locked_dbs[i] : "<none>")); } DEBUGADD(level, ("\n")); } -static void dbwrap_lock_order_lock(struct db_context *db, - struct db_context ***lockptr) +void dbwrap_lock_order_lock(const char *db_name, + enum dbwrap_lock_order lock_order) { - static struct db_context *locked_dbs[DBWRAP_LOCK_ORDER_MAX]; int idx; - DBG_INFO("check lock order %d for %s\n", (int)db->lock_order, - db->name); + DBG_INFO("check lock order %d for %s\n", + (int)lock_order, + db_name); - if (!DBWRAP_LOCK_ORDER_VALID(db->lock_order)) { + if (!DBWRAP_LOCK_ORDER_VALID(lock_order)) { DBG_ERR("Invalid lock order %d of %s\n", - (int)db->lock_order, db->name); + lock_order, + db_name); smb_panic("lock order violation"); } - for (idx=db->lock_order-1; idx<DBWRAP_LOCK_ORDER_MAX; idx++) { + for (idx=lock_order-1; idx<DBWRAP_LOCK_ORDER_MAX; idx++) { if (locked_dbs[idx] != NULL) { DBG_ERR("Lock order violation: Trying %s at %d while " "%s at %d is locked\n", - db->name, (int)db->lock_order, - locked_dbs[idx]->name, idx + 1); - debug_lock_order(0, locked_dbs); + db_name, + (int)lock_order, + locked_dbs[idx], + idx + 1); + debug_lock_order(0); smb_panic("lock order violation"); } } - locked_dbs[db->lock_order-1] = db; - *lockptr = &locked_dbs[db->lock_order-1]; + locked_dbs[lock_order-1] = db_name; - debug_lock_order(10, locked_dbs); + debug_lock_order(10); } -static void dbwrap_lock_order_unlock(struct db_context *db, - struct db_context **lockptr) +void dbwrap_lock_order_unlock(const char *db_name, + enum dbwrap_lock_order lock_order) { DBG_INFO("release lock order %d for %s\n", - (int)db->lock_order, db->name); + (int)lock_order, + db_name); + + if (!DBWRAP_LOCK_ORDER_VALID(lock_order)) { + DBG_ERR("Invalid lock order %d of %s\n", + lock_order, + db_name); + smb_panic("lock order violation"); + } - if (*lockptr == NULL) { - DBG_ERR("db %s at order %d unlocked\n", db->name, - (int)db->lock_order); + if (locked_dbs[lock_order-1] == NULL) { + DBG_ERR("db %s at order %d unlocked\n", + db_name, + (int)lock_order); smb_panic("lock order violation"); } - if (*lockptr != db) { + if (locked_dbs[lock_order-1] != db_name) { DBG_ERR("locked db at lock order %d is %s, expected %s\n", - (int)(*lockptr)->lock_order, (*lockptr)->name, - db->name); + (int)lock_order, + locked_dbs[lock_order-1], + db_name); smb_panic("lock order violation"); } - *lockptr = NULL; + locked_dbs[lock_order-1] = NULL; } struct dbwrap_lock_order_state { struct db_context *db; - struct db_context **lockptr; }; static int dbwrap_lock_order_state_destructor( struct dbwrap_lock_order_state *s) { - dbwrap_lock_order_unlock(s->db, s->lockptr); + struct db_context *db = s->db; + dbwrap_lock_order_unlock(db->name, db->lock_order); return 0; } @@ -211,7 +228,7 @@ static struct dbwrap_lock_order_state *dbwrap_check_lock_order( } state->db = db; - dbwrap_lock_order_lock(db, &state->lockptr); + dbwrap_lock_order_lock(db->name, db->lock_order); talloc_set_destructor(state, dbwrap_lock_order_state_destructor); return state; @@ -540,18 +557,16 @@ NTSTATUS dbwrap_do_locked(struct db_context *db, TDB_DATA key, struct db_record *rec; if (db->do_locked != NULL) { - struct db_context **lockptr = NULL; NTSTATUS status; if (db->lock_order != DBWRAP_LOCK_ORDER_NONE) { - dbwrap_lock_order_lock(db, &lockptr); + dbwrap_lock_order_lock(db->name, db->lock_order); } status = db->do_locked(db, key, fn, private_data); - if (db->lock_order != DBWRAP_LOCK_ORDER_NONE && - lockptr != NULL) { - dbwrap_lock_order_unlock(db, lockptr); + if (db->lock_order != DBWRAP_LOCK_ORDER_NONE) { + dbwrap_lock_order_unlock(db->name, db->lock_order); } return status; diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h index b5a7fb315c7..0069353fae5 100644 --- a/lib/dbwrap/dbwrap.h +++ b/lib/dbwrap/dbwrap.h @@ -79,6 +79,11 @@ struct db_record *dbwrap_try_fetch_locked(struct db_context *db, TDB_DATA key); struct db_context *dbwrap_record_get_db(struct db_record *rec); +void dbwrap_lock_order_lock(const char *db_name, + enum dbwrap_lock_order lock_order); +void dbwrap_lock_order_unlock(const char *db_name, + enum dbwrap_lock_order lock_order); + NTSTATUS dbwrap_do_locked(struct db_context *db, TDB_DATA key, void (*fn)(struct db_record *rec, TDB_DATA value, diff --git a/source3/include/g_lock.h b/source3/include/g_lock.h index 54f60e410ba..5892f10fcd6 100644 --- a/source3/include/g_lock.h +++ b/source3/include/g_lock.h @@ -36,6 +36,8 @@ struct g_lock_ctx *g_lock_ctx_init_backend( TALLOC_CTX *mem_ctx, struct messaging_context *msg, struct db_context **backend); +void g_lock_set_lock_order(struct g_lock_ctx *ctx, + enum dbwrap_lock_order lock_order); struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx, struct messaging_context *msg); @@ -49,12 +51,30 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key, enum g_lock_type lock_type, struct timeval timeout); NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, TDB_DATA key); +NTSTATUS g_lock_writev_data( + struct g_lock_ctx *ctx, + TDB_DATA key, + const TDB_DATA *dbufs, + size_t num_dbufs); NTSTATUS g_lock_write_data(struct g_lock_ctx *ctx, TDB_DATA key, const uint8_t *buf, size_t buflen); int g_lock_locks(struct g_lock_ctx *ctx, int (*fn)(TDB_DATA key, void *private_data), void *private_data); +struct tevent_req *g_lock_dump_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct g_lock_ctx *ctx, + TDB_DATA key, + void (*fn)(struct server_id exclusive, + size_t num_shared, + struct server_id *shared, + const uint8_t *data, + size_t datalen, + void *private_data), + void *private_data); +NTSTATUS g_lock_dump_recv(struct tevent_req *req); NTSTATUS g_lock_dump(struct g_lock_ctx *ctx, TDB_DATA key, void (*fn)(struct server_id exclusive, @@ -64,5 +84,18 @@ NTSTATUS g_lock_dump(struct g_lock_ctx *ctx, size_t datalen, void *private_data), void *private_data); +int g_lock_seqnum(struct g_lock_ctx *ctx); + +struct tevent_req *g_lock_watch_data_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct g_lock_ctx *ctx, + TDB_DATA key, + struct server_id blocker); +NTSTATUS g_lock_watch_data_recv( + struct tevent_req *req, + bool *blockerdead, + struct server_id *blocker); +void g_lock_wake_watchers(struct g_lock_ctx *ctx, TDB_DATA key); #endif diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c index eac52c5a431..e67341607a4 100644 --- a/source3/lib/dbwrap/dbwrap_open.c +++ b/source3/lib/dbwrap/dbwrap_open.c @@ -67,7 +67,8 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, const char *base; struct loadparm_context *lp_ctx = NULL; - if (!DBWRAP_LOCK_ORDER_VALID(lock_order)) { + if ((lock_order != DBWRAP_LOCK_ORDER_NONE) && + !DBWRAP_LOCK_ORDER_VALID(lock_order)) { errno = EINVAL; return NULL; } diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 4bf30188a43..d9843359dd1 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -36,12 +36,14 @@ struct g_lock_ctx { struct db_context *db; struct messaging_context *msg; + enum dbwrap_lock_order lock_order; }; struct g_lock { struct server_id exclusive; size_t num_shared; uint8_t *shared; + uint64_t data_seqnum; size_t datalen; uint8_t *data; }; @@ -50,9 +52,16 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck) { struct server_id exclusive; size_t num_shared, shared_len; - - if (buflen < (SERVER_ID_BUF_LENGTH + sizeof(uint32_t))) { - *lck = (struct g_lock) { .exclusive.pid = 0 }; + uint64_t data_seqnum; + + if (buflen < (SERVER_ID_BUF_LENGTH + /* exclusive */ + sizeof(uint64_t) + /* seqnum */ + sizeof(uint32_t))) { /* num_shared */ + struct g_lock ret = { .exclusive.pid = 0 }; + generate_random_buffer( + (uint8_t *)&ret.data_seqnum, + sizeof(ret.data_seqnum)); + *lck = ret; return true; } @@ -60,11 +69,18 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck) buf += SERVER_ID_BUF_LENGTH; buflen -= SERVER_ID_BUF_LENGTH; + data_seqnum = BVAL(buf, 0); + buf += sizeof(uint64_t); + buflen -= sizeof(uint64_t); + num_shared = IVAL(buf, 0); buf += sizeof(uint32_t); buflen -= sizeof(uint32_t); if (num_shared > buflen/SERVER_ID_BUF_LENGTH) { + DBG_DEBUG("num_shared=%zu, buflen=%zu\n", + num_shared, + buflen); return false; } @@ -74,6 +90,7 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck) .exclusive = exclusive, .num_shared = num_shared, .shared = buf, + .data_seqnum = data_seqnum, .datalen = buflen-shared_len, .data = buf+shared_len, }; @@ -107,32 +124,54 @@ static void g_lock_del_shared(struct g_lock *lck, size_t i) static NTSTATUS g_lock_store( struct db_record *rec, struct g_lock *lck, - struct server_id *new_shared) + struct server_id *new_shared, + const TDB_DATA *new_dbufs, + size_t num_new_dbufs) { uint8_t exclusive[SERVER_ID_BUF_LENGTH]; + uint8_t seqnum_buf[sizeof(uint64_t)]; uint8_t sizebuf[sizeof(uint32_t)]; - uint8_t shared[SERVER_ID_BUF_LENGTH]; - - struct TDB_DATA dbufs[] = { - { .dptr = exclusive, .dsize = sizeof(exclusive) }, - { .dptr = sizebuf, .dsize = sizeof(sizebuf) }, - { .dptr = lck->shared, - .dsize = lck->num_shared * SERVER_ID_BUF_LENGTH }, - { 0 }, - { .dptr = lck->data, .dsize = lck->datalen } + uint8_t new_shared_buf[SERVER_ID_BUF_LENGTH]; + + struct TDB_DATA dbufs[6 + num_new_dbufs]; + + dbufs[0] = (TDB_DATA) { + .dptr = exclusive, .dsize = sizeof(exclusive), + }; + dbufs[1] = (TDB_DATA) { + .dptr = seqnum_buf, .dsize = sizeof(seqnum_buf), + }; + dbufs[2] = (TDB_DATA) { + .dptr = sizebuf, .dsize = sizeof(sizebuf), + }; + dbufs[3] = (TDB_DATA) { + .dptr = lck->shared, + .dsize = lck->num_shared * SERVER_ID_BUF_LENGTH, }; + dbufs[4] = (TDB_DATA) { 0 }; + dbufs[5] = (TDB_DATA) { + .dptr = lck->data, .dsize = lck->datalen, + }; + + if (num_new_dbufs != 0) { + memcpy(&dbufs[6], + new_dbufs, + num_new_dbufs * sizeof(TDB_DATA)); + } server_id_put(exclusive, lck->exclusive); + SBVAL(seqnum_buf, 0, lck->data_seqnum); if (new_shared != NULL) { if (lck->num_shared >= UINT32_MAX) { return NT_STATUS_BUFFER_OVERFLOW; } - server_id_put(shared, *new_shared); + server_id_put(new_shared_buf, *new_shared); - dbufs[3] = (TDB_DATA) { - .dptr = shared, .dsize = sizeof(shared), + dbufs[4] = (TDB_DATA) { + .dptr = new_shared_buf, + .dsize = sizeof(new_shared_buf), }; lck->num_shared += 1; @@ -155,6 +194,7 @@ struct g_lock_ctx *g_lock_ctx_init_backend( return NULL; } result->msg = msg; + result->lock_order = DBWRAP_LOCK_ORDER_NONE; result->db = db_open_watched(result, backend, msg); if (result->db == NULL) { @@ -165,6 +205,12 @@ struct g_lock_ctx *g_lock_ctx_init_backend( return result; } +void g_lock_set_lock_order(struct g_lock_ctx *ctx, + enum dbwrap_lock_order lock_order) +{ + ctx->lock_order = lock_order; +} + struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx, struct messaging_context *msg) { @@ -235,7 +281,7 @@ static NTSTATUS g_lock_cleanup_dead( } if (modified) { - status = g_lock_store(rec, lck, NULL); + status = g_lock_store(rec, lck, NULL, NULL, 0); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("g_lock_store() failed: %s\n", nt_errstr(status)); @@ -454,7 +500,7 @@ noexclusive: lck.exclusive = self; - status = g_lock_store(rec, &lck, NULL); + status = g_lock_store(rec, &lck, NULL, NULL, 0); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("g_lock_store() failed: %s\n", nt_errstr(status)); @@ -483,7 +529,7 @@ noexclusive: do_shared: if (lck.num_shared == 0) { - status = g_lock_store(rec, &lck, &self); + status = g_lock_store(rec, &lck, &self, NULL, 0); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("g_lock_store() failed: %s\n", nt_errstr(status)); @@ -494,7 +540,7 @@ do_shared: g_lock_cleanup_shared(&lck); - status = g_lock_store(rec, &lck, &self); + status = g_lock_store(rec, &lck, &self, NULL, 0); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("g_lock_store() failed: %s\n", nt_errstr(status)); @@ -652,7 +698,23 @@ static void g_lock_lock_retry(struct tevent_req *subreq) NTSTATUS g_lock_lock_recv(struct tevent_req *req) { - return tevent_req_simple_recv_ntstatus(req); + struct g_lock_lock_state *state = tevent_req_data( + req, struct g_lock_lock_state); + struct g_lock_ctx *ctx = state->ctx; + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + + if ((ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) && + ((state->type == G_LOCK_READ) || + (state->type == G_LOCK_WRITE))) { + const char *name = dbwrap_name(ctx->db); + dbwrap_lock_order_lock(name, ctx->lock_order); + } + + return NT_STATUS_OK; } struct g_lock_lock_simple_state { @@ -686,13 +748,13 @@ static void g_lock_lock_simple_fn( goto not_granted; } lck.exclusive = state->me; - state->status = g_lock_store(rec, &lck, NULL); + state->status = g_lock_store(rec, &lck, NULL, NULL, 0); return; } if (state->type == G_LOCK_READ) { g_lock_cleanup_shared(&lck); - state->status = g_lock_store(rec, &lck, &state->me); + state->status = g_lock_store(rec, &lck, &state->me, NULL, 0); return; } @@ -731,6 +793,10 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key, return status; } if (NT_STATUS_IS_OK(state.status)) { + if (ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) { + const char *name = dbwrap_name(ctx->db); + dbwrap_lock_order_lock(name, ctx->lock_order); + } return NT_STATUS_OK; } if (!NT_STATUS_EQUAL( @@ -829,7 +895,7 @@ static void g_lock_unlock_fn( return; } -- Samba Shared Repository