[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha2-1067-ga0decdf

Stefan Metzmacher metze at samba.org
Wed Feb 27 18:36:05 GMT 2008


The branch, v4-0-test has been updated
       via  a0decdf63e2f7ef6ee62a3fda5070b2fccee5682 (commit)
       via  e3a9ad303f6f935aa2b5d60036f9e6dfba5cc893 (commit)
       via  656011add338ab87188849c4a716d3c65a102a74 (commit)
       via  b66c246c5db78db897bcf21a6ea3c777d65cfc6a (commit)
       via  7bac95db5edcc7432aea067e0a9ba9230c7dc1b0 (commit)
       via  22c35d9ee7858c0ff58d5d0b4a9bf69fe0b8653f (commit)
       via  32f138d4b313a6c5e8ef8e15945df02e3b4db864 (commit)
       via  3886a5dea2fa26eeed8bc1d20c44ef012ea1f746 (commit)
       via  06547036e6554dc94f683263b54d528eac227ea8 (commit)
       via  2453628623795c34ece18a285e6c2de40c4518de (commit)
       via  f4f593a1acd4a39f7be639465f0be4b3a97a9bfc (commit)
       via  79e42a5dfbfd59b856bca16456295cd2c93ab0ca (commit)
       via  48e703d5a6b8a7b273d0bf15fc6198ef25b0a7c4 (commit)
       via  b22587a5db4a1e2d5fa1a944896330f1a86eef11 (commit)
       via  fd5b4b3d4ec52572619dba065d689d58bec71ae0 (commit)
       via  1cddadb052106394046f03d65297ea68232e7492 (commit)
       via  546536dde07d82dbba6724df95cdd1ba50caf8c5 (commit)
      from  d2eb404ba1711abf6bb2718f8bb1dbbd104e7d4d (commit)

http://gitweb.samba.org/?samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit a0decdf63e2f7ef6ee62a3fda5070b2fccee5682
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 16:23:57 2008 +0100

    RAW-OPLOCK: be more strict with share modes against windows and samba4
    
    But still allow samba3 behavior.
    
    metze

commit e3a9ad303f6f935aa2b5d60036f9e6dfba5cc893
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 16:22:45 2008 +0100

    selftest: samba4 doesn't pass RAW-OPLOCK BATCH19 und 20 yet
    
    metze

commit 656011add338ab87188849c4a716d3c65a102a74
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 16:22:04 2008 +0100

    RAW-OPLOCK: use torture_result(TORTURE_FAIL) so that the knownfailures file work
    
    metze

commit b66c246c5db78db897bcf21a6ea3c777d65cfc6a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 15:45:08 2008 +0100

    RAW-OPLOCK: add BATCH20 test renaming via setpathinfo() and setfileinfo()
    
    metze

commit 7bac95db5edcc7432aea067e0a9ba9230c7dc1b0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 15:43:04 2008 +0100

    RAW-OPLOCK: add BATCH19 test renaming via setpathinfo
    
    This is really strange as, it seems to complete ignore
    oplocks and share modes and doesn't match the behavior
    of RENAME and NTRENAME.
    
    metze

commit 22c35d9ee7858c0ff58d5d0b4a9bf69fe0b8653f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 11:07:53 2008 +0100

    RAW-OPLOCK: add BATCH18 test a ntrename with FLAG_RENAME
    
    metze

commit 32f138d4b313a6c5e8ef8e15945df02e3b4db864
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 10:41:47 2008 +0100

    RAW-OPLOCK: add BATCH17 test rename on a file with oplock
    
    metze

commit 3886a5dea2fa26eeed8bc1d20c44ef012ea1f746
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 10:40:19 2008 +0100

    RAW-OPLOCK: add EXCLISIVE6 test a rename on a file with an oplock
    
    metze

commit 06547036e6554dc94f683263b54d528eac227ea8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 10:02:52 2008 +0100

    RAW-OPLOCK: add EXCLUSIVE5 to test attribute only with OVERWRITE_IF
    
    metze

commit 2453628623795c34ece18a285e6c2de40c4518de
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 09:41:44 2008 +0100

    RAW-OPLOCK: add BATCH16 and tests attribute only with OVERWRITE_IF
    
    metze

commit f4f593a1acd4a39f7be639465f0be4b3a97a9bfc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 11:25:33 2008 +0100

    pvfs_rename: we need a do a odb_rename() after pvfs_do_rename()
    
    metze

commit 79e42a5dfbfd59b856bca16456295cd2c93ab0ca
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 11:24:37 2008 +0100

    pvfs_rename: add retry logic after sharing violation or non granted oplock
    
    metze

commit 48e703d5a6b8a7b273d0bf15fc6198ef25b0a7c4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 09:40:49 2008 +0100

    opendb_tdb: EXCLUSIVE oplock use the same matching logic
    
    metze

commit b22587a5db4a1e2d5fa1a944896330f1a86eef11
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 27 08:51:25 2008 +0100

    RAW-OPLOCK: add EXCLUSIVE4 a attribute only open doesn't break an exclusive oplock
    
    metze

commit fd5b4b3d4ec52572619dba065d689d58bec71ae0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 26 16:16:31 2008 +0100

    RAW-OPLOCK: add EXCLUSIVE3
    
    This tests that a setpathinfo EOF breaks
    an exclusive oplock to none.
    
    metze

commit 1cddadb052106394046f03d65297ea68232e7492
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 26 15:51:17 2008 +0100

    RAW-OPLOCK: add EXCLUSIVE2
    
    Exclusive oplocks break to LEVEL2
    
    metze

commit 546536dde07d82dbba6724df95cdd1ba50caf8c5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 26 14:58:00 2008 +0100

    RAW-OPLOCK: rename test (NORMAL => EXCLUSIVE1)
    
    metze

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

Summary of changes:
 source/ntvfs/common/opendb_tdb.c |   24 +-
 source/ntvfs/posix/pvfs_rename.c |  108 +++++-
 source/samba4-knownfail          |    2 +
 source/torture/raw/oplock.c      |  872 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 996 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/ntvfs/common/opendb_tdb.c b/source/ntvfs/common/opendb_tdb.c
index fe5a0a8..a51c823 100644
--- a/source/ntvfs/common/opendb_tdb.c
+++ b/source/ntvfs/common/opendb_tdb.c
@@ -376,8 +376,26 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
 	   exclusive oplocks afterwards. */
 	for (i=0;i<file->num_entries;i++) {
 		if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) {
+			bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II;
+			/* if this is an attribute only access
+			 * it doesn't conflict with an EXCLUSIVE oplock
+			 * but we'll not grant the oplock below
+			 */
+			attrs_only = access_attributes_only(access_mask,
+							    open_disposition,
+							    break_to_none);
+			if (attrs_only) {
+				break;
+			}
+			/*
+			 * send an oplock break to the holder of the
+			 * oplock and tell caller to retry later
+			 */
+			if (break_to_none) {
+				oplock_return = OPLOCK_BREAK_TO_NONE;
+			}
 			odb_oplock_break_send(odb, &file->entries[i],
-					      OPLOCK_BREAK_TO_NONE);
+					      oplock_return);
 			return NT_STATUS_OPLOCK_NOT_GRANTED;
 		}
 	}
@@ -449,8 +467,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
 				e.oplock_level	= OPLOCK_EXCLUSIVE;
 				*oplock_granted	= EXCLUSIVE_OPLOCK_RETURN;
 			} else {
-				e.oplock_level	= OPLOCK_NONE;
-				*oplock_granted	= NO_OPLOCK_RETURN;
+				e.oplock_level	= OPLOCK_LEVEL_II;
+				*oplock_granted	= LEVEL_II_OPLOCK_RETURN;
 			}
 		} else if (oplock_level == OPLOCK_BATCH) {
 			if (file.num_entries == 0) {
diff --git a/source/ntvfs/posix/pvfs_rename.c b/source/ntvfs/posix/pvfs_rename.c
index 5693e79..3c60c00 100644
--- a/source/ntvfs/posix/pvfs_rename.c
+++ b/source/ntvfs/posix/pvfs_rename.c
@@ -181,6 +181,84 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx,
 }
 
 /*
+  retry an rename after a sharing violation
+*/
+static void pvfs_retry_rename(struct pvfs_odb_retry *r,
+			      struct ntvfs_module_context *ntvfs,
+			      struct ntvfs_request *req,
+			      void *_io,
+			      void *private_data,
+			      enum pvfs_wait_notice reason)
+{
+	union smb_rename *io = talloc_get_type(_io, union smb_rename);
+	NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
+
+	talloc_free(r);
+
+	switch (reason) {
+	case PVFS_WAIT_CANCEL:
+/*TODO*/
+		status = NT_STATUS_CANCELLED;
+		break;
+	case PVFS_WAIT_TIMEOUT:
+		/* if it timed out, then give the failure
+		   immediately */
+/*TODO*/
+		status = NT_STATUS_SHARING_VIOLATION;
+		break;
+	case PVFS_WAIT_EVENT:
+
+		/* try the open again, which could trigger another retry setup
+		   if it wants to, so we have to unmark the async flag so we
+		   will know if it does a second async reply */
+		req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC;
+
+		status = pvfs_rename(ntvfs, req, io);
+		if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) {
+			/* the 2nd try also replied async, so we don't send
+			   the reply yet */
+			return;
+		}
+
+		/* re-mark it async, just in case someone up the chain does
+		   paranoid checking */
+		req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+		break;
+	}
+
+	/* send the reply up the chain */
+	req->async_states->status = status;
+	req->async_states->send_fn(req);
+}
+
+/*
+  setup for a rename retry after a sharing violation
+  or a non granted oplock
+*/
+static NTSTATUS pvfs_rename_setup_retry(struct ntvfs_module_context *ntvfs,
+					struct ntvfs_request *req,
+					union smb_rename *io,
+					struct odb_lock *lck,
+					NTSTATUS status)
+{
+	struct pvfs_state *pvfs = ntvfs->private_data;
+	struct timeval end_time;
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       0, pvfs->sharing_violation_delay);
+	} else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       pvfs->oplock_break_timeout, 0);
+	} else {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL,
+				    pvfs_retry_rename);
+}
+
+/*
   rename one file from a wildcard set
 */
 static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, 
@@ -354,8 +432,19 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
 	}
 
 	status = pvfs_can_rename(pvfs, req, name1, &lck);
+	/*
+	 * on a sharing violation we need to retry when the file is closed by
+	 * the other user, or after 1 second
+	 * on a non granted oplock we need to retry when the file is closed by
+	 * the other user, or after 30 seconds
+	 */
+	if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+	     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+	    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+		return pvfs_rename_setup_retry(pvfs->ntvfs, req, ren, lck, status);
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(lck);
 		return status;
 	}
 
@@ -377,6 +466,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
 	struct pvfs_state *pvfs = ntvfs->private_data;
 	NTSTATUS status;
 	struct pvfs_filename *name1, *name2;
+	struct odb_lock *lck = NULL;
 
 	switch (ren->ntrename.in.flags) {
 	case RENAME_FLAG_RENAME:
@@ -422,7 +512,18 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
 		return status;
 	}
 
-	status = pvfs_can_rename(pvfs, req, name1, NULL);
+	status = pvfs_can_rename(pvfs, req, name1, &lck);
+	/*
+	 * on a sharing violation we need to retry when the file is closed by
+	 * the other user, or after 1 second
+	 * on a non granted oplock we need to retry when the file is closed by
+	 * the other user, or after 30 seconds
+	 */
+	if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+	     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+	    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+		return pvfs_rename_setup_retry(pvfs->ntvfs, req, ren, lck, status);
+	}
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
@@ -432,6 +533,9 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
 		status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE);
 		NT_STATUS_NOT_OK_RETURN(status);
 		status = pvfs_do_rename(pvfs, name1, name2->full_name);
+		if (NT_STATUS_IS_OK(status)) {
+			status = odb_rename(lck, name2->full_name);
+		}
 		NT_STATUS_NOT_OK_RETURN(status);
 		break;
 
diff --git a/source/samba4-knownfail b/source/samba4-knownfail
index 4d850ca..aaa1177 100644
--- a/source/samba4-knownfail
+++ b/source/samba4-knownfail
@@ -3,6 +3,8 @@ local.iconv.*.next_codepoint()
 base.delaywrite.finfo update on close
 base.delete.*.deltest20a
 base.delete.*.deltest20b
+raw.oplock.*BATCH19
+raw.oplock.*BATCH20
 rpc.winreg
 local.registry.*.security # Not implemented yet
 rpc.wkssvc
diff --git a/source/torture/raw/oplock.c b/source/torture/raw/oplock.c
index e81b634..7ac88c0 100644
--- a/source/torture/raw/oplock.c
+++ b/source/torture/raw/oplock.c
@@ -27,11 +27,19 @@
 
 #define CHECK_VAL(v, correct) do { \
 	if ((v) != (correct)) { \
-		torture_comment(tctx, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
+		torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
 				__location__, #v, (int)v, (int)correct); \
 		ret = false; \
 	}} while (0)
 
+#define CHECK_STRMATCH(v, correct) do { \
+	if (!v || strstr((v),(correct)) == NULL) { \
+		torture_result(tctx, TORTURE_FAIL,  "(%s): wrong value for %s got '%s' - should be '%s'\n", \
+				__location__, #v, v?v:"NULL", correct); \
+		ret = false; \
+	} \
+} while (0)
+
 #define CHECK_STATUS(tctx, status, correct) do { \
 	if (!NT_STATUS_EQUAL(status, correct)) { \
 		torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
@@ -123,9 +131,9 @@ static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t ti
 	return true;
 }
 
-static bool test_raw_oplock_normal(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
 {
-	const char *fname = BASEDIR "\\test_normal.dat";
+	const char *fname = BASEDIR "\\test_exclusive1.dat";
 	NTSTATUS status;
 	bool ret = true;
 	union smb_open io;
@@ -156,7 +164,7 @@ static bool test_raw_oplock_normal(struct torture_context *tctx, struct smbcli_s
 	io.ntcreatex.in.security_flags = 0;
 	io.ntcreatex.in.fname = fname;
 
-	torture_comment(tctx, "open a file with a normal oplock\n");
+	torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
 	ZERO_STRUCT(break_info);
 	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 
@@ -188,6 +196,381 @@ done:
 	return ret;
 }
 
+static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+	const char *fname = BASEDIR "\\test_exclusive2.dat";
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	union smb_unlink unl;
+	uint16_t fnum=0, fnum2=0;
+
+	if (!torture_setup_dir(cli1, BASEDIR)) {
+		return false;
+	}
+
+	/* cleanup */
+	smbcli_unlink(cli1->tree, fname);
+
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	/*
+	  base ntcreatex parms
+	*/
+	io.generic.level = RAW_OPEN_NTCREATEX;
+	io.ntcreatex.in.root_fid = 0;
+	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+	io.ntcreatex.in.alloc_size = 0;
+	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+	io.ntcreatex.in.create_options = 0;
+	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+	io.ntcreatex.in.security_flags = 0;
+	io.ntcreatex.in.fname = fname;
+
+	torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
+	ZERO_STRUCT(break_info);
+	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
+		NTCREATEX_SHARE_ACCESS_WRITE|
+		NTCREATEX_SHARE_ACCESS_DELETE;
+
+	status = smb_raw_open(cli1->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
+
+	torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
+	status = smb_raw_open(cli2->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum2 = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+	CHECK_VAL(break_info.count, 1);
+	CHECK_VAL(break_info.fnum, fnum);
+	CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
+	CHECK_VAL(break_info.failures, 0);
+	ZERO_STRUCT(break_info);
+
+	/* now we have 2 level II oplocks... */
+	torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
+	unl.unlink.in.pattern = fname;
+	unl.unlink.in.attrib = 0;
+	status = smb_raw_unlink(cli2->tree, &unl);
+	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+
+	torture_comment(tctx, "close 1st handle\n");
+	smbcli_close(cli1->tree, fnum);
+
+	torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
+	unl.unlink.in.pattern = fname;
+	unl.unlink.in.attrib = 0;
+	status = smb_raw_unlink(cli2->tree, &unl);
+	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+
+	torture_comment(tctx, "close 1st handle\n");
+	smbcli_close(cli2->tree, fnum2);
+
+	torture_comment(tctx, "unlink it\n");
+	unl.unlink.in.pattern = fname;
+	unl.unlink.in.attrib = 0;
+	status = smb_raw_unlink(cli2->tree, &unl);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+
+done:
+	smb_raw_exit(cli1->session);
+	smb_raw_exit(cli2->session);
+	smbcli_deltree(cli1->tree, BASEDIR);
+	return ret;
+}
+
+static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+	const char *fname = BASEDIR "\\test_exclusive3.dat";
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	union smb_setfileinfo sfi;
+	uint16_t fnum=0;
+	bool s3 = torture_setting_bool(tctx, "samba3", false);
+
+	if (!torture_setup_dir(cli1, BASEDIR)) {
+		return false;
+	}
+
+	/* cleanup */
+	smbcli_unlink(cli1->tree, fname);
+
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	/*
+	  base ntcreatex parms
+	*/
+	io.generic.level = RAW_OPEN_NTCREATEX;
+	io.ntcreatex.in.root_fid = 0;
+	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+	io.ntcreatex.in.alloc_size = 0;
+	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+	io.ntcreatex.in.create_options = 0;
+	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+	io.ntcreatex.in.security_flags = 0;
+	io.ntcreatex.in.fname = fname;
+
+	torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
+			s3?"all":"none");
+	ZERO_STRUCT(break_info);
+	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
+	if (s3) {
+		io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
+			NTCREATEX_SHARE_ACCESS_WRITE|
+			NTCREATEX_SHARE_ACCESS_DELETE;
+	}
+
+	status = smb_raw_open(cli1->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
+
+	torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
+	ZERO_STRUCT(sfi);
+	sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+	sfi.generic.in.file.path = fname;
+	sfi.end_of_file_info.in.size = 100;
+
+	status = smb_raw_setpathinfo(cli2->tree, &sfi);
+
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	CHECK_VAL(break_info.count, 1);
+	CHECK_VAL(break_info.failures, 0);
+	CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
+
+	smbcli_close(cli1->tree, fnum);
+
+done:
+	smb_raw_exit(cli1->session);
+	smb_raw_exit(cli2->session);
+	smbcli_deltree(cli1->tree, BASEDIR);
+	return ret;
+}
+
+static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+	const char *fname = BASEDIR "\\test_exclusive4.dat";
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	uint16_t fnum=0, fnum2=0;
+
+	if (!torture_setup_dir(cli1, BASEDIR)) {
+		return false;
+	}
+
+	/* cleanup */
+	smbcli_unlink(cli1->tree, fname);
+
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	/*
+	  base ntcreatex parms
+	*/
+	io.generic.level = RAW_OPEN_NTCREATEX;
+	io.ntcreatex.in.root_fid = 0;
+	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+	io.ntcreatex.in.alloc_size = 0;
+	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+	io.ntcreatex.in.create_options = 0;
+	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+	io.ntcreatex.in.security_flags = 0;
+	io.ntcreatex.in.fname = fname;
+
+	torture_comment(tctx, "open with exclusive oplock\n");
+	ZERO_STRUCT(break_info);
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
+	status = smb_raw_open(cli1->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
+
+	ZERO_STRUCT(break_info);
+	torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
+
+	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
+	io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
+	status = smb_raw_open(cli2->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum2 = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+
+	smbcli_close(cli1->tree, fnum);
+	smbcli_close(cli2->tree, fnum2);
+
+done:
+	smb_raw_exit(cli1->session);
+	smb_raw_exit(cli2->session);
+	smbcli_deltree(cli1->tree, BASEDIR);
+	return ret;
+}
+
+static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+	const char *fname = BASEDIR "\\test_exclusive5.dat";
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	uint16_t fnum=0, fnum2=0;
+
+	if (!torture_setup_dir(cli1, BASEDIR)) {
+		return false;
+	}
+
+	/* cleanup */
+	smbcli_unlink(cli1->tree, fname);
+
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+	smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list