summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2020-04-24 17:30:44 +0200
committerRalph Boehme <slow@samba.org>2020-05-05 11:48:39 +0000
commit7c3cce98886ca31b293e3dd1ad905ed215812919 (patch)
tree917a2a375c799b530cac02e6648c22258a501fb4 /source3/locking
parent7cd687fd05719eee0acd72a2f2bf045841ff895b (diff)
downloadsamba-7c3cce98886ca31b293e3dd1ad905ed215812919.tar.gz
smbd: Simplify reset_share_mode_entry()
This has more lines, but it's a lot simpler: reset_share_mode_entry is only called during durable reconnect, which only works with a single share mode entry. See durable_reconnect_fn(). Thus we don't have to keep the share mode array sorted, there is just a single entry. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/share_mode_lock.c110
1 files changed, 73 insertions, 37 deletions
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 87468bd7f3f..e66c375a142 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -2241,17 +2241,72 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck,
return true;
}
-static void reset_share_mode_entry_del_fn(
- struct share_mode_entry *e,
- size_t num_share_modes,
- bool *modified,
- void *private_data)
+struct reset_share_mode_entry_state {
+ struct server_id old_pid;
+ uint64_t old_share_file_id;
+ struct server_id new_pid;
+ uint64_t new_mid;
+ uint64_t new_share_file_id;
+ bool ok;
+};
+
+static void reset_share_mode_entry_fn(
+ struct db_record *rec, TDB_DATA value, void *private_data)
{
- struct set_share_mode_state *state = private_data;
+ struct reset_share_mode_entry_state *state = private_data;
+ struct share_mode_entry e;
+ struct share_mode_entry_buf e_buf;
+ TDB_DATA newval = { .dptr = e_buf.buf, .dsize = sizeof(e_buf.buf) };
+ NTSTATUS status;
+ int ret;
+ bool ok;
- state->e = *e;
- e->stale = true;
- state->status = NT_STATUS_OK;
+ if (value.dsize != SHARE_MODE_ENTRY_SIZE) {
+ DBG_WARNING("Expect one entry, got %zu bytes\n",
+ value.dsize);
+ return;
+ }
+
+ ok = share_mode_entry_get(value.dptr, &e);
+ if (!ok) {
+ DBG_WARNING("share_mode_entry_get failed\n");
+ return;
+ }
+
+ ret = share_mode_entry_cmp(
+ state->old_pid,
+ state->old_share_file_id,
+ e.pid,
+ e.share_file_id);
+ if (ret != 0) {
+ struct server_id_buf tmp1, tmp2;
+ DBG_WARNING("Expected pid=%s, file_id=%"PRIu64", "
+ "got pid=%s, file_id=%"PRIu64"\n",
+ server_id_str_buf(state->old_pid, &tmp1),
+ state->old_share_file_id,
+ server_id_str_buf(e.pid, &tmp2),
+ e.share_file_id);
+ return;
+ }
+
+ e.pid = state->new_pid;
+ e.op_mid = state->new_mid;
+ e.share_file_id = state->new_share_file_id;
+
+ ok = share_mode_entry_put(&e, &e_buf);
+ if (!ok) {
+ DBG_WARNING("share_mode_entry_put failed\n");
+ return;
+ }
+
+ status = dbwrap_record_store(rec, newval, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("dbwrap_record_store failed: %s\n",
+ nt_errstr(status));
+ return;
+ }
+
+ state->ok = true;
}
bool reset_share_mode_entry(
@@ -2263,46 +2318,27 @@ bool reset_share_mode_entry(
uint64_t new_share_file_id)
{
struct share_mode_data *d = lck->data;
- struct set_share_mode_state state = {
- .status = NT_STATUS_INTERNAL_ERROR,
+ struct reset_share_mode_entry_state state = {
+ .old_pid = old_pid,
+ .old_share_file_id = old_share_file_id,
+ .new_pid = new_pid,
+ .new_mid = new_mid,
+ .new_share_file_id = new_share_file_id,
};
NTSTATUS status;
- bool ok;
-
- ok = share_mode_entry_do(
- lck,
- old_pid,
- old_share_file_id,
- reset_share_mode_entry_del_fn,
- &state);
- if (!ok) {
- DBG_DEBUG("share_mode_entry_do failed\n");
- return false;
- }
- if (!NT_STATUS_IS_OK(state.status)) {
- DBG_DEBUG("reset_share_mode_entry_del_fn failed: %s\n",
- nt_errstr(state.status));
- return false;
- }
-
- state.status = NT_STATUS_INTERNAL_ERROR;
- state.e.pid = new_pid;
- state.e.op_mid = new_mid;
- state.e.share_file_id = new_share_file_id;
status = dbwrap_do_locked(
share_entries_db,
locking_key(&d->id),
- set_share_mode_fn,
+ reset_share_mode_entry_fn,
&state);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("dbwrap_do_locked failed: %s\n",
nt_errstr(status));
return false;
}
- if (!NT_STATUS_IS_OK(state.status)) {
- DBG_WARNING("set_share_mode_fn failed: %s\n",
- nt_errstr(state.status));
+ if (!state.ok) {
+ DBG_WARNING("reset_share_mode_fn failed\n");
return false;
}
d->have_share_modes = true;