svn commit: samba r14601 - in trunk/source/smbd: .

jra at samba.org jra at samba.org
Tue Mar 21 06:53:41 GMT 2006


Author: jra
Date: 2006-03-21 06:53:41 +0000 (Tue, 21 Mar 2006)
New Revision: 14601

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=14601

Log:
Fix another logic bug in new oplock handling. Just
because lck->num_share_modes != 0 doesn't mean that
there *are* other valid share modes. They may be
all marked "UNUSED" or be deferred open entries.
In that case don't downgrade the granted oplock to
level2 needlessly - a client can have an exclusive
oplock in this case. The original code handled this
correctly in the lck->num_share_modes == 0 case but
not in the case where there were no valid share modes
but lck->num_share_modes != 0. I'll clean up my
Samba4 torture tester for this and commit it tomorrow.
Jeremy.

Modified:
   trunk/source/smbd/open.c


Changeset:
Modified: trunk/source/smbd/open.c
===================================================================
--- trunk/source/smbd/open.c	2006-03-21 02:56:49 UTC (rev 14600)
+++ trunk/source/smbd/open.c	2006-03-21 06:53:41 UTC (rev 14601)
@@ -612,6 +612,7 @@
 {
 	int i;
 	struct share_mode_entry *exclusive = NULL;
+	BOOL valid_entry = False;
 	BOOL delay_it = False;
 	BOOL have_level2 = False;
 
@@ -620,33 +621,36 @@
 		return False;
 	}
 
-	if (lck->num_share_modes == 0) {
-		/* No files open at all: Directly grant whatever the client
-		 * wants. */
-
-		if (fsp->oplock_type == NO_OPLOCK) {
-			/* Store a level2 oplock, but don't tell the client */
-			fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
-		}
-		return False;
-	}
-
 	for (i=0; i<lck->num_share_modes; i++) {
 
 		if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
 			continue;
 		}
 
+		/* At least one entry is not an invalid or deferred entry. */
+		valid_entry = True;
+
 		if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
 			SMB_ASSERT(exclusive == NULL);			
 			exclusive = &lck->share_modes[i];
 		}
 
 		if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
+			SMB_ASSERT(exclusive == NULL);			
 			have_level2 = True;
 		}
 	}
 
+	if (!valid_entry) {
+		/* All entries are placeholders or deferred.
+		 * Directly grant whatever the client wants. */
+		if (fsp->oplock_type == NO_OPLOCK) {
+			/* Store a level2 oplock, but don't tell the client */
+			fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
+		}
+		return False;
+	}
+
 	if (exclusive != NULL) { /* Found an exclusive oplock */
 		SMB_ASSERT(!have_level2);
 		delay_it = is_delete_request(fsp) ?
@@ -654,7 +658,8 @@
 	}
 
 	if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
-		/* We can at most grant level2 */
+		/* We can at most grant level2 as there are other
+		 * level2 or NO_OPLOCK entries. */
 		fsp->oplock_type = LEVEL_II_OPLOCK;
 	}
 



More information about the samba-cvs mailing list