]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Add quick leases_db_get_current_state()
authorVolker Lendecke <vl@samba.org>
Tue, 13 Aug 2019 20:07:47 +0000 (22:07 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 17 Sep 2019 22:49:36 +0000 (22:49 +0000)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/locking/leases_db.c
source3/locking/leases_db.h

index 17778050accea79cfc5942d97be8cad4404fab39..b739d618c49579c40b1915ff2f57b0fc0e04f91d 100644 (file)
@@ -47,7 +47,10 @@ bool leases_db_init(bool read_only)
        }
 
        leases_db = db_open(NULL, db_path, 0,
-                           TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|
+                           TDB_DEFAULT|
+                           TDB_VOLATILE|
+                           TDB_CLEAR_IF_FIRST|
+                           TDB_SEQNUM|
                            TDB_INCOMPATIBLE_HASH,
                            read_only ? O_RDONLY : O_RDWR|O_CREAT, 0644,
                            DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
@@ -625,7 +628,79 @@ NTSTATUS leases_db_get(const struct GUID *client_guid,
                return status;
        }
        return state.status;
+}
+
+struct leases_db_get_current_state_state {
+       int seqnum;
+       uint32_t current_state;
+       NTSTATUS status;
+};
+
+/*
+ * This function is an optimization that
+ * relies on the fact that the
+ * smb2_lease_state current_state
+ * (which is a uint32_t size)
+ * from struct leases_db_value is the first
+ * entry in the ndr-encoded struct leases_db_value.
+ * Read it without having to ndr decode all
+ * the values in struct leases_db_value.
+ */
+
+static void leases_db_get_current_state_fn(
+       TDB_DATA key, TDB_DATA data, void *private_data)
+{
+       struct leases_db_get_current_state_state *state = private_data;
+       struct ndr_pull ndr;
+       enum ndr_err_code ndr_err;
+
+       if (data.dsize < sizeof(uint32_t)) {
+               state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+               return;
+       }
+
+       state->seqnum = dbwrap_get_seqnum(leases_db);
+
+       ndr = (struct ndr_pull) {
+               .data = data.dptr, .data_size = data.dsize,
+       };
+       ndr_err = ndr_pull_uint32(&ndr, NDR_SCALARS, &state->current_state);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               state->status = ndr_map_error2ntstatus(ndr_err);
+       }
+}
 
+NTSTATUS leases_db_get_current_state(
+       const struct GUID *client_guid,
+       const struct smb2_lease_key *lease_key,
+       int *database_seqnum,
+       uint32_t *current_state)
+{
+       struct leases_db_get_current_state_state state = { 0 };
+       struct leases_db_key_buf keybuf;
+       TDB_DATA db_key = { 0 };
+       NTSTATUS status;
+
+       if (!leases_db_init(true)) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       state.seqnum = dbwrap_get_seqnum(leases_db);
+       if (*database_seqnum == state.seqnum) {
+               return NT_STATUS_OK;
+       }
+
+       db_key = leases_db_key(&keybuf, client_guid, lease_key);
+
+       status = dbwrap_parse_record(
+               leases_db, db_key, leases_db_get_current_state_fn, &state);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       *database_seqnum = state.seqnum;
+       *current_state = state.current_state;
+
+       return NT_STATUS_OK;
 }
 
 NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
index 99a4a78315ce61958d4c1dc849ea9b66cf4ae4e6..9c149c19f076f048088c3b075df2fc2dd03c306c 100644 (file)
@@ -68,6 +68,11 @@ NTSTATUS leases_db_get(const struct GUID *client_guid,
                       uint32_t *breaking_to_required,
                       uint16_t *lease_version,
                       uint16_t *epoch);
+NTSTATUS leases_db_get_current_state(
+       const struct GUID *client_guid,
+       const struct smb2_lease_key *lease_key,
+       int *database_seqnum,
+       uint32_t *current_state);
 NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
                        uint32_t num_files,
                        const struct leases_db_file *files,