Latest leases patchset - getting there !

Stefan (metze) Metzmacher metze at samba.org
Fri Nov 14 00:57:58 MST 2014


Am 14.11.2014 um 08:50 schrieb Stefan (metze) Metzmacher:
> Am 14.11.2014 um 08:39 schrieb Jeremy Allison:
>> On Fri, Nov 14, 2014 at 08:29:00AM +0100, Stefan (metze) Metzmacher wrote:
>>> Am 14.11.2014 um 08:12 schrieb Jeremy Allison:
>>>> On Thu, Nov 13, 2014 at 08:09:33PM -0800, Jeremy Allison wrote:
>>>>> On Fri, Nov 14, 2014 at 03:02:19AM +0100, Stefan (metze) Metzmacher wrote:
>>>>>>
>>>>>> This is fixed with todo19.diff.txt :-)
>>>>>>
>>>>>> There we just need to check what to do in the timeout handler.
>>>>>
>>>>> W00t! Great Metze !!!!!
>>>>>
>>>>> I think that's the last outstanding issue, right ?
>>>>
>>>> FYI. I'm making progress with the breaking2
>>>> test.
>>>>
>>>> I understand what is going on, but not quite
>>>> sure yet how to get to what is needed...
>>>>
>>>> The 'will_overwrite' is the key. I think we
>>>> can separate out the lease break inside
>>>> delay_for_oplock() when will_overwrite
>>>> is true from a direct break to NONE,
>>>> to a break to READ - and then have
>>>> the break to NONE happen when the
>>>> ftruncate happens when the open
>>>> actually takes place).
>>>
>>> Yep, I think the truncate needs to be wrapped into
>>> contend_level2_oplocks_begin() contend_level2_oplocks_end()
>>
>> It already is. Check the inside of the vfs_set_filelen()
>> call.
>>
>>> And we only need to downgrade to none in delay_for_oplocks()
>>> for real oplocks.
>>
>> Yep, we should go to READ for leases, and let
>> the truncate break to none.
> 
> I have the patch almost finished...

Doesn't fully work yet, but this should be the direction I think...

metze
-------------- next part --------------
From 5af92644aac4edcc8b83fb017d64ceb6acbbf91a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 14 Nov 2014 08:56:38 +0100
Subject: [PATCH] delay_for_oplock only read...

---
 source3/smbd/open.c | 114 ++++++++++++++++++++--------------------------------
 1 file changed, 44 insertions(+), 70 deletions(-)

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 5f69869..753fd48 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1416,41 +1416,6 @@ static bool delay_for_oplock(files_struct *fsp,
 		return false;
 	}
 
-	if (have_sharing_violation) {
-		for (i=0; i<d->num_share_modes; i++) {
-			struct share_mode_entry *e = &d->share_modes[i];
-			uint32_t e_lease_type = get_lease_type(d, e);
-
-			if (!(e_lease_type & SMB2_LEASE_HANDLE)) {
-				continue;
-			}
-			if (is_same_lease(fsp, d, e, lease)) {
-				continue;
-			}
-			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;
-		}
-	}
-
-	if (have_broken) {
-		return true;
-	}
-	if (have_sharing_violation) {
-		return false;
-	}
-
 	switch (create_disposition) {
 	case FILE_SUPERSEDE:
 	case FILE_OVERWRITE:
@@ -1464,56 +1429,65 @@ static bool delay_for_oplock(files_struct *fsp,
 
 	for (i=0; i<d->num_share_modes; i++) {
 		struct share_mode_entry *e = &d->share_modes[i];
+		struct share_mode_oplock *o = NULL;
 		uint32_t e_lease_type = get_lease_type(d, e);
+		uint32_t break_to;
+
+		if (e->op_type == LEASE_OPLOCK) {
+			o = &d->leases[e->lease_idx];
+		}
+
+		if (have_sharing_violation) {
+			break_to = e_lease_type & ~SMB2_LEASE_HANDLE;
+		} else {
+			break_to = e_lease_type & ~SMB2_LEASE_WRITE;
+		}
+
+		if (e->op_type != LEASE_OPLOCK) {
+			break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+		}
 
 		DEBUG(10, ("entry %u: e_lease_type %u, will_overwrite: %u\n",
 			   (unsigned)i, (unsigned)e_lease_type,
 			   (unsigned)will_overwrite));
 
-		if (e_lease_type & SMB2_LEASE_WRITE) {
-			uint32_t break_to;
-
-			if (share_mode_stale_pid(d, i)) {
-				return false;
-			}
-			if ((e->op_type == LEASE_OPLOCK) &&
-			    (lease != NULL) &&
-			    smb2_lease_equal(fsp_client_guid(fsp),
-					     &lease->lease_key,
-					     &d->leases[e->lease_idx].client_guid,
-					     &d->leases[e->lease_idx].lease_key)) {
-				return false;
+		if ((e_lease_type & ~break_to) == 0) {
+			if (o == NULL) {
+				continue;
 			}
 
-			break_to = e_lease_type & ~SMB2_LEASE_WRITE;
-			if (will_overwrite) {
-				/*
-				 * There's no H only lease that we could break
-				 * to
-				 */
-				break_to = SMB2_LEASE_NONE;
+			if (o->breaking) {
+				have_broken = true;
 			}
-
-			DEBUG(10, ("breaking SMB2_LEASE_WRITE to %d\n",
-				   (int)break_to));
-			send_break_message(fsp->conn->sconn->msg_ctx, e,
-					   break_to);
-			return true;
+			continue;
 		}
 
-		if (will_overwrite && (e_lease_type & SMB2_LEASE_READ)) {
-			if (share_mode_stale_pid(d, i)) {
+		if (lease != NULL && o != NULL) {
+			bool ign;
+
+			ign = smb2_lease_equal(fsp_client_guid(fsp),
+					       &lease->lease_key,
+					       &o->client_guid,
+					       &o->lease_key);
+			if (ign) {
 				continue;
 			}
-			DEBUG(10, ("breaking SMB2_LEASE_READ\n"));
-			send_break_message(fsp->conn->sconn->msg_ctx, e,
-					   SMB2_LEASE_NONE);
-			/*
-			 * This is an async break. No need to wait for a
-			 * response.
-			 */
+		}
+
+		if (share_mode_stale_pid(d, i)) {
 			continue;
 		}
+
+		if ((e->op_type != LEASE_OPLOCK) && will_overwrite) {
+			break_to &= ~SMB2_LEASE_READ;
+		}
+
+		DEBUG(10, ("breaking SMB2_LEASE_WRITE to %d\n",
+			   (int)break_to));
+		send_break_message(fsp->conn->sconn->msg_ctx, e,
+				   break_to);
+		have_broken = true;
+		continue;
 	}
 
 	return have_broken;
-- 
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/b7f6e4b4/attachment.pgp>


More information about the samba-technical mailing list