diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-05-29 14:49:19 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:22:53 -0500 |
commit | 3f5742e20b30010ef88e19b6ee41c6b071258aee (patch) | |
tree | 06ca13e711f78bbe7a39d592ff21662cafc90476 /source3/locking | |
parent | d3ed91d9e1f3ba9f3d5093b3607dd563b37c27ed (diff) | |
download | samba-3f5742e20b30010ef88e19b6ee41c6b071258aee.tar.gz samba-3f5742e20b30010ef88e19b6ee41c6b071258aee.tar.bz2 samba-3f5742e20b30010ef88e19b6ee41c6b071258aee.zip |
r23204: Add MSG_SMB_BRL_VALIDATE. Tridge, this is a bit different from your bzr
branch, please check if it fulfils your needs.
Two changes: The validation is not done inside the brlock.c traverse_fn,
it's done as a separate routine.
Secondly, this patch does not call the checker routines in smbcontrol
directly but depends on a running smbd.
(This used to be commit 7e39d77c1f90d9025cab08918385d140e20ca25b)
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/brlock.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b51076bf43..a50d4faa52 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1686,3 +1686,109 @@ struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx, { return brl_get_locks_internal(mem_ctx, fsp, True); } + +struct brl_revalidate_state { + ssize_t array_size; + uint32 num_pids; + struct server_id *pids; +}; + +/* + * Collect PIDs of all processes with pending entries + */ + +static void brl_revalidate_collect(struct file_id id, struct server_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, br_off size, + void *private_data) +{ + struct brl_revalidate_state *state = + (struct brl_revalidate_state *)private_data; + + if (!IS_PENDING_LOCK(lock_type)) { + return; + } + + add_to_large_array(state, sizeof(pid), (void *)&pid, + &state->pids, &state->num_pids, + &state->array_size); +} + +/* + * qsort callback to sort the processes + */ + +static int compare_procids(const void *p1, const void *p2) +{ + const struct server_id *i1 = (struct server_id *)i1; + const struct server_id *i2 = (struct server_id *)i2; + + if (i1->pid < i2->pid) return -1; + if (i2->pid > i2->pid) return 1; + return 0; +} + +/* + * Send a MSG_SMB_UNLOCK message to all processes with pending byte range + * locks so that they retry. Mainly used in the cluster code after a node has + * died. + * + * Done in two steps to avoid double-sends: First we collect all entries in an + * array, then qsort that array and only send to non-dupes. + */ + +static void brl_revalidate(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct brl_revalidate_state *state; + uint32 i; + struct server_id last_pid; + + if (!(state = TALLOC_ZERO_P(NULL, struct brl_revalidate_state))) { + DEBUG(0, ("talloc failed\n")); + return; + } + + brl_forall(brl_revalidate_collect, state); + + if (state->array_size == -1) { + DEBUG(0, ("talloc failed\n")); + goto done; + } + + if (state->num_pids == 0) { + goto done; + } + + qsort(state->pids, state->num_pids, sizeof(state->pids[0]), + compare_procids); + + ZERO_STRUCT(last_pid); + + for (i=0; i<state->num_pids; i++) { + if (procid_equal(&last_pid, &state->pids[i])) { + /* + * We've seen that one already + */ + continue; + } + + messaging_send(msg_ctx, state->pids[i], MSG_SMB_UNLOCK, + &data_blob_null); + last_pid = state->pids[i]; + } + + done: + TALLOC_FREE(state); + return; +} + +void brl_register_msgs(struct messaging_context *msg_ctx) +{ + messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE, + brl_revalidate); +} |