From: Volker Lendecke Date: Mon, 5 Aug 2019 16:50:08 +0000 (+0200) Subject: smbd: Factor out remove_lease_if_stale() X-Git-Tag: tdb-1.4.2~285 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6e7d28c8e03a832bd0704e7f72b25e448746c35a;p=thirdparty%2Fsamba.git smbd: Factor out remove_lease_if_stale() remove_lease_if_stale() does not have the check if (e == e2) { /* Not ourselves. */ continue; } that remove_share_mode_lease() had. However, remove_share_mode_lease() has already set e->op_type=NO_OPLOCK, so that the if (e->op_type != LEASE_OPLOCK) { continue; } statement has the same effect. Why? The next commit will need it for proper error path cleanup. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5ef844c51c6..c19b899e468 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -645,6 +645,42 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e) return (num_props != 0); } +NTSTATUS remove_lease_if_stale(const struct share_mode_data *d, + const struct GUID *client_guid, + const struct smb2_lease_key *lease_key) +{ + uint32_t i; + NTSTATUS status; + + for (i=0; inum_share_modes; i++) { + const struct share_mode_entry *e = &d->share_modes[i]; + bool same; + + if (e->stale) { + continue; + } + if (e->op_type != LEASE_OPLOCK) { + continue; + } + + same = smb2_lease_equal( + &e->client_guid, + &e->lease_key, + client_guid, + lease_key); + if (same) { + return NT_STATUS_RESOURCE_IN_USE; + } + } + + status = leases_db_del(client_guid, lease_key, &d->id); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("leases_db_del failed: %s\n", + nt_errstr(status)); + } + return status; +} + /* * See if we need to remove a lease being referred to by a * share mode that is being marked stale or deleted. @@ -654,7 +690,6 @@ static void remove_share_mode_lease(struct share_mode_data *d, struct share_mode_entry *e) { uint16_t op_type; - uint32_t i; op_type = e->op_type; e->op_type = NO_OPLOCK; @@ -665,45 +700,7 @@ static void remove_share_mode_lease(struct share_mode_data *d, return; } - /* - * This used to reference a lease. If there's no other one referencing - * it, remove it. - */ - - for (i=0; inum_share_modes; i++) { - struct share_mode_entry *e2 = &d->share_modes[i]; - - if (e2->stale) { - continue; - } - if (e == e2) { - /* Not ourselves. */ - continue; - } - if (smb2_lease_equal(&e->client_guid, - &e->lease_key, - &e2->client_guid, - &e2->lease_key)) { - break; - } - } - if (i < d->num_share_modes) { - /* - * Found another one - */ - return; - } - - { - NTSTATUS status; - - status = leases_db_del(&e->client_guid, - &e->lease_key, - &d->id); - - DEBUG(10, ("%s: leases_db_del returned %s\n", __func__, - nt_errstr(status))); - } + remove_lease_if_stale(d, &e->client_guid, &e->lease_key); } /* diff --git a/source3/locking/proto.h b/source3/locking/proto.h index 37f36870751..53688cb52df 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -162,6 +162,9 @@ bool set_share_mode(struct share_mode_lock *lck, uint16_t op_type, uint32_t share_access, uint32_t access_mask); +NTSTATUS remove_lease_if_stale(const struct share_mode_data *d, + const struct GUID *client_guid, + const struct smb2_lease_key *lease_key); void remove_stale_share_mode_entries(struct share_mode_data *d); bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp); bool mark_share_mode_disconnected(struct share_mode_lock *lck,