From 7cc9b426a44b1e12c6261836d0a86eabb7c92c34 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Sep 2018 13:00:49 +0200 Subject: [PATCH] smbd: Split up grant_fsp_lease() Simple refactoring into simpler routines. View best with "git show -b" Signed-off-by: Volker Lendecke Reviewed-by: Christof Schmitt --- source3/smbd/open.c | 176 +++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 76 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 26782bf5d30..1ad4596cff7 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2094,101 +2094,107 @@ struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp, return new_fsp->lease; } -static NTSTATUS grant_fsp_lease(struct files_struct *fsp, - struct share_mode_lock *lck, - const struct smb2_lease *lease, - uint32_t granted) +static NTSTATUS try_lease_upgrade(struct files_struct *fsp, + struct share_mode_lock *lck, + const struct GUID *client_guid, + const struct smb2_lease *lease, + uint32_t granted) { struct share_mode_data *d = lck->data; - const struct GUID *client_guid = fsp_client_guid(fsp); - struct share_mode_lease *tmp; - NTSTATUS status; int idx; + struct share_mode_lease *l = NULL; + bool do_upgrade; + uint32_t existing, requested; idx = find_share_mode_lease(d, client_guid, &lease->lease_key); + if (idx == -1) { + return NT_STATUS_NOT_FOUND; + } + l = &d->leases[idx]; - if (idx != -1) { - struct share_mode_lease *l = &d->leases[idx]; - bool do_upgrade; - uint32_t existing, requested; + fsp->lease = find_fsp_lease( + fsp, + &lease->lease_key, + l->current_state, + l->lease_version, + l->epoch); + if (fsp->lease == NULL) { + DEBUG(1, ("Did not find existing lease for file %s\n", + fsp_str_dbg(fsp))); + return NT_STATUS_NO_MEMORY; + } - fsp->lease = find_fsp_lease( - fsp, - &lease->lease_key, - l->current_state, - l->lease_version, - l->epoch); - if (fsp->lease == NULL) { - DEBUG(1, ("Did not find existing lease for file %s\n", - fsp_str_dbg(fsp))); - return NT_STATUS_NO_MEMORY; - } + /* + * Upgrade only if the requested lease is a strict upgrade. + */ + existing = l->current_state; + requested = lease->lease_state; - /* - * Upgrade only if the requested lease is a strict upgrade. - */ - existing = l->current_state; - requested = lease->lease_state; + /* + * Tricky: This test makes sure that "requested" is a + * strict bitwise superset of "existing". + */ + do_upgrade = ((existing & requested) == existing); - /* - * Tricky: This test makes sure that "requested" is a - * strict bitwise superset of "existing". - */ - do_upgrade = ((existing & requested) == existing); + /* + * Upgrade only if there's a change. + */ + do_upgrade &= (granted != existing); - /* - * Upgrade only if there's a change. - */ - do_upgrade &= (granted != existing); + /* + * Upgrade only if other leases don't prevent what was asked + * for. + */ + do_upgrade &= (granted == requested); - /* - * Upgrade only if other leases don't prevent what was asked - * for. - */ - do_upgrade &= (granted == requested); + /* + * only upgrade if we are not in breaking state + */ + do_upgrade &= !l->breaking; - /* - * only upgrade if we are not in breaking state - */ - do_upgrade &= !l->breaking; + DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", " + "granted=%"PRIu32", do_upgrade=%d\n", + existing, requested, granted, (int)do_upgrade)); - DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", " - "granted=%"PRIu32", do_upgrade=%d\n", - existing, requested, granted, (int)do_upgrade)); + if (do_upgrade) { + l->current_state = granted; + l->epoch += 1; + } - if (do_upgrade) { - l->current_state = granted; - l->epoch += 1; - } + { + NTSTATUS set_status; - { - NTSTATUS set_status; + set_status = leases_db_set( + client_guid, + &lease->lease_key, + l->current_state, + l->breaking, + l->breaking_to_requested, + l->breaking_to_required, + l->lease_version, + l->epoch); - set_status = leases_db_set( - client_guid, - &lease->lease_key, - l->current_state, - l->breaking, - l->breaking_to_requested, - l->breaking_to_required, - l->lease_version, - l->epoch); - - if (!NT_STATUS_IS_OK(set_status)) { - DBG_DEBUG("leases_db_set failed: %s\n", - nt_errstr(set_status)); - return set_status; - } + if (!NT_STATUS_IS_OK(set_status)) { + DBG_DEBUG("leases_db_set failed: %s\n", + nt_errstr(set_status)); + return set_status; } - - /* Ensure we're in sync with current lease state. */ - fsp_lease_update(lck, fsp_client_guid(fsp), fsp->lease); - return NT_STATUS_OK; } - /* - * Create new lease - */ + fsp_lease_update(lck, fsp_client_guid(fsp), fsp->lease); + + return NT_STATUS_OK; +} + +static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp, + struct share_mode_lock *lck, + const struct GUID *client_guid, + const struct smb2_lease *lease, + uint32_t granted) +{ + struct share_mode_data *d = lck->data; + struct share_mode_lease *tmp; + NTSTATUS status; tmp = talloc_realloc(d, d->leases, struct share_mode_lease, d->num_leases+1); @@ -2241,6 +2247,24 @@ static NTSTATUS grant_fsp_lease(struct files_struct *fsp, return NT_STATUS_OK; } +static NTSTATUS grant_fsp_lease(struct files_struct *fsp, + struct share_mode_lock *lck, + const struct smb2_lease *lease, + uint32_t granted) +{ + const struct GUID *client_guid = fsp_client_guid(fsp); + NTSTATUS status; + + status = try_lease_upgrade(fsp, lck, client_guid, lease, granted); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + status = grant_new_fsp_lease( + fsp, lck, client_guid, lease, granted); + } + + return status; +} + static bool is_same_lease(const files_struct *fsp, const struct share_mode_data *d, const struct share_mode_entry *e, -- 2.34.1