static void defer_rename_done(struct tevent_req *subreq);
+struct delay_rename_lease_break_state {
+ struct files_struct *fsp;
+ bool delay;
+};
+
+static bool delay_rename_lease_break_fn(
+ struct share_mode_entry *e,
+ void *private_data)
+{
+ struct delay_rename_lease_break_state *state = private_data;
+ struct files_struct *fsp = state->fsp;
+ uint32_t e_lease_type, break_to;
+ bool ours, stale;
+
+ ours = smb2_lease_equal(fsp_client_guid(fsp),
+ &fsp->lease->lease.lease_key,
+ &e->client_guid,
+ &e->lease_key);
+ if (ours) {
+ return false;
+ }
+
+ e_lease_type = get_lease_type(e, fsp->file_id);
+
+ if ((e_lease_type & SMB2_LEASE_HANDLE) == 0) {
+ return false;
+ }
+
+ stale = share_entry_stale_pid(e);
+ if (stale) {
+ return false;
+ }
+
+ break_to = (e_lease_type & ~SMB2_LEASE_HANDLE);
+
+ send_break_message(
+ fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
+
+ return false;
+}
+
static struct tevent_req *delay_rename_for_lease_break(struct tevent_req *req,
struct smbd_smb2_request *smb2req,
struct tevent_context *ev,
{
struct tevent_req *subreq;
- uint32_t i;
- struct share_mode_data *d = lck->data;
struct defer_rename_state *rename_state;
- bool delay = false;
+ struct delay_rename_lease_break_state state = { .fsp = fsp };
struct timeval timeout;
+ bool ok;
if (fsp->oplock_type != LEASE_OPLOCK) {
return NULL;
}
- for (i=0; i<d->num_share_modes; i++) {
- struct share_mode_entry *e = &d->share_modes[i];
- uint32_t e_lease_type;
- uint32_t break_to;
-
- if (e->op_type != LEASE_OPLOCK) {
- continue;
- }
-
- e_lease_type = get_lease_type(e, d->id);
-
- if (!(e_lease_type & SMB2_LEASE_HANDLE)) {
- continue;
- }
-
- if (smb2_lease_equal(fsp_client_guid(fsp),
- &fsp->lease->lease.lease_key,
- &e->client_guid,
- &e->lease_key)) {
- continue;
- }
-
- if (share_mode_stale_pid(d, i)) {
- continue;
- }
-
- delay = true;
- break_to = (e_lease_type & ~SMB2_LEASE_HANDLE);
-
- send_break_message(fsp->conn->sconn->msg_ctx, &fsp->file_id,
- e, break_to);
+ ok = share_mode_forall_leases(
+ lck, delay_rename_lease_break_fn, &state);
+ if (!ok) {
+ return NULL;
}
- if (!delay) {
+ if (!state.delay) {
return NULL;
}