The branch, master has been updated via 4abccf0 s3: Fix a panic when shutting down via 0f284be s3:lib: use includes.h with cbuf and srprs via 4931a90 s4:torture:smb2: simplify durable-open.file-position test to only use one I/O and one handle via 97be058 s4:torture:smb2: change the durable-open.file-position test to use one connection only via 3295630 s4:torture:smb2: fix durable-v2-open.reopen2 to pass against windows via 1b96a6d s4:torture:smb2: simplify the durable-v2.reopen2 test (using only one i/o struct) via fc0631c s4:torture:smb2: simplify the durable-v2-open.reopen1 test via 67290e7 s4:torture:smb2: in the durable-v2-reopen1 test, use a minimal request via d3946fe s4:torture:smb2: fix cut'n'paste error in the durable-v2-open.reopen2 test via e1dd2fc s4:torture:smb2: fix name of test file in the durable-open.alloc-size test from cd93c7d waf: add tests for NFS quota stuff
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4abccf0b65235d6a01c0dc194f06fac748ee4029 Author: Volker Lendecke <v...@samba.org> Date: Fri Aug 17 12:22:17 2012 +0200 s3: Fix a panic when shutting down When a client disconnects while we have aio open, there is no close request that cleans up. We can't send out the replies anymore, so just drop the aio requests that are pending. Found using the new python lib writing multiple files simultaneously TODO: check tdis and logoff Signed-off-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Sat Sep 8 01:27:34 CEST 2012 on sn-devel-104 commit 0f284beb67680a152a86e0bec70808ee40e471dc Author: Gregor Beck <gb...@sernet.de> Date: Thu Sep 6 11:52:58 2012 +0200 s3:lib: use includes.h with cbuf and srprs hopefully fixes build on hpux Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 4931a9010fe9fc1a9b3aafd1203a7acfaa1a5b2e Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 17:36:56 2012 +0200 s4:torture:smb2: simplify durable-open.file-position test to only use one I/O and one handle Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 97be058c9ec373d2a67b134aa8a557125254f497 Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 17:23:46 2012 +0200 s4:torture:smb2: change the durable-open.file-position test to use one connection only And do a tcp disconnect followed by a session reconnect instead of immediately using the already opened second connection. Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 32956300a75f2952cf32b92fd2403325206be772 Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 16:12:39 2012 +0200 s4:torture:smb2: fix durable-v2-open.reopen2 to pass against windows The DH2Q response blob is not sent upon successful durable handle v2 reconnect. Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 1b96a6df194b2ac87673cddc0e5506787c952961 Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 15:44:42 2012 +0200 s4:torture:smb2: simplify the durable-v2.reopen2 test (using only one i/o struct) Signed-off-by: Stefan Metzmacher <me...@samba.org> commit fc0631cae6e8a2cf601c8ae929709ca25d486364 Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 15:36:33 2012 +0200 s4:torture:smb2: simplify the durable-v2-open.reopen1 test only use one smb2_create i/o struct and store the create GUID centrally Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 67290e7d2eb8b25b093d38371db046deca781a79 Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 15:33:54 2012 +0200 s4:torture:smb2: in the durable-v2-reopen1 test, use a minimal request don't copy the old request, but only set the necessary fields Signed-off-by: Stefan Metzmacher <me...@samba.org> commit d3946fed75799739859c1d08f0a7dd361a39908e Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 14:29:05 2012 +0200 s4:torture:smb2: fix cut'n'paste error in the durable-v2-open.reopen2 test Signed-off-by: Stefan Metzmacher <me...@samba.org> commit e1dd2fc2fa966036f7e0c5cf64416a630d607efa Author: Michael Adam <ob...@samba.org> Date: Fri Sep 7 10:50:48 2012 +0200 s4:torture:smb2: fix name of test file in the durable-open.alloc-size test Signed-off-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/lib/cbuf.h | 5 - source3/lib/srprs.c | 5 +- source3/lib/srprs.h | 3 - source3/smbd/close.c | 42 +++++++-- source4/torture/smb2/durable_open.c | 94 +++++++++++--------- source4/torture/smb2/durable_v2_open.c | 145 ++++++++++++++++---------------- 6 files changed, 158 insertions(+), 136 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/lib/cbuf.h b/source3/lib/cbuf.h index 90318ec..b9c5552 100644 --- a/source3/lib/cbuf.h +++ b/source3/lib/cbuf.h @@ -29,11 +29,6 @@ #ifndef __CBUF_H #define __CBUF_H -#include <stddef.h> -#include <stdbool.h> -#include <stdint.h> - - struct cbuf; typedef struct cbuf cbuf; diff --git a/source3/lib/srprs.c b/source3/lib/srprs.c index 5a032d2..35920f1 100644 --- a/source3/lib/srprs.c +++ b/source3/lib/srprs.c @@ -24,12 +24,9 @@ * @brief A simple recursive parser. */ +#include "includes.h" #include "srprs.h" #include "cbuf.h" -#include <ctype.h> -#include <string.h> -#include <assert.h> -#include <stdio.h> bool srprs_skipws(const char** ptr) { while (isspace(**ptr)) diff --git a/source3/lib/srprs.h b/source3/lib/srprs.h index 350e08c..c1aec13 100644 --- a/source3/lib/srprs.h +++ b/source3/lib/srprs.h @@ -34,9 +34,6 @@ #ifndef __SRPRS_H #define __SRPRS_H -#include <stddef.h> -#include <stdbool.h> -#include <stdint.h> struct cbuf; /** diff --git a/source3/smbd/close.c b/source3/smbd/close.c index d4b9ad0..5143232 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -708,18 +708,40 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, connection_struct *conn = fsp->conn; if (fsp->num_aio_requests != 0) { + + if (close_type != SHUTDOWN_CLOSE) { + /* + * reply_close and the smb2 close must have + * taken care of this. No other callers of + * close_file should ever have created async + * I/O. + * + * We need to panic here because if we close() + * the fd while we have outstanding async I/O + * requests, in the worst case we could end up + * writing to the wrong file. + */ + DEBUG(0, ("fsp->num_aio_requests=%u\n", + fsp->num_aio_requests)); + smb_panic("can not close with outstanding aio " + "requests"); + } + /* - * reply_close and the smb2 close must have taken care of - * this. No other callers of close_file should ever have - * created async I/O. - * - * We need to panic here because if we close() the fd while we - * have outstanding async I/O requests, in the worst case we - * could end up writing to the wrong file. + * For shutdown close, just drop the async requests + * including a potential close request pending for + * this fsp. Drop the close request first, the + * destructor for the aio_requests would execute it. */ - DEBUG(0, ("fsp->num_aio_requests=%u\n", - fsp->num_aio_requests)); - smb_panic("can not close with outstanding aio requests"); + TALLOC_FREE(fsp->deferred_close); + + while (fsp->num_aio_requests != 0) { + /* + * The destructor of the req will remove + * itself from the fsp + */ + TALLOC_FREE(fsp->aio_requests[0]); + } } /* diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index c42588a..1cf183b 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -834,37 +834,37 @@ done: regarding the position information on the handle */ bool test_durable_open_file_position(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); - struct smb2_handle h1, h2; - struct smb2_create io1, io2; + struct smb2_handle h; + struct smb2_create io; NTSTATUS status; const char *fname = "durable_open_position.dat"; union smb_fileinfo qfinfo; union smb_setfileinfo sfinfo; bool ret = true; uint64_t pos; + uint64_t previous_session_id; - smb2_util_unlink(tree1, fname); + smb2_util_unlink(tree, fname); - smb2_oplock_create(&io1, fname, SMB2_OPLOCK_LEVEL_BATCH); - io1.in.durable_open = true; + smb2_oplock_create(&io, fname, SMB2_OPLOCK_LEVEL_BATCH); + io.in.durable_open = true; - status = smb2_create(tree1, mem_ctx, &io1); + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); - h1 = io1.out.file.handle; - CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io1.out.durable_open, true); - CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + h = io.out.file.handle; + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.durable_open, true); + CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); /* TODO: check extra blob content */ ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; - qfinfo.generic.in.file.handle = h1; - status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo); + qfinfo.generic.in.file.handle = h; + status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(qfinfo.position_information.out.position, 0); pos = qfinfo.position_information.out.position; @@ -873,64 +873,74 @@ bool test_durable_open_file_position(struct torture_context *tctx, ZERO_STRUCT(sfinfo); sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION; - sfinfo.generic.in.file.handle = h1; + sfinfo.generic.in.file.handle = h; sfinfo.position_information.in.position = 0x1000; - status = smb2_setinfo_file(tree1, &sfinfo); + status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; - qfinfo.generic.in.file.handle = h1; - status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo); + qfinfo.generic.in.file.handle = h; + status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(qfinfo.position_information.out.position, 0x1000); pos = qfinfo.position_information.out.position; torture_comment(tctx, "position: %llu\n", (unsigned long long)pos); - talloc_free(tree1); - tree1 = NULL; + previous_session_id = smb2cli_session_current_id(tree->session->smbXcli); + + /* tcp disconnect */ + talloc_free(tree); + tree = NULL; + + /* do a session reconnect */ + if (!torture_smb2_connection_ext(tctx, previous_session_id, &tree)) { + torture_warning(tctx, "couldn't reconnect, bailing\n"); + ret = false; + goto done; + } ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; - qfinfo.generic.in.file.handle = h1; - status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo); + qfinfo.generic.in.file.handle = h; + status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_FILE_CLOSED); - ZERO_STRUCT(io2); - io2.in.fname = fname; - io2.in.durable_handle = &h1; + ZERO_STRUCT(io); + io.in.fname = fname; + io.in.durable_handle = &h; - status = smb2_create(tree2, mem_ctx, &io2); + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); - CHECK_VAL(io2.out.reserved, 0x00); - CHECK_VAL(io2.out.create_action, NTCREATEX_ACTION_EXISTED); - CHECK_VAL(io2.out.alloc_size, 0); - CHECK_VAL(io2.out.size, 0); - CHECK_VAL(io2.out.file_attr, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io2.out.reserved2, 0); + CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + CHECK_VAL(io.out.reserved, 0x00); + CHECK_VAL(io.out.create_action, NTCREATEX_ACTION_EXISTED); + CHECK_VAL(io.out.alloc_size, 0); + CHECK_VAL(io.out.size, 0); + CHECK_VAL(io.out.file_attr, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.reserved2, 0); - h2 = io2.out.file.handle; + h = io.out.file.handle; ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; - qfinfo.generic.in.file.handle = h2; - status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo); + qfinfo.generic.in.file.handle = h; + status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(qfinfo.position_information.out.position, 0x1000); pos = qfinfo.position_information.out.position; torture_comment(tctx, "position: %llu\n", (unsigned long long)pos); - smb2_util_close(tree2, h2); + smb2_util_close(tree, h); talloc_free(mem_ctx); - smb2_util_unlink(tree2, fname); + smb2_util_unlink(tree, fname); + done: - talloc_free(tree1); - talloc_free(tree2); + talloc_free(tree); return ret; } @@ -1487,7 +1497,7 @@ bool test_durable_open_alloc_size(struct torture_context *tctx, const uint8_t *b = NULL; /* Choose a random name in case the state is left a little funky. */ - snprintf(fname, 256, "durable_open_initial_alloc_%s.dat", + snprintf(fname, 256, "durable_open_alloc_size_%s.dat", generate_random_str(tctx, 8)); smb2_util_unlink(tree, fname); @@ -1624,7 +1634,7 @@ struct torture_suite *torture_smb2_durable_open_init(void) torture_suite_add_1smb2_test(suite, "reopen4", test_durable_open_reopen4); torture_suite_add_1smb2_test(suite, "delete_on_close1", test_durable_open_delete_on_close1); - torture_suite_add_2smb2_test(suite, "file-position", + torture_suite_add_1smb2_test(suite, "file-position", test_durable_open_file_position); torture_suite_add_2smb2_test(suite, "oplock", test_durable_open_oplock); torture_suite_add_2smb2_test(suite, "lease", test_durable_open_lease); diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c index 3b5f7b6..0a46778 100644 --- a/source4/torture/smb2/durable_v2_open.c +++ b/source4/torture/smb2/durable_v2_open.c @@ -382,7 +382,8 @@ bool test_durable_v2_open_reopen1(struct torture_context *tctx, char fname[256]; struct smb2_handle _h; struct smb2_handle *h = NULL; - struct smb2_create io1, io2; + struct smb2_create io; + struct GUID create_guid = GUID_random(); bool ret = true; /* Choose a random name in case the state is left a little funky. */ @@ -391,33 +392,32 @@ bool test_durable_v2_open_reopen1(struct torture_context *tctx, smb2_util_unlink(tree, fname); - smb2_oplock_create_share(&io1, fname, + smb2_oplock_create_share(&io, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); - io1.in.durable_open = false; - io1.in.durable_open_v2 = true; - io1.in.persistent_open = false; - io1.in.create_guid = GUID_random(); - io1.in.timeout = UINT32_MAX; + io.in.durable_open = false; + io.in.durable_open_v2 = true; + io.in.persistent_open = false; + io.in.create_guid = create_guid; + io.in.timeout = UINT32_MAX; - status = smb2_create(tree, mem_ctx, &io1); + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); - _h = io1.out.file.handle; + _h = io.out.file.handle; h = &_h; - CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(io1.out.durable_open, false); - CHECK_VAL(io1.out.durable_open_v2, true); - CHECK_VAL(io1.out.persistent_open, false); - CHECK_VAL(io1.out.timeout, io1.in.timeout); + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(io.out.durable_open, false); + CHECK_VAL(io.out.durable_open_v2, true); + CHECK_VAL(io.out.persistent_open, false); + CHECK_VAL(io.out.timeout, io.in.timeout); /* try a durable reconnect while the file is still open */ - ZERO_STRUCT(io2); - io2.in = io1.in; - io2.in.durable_open_v2 = false; - io2.in.durable_handle_v2 = h; - io2.in.create_guid = io1.in.create_guid; - status = smb2_create(tree, mem_ctx, &io2); + ZERO_STRUCT(io); + io.in.fname = ""; + io.in.durable_handle_v2 = h; + io.in.create_guid = create_guid; + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); done: @@ -446,7 +446,8 @@ bool test_durable_v2_open_reopen2(struct torture_context *tctx, char fname[256]; struct smb2_handle _h; struct smb2_handle *h = NULL; - struct smb2_create io1, io2; + struct smb2_create io; + struct GUID create_guid = GUID_random(); bool ret = true; /* Choose a random name in case the state is left a little funky. */ @@ -455,25 +456,25 @@ bool test_durable_v2_open_reopen2(struct torture_context *tctx, smb2_util_unlink(tree, fname); - smb2_oplock_create_share(&io1, fname, + smb2_oplock_create_share(&io, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); - io1.in.durable_open = false; - io1.in.durable_open_v2 = true; - io1.in.persistent_open = false; - io1.in.create_guid = GUID_random(); - io1.in.timeout = UINT32_MAX; + io.in.durable_open = false; + io.in.durable_open_v2 = true; + io.in.persistent_open = false; + io.in.create_guid = create_guid; + io.in.timeout = UINT32_MAX; - status = smb2_create(tree, mem_ctx, &io1); + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); - _h = io1.out.file.handle; + _h = io.out.file.handle; h = &_h; - CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(io1.out.durable_open, false); - CHECK_VAL(io1.out.durable_open_v2, true); - CHECK_VAL(io1.out.persistent_open, false); - CHECK_VAL(io1.out.timeout, io1.in.timeout); + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(io.out.durable_open, false); + CHECK_VAL(io.out.durable_open_v2, true); + CHECK_VAL(io.out.persistent_open, false); + CHECK_VAL(io.out.timeout, io.in.timeout); /* disconnect, reconnect and then do durable reopen */ talloc_free(tree); @@ -485,57 +486,57 @@ bool test_durable_v2_open_reopen2(struct torture_context *tctx, goto done; } - ZERO_STRUCT(io2); - io2.in.fname = ""; - io2.in.durable_handle_v2 = h; - status = smb2_create(tree, mem_ctx, &io2); + ZERO_STRUCT(io); + io.in.fname = ""; + io.in.durable_handle_v2 = h; + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); - ZERO_STRUCT(io2); - io2.in.fname = "__non_existing_fname__"; - io2.in.durable_handle_v2 = h; - status = smb2_create(tree, mem_ctx, &io2); + ZERO_STRUCT(io); + io.in.fname = "__non_existing_fname__"; + io.in.durable_handle_v2 = h; + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); - ZERO_STRUCT(io2); - io2.in.fname = fname; - io2.in.durable_handle_v2 = h; - status = smb2_create(tree, mem_ctx, &io2); + ZERO_STRUCT(io); + io.in.fname = fname; + io.in.durable_handle_v2 = h; + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); - ZERO_STRUCT(io2); + ZERO_STRUCT(io); /* * These are completely ignored by the server */ - io2.in.security_flags = 0x78; - io2.in.oplock_level = 0x78; - io2.in.impersonation_level = 0x12345678; - io2.in.create_flags = 0x12345678; - io2.in.reserved = 0x12345678; - io2.in.desired_access = 0x12345678; - io2.in.file_attributes = 0x12345678; - io2.in.share_access = 0x12345678; - io2.in.create_disposition = 0x12345678; - io2.in.create_options = 0x12345678; - io2.in.fname = "__non_existing_fname__"; + io.in.security_flags = 0x78; + io.in.oplock_level = 0x78; + io.in.impersonation_level = 0x12345678; + io.in.create_flags = 0x12345678; + io.in.reserved = 0x12345678; + io.in.desired_access = 0x12345678; + io.in.file_attributes = 0x12345678; + io.in.share_access = 0x12345678; + io.in.create_disposition = 0x12345678; + io.in.create_options = 0x12345678; + io.in.fname = "__non_existing_fname__"; /* - * only io2.in.durable_handle_v2 and - * io2.in.create_guid are checked + * only io.in.durable_handle_v2 and + * io.in.create_guid are checked */ - io2.in.durable_open_v2 = false; - io2.in.durable_handle_v2 = h; - io2.in.create_guid = io1.in.create_guid; + io.in.durable_open_v2 = false; + io.in.durable_handle_v2 = h; + io.in.create_guid = create_guid; h = NULL; - status = smb2_create(tree, mem_ctx, &io2); + status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io1.out.durable_open, false); - CHECK_VAL(io1.out.durable_open_v2, true); - CHECK_VAL(io1.out.persistent_open, false); - CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b")); - _h = io2.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.durable_open, false); + CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */ + CHECK_VAL(io.out.persistent_open, false); + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); + _h = io.out.file.handle; h = &_h; done: -- Samba Shared Repository