]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Use share_mode_forall_entries() in share_mode_forall_leases()
authorVolker Lendecke <vl@samba.org>
Mon, 26 Aug 2019 20:05:14 +0000 (22:05 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 17 Sep 2019 22:49:37 +0000 (22:49 +0000)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/locking/locking.c

index ae42058e6055a9166a5d41db5e752272249b9b9b..6afbb40adadecd44c04066036e9e80ca894279c1 100644 (file)
@@ -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; i<d->num_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; i<num_leases; i++) {
+               struct leases_db_key *l = &leases[i];
+               bool same = smb2_lease_equal(
+                       &e->client_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; j<num_leases; j++) {
-                       uint32_t idx = leases[j];
-                       struct share_mode_entry *l = &d->share_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;
 }