[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Thu Sep 22 22:24:03 UTC 2016
The branch, master has been updated
via bff3e5e torture/ioctl: switch sparse src/dest dup ext behaviour
via 710f067 torture/smb2/ioctl: don't check for untruncated dest failure
via 281ce60 torture/ioctl: add FSCTL_DUP_EXTENTS_TO_FILE tests
via dd02a5c libcli: add FILE_SUPPORTS_BLOCK_REFCOUNTING
via 0ad260e idl/ioctl: fix DUPLICATE_EXTENTS_TO_FILE fid field
via de7d7ac torture/ioctl: make sparse file support check generic
from 872a18b s4-torture: parse spoolss ndr packets using iremotewinspool calls
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit bff3e5efba36395a68f134bf58566611b65f35d5
Author: David Disseldorp <ddiss at samba.org>
Date: Thu Sep 22 00:00:07 2016 -0700
torture/ioctl: switch sparse src/dest dup ext behaviour
Contrary to 2.3.8 FSCTL_DUPLICATE_EXTENTS_TO_FILE
STATUS_NOT_SUPPORTED: Target file is sparse, while source is a
non-sparse file.
...Windows Server 2016 RTM appears to respond the other way around.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Fri Sep 23 00:23:09 CEST 2016 on sn-devel-144
commit 710f06702b9243dcbad3c2170271a030d2ff5a01
Author: David Disseldorp <ddiss at samba.org>
Date: Wed Sep 21 16:43:54 2016 -0700
torture/smb2/ioctl: don't check for untruncated dest failure
This should fail, but passes against WS2016 RTM...
2.3.8 FSCTL_DUPLICATE_EXTENTS_TO_FILE Reply:
The destination range extends beyond the target file's allocation size.
The caller might need to increase the target's allocation size before
using FSCTL_DUPLICATE_EXTENTS_TO_FILE.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 281ce600de9a8eafbecf82a5444e922a31311552
Author: David Disseldorp <ddiss at samba.org>
Date: Fri Jan 30 12:59:42 2015 +0100
torture/ioctl: add FSCTL_DUP_EXTENTS_TO_FILE tests
FSCTL_DUPLICATE_EXTENTS_TO_FILE is yet another copy offload mechanism,
this time only targeting COW FSes, where the request triggers a meta-
data only clone of the source range.
These tests attempt to cover most of the normal use cases, as well as
number of more exotic scenarios.
FILE_SUPPORTS_BLOCK_REFCOUNTING FS attribute presence is checked prior
to running the tests, so they will currently be skipped during Samba
self test (which lacks the flag).
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit dd02a5c91763e83bae2e453f801a0f868cd7ac29
Author: David Disseldorp <ddiss at samba.org>
Date: Mon Jul 20 17:56:34 2015 +0200
libcli: add FILE_SUPPORTS_BLOCK_REFCOUNTING
This FS attribute is used to advertise whether the server supports
FSCTL_DUP_EXTENTS_TO_FILE requests.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 0ad260e8f08b5f91e55468892e52dcfe9eee536a
Author: David Disseldorp <ddiss at samba.org>
Date: Tue Sep 20 09:10:37 2016 -0700
idl/ioctl: fix DUPLICATE_EXTENTS_TO_FILE fid field
This idl was based on an earlier draft documentation version. The
current documentation now shows:
"SourceFileID (16 bytes): An SMB2_FILEID structure, as specified in
[MS-SMB2] section 2.2.14.1, that is an identifier of the open to the
source file.".
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit de7d7ac608889784965f2fec08f9a721f20d22eb
Author: David Disseldorp <ddiss at samba.org>
Date: Mon Jul 20 17:52:44 2015 +0200
torture/ioctl: make sparse file support check generic
Rename test_ioctl_sparse_fs_supported() to test_ioctl_fs_supported() and
allow callers to query generic FileSystemAttributes flags via the new
fs_support_flags parameter.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
libcli/smb/smb_constants.h | 1 +
librpc/idl/ioctl.idl | 3 +-
source4/torture/smb2/ioctl.c | 1374 ++++++++++++++++++++++++++++++++++++++++--
3 files changed, 1332 insertions(+), 46 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index 2fcb590..b963c73 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -402,6 +402,7 @@ enum csc_policy {
#define FILE_SUPPORTS_ENCRYPTION 0x00020000
#define FILE_NAMED_STREAMS 0x00040000
#define FILE_READ_ONLY_VOLUME 0x00080000
+#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000
/* ShareAccess field. */
#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */
diff --git a/librpc/idl/ioctl.idl b/librpc/idl/ioctl.idl
index dbeef14..eb2dc8a 100644
--- a/librpc/idl/ioctl.idl
+++ b/librpc/idl/ioctl.idl
@@ -89,8 +89,7 @@ interface copychunk
} fsctl_offload_write_output;
typedef [public] struct {
- /* The FileHandle field is the volatile part of the fileid */
- hyper fid_volatile;
+ uint8 source_fid[16];
hyper source_off;
hyper target_off;
hyper byte_count;
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index 0aa3714..2baf7b6 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -3,7 +3,7 @@
test suite for SMB2 ioctl operations
- Copyright (C) David Disseldorp 2011-2015
+ Copyright (C) David Disseldorp 2011-2016
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2586,11 +2586,16 @@ static bool test_ioctl_network_interface_info(struct torture_context *torture,
return true;
}
-static NTSTATUS test_ioctl_sparse_fs_supported(struct torture_context *torture,
- struct smb2_tree *tree,
- TALLOC_CTX *mem_ctx,
- struct smb2_handle *fh,
- bool *sparse_support)
+/*
+ * Check whether all @fs_support_flags are set in the server's
+ * RAW_QFS_ATTRIBUTE_INFORMATION FileSystemAttributes response.
+ */
+static NTSTATUS test_ioctl_fs_supported(struct torture_context *torture,
+ struct smb2_tree *tree,
+ TALLOC_CTX *mem_ctx,
+ struct smb2_handle *fh,
+ uint64_t fs_support_flags,
+ bool *supported)
{
NTSTATUS status;
union smb_fsinfo info;
@@ -2603,10 +2608,11 @@ static NTSTATUS test_ioctl_sparse_fs_supported(struct torture_context *torture,
return status;
}
- if (info.attribute_info.out.fs_attr & FILE_SUPPORTS_SPARSE_FILES) {
- *sparse_support = true;
+ if ((info.attribute_info.out.fs_attr & fs_support_flags)
+ == fs_support_flags) {
+ *supported = true;
} else {
- *sparse_support = false;
+ *supported = false;
}
return NT_STATUS_OK;
}
@@ -2671,8 +2677,8 @@ static bool test_ioctl_sparse_file_flag(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -2722,8 +2728,8 @@ static bool test_ioctl_sparse_file_attr(struct torture_context *torture,
(FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_SPARSE));
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -2753,8 +2759,8 @@ static bool test_ioctl_sparse_dir_flag(struct torture_context *torture,
FILE_ATTRIBUTE_DIRECTORY);
torture_assert(torture, ok, "setup sparse directory");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &dirh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &dirh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, dirh);
@@ -2794,8 +2800,8 @@ static bool test_ioctl_sparse_set_nobuf(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -2864,8 +2870,8 @@ static bool test_ioctl_sparse_set_oversize(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3024,8 +3030,8 @@ static bool test_ioctl_sparse_qar(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3149,8 +3155,8 @@ static bool test_ioctl_sparse_qar_malformed(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3282,8 +3288,8 @@ static bool test_ioctl_sparse_punch(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3423,8 +3429,8 @@ static bool test_ioctl_sparse_hole_dealloc(struct torture_context *torture,
torture_assert(torture, ok, "setup file 1");
/* check for FS sparse file */
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3680,8 +3686,8 @@ static bool test_ioctl_sparse_compressed(struct torture_context *torture,
torture_assert(torture, ok, "setup file 1");
/* check for FS sparse file and compression support */
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -3788,8 +3794,8 @@ static bool test_ioctl_sparse_copy_chunk(struct torture_context *torture,
torture_assert(torture, ok, "setup file");
/* check for FS sparse file support */
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &src_h,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &src_h,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
smb2_util_close(tree, src_h);
if (!ok) {
@@ -3988,8 +3994,8 @@ static bool test_ioctl_sparse_punch_invalid(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -4096,8 +4102,8 @@ static bool test_ioctl_sparse_perms(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
smb2_util_close(tree, fh);
if (!ok) {
@@ -4339,8 +4345,8 @@ static bool test_ioctl_sparse_lck(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
torture_skip(torture, "Sparse files not supported\n");
@@ -4446,8 +4452,8 @@ static bool test_ioctl_sparse_qar_ob1(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
torture_skip(torture, "Sparse files not supported\n");
@@ -4602,8 +4608,8 @@ static bool test_ioctl_sparse_qar_multi(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
torture_skip(torture, "Sparse files not supported\n");
@@ -4675,8 +4681,8 @@ static bool test_ioctl_sparse_qar_overflow(struct torture_context *torture,
FILE_ATTRIBUTE_NORMAL);
torture_assert(torture, ok, "setup file");
- status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
- &ok);
+ status = test_ioctl_fs_supported(torture, tree, tmp_ctx, &fh,
+ FILE_SUPPORTS_SPARSE_FILES, &ok);
torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
if (!ok) {
smb2_util_close(tree, fh);
@@ -4846,8 +4852,1260 @@ static bool test_ioctl_trim_simple(struct torture_context *torture,
return true;
}
+static bool test_setup_dup_extents(struct torture_context *tctx,
+ struct smb2_tree *tree,
+ TALLOC_CTX *mem_ctx,
+ struct smb2_handle *src_h,
+ uint64_t src_size,
+ uint32_t src_desired_access,
+ struct smb2_handle *dest_h,
+ uint64_t dest_size,
+ uint32_t dest_desired_access,
+ struct fsctl_dup_extents_to_file *dup_ext_buf,
+ union smb_ioctl *ioctl)
+{
+ bool ok;
+
+ ok = test_setup_create_fill(tctx, tree, mem_ctx, FNAME,
+ src_h, src_size, src_desired_access,
+ FILE_ATTRIBUTE_NORMAL);
+ torture_assert(tctx, ok, "src file create fill");
+
+ ok = test_setup_create_fill(tctx, tree, mem_ctx, FNAME2,
+ dest_h, dest_size, dest_desired_access,
+ FILE_ATTRIBUTE_NORMAL);
+ torture_assert(tctx, ok, "dest file create fill");
+
+ ZERO_STRUCTPN(ioctl);
+ ioctl->smb2.level = RAW_IOCTL_SMB2;
+ ioctl->smb2.in.file.handle = *dest_h;
+ ioctl->smb2.in.function = FSCTL_DUP_EXTENTS_TO_FILE;
+ ioctl->smb2.in.max_response_size = 0;
+ ioctl->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+ ZERO_STRUCTPN(dup_ext_buf);
+ smb2_push_handle(dup_ext_buf->source_fid, src_h);
+
+ return true;
+}
+
+static bool test_ioctl_dup_extents_simple(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ struct smb2_handle src_h;
+ struct smb2_handle dest_h;
+ NTSTATUS status;
+ union smb_ioctl ioctl;
+ TALLOC_CTX *tmp_ctx = talloc_new(tree);
+ struct fsctl_dup_extents_to_file dup_ext_buf;
+ enum ndr_err_code ndr_ret;
+ union smb_fileinfo io;
+ union smb_setfileinfo sinfo;
+ bool ok;
+
+ ok = test_setup_dup_extents(tctx, tree, tmp_ctx,
+ &src_h, 4096, /* fill 4096 byte src file */
+ SEC_RIGHTS_FILE_ALL,
+ &dest_h, 0, /* 0 byte dest file */
+ SEC_RIGHTS_FILE_ALL,
+ &dup_ext_buf,
+ &ioctl);
+ if (!ok) {
+ torture_fail(tctx, "setup dup extents error");
+ }
+
+ status = test_ioctl_fs_supported(tctx, tree, tmp_ctx, &src_h,
+ FILE_SUPPORTS_BLOCK_REFCOUNTING, &ok);
+ torture_assert_ntstatus_ok(tctx, status, "SMB2_GETINFO_FS");
+ if (!ok) {
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+ talloc_free(tmp_ctx);
+ torture_skip(tctx, "block refcounting not supported\n");
+ }
+
+ /* extend dest to match src len */
+ ZERO_STRUCT(sinfo);
+ sinfo.end_of_file_info.level =
+ RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+ sinfo.end_of_file_info.in.file.handle = dest_h;
+ sinfo.end_of_file_info.in.size = 4096;
+ status = smb2_setinfo_file(tree, &sinfo);
+ torture_assert_ntstatus_ok(tctx, status, "smb2_setinfo_file");
+
+ /* copy all src file data */
+ dup_ext_buf.source_off = 0;
+ dup_ext_buf.target_off = 0;
+ dup_ext_buf.byte_count = 4096;
+
+ ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+ &dup_ext_buf,
+ (ndr_push_flags_fn_t)ndr_push_fsctl_dup_extents_to_file);
+ torture_assert_ndr_success(tctx, ndr_ret,
+ "ndr_push_fsctl_dup_extents_to_file");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_ok(tctx, status,
+ "FSCTL_DUP_EXTENTS_TO_FILE");
+
+ /* the file size shouldn't have been changed by this operation! */
+ ZERO_STRUCT(io);
+ io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ io.generic.in.file.handle = dest_h;
+ status = smb2_getinfo_file(tree, tmp_ctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "getinfo");
+ torture_assert_int_equal(tctx, (int)io.all_info2.out.size,
+ 4096, "size after IO");
+
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+
+ /* reopen for pattern check */
+ ok = test_setup_open(tctx, tree, tmp_ctx, FNAME, &src_h,
+ SEC_RIGHTS_FILE_ALL, FILE_ATTRIBUTE_NORMAL);
+ torture_assert_ntstatus_ok(tctx, status, "src open after dup");
+ ok = test_setup_open(tctx, tree, tmp_ctx, FNAME2, &dest_h,
+ SEC_RIGHTS_FILE_ALL, FILE_ATTRIBUTE_NORMAL);
+ torture_assert_ntstatus_ok(tctx, status, "dest open after dup");
+
+ ok = check_pattern(tctx, tree, tmp_ctx, src_h, 0, 4096, 0);
+ if (!ok) {
+ torture_fail(tctx, "inconsistent src file data");
+ }
+
+ ok = check_pattern(tctx, tree, tmp_ctx, dest_h, 0, 4096, 0);
+ if (!ok) {
+ torture_fail(tctx, "inconsistent dest file data");
+ }
+
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+ talloc_free(tmp_ctx);
+ return true;
+}
+
+static bool test_ioctl_dup_extents_len_beyond_dest(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ struct smb2_handle src_h;
+ struct smb2_handle dest_h;
+ NTSTATUS status;
+ union smb_ioctl ioctl;
+ TALLOC_CTX *tmp_ctx = talloc_new(tree);
+ struct fsctl_dup_extents_to_file dup_ext_buf;
+ enum ndr_err_code ndr_ret;
+ union smb_fileinfo io;
+ union smb_setfileinfo sinfo;
+ bool ok;
+
+ ok = test_setup_dup_extents(tctx, tree, tmp_ctx,
+ &src_h, 32768, /* fill 32768 byte src file */
+ SEC_RIGHTS_FILE_ALL,
+ &dest_h, 0, /* 0 byte dest file */
+ SEC_RIGHTS_FILE_ALL,
+ &dup_ext_buf,
+ &ioctl);
+ if (!ok) {
+ torture_fail(tctx, "setup dup extents error");
+ }
+
+ status = test_ioctl_fs_supported(tctx, tree, tmp_ctx, &src_h,
+ FILE_SUPPORTS_BLOCK_REFCOUNTING, &ok);
+ torture_assert_ntstatus_ok(tctx, status, "SMB2_GETINFO_FS");
+ if (!ok) {
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+ talloc_free(tmp_ctx);
+ torture_skip(tctx, "block refcounting not supported\n");
+ }
+
+ ZERO_STRUCT(io);
+ io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ io.generic.in.file.handle = dest_h;
+ status = smb2_getinfo_file(tree, tmp_ctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "getinfo");
+ torture_assert_int_equal(tctx, (int)io.all_info2.out.size,
+ 0, "size after IO");
+
+ /* copy all src file data */
+ dup_ext_buf.source_off = 0;
+ dup_ext_buf.target_off = 0;
+ dup_ext_buf.byte_count = 32768;
+
+ ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+ &dup_ext_buf,
+ (ndr_push_flags_fn_t)ndr_push_fsctl_dup_extents_to_file);
+ torture_assert_ndr_success(tctx, ndr_ret,
+ "ndr_push_fsctl_dup_extents_to_file");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+#if 0
+ /*
+ * 2.3.8 FSCTL_DUPLICATE_EXTENTS_TO_FILE Reply - this should fail, but
+ * passes against WS2016 RTM!
+ */
+ torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED,
+ "FSCTL_DUP_EXTENTS_TO_FILE");
+#endif
+
+ /* the file sizes shouldn't have been changed */
+ ZERO_STRUCT(io);
+ io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ io.generic.in.file.handle = src_h;
+ status = smb2_getinfo_file(tree, tmp_ctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "getinfo");
+ torture_assert_int_equal(tctx, (int)io.all_info2.out.size,
+ 32768, "size after IO");
+
+ ZERO_STRUCT(io);
+ io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ io.generic.in.file.handle = dest_h;
+ status = smb2_getinfo_file(tree, tmp_ctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "getinfo");
+ torture_assert_int_equal(tctx, (int)io.all_info2.out.size,
+ 0, "size after IO");
+
+ /* extend dest */
+ ZERO_STRUCT(sinfo);
+ sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+ sinfo.end_of_file_info.in.file.handle = dest_h;
+ sinfo.end_of_file_info.in.size = 32768;
+ status = smb2_setinfo_file(tree, &sinfo);
+ torture_assert_ntstatus_ok(tctx, status, "smb2_setinfo_file");
+
+ ok = check_zero(tctx, tree, tmp_ctx, dest_h, 0, 32768);
+ if (!ok) {
+ torture_fail(tctx, "inconsistent file data");
+ }
+
+ /* reissue ioctl, now with enough space */
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_ok(tctx, status,
+ "FSCTL_DUP_EXTENTS_TO_FILE");
+
+ ok = check_pattern(tctx, tree, tmp_ctx, dest_h, 0, 32768, 0);
+ if (!ok) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list