diff options
author | Volker Lendecke <vl@samba.org> | 2019-08-13 22:07:47 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-09-17 22:49:36 +0000 |
commit | cc2e5b41646f6c18288ffb4b0ea16f4ea2cb4874 (patch) | |
tree | 1435330a00a0a40782e8f40d4de3987ce1aa2695 /source3/locking | |
parent | 8d63b622df42111b603d5f6fe2fa31490eb7cd98 (diff) | |
download | samba-cc2e5b41646f6c18288ffb4b0ea16f4ea2cb4874.tar.gz |
smbd: Add quick leases_db_get_current_state()
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/leases_db.c | 77 | ||||
-rw-r--r-- | source3/locking/leases_db.h | 5 |
2 files changed, 81 insertions, 1 deletions
diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c index 17778050acc..b739d618c49 100644 --- a/source3/locking/leases_db.c +++ b/source3/locking/leases_db.c @@ -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, diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h index 99a4a78315c..9c149c19f07 100644 --- a/source3/locking/leases_db.h +++ b/source3/locking/leases_db.h @@ -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, |