[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Aug 20 00:34:05 UTC 2019


The branch, master has been updated
       via  8a05d2b074d smbd: Move lease type detection in delay_for_oplock()
       via  9a11f361cc1 smbd: Merge grant_fsp_oplock_type() into delay_for_oplock()
       via  7a6fa34130e smbd: Move delay_for_oplock() down
       via  a4192bc70d7 smbd: Make delay_for_oplock() return NTSTATUS
       via  10679b67d13 smbd: Slightly simplify grant_fsp_oplock_type()
       via  d1cb71fa500 smbd: Slightly simplify delay_for_oplock()
       via  385a7fb196f smbd: Introduce handle_share_mode_lease()
       via  d4e98b8ae5f smbd: Move set_share_mode() out of grant_fsp_oplock_type()
       via  5c6163d3e66 smbd: Move grant_fsp_oplock_type() close to delay_for_oplock()
       via  3ecfa36e777 smbd: Slightly simplify open_file_ntcreate()
       via  3bd7b119e68 smbd: Remove a late ref to "file_existed" in open_file_ntcreate()
       via  f8fe0116c11 smbd: Move resetting "oplock_request" to before delay_for_oplock()
       via  002c6d0efb7 smbd: For kernel-oplocked files don't call delay_for_oplock()
       via  706f0af2e4b smbd: Optionally wait for a share mode record in setup_poll_open()
       via  4d6f89c9883 smbd: Simplify has_other_nonposix_opens()
       via  6be8057317a smbd: Align integer types
       via  28868d24576 smbd: Simplify delay_for_oplock()
       via  021e2d01e68 smbd: Move is_same_lease() up in the file
       via  71c9fd73d42 smbd: Simplify is_same_lease()
       via  9034cb39d7c smbd: Optimize delay_for_oplock()
       via  38463a91aaf lib: Remove a duplicate function prototype
       via  aeb4265ec2f smbd: Remove a misleading comment
       via  d09bd5f8fd4 smbd: Merge two DEBUGs into one
       via  13fb42ac400 smbd: Avoid casts in share_conflict()
       via  a0b0ea8f356 smbd: Save two lines in find_share_mode_entry
       via  58b5bfba11a lib: Micro-optimization for db_tdb_do_locked()
      from  7d96ed63226 third_party: Remove historical tombstone about zlib divergance

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8a05d2b074d588a481aa372f2923f55cfb3e3a23
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Aug 13 16:56:58 2019 +0200

    smbd: Move lease type detection in delay_for_oplock()
    
    Walk the share_modes array only once.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Aug 20 00:33:12 UTC 2019 on sn-devel-184

commit 9a11f361cc19d3b8da3469424697486d0fd8dd6d
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 21:23:24 2019 +0200

    smbd: Merge grant_fsp_oplock_type() into delay_for_oplock()
    
    This is a preparation for the next commit: Only walk the share_modes[]
    array once when handling oplocks and leases.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7a6fa34130e8e6bea4672d08637af49097654119
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 21:17:05 2019 +0200

    smbd: Move delay_for_oplock() down
    
    We'll merge grant_fsp_oplock_type() into this function. This makes the next
    commit smaller, and the newly extended delay_for_oplocks will for example
    reference static file_has_brlocks() above. Make forward declarations
    unnecessary.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a4192bc70d7717a5072ccdd8e53b7dda7e6d9c98
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 21:15:22 2019 +0200

    smbd: Make delay_for_oplock() return NTSTATUS
    
    A further commit will merge grant_fsp_oplock_type (returning NTSTATUS)
    into delay_for_oplock(). Make that commit smaller.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 10679b67d1372bde37a1cdd639bebcc5f79a9c1b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 9 13:39:34 2019 +0200

    smbd: Slightly simplify grant_fsp_oplock_type()
    
    This is never called with INTERNAL_OPENs anymore
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d1cb71fa500ede015600ace58411c857b051794e
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 9 13:38:40 2019 +0200

    smbd: Slightly simplify delay_for_oplock()
    
    This is never called for INTERNAL_OPENs anymore, see
    handle_share_mode_lease()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 385a7fb196f7a6bdcdeb74b6e8553da7c810c1ca
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 7 12:15:45 2019 +0200

    smbd: Introduce handle_share_mode_lease()
    
    This consolidates the core share_mode_lock access of open_file_ntcreate
    into one routine.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d4e98b8ae5f08d6e332b15d868e7bf85995974f3
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Aug 6 16:28:29 2019 +0200

    smbd: Move set_share_mode() out of grant_fsp_oplock_type()
    
    This shows that "req", "share_access" and "access_mask" are not needed
    for the core logic of grant_fsp_oplock_type() and it separates
    concerns a bit: open_directory() also does the set_share_mode() in the
    main open routine, not in a helper like grant_fsp_oplock_type()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5c6163d3e664c20034fb41969e886372e3c88aa6
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jul 25 16:31:17 2019 +0200

    smbd: Move grant_fsp_oplock_type() close to delay_for_oplock()
    
    Note that this is not a cut&paste: Instead of fsp->access_mask we use
    the access_mask the client requested. At the new code location
    fsp->access_mask (a.k.a. open_access_mask) might have FILE_WRITE_DATA
    from O_TRUNC (a.k.a. FILE_OVERWRITE).
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3ecfa36e777cf377a4ae06644b0880fef4867452
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 15:24:16 2019 +0200

    smbd: Slightly simplify open_file_ntcreate()
    
    There is no reference to "file_existed" after this point anymore
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3bd7b119e6882aee04badc92f2ddbcbc1964c115
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 15:21:49 2019 +0200

    smbd: Remove a late ref to "file_existed" in open_file_ntcreate()
    
    If you follow "existing_dos_attributes" through the routine, this can
    only ever be !=0 if SMB_VFS_GET_DOS_ATTRIBUTES() was successful. This
    can only have been successful if the file existed.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f8fe0116c1158d8fdf0401ca46e8f12b84c04738
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jul 25 11:52:21 2019 +0200

    smbd: Move resetting "oplock_request" to before delay_for_oplock()
    
    It seems to make little sense to me to do the oplock break with one
    setting and then later on grant_fsp_oplock_type with another
    one. Survives tests, I can't think of any scenario where this (to me)
    simplification would break anything
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 002c6d0efb7bb41c158fc9056a176c5cce72f393
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 18 08:57:38 2019 +0200

    smbd: For kernel-oplocked files don't call delay_for_oplock()
    
    The kernel has already sent the signal. We don't have to send another
    message. Instead, just directly wait for the downgrade to happen via
    the watch on the share mode lock assuming it's there. Also setup the
    polling interval: I could imagine that in some race situation the file
    has already been closed and re-opened by a nonsamba process while we
    were waiting.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 706f0af2e4b5012644da742c94fc12eb756054fd
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 18 08:55:14 2019 +0200

    smbd: Optionally wait for a share mode record in setup_poll_open()
    
    This will be used when waiting for a oplock break that has been
    signalled via a kernel oplock break.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4d6f89c9883abaf7e9152887b7fa13449579c09c
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 14 21:27:53 2019 +0200

    smbd: Simplify has_other_nonposix_opens()
    
    We pick quite some information from "fsp" already, so from an API design
    perspecitve it's only fair to only use its implicit server_id. This is
    what all the callers did anyway.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 6be8057317a05b247169b8a30f968d1d2c085562
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 14 21:39:50 2019 +0200

    smbd: Align integer types
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 28868d24576dbd437329b7a59104cb7c15ee4624
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 15:01:24 2019 +0200

    smbd: Simplify delay_for_oplock()
    
    Use is_same_lease()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 021e2d01e68714556bd811ff2bc2a04c71a6c1fd
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 15:01:00 2019 +0200

    smbd: Move is_same_lease() up in the file
    
    The next commit will need it there
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 71c9fd73d42e092cf65de25fb7773fc1395ff601
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 14:28:51 2019 +0200

    smbd: Simplify is_same_lease()
    
    It does not use "struct share_mode_data"
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 9034cb39d7c0d8d6387f4977f894349db187d6b5
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 14:44:08 2019 +0200

    smbd: Optimize delay_for_oplock()
    
    get_lease_type() can involve a database access. Do that only if
    necessary, and that is at most once in this loop.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 38463a91aafa2643551b4e4508c3e575d9e914a1
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 16:45:30 2019 +0200

    lib: Remove a duplicate function prototype
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit aeb4265ec2f5d75250b1bc4d884628426df28dca
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 9 13:48:53 2019 +0200

    smbd: Remove a misleading comment
    
    open_mode_check() is done before the oplock breaks.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit d09bd5f8fd4b2de28efcefc5839bd69bb088b88f
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Aug 12 12:12:48 2019 +0200

    smbd: Merge two DEBUGs into one
    
    This looks easier to understand to me, less lines in logfiles
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 13fb42ac40067d1b335511e48354169ee15f29b3
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Aug 12 11:44:39 2019 +0200

    smbd: Avoid casts in share_conflict()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit a0b0ea8f356ac3a788d7b33d249ed6ec3eecc4bb
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 10 22:15:05 2019 +0200

    smbd: Save two lines in find_share_mode_entry
    
    Directly initialized variables give compilers less reason to complain
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 58b5bfba11a66d250267efe901dfba76f82005f8
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Aug 13 14:43:08 2019 +0200

    lib: Micro-optimization for db_tdb_do_locked()
    
    We don't need the tdb lock for the talloc_free(buf) anymore
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/dbwrap/dbwrap_tdb.c   |   4 +-
 lib/util/idtree.h         |   5 -
 source3/locking/locking.c |   4 +-
 source3/smbd/close.c      |  12 +-
 source3/smbd/open.c       | 654 ++++++++++++++++++++++++----------------------
 source3/smbd/proto.h      |   3 +-
 source3/smbd/trans2.c     |   3 +-
 7 files changed, 346 insertions(+), 339 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/dbwrap/dbwrap_tdb.c b/lib/dbwrap/dbwrap_tdb.c
index 00d283c66e6..eb08a01a161 100644
--- a/lib/dbwrap/dbwrap_tdb.c
+++ b/lib/dbwrap/dbwrap_tdb.c
@@ -218,10 +218,10 @@ static NTSTATUS db_tdb_do_locked(struct db_context *db, TDB_DATA key,
 
 	fn(&rec, private_data);
 
-	talloc_free(buf);
-
 	tdb_chainunlock(ctx->wtdb->tdb, key);
 
+	talloc_free(buf);
+
 	return NT_STATUS_OK;
 }
 
diff --git a/lib/util/idtree.h b/lib/util/idtree.h
index e7864a86968..79d2d8cd260 100644
--- a/lib/util/idtree.h
+++ b/lib/util/idtree.h
@@ -50,11 +50,6 @@ int idr_get_new(struct idr_context *idp, void *ptr, int limit);
 */
 int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit);
 
-/**
-  allocate a new id randomly in the given range
-*/
-int idr_get_new_random(struct idr_context *idp, void *ptr, int limit);
-
 /**
   find a pointer value previously set with idr_get_new given an id
 */
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index c19b899e468..113f63476e4 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -836,11 +836,9 @@ static struct share_mode_entry *find_share_mode_entry(
 	struct share_mode_lock *lck, files_struct *fsp)
 {
 	struct share_mode_data *d = lck->data;
-	struct server_id pid;
+	struct server_id pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
 	uint32_t i;
 
-	pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
-
 	for (i=0; i<d->num_share_modes; i++) {
 		struct share_mode_entry *e = &d->share_modes[i];
 
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 04c19cf32c0..12d7f8c9a95 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -166,7 +166,7 @@ NTSTATUS delete_all_streams(connection_struct *conn,
 			const struct smb_filename *smb_fname)
 {
 	struct stream_struct *stream_info = NULL;
-	int i;
+	unsigned int i;
 	unsigned int num_streams = 0;
 	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
@@ -234,10 +234,10 @@ NTSTATUS delete_all_streams(connection_struct *conn,
 }
 
 bool has_other_nonposix_opens(struct share_mode_lock *lck,
-			      struct files_struct *fsp,
-			      struct server_id self)
+			      struct files_struct *fsp)
 {
 	struct share_mode_data *data = lck->data;
+	struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
 	uint32_t i;
 
 	for (i=0; i<data->num_share_modes; i++) {
@@ -274,7 +274,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 					enum file_close_type close_type)
 {
 	connection_struct *conn = fsp->conn;
-	struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
 	bool delete_file = false;
 	bool changed_user = false;
 	struct share_mode_lock *lck = NULL;
@@ -353,7 +352,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
 	delete_file = is_delete_on_close_set(lck, fsp->name_hash);
 
-	delete_file &= !has_other_nonposix_opens(lck, fsp, self);
+	delete_file &= !has_other_nonposix_opens(lck, fsp);
 
 	/*
 	 * NT can set delete_on_close of the last open
@@ -1081,7 +1080,6 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 				enum file_close_type close_type)
 {
-	struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
 	struct share_mode_lock *lck = NULL;
 	bool delete_dir = False;
 	NTSTATUS status = NT_STATUS_OK;
@@ -1160,7 +1158,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 	delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
 					&del_nt_token, &del_token);
 
-	delete_dir &= !has_other_nonposix_opens(lck, fsp, self);
+	delete_dir &= !has_other_nonposix_opens(lck, fsp);
 
 	if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
 				delete_dir) {
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 13a7d7237c7..b654b3ceb9c 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -56,6 +56,16 @@ struct deferred_open_record {
 	 * opens and just terminates smbd if the async open times out.
 	 */
 	struct tevent_timer *te;
+
+	/*
+	 * For the samba kernel oplock case we use both a timeout and
+	 * a watch on locking.tdb. This way in case it's smbd holding
+	 * the kernel oplock we get directly notified for the retry
+	 * once the kernel oplock is properly broken. Store the req
+	 * here so that it can be timely discarded once the timer
+	 * above fires.
+	 */
+	struct tevent_req *watch_req;
 };
 
 /****************************************************************************
@@ -1461,28 +1471,29 @@ static bool share_conflict(struct share_mode_entry *entry,
 			   uint32_t access_mask,
 			   uint32_t share_access)
 {
-	DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
-		  "entry->share_access = 0x%x, "
-		  "entry->private_options = 0x%x\n",
-		  (unsigned int)entry->access_mask,
-		  (unsigned int)entry->share_access,
-		  (unsigned int)entry->private_options));
+	DBG_DEBUG("entry->access_mask = 0x%"PRIx32", "
+		  "entry->share_access = 0x%"PRIx32", "
+		  "entry->private_options = 0x%"PRIx32", "
+		  "access_mask = 0x%"PRIx32", "
+		  "share_access = 0x%"PRIx32"\n",
+		  entry->access_mask,
+		  entry->share_access,
+		  entry->private_options,
+		  access_mask,
+		  share_access);
 
 	if (server_id_is_disconnected(&entry->pid)) {
 		return false;
 	}
 
-	DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
-		  (unsigned int)access_mask, (unsigned int)share_access));
-
 	if ((entry->access_mask & (FILE_WRITE_DATA|
 				   FILE_APPEND_DATA|
 				   FILE_READ_DATA|
 				   FILE_EXECUTE|
 				   DELETE_ACCESS)) == 0) {
-		DEBUG(10,("share_conflict: No conflict due to "
-			  "entry->access_mask = 0x%x\n",
-			  (unsigned int)entry->access_mask ));
+		DBG_DEBUG("No conflict due to "
+			  "entry->access_mask = 0x%"PRIx32"\n",
+			  entry->access_mask);
 		return False;
 	}
 
@@ -1491,9 +1502,8 @@ static bool share_conflict(struct share_mode_entry *entry,
 			    FILE_READ_DATA|
 			    FILE_EXECUTE|
 			    DELETE_ACCESS)) == 0) {
-		DEBUG(10,("share_conflict: No conflict due to "
-			  "access_mask = 0x%x\n",
-			  (unsigned int)access_mask ));
+		DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
+			  access_mask);
 		return False;
 	}
 
@@ -1655,7 +1665,6 @@ static NTSTATUS open_mode_check(connection_struct *conn,
 	}
 #endif
 
-	/* Now we check the share modes, after any oplock breaks. */
 	for(i = 0; i < lck->data->num_share_modes; i++) {
 
 		if (!is_valid_share_mode_entry(&lck->data->share_modes[i])) {
@@ -1830,122 +1839,21 @@ static bool validate_oplock_types(struct share_mode_lock *lck)
 	return true;
 }
 
-static bool delay_for_oplock(files_struct *fsp,
-			     int oplock_request,
-			     const struct smb2_lease *lease,
-			     struct share_mode_lock *lck,
-			     bool have_sharing_violation,
-			     uint32_t create_disposition,
-			     bool first_open_attempt)
+static bool is_same_lease(const files_struct *fsp,
+			  const struct share_mode_entry *e,
+			  const struct smb2_lease *lease)
 {
-	struct share_mode_data *d = lck->data;
-	uint32_t i;
-	bool delay = false;
-	bool will_overwrite;
-	const uint32_t delay_mask = have_sharing_violation ?
-		SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
-
-	if ((oplock_request & INTERNAL_OPEN_ONLY) ||
-	    is_stat_open(fsp->access_mask)) {
+	if (e->op_type != LEASE_OPLOCK) {
 		return false;
 	}
-
-	switch (create_disposition) {
-	case FILE_SUPERSEDE:
-	case FILE_OVERWRITE:
-	case FILE_OVERWRITE_IF:
-		will_overwrite = true;
-		break;
-	default:
-		will_overwrite = false;
-		break;
+	if (lease == NULL) {
+		return false;
 	}
 
-	for (i=0; i<d->num_share_modes; i++) {
-		struct share_mode_entry *e = &d->share_modes[i];
-		bool e_is_lease = (e->op_type == LEASE_OPLOCK);
-		uint32_t e_lease_type = get_lease_type(d, e);
-		uint32_t break_to;
-		bool lease_is_breaking = false;
-
-		if (e_is_lease) {
-			NTSTATUS status;
-
-			if (lease != NULL) {
-				bool our_lease = smb2_lease_equal(
-					fsp_client_guid(fsp),
-					&lease->lease_key,
-					&e->client_guid,
-					&e->lease_key);
-				if (our_lease) {
-					DBG_DEBUG("Ignoring our own lease\n");
-					continue;
-				}
-			}
-
-			status = leases_db_get(
+	return smb2_lease_equal(fsp_client_guid(fsp),
+				&lease->lease_key,
 				&e->client_guid,
-				&e->lease_key,
-				&fsp->file_id,
-				NULL, /* current_state */
-				&lease_is_breaking,
-				NULL, /* breaking_to_requested */
-				NULL, /* breaking_to_required */
-				NULL, /* lease_version */
-				NULL); /* epoch */
-			SMB_ASSERT(NT_STATUS_IS_OK(status));
-		}
-
-		break_to = e_lease_type & ~delay_mask;
-
-		if (will_overwrite) {
-			break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
-		}
-
-		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 & ~break_to) == 0) {
-			if (lease_is_breaking) {
-				delay = true;
-			}
-			continue;
-		}
-
-		if (share_mode_stale_pid(d, i)) {
-			continue;
-		}
-
-		if (will_overwrite) {
-			/*
-			 * If we break anyway break to NONE directly.
-			 * Otherwise vfs_set_filelen() will trigger the
-			 * break.
-			 */
-			break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
-		}
-
-		if (!e_is_lease) {
-			/*
-			 * Oplocks only support breaking to R or NONE.
-			 */
-			break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
-		}
-
-		DEBUG(10, ("breaking from %d to %d\n",
-			   (int)e_lease_type, (int)break_to));
-		send_break_message(fsp->conn->sconn->msg_ctx, &fsp->file_id,
-				   e, break_to);
-		if (e_lease_type & delay_mask) {
-			delay = true;
-		}
-		if (lease_is_breaking && !first_open_attempt) {
-			delay = true;
-		}
-	}
-
-	return delay;
+				&e->lease_key);
 }
 
 static bool file_has_brlocks(files_struct *fsp)
@@ -2165,24 +2073,6 @@ static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
 	return status;
 }
 
-static bool is_same_lease(const files_struct *fsp,
-			  const struct share_mode_data *d,
-			  const struct share_mode_entry *e,
-			  const struct smb2_lease *lease)
-{
-	if (e->op_type != LEASE_OPLOCK) {
-		return false;
-	}
-	if (lease == NULL) {
-		return false;
-	}
-
-	return smb2_lease_equal(fsp_client_guid(fsp),
-				&lease->lease_key,
-				&e->client_guid,
-				&e->lease_key);
-}
-
 static int map_lease_type_to_oplock(uint32_t lease_type)
 {
 	int result = NO_OPLOCK;
@@ -2203,27 +2093,144 @@ static int map_lease_type_to_oplock(uint32_t lease_type)
 	return result;
 }
 
-static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
-				      struct files_struct *fsp,
-				      struct share_mode_lock *lck,
-				      int oplock_request,
-				      const struct smb2_lease *lease,
-				      uint32_t share_access,
-				      uint32_t access_mask)
+static NTSTATUS delay_for_oplock(files_struct *fsp,
+				 int oplock_request,
+				 const struct smb2_lease *lease,
+				 struct share_mode_lock *lck,
+				 bool have_sharing_violation,
+				 uint32_t create_disposition,
+				 bool first_open_attempt)
 {
 	struct share_mode_data *d = lck->data;
+	uint32_t i;
+	bool delay = false;
+	bool will_overwrite;
+	const uint32_t delay_mask = have_sharing_violation ?
+		SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
 	bool got_handle_lease = false;
 	bool got_oplock = false;
-	uint32_t i;
+	bool have_other_lease = false;
 	uint32_t granted;
-	bool ok;
 	NTSTATUS status;
 
-	if (oplock_request & INTERNAL_OPEN_ONLY) {
-		/* No oplocks on internal open. */
-		oplock_request = NO_OPLOCK;
-		DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
-			fsp->oplock_type, fsp_str_dbg(fsp)));
+	if (is_stat_open(fsp->access_mask)) {
+		goto grant;
+	}
+
+	switch (create_disposition) {
+	case FILE_SUPERSEDE:
+	case FILE_OVERWRITE:
+	case FILE_OVERWRITE_IF:
+		will_overwrite = true;
+		break;
+	default:
+		will_overwrite = false;
+		break;
+	}
+
+	for (i=0; i<d->num_share_modes; i++) {
+		struct share_mode_entry *e = &d->share_modes[i];
+		bool e_is_lease = (e->op_type == LEASE_OPLOCK);
+		uint32_t e_lease_type = get_lease_type(d, e);
+		uint32_t break_to;
+		bool lease_is_breaking = false;
+
+		if (e_is_lease) {
+			if (lease != NULL) {
+				bool our_lease = is_same_lease(fsp, e, lease);
+				if (our_lease) {
+					DBG_DEBUG("Ignoring our own lease\n");
+					continue;
+				}
+			}
+
+			status = leases_db_get(
+				&e->client_guid,
+				&e->lease_key,
+				&fsp->file_id,
+				NULL, /* current_state */
+				&lease_is_breaking,
+				NULL, /* breaking_to_requested */
+				NULL, /* breaking_to_required */
+				NULL, /* lease_version */
+				NULL); /* epoch */
+			SMB_ASSERT(NT_STATUS_IS_OK(status));
+		}
+
+		if (!got_handle_lease &&
+		    ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
+		    !share_mode_stale_pid(d, i)) {
+			got_handle_lease = true;
+		}
+
+		if (!got_oplock &&
+		    (e->op_type != LEASE_OPLOCK) &&
+		    !share_mode_stale_pid(d, i)) {
+			got_oplock = true;
+		}
+
+		if (!have_other_lease &&
+		    !is_same_lease(fsp, e, lease) &&
+		    !share_mode_stale_pid(d, i)) {
+			have_other_lease = true;
+		}
+
+		break_to = e_lease_type & ~delay_mask;
+
+		if (will_overwrite) {
+			break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
+		}
+
+		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 & ~break_to) == 0) {
+			if (lease_is_breaking) {
+				delay = true;
+			}
+			continue;
+		}
+
+		if (share_mode_stale_pid(d, i)) {
+			continue;
+		}
+
+		if (will_overwrite) {
+			/*
+			 * If we break anyway break to NONE directly.
+			 * Otherwise vfs_set_filelen() will trigger the
+			 * break.
+			 */
+			break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
+		}
+
+		if (!e_is_lease) {
+			/*
+			 * Oplocks only support breaking to R or NONE.
+			 */
+			break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+		}
+
+		DEBUG(10, ("breaking from %d to %d\n",
+			   (int)e_lease_type, (int)break_to));
+		send_break_message(fsp->conn->sconn->msg_ctx, &fsp->file_id,
+				   e, break_to);
+		if (e_lease_type & delay_mask) {
+			delay = true;
+		}
+		if (lease_is_breaking && !first_open_attempt) {
+			delay = true;
+		}
+	}
+
+	if (delay) {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list