svn commit: samba r15961 - in trunk/source: include smbd

jra at samba.org jra at samba.org
Tue May 30 18:39:04 GMT 2006


Author: jra
Date: 2006-05-30 18:39:04 +0000 (Tue, 30 May 2006)
New Revision: 15961

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

Log:
Bring HEAD up to date with the RAW-OPLOCK test fixes.
Jeremy.

Modified:
   trunk/source/include/smb.h
   trunk/source/smbd/nttrans.c
   trunk/source/smbd/open.c
   trunk/source/smbd/oplock.c
   trunk/source/smbd/trans2.c


Changeset:
Modified: trunk/source/include/smb.h
===================================================================
--- trunk/source/include/smb.h	2006-05-30 18:38:10 UTC (rev 15960)
+++ trunk/source/include/smb.h	2006-05-30 18:39:04 UTC (rev 15961)
@@ -1538,19 +1538,26 @@
 
 /*
  * Bits we test with.
+ * Note these must fit into 16-bits.
  */
-                                                                                                                              
+
 #define NO_OPLOCK 0
 #define EXCLUSIVE_OPLOCK 1
 #define BATCH_OPLOCK 2
 #define LEVEL_II_OPLOCK 4
+
+/* The following are Samba-private. */
 #define INTERNAL_OPEN_ONLY 8
 #define FAKE_LEVEL_II_OPLOCK 16	/* Client requested no_oplock, but we have to
 				 * inform potential level2 holders on
 				 * write. */
 #define DEFERRED_OPEN_ENTRY 32
 #define UNUSED_SHARE_MODE_ENTRY 64
+#define FORCE_OPLOCK_BREAK_TO_NONE 128
 
+/* None of the following should ever appear in fsp->oplock_request. */
+#define SAMBA_PRIVATE_OPLOCK_MASK (INTERNAL_OPEN_ONLY|DEFERRED_OPEN_ENTRY|UNUSED_SHARE_MODE_ENTRY|FORCE_OPLOCK_BREAK_TO_NONE)
+
 #define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
 #define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
 #define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)LEVEL_II_OPLOCK|(unsigned int)FAKE_LEVEL_II_OPLOCK))

Modified: trunk/source/smbd/nttrans.c
===================================================================
--- trunk/source/smbd/nttrans.c	2006-05-30 18:38:10 UTC (rev 15960)
+++ trunk/source/smbd/nttrans.c	2006-05-30 18:39:04 UTC (rev 15961)
@@ -1658,11 +1658,11 @@
 
         status = open_file_ntcreate(conn,oldname,&sbuf1,
 			FILE_READ_DATA, /* Read-only. */
-			0, /* No sharing. */
+			FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 			FILE_OPEN,
 			0, /* No create options. */
 			FILE_ATTRIBUTE_NORMAL,
-			INTERNAL_OPEN_ONLY,
+			NO_OPLOCK,
 			&info, &fsp1);
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1671,11 +1671,11 @@
 
         status = open_file_ntcreate(conn,newname,&sbuf2,
 			FILE_WRITE_DATA, /* Read-only. */
-			0, /* No sharing. */
+			FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 			FILE_CREATE,
 			0, /* No create options. */
 			fattr,
-			INTERNAL_OPEN_ONLY,
+			NO_OPLOCK,
 			&info, &fsp2);
 
 	if (!NT_STATUS_IS_OK(status)) {

Modified: trunk/source/smbd/open.c
===================================================================
--- trunk/source/smbd/open.c	2006-05-30 18:38:10 UTC (rev 15960)
+++ trunk/source/smbd/open.c	2006-05-30 18:39:04 UTC (rev 15961)
@@ -599,7 +599,7 @@
 }
 
 /*
- * 1) No files open at all: Grant whatever the client wants.
+ * 1) No files open at all or internal open: Grant whatever the client wants.
  *
  * 2) Exclusive (or batch) oplock around: If the requested access is a delete
  *    request, break if the oplock around is a batch oplock. If it's another
@@ -608,7 +608,10 @@
  * 3) Only level2 around: Grant level2 and do nothing else.
  */
 
-static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, int pass_number)
+static BOOL delay_for_oplocks(struct share_mode_lock *lck,
+				files_struct *fsp,
+				int pass_number,
+				int oplock_request)
 {
 	int i;
 	struct share_mode_entry *exclusive = NULL;
@@ -616,7 +619,7 @@
 	BOOL delay_it = False;
 	BOOL have_level2 = False;
 
-	if (is_stat_open(fsp->access_mask)) {
+	if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
 		fsp->oplock_type = NO_OPLOCK;
 		return False;
 	}
@@ -683,8 +686,19 @@
 			   procid_str_static(&exclusive->pid)));
 		exclusive->op_mid = get_current_mid();
 
+		if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
+			/* Send the message with this bit set. */
+			exclusive->op_type |= FORCE_OPLOCK_BREAK_TO_NONE;
+		}
+
+		/* Create the message. */
 		share_mode_entry_to_message(msg, exclusive);
 
+		/* And remove it again - we don't want this stored. */
+		if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
+			exclusive->op_type &= ~FORCE_OPLOCK_BREAK_TO_NONE;
+		}
+
 		become_root();
 		ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
 				       msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
@@ -692,7 +706,6 @@
 		if (!ret) {
 			DEBUG(3, ("Could not send oplock break message\n"));
 		}
-		file_free(fsp);
 	}
 
 	return delay_it;
@@ -1088,7 +1101,6 @@
 	int flags2=0;
 	BOOL file_existed = VALID_STAT(*psbuf);
 	BOOL def_acl = False;
-	BOOL internal_only_open = False;
 	SMB_DEV_T dev = 0;
 	SMB_INO_T inode = 0;
 	NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
@@ -1131,11 +1143,6 @@
 		   create_disposition, create_options, unx_mode,
 		   oplock_request));
 
-	if (oplock_request == INTERNAL_OPEN_ONLY) {
-		internal_only_open = True;
-		oplock_request = 0;
-	}
-
 	if ((pml = get_open_deferred_message(mid)) != NULL) {
 		struct deferred_open_record *state =
 			(struct deferred_open_record *)pml->private_data.data;
@@ -1172,7 +1179,8 @@
 	/* ignore any oplock requests if oplocks are disabled */
 	if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
 	    IS_VETO_OPLOCK_PATH(conn, fname)) {
-		oplock_request = 0;
+		/* Mask off everything except the private Samba bits. */
+		oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
 	}
 
 	/* this is for OS/2 long file names - say we don't support them */
@@ -1344,7 +1352,8 @@
 	fsp->share_access = share_access;
 	fsp->fh->private_options = create_options;
 	fsp->access_mask = access_mask;
-	fsp->oplock_type = oplock_request;
+	/* Ensure no SAMBA_PRIVATE bits can be set. */
+	fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
 
 	if (timeval_is_zero(&request_time)) {
 		request_time = fsp->open_time;
@@ -1359,14 +1368,16 @@
 					fname);
 
 		if (lck == NULL) {
+			file_free(fsp);
 			DEBUG(0, ("Could not get share mode lock\n"));
 			return NT_STATUS_SHARING_VIOLATION;
 		}
 
 		/* First pass - send break only on batch oplocks. */
-		if (delay_for_oplocks(lck, fsp, 1)) {
+		if (delay_for_oplocks(lck, fsp, 1, oplock_request)) {
 			schedule_defer_open(lck, request_time);
 			TALLOC_FREE(lck);
+			file_free(fsp);
 			return NT_STATUS_SHARING_VIOLATION;
 		}
 
@@ -1377,9 +1388,10 @@
 		if (NT_STATUS_IS_OK(status)) {
 			/* We might be going to allow this open. Check oplock status again. */
 			/* Second pass - send break for both batch or exclusive oplocks. */
-			if (delay_for_oplocks(lck, fsp, 2)) {
+			if (delay_for_oplocks(lck, fsp, 2, oplock_request)) {
 				schedule_defer_open(lck, request_time);
 				TALLOC_FREE(lck);
+				file_free(fsp);
 				return NT_STATUS_SHARING_VIOLATION;
 			}
 		}
@@ -1453,7 +1465,7 @@
 			 * cope with the braindead 1 second delay.
 			 */
 
-			if (!internal_only_open &&
+			if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
 			    lp_defer_sharing_violations()) {
 				struct timeval timeout;
 				struct deferred_open_record state;

Modified: trunk/source/smbd/oplock.c
===================================================================
--- trunk/source/smbd/oplock.c	2006-05-30 18:38:10 UTC (rev 15960)
+++ trunk/source/smbd/oplock.c	2006-05-30 18:39:04 UTC (rev 15961)
@@ -540,6 +540,7 @@
 	}
 
 	if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && 
+	    !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) &&
 	    !koplocks && /* NOTE: we force levelII off for kernel oplocks -
 			  * this will change when it is supported */
 	    lp_level2_oplocks(SNUM(fsp->conn))) {

Modified: trunk/source/smbd/trans2.c
===================================================================
--- trunk/source/smbd/trans2.c	2006-05-30 18:38:10 UTC (rev 15960)
+++ trunk/source/smbd/trans2.c	2006-05-30 18:39:04 UTC (rev 15961)
@@ -4020,15 +4020,19 @@
  
 					status = open_file_ntcreate(conn, fname, &sbuf,
 									FILE_WRITE_DATA,
-									FILE_SHARE_READ|FILE_SHARE_WRITE,
+									FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 									FILE_OPEN,
 									0,
 									FILE_ATTRIBUTE_NORMAL,
-									INTERNAL_OPEN_ONLY,
+									FORCE_OPLOCK_BREAK_TO_NONE,
 									NULL, &new_fsp);
  
 					if (!NT_STATUS_IS_OK(status)) {
-						return(UNIXERROR(ERRDOS,ERRbadpath));
+						if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+							/* We have re-scheduled this call. */
+							return -1;
+						}
+						return(UNIXERROR(ERRDOS,ERRnoaccess));
 					}
 					ret = vfs_allocate_file_space(new_fsp, allocation_size);
 					if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
@@ -4561,7 +4565,6 @@
 						POSIX_LOCK,
 						&my_lock_ctx);
 
-				/* TODO: Deal with rescheduling blocking lock fail here... */
 				if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
 					/*
 					 * A blocking lock was requested. Package up
@@ -4660,15 +4663,19 @@
 
 			status = open_file_ntcreate(conn, fname, &sbuf,
 						FILE_WRITE_DATA,
-						FILE_SHARE_READ|FILE_SHARE_WRITE,
+						FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
 						FILE_OPEN,
 						0,
 						FILE_ATTRIBUTE_NORMAL,
-						INTERNAL_OPEN_ONLY,
+						FORCE_OPLOCK_BREAK_TO_NONE,
 						NULL, &new_fsp);
 	
 			if (!NT_STATUS_IS_OK(status)) {
-				return(UNIXERROR(ERRDOS,ERRbadpath));
+				if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+					/* We have re-scheduled this call. */
+					return -1;
+				}
+				return(UNIXERROR(ERRDOS,ERRnoaccess));
 			}
 			ret = vfs_set_filelen(new_fsp, size);
 			close_file(new_fsp,NORMAL_CLOSE);



More information about the samba-cvs mailing list