]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Add share_mode_count_entries()
authorVolker Lendecke <vl@samba.org>
Fri, 29 Nov 2019 14:45:22 +0000 (15:45 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 17 Dec 2019 22:40:32 +0000 (22:40 +0000)
In order to not write the share mode on every open/close, we need to get rid of
share_mode_data->num_share_modes. "net tdb" needs this information precisely
though, and it's pretty cheap to calculate.

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

index 432278e3c3078bc48a7077b977d93eabe4d4353b..dfbd59ede0c36fb6de6eb1f56873eb9ece64e223 100644 (file)
@@ -244,6 +244,7 @@ bool share_mode_forall_entries(
                   void *private_data),
        void *private_data);
 
+NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes);
 
 /* The following definitions come from locking/posix.c  */
 
index 6704f34523a4de590391b9c307d58df464ee4eec..f43cbd287d3b6158d6aa8f1355bf43f6300ec48b 100644 (file)
@@ -1838,6 +1838,52 @@ bool share_mode_forall_entries(
        return state.ok;
 }
 
+struct share_mode_count_entries_state {
+       size_t num_share_modes;
+       NTSTATUS status;
+};
+
+static void share_mode_count_entries_fn(
+       TDB_DATA key, TDB_DATA data, void *private_data)
+{
+       struct share_mode_count_entries_state *state = private_data;
+
+       if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
+               DBG_WARNING("Invalid data size %zu\n", data.dsize);
+               state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+               return;
+       }
+       state->num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
+       state->status = NT_STATUS_OK;
+}
+
+NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes)
+{
+       struct share_mode_count_entries_state state = {
+               .status = NT_STATUS_NOT_FOUND,
+       };
+       NTSTATUS status;
+
+       status = dbwrap_parse_record(
+               share_entries_db,
+               locking_key(&fid),
+               share_mode_count_entries_fn,
+               &state);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("dbwrap_parse_record failed: %s\n",
+                         nt_errstr(status));
+               return status;
+       }
+       if (!NT_STATUS_IS_OK(state.status)) {
+               DBG_DEBUG("share_mode_forall_entries_fn failed: %s\n",
+                         nt_errstr(state.status));
+               return state.status;
+       }
+
+       *num_share_modes = state.num_share_modes;
+       return NT_STATUS_OK;
+}
+
 struct share_mode_entry_do_state {
        struct server_id pid;
        uint64_t share_file_id;