Latest leases patchset - getting there !
Stefan (metze) Metzmacher
metze at samba.org
Thu Nov 13 19:02:19 MST 2014
Am 14.11.2014 um 02:56 schrieb Jeremy Allison:
> On Fri, Nov 14, 2014 at 01:42:58AM +0100, Stefan (metze) Metzmacher wrote:
>>> On Thu, Nov 13, 2014 at 09:09:05PM +0100, Stefan (metze) Metzmacher wrote:
>>>> Am 13.11.2014 um 08:12 schrieb Jeremy Allison:
>>>>> On Thu, Nov 13, 2014 at 01:17:43AM +0100, Stefan (metze) Metzmacher wrote:
>>>>>>
>>>>>> I've integrated this with a few more tests we fail (sorry...:-)
>>>>>>
>>>>>> ontop17.diff.txt replaces the older ontop13.diff.txt
>>>>>> and also includes your changes.
>>>>>
>>>>> No problem. Attached are some new patches to fix the new
>>>>> tests we fail :-). They apply on top of ontop17.diff.txt.
>>>>>
>>>>> on-top-of-ontop17.patchset
>>>>>
>>>>> The current state of play with this new code are:
>>>>>
>>>>> request PASS
>>>>> break_twice PASS
>>>>> nobreakself PASS
>>>>> upgrade PASS
>>>>> upgrade2 PASS
>>>>> upgrade3 PASS
>>>>> break PASS
>>>>> oplock PASS
>>>>> multibreak PASS
>>>>> breaking1 --- PASS WITH smbtorture MODIFICATION (*)
>>>>
>>>> fixed in ontop17-3.diff.txt
>>>>
>>>>> breaking2 --- TEST CRASHES in smbtorture.(**)
>>>>
>>>> the crash is fixed in ontop17-3.diff.txt
>>>>
>>>>> complex1 PASS
>>>>> v2_epoch1 PASS
>>>>> v2_epoch2 insane test - see below
>>>>> v2_epoch3 insane test - see below
>>>>
>>>> I've fixed those in ontop17-3.diff.txt
>>>
>>> Looks like you added lease_version to struct share_mode_oplock,
>>> but I don't see the patch adding this to the IDL, or the
>>> code that sets this on lease creation.
>>>
>>> Are you missing a posted patch ?
>>
>> Yes, sorry.
>>
>> Here's the full patchset (leases18.diff.txt) on top of master.
>>
>> And the partial patch (todo18.diff.txt) on top of it.
>
> With just leases18.diff.txt all tests except breaking2
> (commented out) pass.
>
> Unfortunately, when I add todo18.diff.txt on top:
>
> nobreakself and multibreak start to fail.
>
> I will investigate and post more I have better
> info.
This is fixed with todo19.diff.txt :-)
There we just need to check what to do in the timeout handler.
metze
metze
-------------- next part --------------
From 165212ac9a7bdac5c2d3722efa6bf176975eee59 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 13 Nov 2014 11:50:14 +0100
Subject: [PATCH] TODO: breaking_to_state... works...
---
source3/locking/locking.c | 60 +++++++++--
source3/locking/proto.h | 4 +-
source3/smbd/globals.h | 6 +-
source3/smbd/open.c | 8 ++
source3/smbd/oplock.c | 244 +++++++++++++++++++++++++++++++++------------
source3/smbd/proto.h | 5 +-
source3/smbd/smb2_break.c | 30 ++++--
source3/smbd/smb2_create.c | 8 --
source3/smbd/smb2_server.c | 17 ++--
9 files changed, 276 insertions(+), 106 deletions(-)
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 006d6d3..b3ab9ad 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -945,6 +945,7 @@ bool fsp_lease_broken(struct share_mode_lock *lck,
{
struct share_mode_data *d = lck->data;
struct share_mode_entry *e;
+ struct share_mode_oplock *o;
if (!file_id_equal(&fsp->file_id, &lck_id)) {
return false;
@@ -960,27 +961,42 @@ bool fsp_lease_broken(struct share_mode_lock *lck,
return false;
}
+ o = &d->leases[e->lease_idx];
+
if (!smb2_lease_equal(&fsp->conn->sconn->client->connections->smb2.client.guid,
- key,
- &d->leases[e->lease_idx].client_guid,
- &d->leases[e->lease_idx].lease_key)) {
+ key, &o->client_guid, &o->lease_key)) {
return false;
}
- fsp->sent_oplock_break = NO_BREAK_SENT;
+
TALLOC_FREE(fsp->oplock_timeout);
- fsp->lease->lease.lease_state = new_lease_state;
+
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ /* Ensure we're in sync with current lease state. */
+ fsp->lease->lease.lease_state = o->current_state;
+ fsp->lease->lease.lease_epoch = o->epoch;
+ if (o->breaking) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ fsp->lease->lease.lease_flags |= SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
+ } else {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ fsp->lease->lease.lease_flags &= ~SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
+ }
+
return true;
}
NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
struct share_mode_lock *lck,
const struct smb2_lease_key *key,
- uint32_t new_lease_state)
+ uint32_t new_lease_state,
+ struct share_mode_oplock **_l)
{
struct share_mode_data *d = lck->data;
struct share_mode_oplock *l;
uint32_t i;
+ *_l = NULL;
+
for (i=0; i<d->num_leases; i++) {
if (smb2_lease_equal(&sconn->client->connections->smb2.client.guid,
key,
@@ -996,18 +1012,44 @@ NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
l = &d->leases[i];
+ if (!l->breaking) {
+ DEBUG(0, ("Attempt to break from %d to %d - but we're not in breaking state\n",
+ (int)l->current_state, (int)new_lease_state));
+ return NT_STATUS_INVALID_OPLOCK_PROTOCOL;
+ }
+
/*
* Can't upgrade anything: l->current_state must be a strict bitwise
* superset of new_lease_state
*/
if ((new_lease_state & l->current_state) != new_lease_state) {
- DEBUG(10, ("Attempt to upgrade from %d to %d\n",
- (int)l->current_state, (int)new_lease_state));
+ DEBUG(0, ("Attempt to upgrade from %d to %d - expected %d\n",
+ (int)l->current_state, (int)new_lease_state,
+ (int)l->breaking_to_state));
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
- l->current_state = new_lease_state;
+ if (l->current_state != new_lease_state) {
+ l->current_state = new_lease_state;
+ d->modified = true;
+ }
+
+ if ((new_lease_state & ~l->breaking_to_state) != 0) {
+ DEBUG(0, ("lease state %d not fully broken from %d to %d\n",
+ (int)new_lease_state,
+ (int)l->current_state,
+ (int)l->breaking_to_state));
+ *_l = l;
+ return NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
+ }
+
+ //TODO: verify new_lease_state == l->breaking_to_state ???
+
+ DEBUG(0, ("breaking from %d to %d - expected %d\n",
+ (int)l->current_state, (int)new_lease_state,
+ (int)l->breaking_to_state));
+
l->breaking_to_state = 0;
l->breaking = 0;
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 94e9b8f..c48cd89 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -179,10 +179,12 @@ bool fsp_lease_broken(struct share_mode_lock *lck,
struct file_id lck_id,
const struct smb2_lease_key *key,
files_struct *fsp, uint32_t new_lease_state);
+struct share_mode_oplock;
NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
struct share_mode_lock *lck,
const struct smb2_lease_key *key,
- uint32_t new_lease_state);
+ uint32_t new_lease_state,
+ struct share_mode_oplock **_l);
bool get_delete_on_close_token(struct share_mode_lock *lck,
uint32_t name_hash,
const struct security_token **pp_nt_tok,
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index f297ff7..0ce1982 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -251,8 +251,6 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
struct smbXsrv_open *op,
uint8_t oplock_level);
NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
- struct smbXsrv_session *session,
- struct smbXsrv_tcon *tcon,
uint16_t new_epoch,
uint32_t lease_flags,
struct smb2_lease_key *lease_key,
@@ -306,7 +304,9 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
struct deferred_open_record;
/* SMB1 -> SMB2 glue. */
-void send_break_message_smb2(files_struct *fsp, uint32_t break_to);
+void send_break_message_smb2(files_struct *fsp,
+ uint32_t break_from,
+ uint32_t break_to);
struct blocking_lock_record *get_pending_smb2req_blr(struct smbd_smb2_request *smb2req);
bool push_blocking_lock_request_smb2( struct byte_range_lock *br_lck,
struct smb_request *req,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 804b6f0..33a2bf9 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1430,6 +1430,14 @@ static bool delay_for_oplock(files_struct *fsp,
if (share_mode_stale_pid(d, i)) {
continue;
}
+
+ //if (e->op_type == LEASE_OPLOCK) {
+ // struct share_mode_oplock *o = NULL;
+ // o = &d->leases[e->lease_idx];
+ // if (o->breaking) {
+ // continue;
+ // }
+ //}
send_break_message(fsp->conn->sconn->msg_ctx, e,
e_lease_type & ~SMB2_LEASE_HANDLE);
have_broken = true;
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 4755ca6..240ff59 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -291,6 +291,40 @@ bool downgrade_oplock(files_struct *fsp)
return ret;
}
+struct downgrade_lease_additional_state {
+ struct tevent_immediate *im;
+ struct smbXsrv_connection *xconn;
+ uint32_t lease_flags;
+ struct smb2_lease_key lease_key;
+ uint32_t current_lease_state;
+ uint32_t new_lease_state;
+ uint16_t new_epoch;
+};
+
+static void downgrade_lease_additional_trigger(struct tevent_context *ev,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct downgrade_lease_additional_state *state =
+ talloc_get_type_abort(private_data,
+ struct downgrade_lease_additional_state);
+ struct smbXsrv_connection *xconn = state->xconn;
+ NTSTATUS status;
+
+ status = smbd_smb2_send_lease_break(xconn,
+ state->new_epoch,
+ state->lease_flags,
+ &state->lease_key,
+ state->current_lease_state,
+ state->new_lease_state);
+ TALLOC_FREE(state);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbd_server_connection_terminate(xconn,
+ nt_errstr(status));
+ return;
+ }
+}
+
struct downgrade_lease_fsps_state {
struct file_id id;
struct share_mode_lock *lck;
@@ -312,22 +346,59 @@ static struct files_struct *downgrade_lease_fsps(struct files_struct *fsp,
return NULL;
}
-NTSTATUS downgrade_lease(struct smbd_server_connection *sconn,
+NTSTATUS downgrade_lease(struct smbXsrv_connection *xconn,
const struct file_id id,
- const struct smb2_lease_key *key,
+ const struct smb2_lease *lease,
uint32_t lease_state)
{
+ struct smbd_server_connection *sconn = xconn->client->sconn;
+ const struct smb2_lease_key *key = &lease->lease_key;
struct share_mode_lock *lck;
+ struct share_mode_oplock *l = NULL;
NTSTATUS status;
- DEBUG(10, ("%s: Downgrading %s to %x\n", __func__,
+ DEBUG(0, ("%s: Downgrading %s to %x\n", __func__,
file_id_string_tos(&id), (unsigned)lease_state));
lck = get_existing_share_mode_lock(talloc_tos(), id);
if (lck == NULL) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- status = downgrade_share_lease(sconn, lck, key, lease_state);
+ status = downgrade_share_lease(sconn, lck, key, lease_state, &l);
+
+ DEBUG(0, ("%s: Downgrading %s to %x => %s\n", __func__,
+ file_id_string_tos(&id), (unsigned)lease_state, nt_errstr(status)));
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_BREAK_IN_PROGRESS)) {
+ struct downgrade_lease_additional_state *state;
+
+ state = talloc_zero(xconn,
+ struct downgrade_lease_additional_state);
+ if (state == NULL) {
+ TALLOC_FREE(lck);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->im = tevent_create_immediate(state);
+ if (state->im == NULL) {
+ TALLOC_FREE(state);
+ TALLOC_FREE(lck);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->xconn = xconn;
+ state->lease_flags = SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED;
+ state->lease_key = l->lease_key;
+ state->current_lease_state = l->current_state;
+ state->new_lease_state = l->breaking_to_state;
+ if (l->lease_version > 1) {
+ state->new_epoch = lease->lease_epoch;
+ }
+
+ tevent_schedule_immediate(state->im, xconn->ev_ctx,
+ downgrade_lease_additional_trigger,
+ state);
+ }
/*
* This sucks. We have to reset fsp->sent_oplock_break on all fsps
@@ -346,6 +417,8 @@ NTSTATUS downgrade_lease(struct smbd_server_connection *sconn,
}
TALLOC_FREE(lck);
+ DEBUG(0, ("%s: Downgrading %s to %x => %s\n", __func__,
+ file_id_string_tos(&id), (unsigned)lease_state, nt_errstr(status)));
return status;
}
@@ -444,6 +517,11 @@ static void oplock_timeout_handler(struct tevent_context *ctx,
{
files_struct *fsp = (files_struct *)private_data;
+ if (fsp->oplock_type == LEASE_OPLOCK) {
+ //TODO
+ SMB_ASSERT(false);
+ }
+
SMB_ASSERT(fsp->sent_oplock_break != NO_BREAK_SENT);
/* Remove the timed event handler. */
@@ -526,7 +604,9 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
struct smbd_server_connection);
struct server_id self = messaging_server_id(sconn->msg_ctx);
struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
+ uint16_t break_from;
uint16_t break_to;
+ bool break_needed = true;
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
@@ -542,7 +622,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
message_to_share_mode_entry(&msg, (char *)data->data);
break_to = msg.op_type;
- DEBUG(10, ("Got oplock break to %u message from pid %s: %s/%llu\n",
+ DEBUG(0, ("Got oplock break to %u message from pid %s: %s/%llu\n",
(unsigned)break_to, server_id_str(talloc_tos(), &src),
file_id_string_tos(&msg.id),
(unsigned long long)msg.share_file_id));
@@ -556,13 +636,21 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
return;
}
- if (fsp->sent_oplock_break != NO_BREAK_SENT) {
- /*
- * Nothing to do anymore
- */
- DEBUG(10, ("fsp->sent_oplock_break = %d\n",
- fsp->sent_oplock_break));
- return;
+ if (fsp->oplock_timeout != NULL) {
+// return;
+ }
+
+ break_from = fsp_lease_type(fsp);
+
+ if (fsp->oplock_type != LEASE_OPLOCK) {
+ if (fsp->sent_oplock_break != NO_BREAK_SENT) {
+ /*
+ * Nothing to do anymore
+ */
+ DEBUG(10, ("fsp->sent_oplock_break = %d\n",
+ fsp->sent_oplock_break));
+ return;
+ }
}
if (!(global_client_caps & CAP_LEVEL_II_OPLOCKS)) {
@@ -581,30 +669,15 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
break_to &= ~SMB2_LEASE_READ;
}
- DEBUG(10, ("msg.op_type=%u, break_to=%u\n",
- (unsigned)msg.op_type, (unsigned)break_to));
-
- if (fsp->oplock_type == NO_OPLOCK) {
- DEBUG(3, ("Already downgraded oplock to none on %s: %s\n",
- file_id_string_tos(&fsp->file_id),
- fsp_str_dbg(fsp)));
- return;
- }
- if ((break_to & SMB2_LEASE_READ) &&
- (fsp->oplock_type == LEVEL_II_OPLOCK)) {
- DEBUG(3, ("Already downgraded oplock to level2 on %s: %s\n",
- file_id_string_tos(&fsp->file_id),
- fsp_str_dbg(fsp)));
- return;
- }
-
if (fsp->oplock_type == LEASE_OPLOCK) {
struct share_mode_lock *lck;
int idx;
+ DEBUG(0,("%s: refresh lease state - begin\n", __func__));
lck = get_existing_share_mode_lock(
talloc_tos(), fsp->file_id);
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
idx = find_share_mode_oplock(
lck->data,
&fsp->conn->sconn->client->connections->
@@ -613,16 +686,78 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
if (idx != -1) {
struct share_mode_oplock *o;
o = &lck->data->leases[idx];
+
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ break_from = o->current_state;
+ break_to &= o->current_state;
+
+ if (o->breaking) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ break_to &= o->breaking_to_state;
+ if (o->breaking_to_state != break_to) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ o->breaking_to_state = break_to;
+ lck->data->modified = true;
+ }
+ break_needed = false;
+ } else if (o->current_state == break_to) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ break_needed = false;
+ } else if (o->current_state == SMB2_LEASE_READ) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ o->current_state = SMB2_LEASE_NONE;
+ lck->data->modified = true;
+ } else {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ o->breaking = true;
+ o->breaking_to_state = break_to;
+ lck->data->modified = true;
+ }
+
+ /* Need to increment the epoch */
+ if (lck->data->modified) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ o->epoch += 1;
+ }
+
/* Ensure we're in sync with current lease state. */
fsp->lease->lease.lease_state = o->current_state;
- /* Need to increment the epoch */
- o->epoch += 1;
fsp->lease->lease.lease_epoch = o->epoch;
- /* And remember to write it out again.. */
- lck->data->modified = true;
+ if (o->breaking) {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ fsp->lease->lease.lease_flags |= SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
+ } else {
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
+ fsp->lease->lease.lease_flags &= ~SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
+ }
}
+ DEBUG(0,("%s: refresh lease state - line(%d)\n", __func__, __LINE__));
TALLOC_FREE(lck);
+ DEBUG(0,("%s: refresh lease state - end\n", __func__));
+ }
+
+ if (!break_needed) {
+ DEBUG(0,("%s: skip break\n", __func__));
+ return;
+ }
+
+ if ((break_from == SMB2_LEASE_NONE) && !break_needed) {
+ DEBUG(3, ("Already downgraded oplock to none on %s: %s\n",
+ file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp)));
+ return;
+ }
+
+ DEBUG(0, ("msg.op_type=%u, break_to=%u\n",
+ (unsigned)msg.op_type, (unsigned)break_to));
+
+ if ((break_from == break_to) && !break_needed) {
+ DEBUG(3, ("Already downgraded oplock to %u on %s: %s\n",
+ (unsigned)break_to,
+ file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp)));
+ return;
}
/* Need to wait before sending a break
@@ -632,33 +767,31 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
}
if (sconn->using_smb2) {
- send_break_message_smb2(fsp, break_to);
+ DEBUG(0,("%s: send_break_message_smb2 \n", __func__));
+ send_break_message_smb2(fsp, break_from, break_to);
} else {
send_break_message_smb1(fsp, (break_to & SMB2_LEASE_READ) ?
OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
}
- if ((fsp_lease_type(fsp) == SMB2_LEASE_READ) &&
+ if ((break_from == SMB2_LEASE_READ) &&
(break_to == SMB2_LEASE_NONE)) {
/*
* This is an async break without a reply and thus no timeout
+ *
+ * leases are handled above.
*/
- if (fsp->oplock_type == LEASE_OPLOCK) {
- /*
- * We must leave the lease around, it might be
- * upgraded later
- */
- downgrade_lease(fsp->conn->sconn, fsp->file_id,
- &fsp->lease->lease.lease_key,
- break_to);
- } else {
+ if (fsp->oplock_type != LEASE_OPLOCK) {
remove_oplock(fsp);
}
return;
}
- fsp->sent_oplock_break = (break_to & SMB2_LEASE_READ) ?
- LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
+ if (fsp->oplock_type != LEASE_OPLOCK) {
+ fsp->sent_oplock_break = (break_to & SMB2_LEASE_READ) ?
+ LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
+ }
+ DEBUG(0,("%s: add_oplock_timeout_handler \n", __func__));
add_oplock_timeout_handler(fsp);
}
@@ -713,7 +846,7 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
}
if (sconn->using_smb2) {
- send_break_message_smb2(fsp, OPLOCKLEVEL_NONE);
+ send_break_message_smb2(fsp, 0, OPLOCKLEVEL_NONE);
} else {
send_break_message_smb1(fsp, OPLOCKLEVEL_NONE);
}
@@ -937,23 +1070,6 @@ done:
return;
}
-bool break_in_progress(const files_struct *fsp)
-{
- files_struct *new_fsp;
-
- for (new_fsp = file_find_di_first(fsp->conn->sconn, fsp->file_id);
- new_fsp != NULL;
- new_fsp = file_find_di_next(new_fsp)) {
- if (new_fsp == fsp) {
- continue;
- }
- if (new_fsp->sent_oplock_break != NO_BREAK_SENT) {
- return true;
- }
- }
- return false;
-}
-
void smbd_contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type)
{
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c8e404e..c4f8920 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -667,11 +667,10 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp);
NTSTATUS set_file_oplock(files_struct *fsp);
bool remove_oplock(files_struct *fsp);
bool downgrade_oplock(files_struct *fsp);
-NTSTATUS downgrade_lease(struct smbd_server_connection *sconn,
+NTSTATUS downgrade_lease(struct smbXsrv_connection *xconn,
const struct file_id id,
- const struct smb2_lease_key *key,
+ const struct smb2_lease *lease,
uint32_t lease_state);
-bool break_in_progress(const files_struct *fsp);
void contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type);
void contend_level2_oplocks_end(files_struct *fsp,
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 9ab118d..f9fce5a 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -354,8 +354,15 @@ static struct tevent_req *smbd_smb2_lease_break_send(
return tevent_req_post(req, ev);
}
- status = downgrade_lease(smb2_req->sconn, fsp->file_id, &in_lease_key,
- in_lease_state);
+ status = downgrade_lease(smb2_req->xconn, fsp->file_id,
+ &fsp->lease->lease, in_lease_state);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_BREAK_IN_PROGRESS)) {
+ /*
+ * here we keep the fsp->oplock_timeout
+ */
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
if (tevent_req_nterror(req, status)) {
DEBUG(10, ("downgrade_lease returned %s\n",
nt_errstr(status)));
@@ -386,7 +393,9 @@ static NTSTATUS smbd_smb2_lease_break_recv(struct tevent_req *req,
SMB2 OPLOCK_BREAK_NOTIFICATION.
*********************************************************/
-void send_break_message_smb2(files_struct *fsp, uint32_t break_to)
+void send_break_message_smb2(files_struct *fsp,
+ uint32_t break_from,
+ uint32_t break_to)
{
NTSTATUS status;
struct smbXsrv_connection *xconn = NULL;
@@ -425,11 +434,12 @@ void send_break_message_smb2(files_struct *fsp, uint32_t break_to)
(unsigned int)break_to ));
if (fsp->oplock_type == LEASE_OPLOCK) {
- bool no_ack;
+ uint32_t break_flags = 0;
uint16_t new_epoch;
- no_ack = ((fsp->lease->lease.lease_state == SMB2_LEASE_READ) &&
- (break_to == SMB2_LEASE_NONE));
+ if (fsp->lease->lease.lease_state != SMB2_LEASE_NONE) {
+ break_flags = SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED;
+ }
if (fsp->lease->lease.lease_version > 1) {
new_epoch = fsp->lease->lease.lease_epoch;
@@ -437,11 +447,9 @@ void send_break_message_smb2(files_struct *fsp, uint32_t break_to)
new_epoch = 0;
}
- status = smbd_smb2_send_lease_break(
- xconn, session, fsp->conn->tcon, new_epoch,
- no_ack ? 0 : SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED,
- &fsp->lease->lease.lease_key,
- fsp->lease->lease.lease_state, break_to);
+ status = smbd_smb2_send_lease_break(xconn, new_epoch, break_flags,
+ &fsp->lease->lease.lease_key,
+ break_from, break_to);
} else {
uint8_t smb2_oplock_level;
smb2_oplock_level = (break_to & SMB2_LEASE_READ) ?
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 482bb66..91583fa 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -1204,14 +1204,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
uint8_t buf[52];
lease = result->lease->lease;
- lease.lease_flags &=
- SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET;
-
- /* Is there a break in progress ? */
- if (break_in_progress(result)) {
- lease.lease_flags |=
- SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
- }
lease_len = sizeof(buf);
if (lease.lease_version == 1) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 36ac0d7..16eed90 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2760,14 +2760,19 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
size_t body_len)
{
struct smbd_smb2_send_break_state *state;
- bool do_encryption = session->global->encryption_required;
+ bool do_encryption = false;
+ uint64_t session_wire_id = 0;
uint64_t nonce_high = 0;
uint64_t nonce_low = 0;
NTSTATUS status;
size_t statelen;
- if (tcon->global->encryption_required) {
- do_encryption = true;
+ if (session != NULL) {
+ session_wire_id = session->global->session_wire_id;
+ do_encryption = session->global->encryption_required;
+ if (tcon->global->encryption_required) {
+ do_encryption = true;
+ }
}
statelen = offsetof(struct smbd_smb2_send_break_state, body) +
@@ -2793,7 +2798,7 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
- SBVAL(state->tf, SMB2_TF_SESSION_ID, session->global->session_wire_id);
+ SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
SIVAL(state->hdr, 0, SMB2_MAGIC);
SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
@@ -2889,8 +2894,6 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
}
NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
- struct smbXsrv_session *session,
- struct smbXsrv_tcon *tcon,
uint16_t new_epoch,
uint32_t lease_flags,
struct smb2_lease_key *lease_key,
@@ -2910,7 +2913,7 @@ NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
- return smbd_smb2_send_break(xconn, session, tcon, body, sizeof(body));
+ return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
}
static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
--
1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20141114/6bd1b3eb/attachment.pgp>
More information about the samba-technical
mailing list