]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Move share_mode_cleanup_disonnected() to scavenger.c
authorVolker Lendecke <vl@samba.org>
Tue, 3 Nov 2020 12:25:57 +0000 (13:25 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 10 Nov 2020 19:49:34 +0000 (19:49 +0000)
Reduce the complexity of share_mode_lock.c, scavenger.c is the only
user of this routine.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/locking/share_mode_lock.c
source3/locking/share_mode_lock.h
source3/smbd/scavenger.c

index ad69ef7c6e25af356eb5a4e9cef048a6a831811f..f4f563ee37c011548826d30dea2aac5470d2fcf8 100644 (file)
@@ -1572,224 +1572,6 @@ int share_entry_forall(int (*fn)(struct file_id fid,
        return share_mode_forall(share_entry_traverse_fn, &state);
 }
 
-struct cleanup_disconnected_state {
-       struct share_mode_lock *lck;
-       uint64_t open_persistent_id;
-       size_t num_disconnected;
-       bool found_connected;
-};
-
-static bool cleanup_disconnected_lease(struct share_mode_entry *e,
-                                      void *private_data)
-{
-       struct cleanup_disconnected_state *state = private_data;
-       NTSTATUS status;
-
-       status = leases_db_del(
-               &e->client_guid, &e->lease_key, &state->lck->data->id);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_DEBUG("leases_db_del failed: %s\n",
-                         nt_errstr(status));
-       }
-
-       return false;
-}
-
-static bool share_mode_find_connected_fn(
-       struct share_mode_entry *e,
-       bool *modified,
-       void *private_data)
-{
-       struct cleanup_disconnected_state *state = private_data;
-       struct share_mode_data *d = state->lck->data;
-       bool disconnected;
-
-       disconnected = server_id_is_disconnected(&e->pid);
-       if (!disconnected) {
-               struct file_id_buf tmp1;
-               struct server_id_buf tmp2;
-               DBG_INFO("file (file-id='%s', servicepath='%s', "
-                        "base_name='%s%s%s') "
-                        "is used by server %s ==> do not cleanup\n",
-                        file_id_str_buf(d->id, &tmp1),
-                        d->servicepath,
-                        d->base_name,
-                        (d->stream_name == NULL)
-                        ? "" : "', stream_name='",
-                        (d->stream_name == NULL)
-                        ? "" : d->stream_name,
-                        server_id_str_buf(e->pid, &tmp2));
-               state->found_connected = true;
-               return true;
-       }
-
-       if (state->open_persistent_id != e->share_file_id) {
-               struct file_id_buf tmp;
-               DBG_INFO("entry for file "
-                        "(file-id='%s', servicepath='%s', "
-                        "base_name='%s%s%s') "
-                        "has share_file_id %"PRIu64" but expected "
-                        "%"PRIu64"==> do not cleanup\n",
-                        file_id_str_buf(d->id, &tmp),
-                        d->servicepath,
-                        d->base_name,
-                        (d->stream_name == NULL)
-                        ? "" : "', stream_name='",
-                        (d->stream_name == NULL)
-                        ? "" : d->stream_name,
-                        e->share_file_id,
-                        state->open_persistent_id);
-               state->found_connected = true;
-               return true;
-       }
-
-       state->num_disconnected += 1;
-
-       return false;
-}
-
-static bool cleanup_disconnected_share_mode_entry_fn(
-       struct share_mode_entry *e,
-       bool *modified,
-       void *private_data)
-{
-       struct cleanup_disconnected_state *state = private_data;
-       struct share_mode_data *d = state->lck->data;
-
-       bool disconnected;
-
-       disconnected = server_id_is_disconnected(&e->pid);
-       if (!disconnected) {
-               struct file_id_buf tmp1;
-               struct server_id_buf tmp2;
-               DBG_ERR("file (file-id='%s', servicepath='%s', "
-                       "base_name='%s%s%s') "
-                       "is used by server %s ==> internal error\n",
-                       file_id_str_buf(d->id, &tmp1),
-                       d->servicepath,
-                       d->base_name,
-                       (d->stream_name == NULL)
-                       ? "" : "', stream_name='",
-                       (d->stream_name == NULL)
-                       ? "" : d->stream_name,
-                       server_id_str_buf(e->pid, &tmp2));
-               smb_panic(__location__);
-       }
-
-       /*
-        * Setting e->stale = true is
-        * the indication to delete the entry.
-        */
-       e->stale = true;
-       return false;
-}
-
-bool share_mode_cleanup_disconnected(struct file_id fid,
-                                    uint64_t open_persistent_id)
-{
-       struct cleanup_disconnected_state state = {
-               .open_persistent_id = open_persistent_id
-       };
-       struct share_mode_data *data;
-       bool ret = false;
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct file_id_buf idbuf;
-       bool ok;
-
-       state.lck = get_existing_share_mode_lock(frame, fid);
-       if (state.lck == NULL) {
-               DBG_INFO("Could not fetch share mode entry for %s\n",
-                        file_id_str_buf(fid, &idbuf));
-               goto done;
-       }
-       data = state.lck->data;
-
-       ok = share_mode_forall_entries(
-               state.lck, share_mode_find_connected_fn, &state);
-       if (!ok) {
-               DBG_DEBUG("share_mode_forall_entries failed\n");
-               goto done;
-       }
-       if (state.found_connected) {
-               DBG_DEBUG("Found connected entry\n");
-               goto done;
-       }
-
-       ok = share_mode_forall_leases(
-               state.lck, cleanup_disconnected_lease, &state);
-       if (!ok) {
-               DBG_DEBUG("failed to clean up leases associated "
-                         "with file (file-id='%s', servicepath='%s', "
-                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
-                         "==> do not cleanup\n",
-                         file_id_str_buf(fid, &idbuf),
-                         data->servicepath,
-                         data->base_name,
-                         (data->stream_name == NULL)
-                         ? "" : "', stream_name='",
-                         (data->stream_name == NULL)
-                         ? "" : data->stream_name,
-                         open_persistent_id);
-               goto done;
-       }
-
-       ok = brl_cleanup_disconnected(fid, open_persistent_id);
-       if (!ok) {
-               DBG_DEBUG("failed to clean up byte range locks associated "
-                         "with file (file-id='%s', servicepath='%s', "
-                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
-                         "==> do not cleanup\n",
-                         file_id_str_buf(fid, &idbuf),
-                         data->servicepath,
-                         data->base_name,
-                         (data->stream_name == NULL)
-                         ? "" : "', stream_name='",
-                         (data->stream_name == NULL)
-                         ? "" : data->stream_name,
-                         open_persistent_id);
-               goto done;
-       }
-
-       DBG_DEBUG("cleaning up %zu entries for file "
-                 "(file-id='%s', servicepath='%s', "
-                 "base_name='%s%s%s') "
-                 "from open_persistent_id %"PRIu64"\n",
-                 state.num_disconnected,
-                 file_id_str_buf(fid, &idbuf),
-                 data->servicepath,
-                 data->base_name,
-                 (data->stream_name == NULL)
-                 ? "" : "', stream_name='",
-                 (data->stream_name == NULL)
-                 ? "" : data->stream_name,
-                 open_persistent_id);
-
-       ok = share_mode_forall_entries(
-               state.lck, cleanup_disconnected_share_mode_entry_fn, &state);
-       if (!ok) {
-               DBG_DEBUG("failed to clean up %zu entries associated "
-                         "with file (file-id='%s', servicepath='%s', "
-                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
-                         "==> do not cleanup\n",
-                         state.num_disconnected,
-                         file_id_str_buf(fid, &idbuf),
-                         data->servicepath,
-                         data->base_name,
-                         (data->stream_name == NULL)
-                         ? "" : "', stream_name='",
-                         (data->stream_name == NULL)
-                         ? "" : data->stream_name,
-                         open_persistent_id);
-               goto done;
-       }
-
-       ret = true;
-done:
-       talloc_free(frame);
-       return ret;
-}
-
 static int share_mode_entry_cmp(
        struct server_id pid1,
        uint64_t share_file_id1,
index 644f2bda9e34ab5faf780c4c5e26568fc04b775f..734db6fd6f409d3efd845d1b93563fb2df7c5d36 100644 (file)
@@ -71,9 +71,6 @@ int share_entry_forall(
                  const struct share_mode_entry *entry,
                  void *private_data),
        void *private_data);
-bool share_mode_cleanup_disconnected(
-       struct file_id fid,
-       uint64_t open_persistent_id);
 
 NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes);
 NTSTATUS share_mode_do_locked(
index a24a5d7ccb908c531d75502392e75741f4a4d792..ef34cdc41f9671388f560bd3b95ab30c2f71fdf6 100644 (file)
@@ -24,7 +24,9 @@
 #include "smbd/globals.h"
 #include "smbd/scavenger.h"
 #include "locking/share_mode_lock.h"
+#include "locking/leases_db.h"
 #include "locking/proto.h"
+#include "librpc/gen_ndr/open_files.h"
 #include "lib/util/server_id.h"
 #include "lib/util/util_process.h"
 #include "lib/util/sys_rw_data.h"
@@ -464,6 +466,224 @@ struct scavenger_timer_context {
        struct scavenger_message msg;
 };
 
+struct cleanup_disconnected_state {
+       struct share_mode_lock *lck;
+       uint64_t open_persistent_id;
+       size_t num_disconnected;
+       bool found_connected;
+};
+
+static bool cleanup_disconnected_lease(struct share_mode_entry *e,
+                                      void *private_data)
+{
+       struct cleanup_disconnected_state *state = private_data;
+       NTSTATUS status;
+
+       status = leases_db_del(
+               &e->client_guid, &e->lease_key, &state->lck->data->id);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("leases_db_del failed: %s\n",
+                         nt_errstr(status));
+       }
+
+       return false;
+}
+
+static bool share_mode_find_connected_fn(
+       struct share_mode_entry *e,
+       bool *modified,
+       void *private_data)
+{
+       struct cleanup_disconnected_state *state = private_data;
+       struct share_mode_data *d = state->lck->data;
+       bool disconnected;
+
+       disconnected = server_id_is_disconnected(&e->pid);
+       if (!disconnected) {
+               struct file_id_buf tmp1;
+               struct server_id_buf tmp2;
+               DBG_INFO("file (file-id='%s', servicepath='%s', "
+                        "base_name='%s%s%s') "
+                        "is used by server %s ==> do not cleanup\n",
+                        file_id_str_buf(d->id, &tmp1),
+                        d->servicepath,
+                        d->base_name,
+                        (d->stream_name == NULL)
+                        ? "" : "', stream_name='",
+                        (d->stream_name == NULL)
+                        ? "" : d->stream_name,
+                        server_id_str_buf(e->pid, &tmp2));
+               state->found_connected = true;
+               return true;
+       }
+
+       if (state->open_persistent_id != e->share_file_id) {
+               struct file_id_buf tmp;
+               DBG_INFO("entry for file "
+                        "(file-id='%s', servicepath='%s', "
+                        "base_name='%s%s%s') "
+                        "has share_file_id %"PRIu64" but expected "
+                        "%"PRIu64"==> do not cleanup\n",
+                        file_id_str_buf(d->id, &tmp),
+                        d->servicepath,
+                        d->base_name,
+                        (d->stream_name == NULL)
+                        ? "" : "', stream_name='",
+                        (d->stream_name == NULL)
+                        ? "" : d->stream_name,
+                        e->share_file_id,
+                        state->open_persistent_id);
+               state->found_connected = true;
+               return true;
+       }
+
+       state->num_disconnected += 1;
+
+       return false;
+}
+
+static bool cleanup_disconnected_share_mode_entry_fn(
+       struct share_mode_entry *e,
+       bool *modified,
+       void *private_data)
+{
+       struct cleanup_disconnected_state *state = private_data;
+       struct share_mode_data *d = state->lck->data;
+
+       bool disconnected;
+
+       disconnected = server_id_is_disconnected(&e->pid);
+       if (!disconnected) {
+               struct file_id_buf tmp1;
+               struct server_id_buf tmp2;
+               DBG_ERR("file (file-id='%s', servicepath='%s', "
+                       "base_name='%s%s%s') "
+                       "is used by server %s ==> internal error\n",
+                       file_id_str_buf(d->id, &tmp1),
+                       d->servicepath,
+                       d->base_name,
+                       (d->stream_name == NULL)
+                       ? "" : "', stream_name='",
+                       (d->stream_name == NULL)
+                       ? "" : d->stream_name,
+                       server_id_str_buf(e->pid, &tmp2));
+               smb_panic(__location__);
+       }
+
+       /*
+        * Setting e->stale = true is
+        * the indication to delete the entry.
+        */
+       e->stale = true;
+       return false;
+}
+
+static bool share_mode_cleanup_disconnected(
+       struct file_id fid, uint64_t open_persistent_id)
+{
+       struct cleanup_disconnected_state state = {
+               .open_persistent_id = open_persistent_id
+       };
+       struct share_mode_data *data;
+       bool ret = false;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct file_id_buf idbuf;
+       bool ok;
+
+       state.lck = get_existing_share_mode_lock(frame, fid);
+       if (state.lck == NULL) {
+               DBG_INFO("Could not fetch share mode entry for %s\n",
+                        file_id_str_buf(fid, &idbuf));
+               goto done;
+       }
+       data = state.lck->data;
+
+       ok = share_mode_forall_entries(
+               state.lck, share_mode_find_connected_fn, &state);
+       if (!ok) {
+               DBG_DEBUG("share_mode_forall_entries failed\n");
+               goto done;
+       }
+       if (state.found_connected) {
+               DBG_DEBUG("Found connected entry\n");
+               goto done;
+       }
+
+       ok = share_mode_forall_leases(
+               state.lck, cleanup_disconnected_lease, &state);
+       if (!ok) {
+               DBG_DEBUG("failed to clean up leases associated "
+                         "with file (file-id='%s', servicepath='%s', "
+                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
+                         "==> do not cleanup\n",
+                         file_id_str_buf(fid, &idbuf),
+                         data->servicepath,
+                         data->base_name,
+                         (data->stream_name == NULL)
+                         ? "" : "', stream_name='",
+                         (data->stream_name == NULL)
+                         ? "" : data->stream_name,
+                         open_persistent_id);
+               goto done;
+       }
+
+       ok = brl_cleanup_disconnected(fid, open_persistent_id);
+       if (!ok) {
+               DBG_DEBUG("failed to clean up byte range locks associated "
+                         "with file (file-id='%s', servicepath='%s', "
+                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
+                         "==> do not cleanup\n",
+                         file_id_str_buf(fid, &idbuf),
+                         data->servicepath,
+                         data->base_name,
+                         (data->stream_name == NULL)
+                         ? "" : "', stream_name='",
+                         (data->stream_name == NULL)
+                         ? "" : data->stream_name,
+                         open_persistent_id);
+               goto done;
+       }
+
+       DBG_DEBUG("cleaning up %zu entries for file "
+                 "(file-id='%s', servicepath='%s', "
+                 "base_name='%s%s%s') "
+                 "from open_persistent_id %"PRIu64"\n",
+                 state.num_disconnected,
+                 file_id_str_buf(fid, &idbuf),
+                 data->servicepath,
+                 data->base_name,
+                 (data->stream_name == NULL)
+                 ? "" : "', stream_name='",
+                 (data->stream_name == NULL)
+                 ? "" : data->stream_name,
+                 open_persistent_id);
+
+       ok = share_mode_forall_entries(
+               state.lck, cleanup_disconnected_share_mode_entry_fn, &state);
+       if (!ok) {
+               DBG_DEBUG("failed to clean up %zu entries associated "
+                         "with file (file-id='%s', servicepath='%s', "
+                         "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
+                         "==> do not cleanup\n",
+                         state.num_disconnected,
+                         file_id_str_buf(fid, &idbuf),
+                         data->servicepath,
+                         data->base_name,
+                         (data->stream_name == NULL)
+                         ? "" : "', stream_name='",
+                         (data->stream_name == NULL)
+                         ? "" : data->stream_name,
+                         open_persistent_id);
+               goto done;
+       }
+
+       ret = true;
+done:
+       talloc_free(frame);
+       return ret;
+}
+
 static void scavenger_timer(struct tevent_context *ev,
                            struct tevent_timer *te,
                            struct timeval t, void *data)