From: Volker Lendecke Date: Mon, 26 Aug 2019 20:05:14 +0000 (+0200) Subject: smbd: Use share_mode_forall_entries() in share_mode_forall_leases() X-Git-Tag: talloc-2.3.1~797 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac119c411c4e268d7fe3c6766d3f9023ea4df456;p=thirdparty%2Fsamba.git smbd: Use share_mode_forall_entries() in share_mode_forall_leases() Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ae42058e605..6afbb40adad 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -48,6 +48,7 @@ #include "util_tdb.h" #include "../librpc/gen_ndr/ndr_open_files.h" #include "librpc/gen_ndr/ndr_file_id.h" +#include "librpc/gen_ndr/ndr_leases_db.h" #include "locking/leases_db.h" #undef DBGC_CLASS @@ -1368,71 +1369,88 @@ bool share_mode_forall_entries( * Walk share mode entries, looking at every lease only once */ -bool share_mode_forall_leases( - struct share_mode_lock *lck, +struct share_mode_forall_leases_state { + TALLOC_CTX *mem_ctx; + struct leases_db_key *leases; bool (*fn)(struct share_mode_entry *e, - void *private_data), + void *private_data); + void *private_data; + NTSTATUS status; +}; + +static bool share_mode_forall_leases_fn( + struct share_mode_entry *e, + bool *modified, void *private_data) { - struct share_mode_data *d = lck->data; - uint32_t *leases = NULL; - uint32_t num_leases = 0; - uint32_t i; + struct share_mode_forall_leases_state *state = private_data; + struct leases_db_key *leases = state->leases; + size_t i, num_leases; + bool stop; - leases = talloc_array(talloc_tos(), uint32_t, d->num_share_modes); - if (leases == NULL) { + if (e->op_type != LEASE_OPLOCK) { return false; } - for (i=0; inum_share_modes; i++) { - struct share_mode_entry *e = &d->share_modes[i]; - uint32_t j; - bool ok, stop; + num_leases = talloc_array_length(leases); - ok = is_valid_share_mode_entry(e); - if (!ok) { - continue; - } - - if (e->op_type != LEASE_OPLOCK) { - continue; + for (i=0; iclient_guid, + &e->lease_key, + &l->client_guid, + &l->lease_key); + if (same) { + return false; } + } - /* - * See if we have already seen "e"'s lease. This is - * O(n^2). If we sort "leases", we can get this down - * to O(n). - */ + leases = talloc_realloc( + state->mem_ctx, + leases, + struct leases_db_key, + num_leases+1); + if (leases == NULL) { + state->status = NT_STATUS_NO_MEMORY; + return true; + } + leases[num_leases] = (struct leases_db_key) { + .client_guid = e->client_guid, + .lease_key = e->lease_key, + }; + state->leases = leases; - for (j=0; jshare_modes[idx]; + stop = state->fn(e, state->private_data); + return stop; +} - if (smb2_lease_equal(&e->client_guid, - &e->lease_key, - &l->client_guid, - &l->lease_key)) { - break; - } - } - if (j < num_leases) { - /* - * Don't look at "e"'s lease, we've already - * seen it. - */ - continue; - } +bool share_mode_forall_leases( + struct share_mode_lock *lck, + bool (*fn)(struct share_mode_entry *e, + void *private_data), + void *private_data) +{ + struct share_mode_forall_leases_state state = { + .mem_ctx = talloc_tos(), + .fn = fn, + .private_data = private_data + }; + bool ok; - stop = fn(e, private_data); - if (stop) { - TALLOC_FREE(leases); - return true; - } + ok = share_mode_forall_entries( + lck, share_mode_forall_leases_fn, &state); + TALLOC_FREE(state.leases); + if (!ok) { + DBG_DEBUG("share_mode_forall_entries failed\n"); + return false; + } - leases[num_leases] = i; - num_leases += 1; + if (!NT_STATUS_IS_OK(state.status)) { + DBG_DEBUG("share_mode_forall_leases_fn returned %s\n", + nt_errstr(state.status)); + return false; } - TALLOC_FREE(leases); return true; }