diff options
author | Volker Lendecke <vl@samba.org> | 2019-09-12 12:41:14 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-09-17 22:49:38 +0000 |
commit | 6a58f29c6205d6a4cc7f98ad0f5c6ebf1dadd385 (patch) | |
tree | 58881644151f06a94386a627d476b7362100b3a9 | |
parent | 8eda954d6d7469c54855d22a97bf625f32ebdad7 (diff) | |
download | samba-6a58f29c6205d6a4cc7f98ad0f5c6ebf1dadd385.tar.gz |
smbd: Use share_mode_forall_leases() in share_mode_cleanup_disconnected()
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r-- | source3/locking/share_mode_lock.c | 126 |
1 files changed, 77 insertions, 49 deletions
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c index b6de20ef4e3..04698f20e39 100644 --- a/source3/locking/share_mode_lock.c +++ b/source3/locking/share_mode_lock.c @@ -1073,17 +1073,20 @@ int share_entry_forall(int (*fn)(struct file_id fid, return share_mode_forall(share_entry_traverse_fn, &state); } -struct cleanup_disconnected_lease_state { - struct file_id fid; +struct cleanup_disconnected_state { + struct share_mode_lock *lck; + uint64_t open_persistent_id; + bool found_connected; }; static bool cleanup_disconnected_lease(struct share_mode_entry *e, void *private_data) { - struct cleanup_disconnected_lease_state *state = private_data; + struct cleanup_disconnected_state *state = private_data; NTSTATUS status; - status = leases_db_del(&e->client_guid, &e->lease_key, &state->fid); + status = leases_db_del( + &e->client_guid, &e->lease_key, &state->lck->data->id); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("leases_db_del failed: %s\n", @@ -1093,65 +1096,90 @@ static bool cleanup_disconnected_lease(struct share_mode_entry *e, return false; } +static bool share_mode_cleanup_disconnected_fn( + struct share_mode_entry *e, + bool *modified, + void *private_data) +{ + struct cleanup_disconnected_state *state = private_data; + struct share_mode_data *d = state->lck->data; + bool disconnected; + + disconnected = server_id_is_disconnected(&e->pid); + if (!disconnected) { + struct file_id_buf tmp1; + struct server_id_buf tmp2; + DBG_INFO("file (file-id='%s', servicepath='%s', " + "base_name='%s%s%s') " + "is used by server %s ==> do not cleanup\n", + file_id_str_buf(d->id, &tmp1), + d->servicepath, + d->base_name, + (d->stream_name == NULL) + ? "" : "', stream_name='", + (d->stream_name == NULL) + ? "" : d->stream_name, + server_id_str_buf(e->pid, &tmp2)); + state->found_connected = true; + return true; + } + + if (state->open_persistent_id != e->share_file_id) { + struct file_id_buf tmp; + DBG_INFO("entry for file " + "(file-id='%s', servicepath='%s', " + "base_name='%s%s%s') " + "has share_file_id %"PRIu64" but expected " + "%"PRIu64"==> do not cleanup\n", + file_id_str_buf(d->id, &tmp), + d->servicepath, + d->base_name, + (d->stream_name == NULL) + ? "" : "', stream_name='", + (d->stream_name == NULL) + ? "" : d->stream_name, + e->share_file_id, + state->open_persistent_id); + state->found_connected = true; + return true; + } + + return false; +} + bool share_mode_cleanup_disconnected(struct file_id fid, uint64_t open_persistent_id) { - struct cleanup_disconnected_lease_state state = { .fid = fid }; + struct cleanup_disconnected_state state = { + .open_persistent_id = open_persistent_id + }; + struct share_mode_data *data; bool ret = false; TALLOC_CTX *frame = talloc_stackframe(); - unsigned n; - struct share_mode_data *data; - struct share_mode_lock *lck; bool ok; - lck = get_existing_share_mode_lock(frame, fid); - if (lck == NULL) { + state.lck = get_existing_share_mode_lock(frame, fid); + if (state.lck == NULL) { DEBUG(5, ("share_mode_cleanup_disconnected: " "Could not fetch share mode entry for %s\n", file_id_string(frame, &fid))); goto done; } - data = lck->data; - - for (n=0; n < data->num_share_modes; n++) { - struct share_mode_entry *entry = &data->share_modes[n]; - - if (!server_id_is_disconnected(&entry->pid)) { - struct server_id_buf tmp; - DEBUG(5, ("share_mode_cleanup_disconnected: " - "file (file-id='%s', servicepath='%s', " - "base_name='%s%s%s') " - "is used by server %s ==> do not cleanup\n", - file_id_string(frame, &fid), - data->servicepath, - data->base_name, - (data->stream_name == NULL) - ? "" : "', stream_name='", - (data->stream_name == NULL) - ? "" : data->stream_name, - server_id_str_buf(entry->pid, &tmp))); - goto done; - } - if (open_persistent_id != entry->share_file_id) { - DBG_INFO("entry for file " - "(file-id='%s', servicepath='%s', " - "base_name='%s%s%s') " - "has share_file_id %"PRIu64" but expected " - "%"PRIu64"==> do not cleanup\n", - file_id_string(frame, &fid), - data->servicepath, - data->base_name, - (data->stream_name == NULL) - ? "" : "', stream_name='", - (data->stream_name == NULL) - ? "" : data->stream_name, - entry->share_file_id, - open_persistent_id); - goto done; - } + data = state.lck->data; + + ok = share_mode_forall_entries( + state.lck, share_mode_cleanup_disconnected_fn, &state); + if (!ok) { + DBG_DEBUG("share_mode_forall_entries failed\n"); + goto done; + } + if (state.found_connected) { + DBG_DEBUG("Found connected entry\n"); + goto done; } - ok = share_mode_forall_leases(lck, cleanup_disconnected_lease, &state); + ok = share_mode_forall_leases( + state.lck, cleanup_disconnected_lease, &state); if (!ok) { DBG_DEBUG("failed to clean up leases associated " "with file (file-id='%s', servicepath='%s', " |