summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2019-09-12 12:41:14 +0200
committerJeremy Allison <jra@samba.org>2019-09-17 22:49:38 +0000
commit6a58f29c6205d6a4cc7f98ad0f5c6ebf1dadd385 (patch)
tree58881644151f06a94386a627d476b7362100b3a9 /source3/locking
parent8eda954d6d7469c54855d22a97bf625f32ebdad7 (diff)
downloadsamba-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>
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/share_mode_lock.c126
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', "