[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Sep 8 13:41:04 MDT 2014


The branch, master has been updated
       via  cd87d9f torture: basic FSCTL_SET_ZERO_DATA tests
       via  5d8bfb5 torture: add file zero-range checker
       via  750e67a torture: malformed FSCTL_QUERY_ALLOCATED_RANGES tests
       via  10e86bf torture: basic FSCTL_QUERY_ALLOCATED_RANGES test
       via  9a9cae9 torture: split pattern write into helper function
       via  3fcbfa9 torture: test oversize FSCTL_SET_SPARSE request
      from  abe499b torture: Correctly initialize array size

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cd87d9f78228a9eb3ebbc0deda41e9c1094905ca
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:20 2014 +0200

    torture: basic FSCTL_SET_ZERO_DATA tests
    
    Attempt to punch holes in a file using FSCTL_SET_ZERO_DATA. Check that
    the resulting data is zeroed. Also confirm that when the file is marked
    sparse, the zeroed range is no longer allocated.
    Finally, check that removing the sparse flag causes any holes to be
    unsparsed.
    
    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): Mon Sep  8 21:40:34 CEST 2014 on sn-devel-104

commit 5d8bfb5c41bbddb3c404bd177048fe2e396ce8f2
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:19 2014 +0200

    torture: add file zero-range checker
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 750e67aeb2f86a6b67dc949e2585ee9a585a628e
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:18 2014 +0200

    torture: malformed FSCTL_QUERY_ALLOCATED_RANGES tests
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 10e86bf481d09913c174f92847c5c1b879f3688c
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:17 2014 +0200

    torture: basic FSCTL_QUERY_ALLOCATED_RANGES test
    
    Add a test and helper function for FSCTL_QUERY_ALLOCATED_RANGES
    requests.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9a9cae9555cc612e7f8d227595a0b931a41801dc
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:16 2014 +0200

    torture: split pattern write into helper function
    
    This allows for patterned writes after file creation, as needed for
    sparse file integrity testing.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3fcbfa967ac61da85a959fada5a4d92b54f459eb
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 2 20:07:15 2014 +0200

    torture: test oversize FSCTL_SET_SPARSE request
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 source4/torture/smb2/ioctl.c |  610 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 593 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index df98b04..344ff0e 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -119,6 +119,42 @@ static uint64_t patt_hash(uint64_t off)
 	return off;
 }
 
+static bool write_pattern(struct torture_context *torture,
+			  struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
+			  struct smb2_handle h, uint64_t off, uint64_t len,
+			  uint64_t patt_off)
+{
+	NTSTATUS status;
+	uint64_t i;
+	uint8_t *buf;
+	uint64_t buf_off = 0;
+
+	if (len == 0) {
+		return true;
+	}
+
+	buf = talloc_zero_size(mem_ctx, len);
+	torture_assert(torture, (buf != NULL), "no memory for file data buf");
+
+	for (i = 0; i <= len - 8; i += 8) {
+		SBVAL(buf, i, patt_hash(patt_off));
+		patt_off += 8;
+	}
+
+	while (len > 0) {
+		uint64_t io_sz = MIN(1024 * 1024, len);
+		status = smb2_util_write(tree, h,
+					 buf + buf_off, off, io_sz);
+		torture_assert_ntstatus_ok(torture, status, "file write");
+
+		len -= io_sz;
+		buf_off += io_sz;
+		off += io_sz;
+	}
+
+	return true;
+}
+
 static bool check_pattern(struct torture_context *torture,
 			  struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
 			  struct smb2_handle h, uint64_t off, uint64_t len,
@@ -150,6 +186,36 @@ static bool check_pattern(struct torture_context *torture,
 	return true;
 }
 
+static bool check_zero(struct torture_context *torture,
+		       struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
+		       struct smb2_handle h, uint64_t off, uint64_t len)
+{
+	uint64_t i;
+	struct smb2_read r;
+	NTSTATUS status;
+
+	ZERO_STRUCT(r);
+	r.in.file.handle = h;
+	r.in.length      = len;
+	r.in.offset      = off;
+	status = smb2_read(tree, mem_ctx, &r);
+	torture_assert_ntstatus_ok(torture, status, "read");
+
+	torture_assert_u64_equal(torture, r.out.data.length, len,
+				 "read data len mismatch");
+
+	for (i = 0; i <= len - 8; i += 8) {
+		uint64_t data = BVAL(r.out.data.data, i);
+		torture_assert_u64_equal(torture, data, 0,
+					 talloc_asprintf(mem_ctx, "read zero "
+							 "bad at %llu\n",
+							 (unsigned long long)i));
+	}
+
+	talloc_free(r.out.data.data);
+	return true;
+}
+
 static bool test_setup_open(struct torture_context *torture,
 			    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
 			    const char *fname,
@@ -189,11 +255,7 @@ static bool test_setup_create_fill(struct torture_context *torture,
 				   uint32_t desired_access,
 				   uint32_t file_attributes)
 {
-	NTSTATUS status;
 	bool ok;
-	uint64_t i;
-	uint8_t *buf = talloc_zero_size(mem_ctx, size);
-	torture_assert(torture, (buf != NULL), "no memory for file data buf");
 
 	smb2_util_unlink(tree, fname);
 
@@ -205,19 +267,8 @@ static bool test_setup_create_fill(struct torture_context *torture,
 	torture_assert(torture, ok, "file open");
 
 	if (size > 0) {
-		uint64_t cur_off = 0;
-		for (i = 0; i <= size - 8; i += 8) {
-			SBVAL(buf, i, patt_hash(i));
-		}
-		while (size > 0) {
-			uint64_t io_sz = MIN(1024 * 1024, size);
-			status = smb2_util_write(tree, *fh,
-						 buf + cur_off, cur_off, io_sz);
-			torture_assert_ntstatus_ok(torture, status, "file write");
-
-			size -= io_sz;
-			cur_off += io_sz;
-		}
+		ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
+		torture_assert(torture, ok, "write pattern");
 	}
 	return true;
 }
@@ -2718,6 +2769,523 @@ static bool test_ioctl_sparse_set_nobuf(struct torture_context *torture,
 	return true;
 }
 
+static bool test_ioctl_sparse_set_oversize(struct torture_context *torture,
+					   struct smb2_tree *tree)
+{
+	struct smb2_handle fh;
+	union smb_ioctl ioctl;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx = talloc_new(tree);
+	bool ok;
+	bool is_sparse;
+	uint8_t buf[100];
+
+	ok = test_setup_create_fill(torture, tree, tmp_ctx,
+				    FNAME, &fh, 0, SEC_RIGHTS_FILE_ALL,
+				    FILE_ATTRIBUTE_NORMAL);
+	torture_assert(torture, ok, "setup file");
+
+	status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
+						&ok);
+	torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
+	if (!ok) {
+		smb2_util_close(tree, fh);
+		torture_skip(torture, "Sparse files not supported\n");
+	}
+
+	status = test_sparse_get(torture, tmp_ctx, tree, fh, &is_sparse);
+	torture_assert_ntstatus_ok(torture, status, "test_sparse_get");
+	torture_assert(torture, !is_sparse, "sparse attr before set");
+
+	ZERO_STRUCT(ioctl);
+	ioctl.smb2.level = RAW_IOCTL_SMB2;
+	ioctl.smb2.in.file.handle = fh;
+	ioctl.smb2.in.function = FSCTL_SET_SPARSE;
+	ioctl.smb2.in.max_response_size = 0;
+	ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+	/*
+	 * Attach a request buffer larger than FILE_SET_SPARSE_BUFFER
+	 * Windows still successfully processes the request.
+	 */
+	ZERO_ARRAY(buf);
+	buf[0] = 0xFF; /* attempt to set sparse */
+	ioctl.smb2.in.out.data = buf;
+	ioctl.smb2.in.out.length = ARRAY_SIZE(buf);
+
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_ok(torture, status, "FSCTL_SET_SPARSE");
+
+	status = test_sparse_get(torture, tmp_ctx, tree, fh, &is_sparse);
+	torture_assert_ntstatus_ok(torture, status, "test_sparse_get");
+	torture_assert(torture, is_sparse, "no sparse attr after set");
+
+	ZERO_STRUCT(ioctl);
+	ioctl.smb2.level = RAW_IOCTL_SMB2;
+	ioctl.smb2.in.file.handle = fh;
+	ioctl.smb2.in.function = FSCTL_SET_SPARSE;
+	ioctl.smb2.in.max_response_size = 0;
+	ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+	ZERO_ARRAY(buf); /* clear sparse */
+	ioctl.smb2.in.out.data = buf;
+	ioctl.smb2.in.out.length = ARRAY_SIZE(buf);
+
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_ok(torture, status, "FSCTL_SET_SPARSE");
+
+	status = test_sparse_get(torture, tmp_ctx, tree, fh, &is_sparse);
+	torture_assert_ntstatus_ok(torture, status, "test_sparse_get");
+	torture_assert(torture, !is_sparse, "sparse attr after clear");
+
+	smb2_util_close(tree, fh);
+	talloc_free(tmp_ctx);
+	return true;
+}
+
+static NTSTATUS test_ioctl_qar_req(struct torture_context *torture,
+				   TALLOC_CTX *mem_ctx,
+				   struct smb2_tree *tree,
+				   struct smb2_handle fh,
+				   int64_t req_off,
+				   int64_t req_len,
+				   struct file_alloced_range_buf **_rsp,
+				   uint64_t *_rsp_count)
+{
+	union smb_ioctl ioctl;
+	NTSTATUS status;
+	enum ndr_err_code ndr_ret;
+	struct file_alloced_range_buf far_buf;
+	struct file_alloced_range_buf *far_rsp = NULL;
+	uint64_t far_count = 0;
+	int i;
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ZERO_STRUCT(ioctl);
+	ioctl.smb2.level = RAW_IOCTL_SMB2;
+	ioctl.smb2.in.file.handle = fh;
+	ioctl.smb2.in.function = FSCTL_QUERY_ALLOCATED_RANGES;
+	ioctl.smb2.in.max_response_size = 1024;
+	ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+	far_buf.file_off = req_off;
+	far_buf.len = req_len;
+
+	ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+				       &far_buf,
+			(ndr_push_flags_fn_t)ndr_push_file_alloced_range_buf);
+	if (ndr_ret != NDR_ERR_SUCCESS) {
+		status = NT_STATUS_UNSUCCESSFUL;
+		goto err_out;
+	}
+
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto err_out;
+	}
+
+	if (ioctl.smb2.out.out.length == 0) {
+		goto done;
+	}
+
+	if ((ioctl.smb2.out.out.length % sizeof(far_buf)) != 0) {
+		torture_comment(torture, "invalid qry_alloced rsp len: %zd:",
+				ioctl.smb2.out.out.length);
+		status = NT_STATUS_INVALID_VIEW_SIZE;
+		goto err_out;
+	}
+
+	far_count = (ioctl.smb2.out.out.length / sizeof(far_buf));
+	far_rsp = talloc_array(mem_ctx, struct file_alloced_range_buf,
+			       far_count);
+	if (far_rsp == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto err_out;
+	}
+
+	for (i = 0; i < far_count; i++) {
+		ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
+					       &far_rsp[i],
+			(ndr_pull_flags_fn_t)ndr_pull_file_alloced_range_buf);
+		if (ndr_ret != NDR_ERR_SUCCESS) {
+			status = NT_STATUS_UNSUCCESSFUL;
+			goto err_out;
+		}
+	}
+
+done:
+	*_rsp = far_rsp;
+	*_rsp_count = far_count;
+	status = NT_STATUS_OK;
+err_out:
+	talloc_free(tmp_ctx);
+	return status;
+}
+
+static bool test_ioctl_sparse_qar(struct torture_context *torture,
+				  struct smb2_tree *tree)
+{
+	struct smb2_handle fh;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx = talloc_new(tree);
+	bool ok;
+	bool is_sparse;
+	struct file_alloced_range_buf *far_rsp = NULL;
+	uint64_t far_count = 0;
+
+	/* zero length file, shouldn't have any ranges */
+	ok = test_setup_create_fill(torture, tree, tmp_ctx,
+				    FNAME, &fh, 0, SEC_RIGHTS_FILE_ALL,
+				    FILE_ATTRIBUTE_NORMAL);
+	torture_assert(torture, ok, "setup file");
+
+	status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
+						&ok);
+	torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
+	if (!ok) {
+		smb2_util_close(tree, fh);
+		torture_skip(torture, "Sparse files not supported\n");
+	}
+
+	status = test_sparse_get(torture, tmp_ctx, tree, fh, &is_sparse);
+	torture_assert_ntstatus_ok(torture, status, "test_sparse_get");
+	torture_assert(torture, !is_sparse, "sparse attr before set");
+
+	status = test_ioctl_qar_req(torture, tmp_ctx, tree, fh,
+				    0,	/* off */
+				    0,	/* len */
+				    &far_rsp,
+				    &far_count);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_QUERY_ALLOCATED_RANGES req failed");
+	torture_assert_u64_equal(torture, far_count, 0,
+				 "unexpected response len");
+
+	status = test_ioctl_qar_req(torture, tmp_ctx, tree, fh,
+				    0,	/* off */
+				    1024,	/* len */
+				    &far_rsp,
+				    &far_count);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_QUERY_ALLOCATED_RANGES req failed");
+	torture_assert_u64_equal(torture, far_count, 0,
+				 "unexpected response len");
+
+	status = test_ioctl_sparse_req(torture, tmp_ctx, tree, fh, true);
+	torture_assert_ntstatus_ok(torture, status, "FSCTL_SET_SPARSE");
+
+	status = test_sparse_get(torture, tmp_ctx, tree, fh, &is_sparse);
+	torture_assert_ntstatus_ok(torture, status, "test_sparse_get");
+	torture_assert(torture, is_sparse, "no sparse attr after set");
+
+	status = test_ioctl_qar_req(torture, tmp_ctx, tree, fh,
+				    0,	/* off */
+				    1024,	/* len */
+				    &far_rsp,
+				    &far_count);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_QUERY_ALLOCATED_RANGES req failed");
+	torture_assert_u64_equal(torture, far_count, 0,
+				 "unexpected response len");
+
+	/* write into the (now) sparse file at 4k offset */
+	ok = write_pattern(torture, tree, tmp_ctx, fh,
+			   4096,	/* off */
+			   1024,	/* len */
+			   4096);	/* pattern offset */
+	torture_assert(torture, ok, "write pattern");
+
+	/* query range before write off, it should be alloced */
+	status = test_ioctl_qar_req(torture, tmp_ctx, tree, fh,
+				    0,	/* off */
+				    4096,	/* len */
+				    &far_rsp,
+				    &far_count);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_QUERY_ALLOCATED_RANGES req failed");
+	torture_assert_u64_equal(torture, far_count, 1,
+				 "unexpected response len");
+	torture_assert_u64_equal(torture, far_rsp[0].file_off, 0, "far offset");
+	torture_assert_u64_equal(torture, far_rsp[0].len, 4096, "far len");
+
+	/*
+	 * Query range before and past write, it should be allocated up to the
+	 * end of the write.
+	 */
+	status = test_ioctl_qar_req(torture, tmp_ctx, tree, fh,
+				    0,	/* off */
+				    8192,	/* len */
+				    &far_rsp,
+				    &far_count);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_QUERY_ALLOCATED_RANGES req failed");
+	torture_assert_u64_equal(torture, far_count, 1,
+				 "unexpected response len");
+	torture_assert_u64_equal(torture, far_rsp[0].file_off, 0, "far offset");
+	torture_assert_u64_equal(torture, far_rsp[0].len, 5120, "far len");
+
+	smb2_util_close(tree, fh);
+	talloc_free(tmp_ctx);
+	return true;
+}
+
+static bool test_ioctl_sparse_qar_malformed(struct torture_context *torture,
+					    struct smb2_tree *tree)
+{
+	struct smb2_handle fh;
+	union smb_ioctl ioctl;
+	struct file_alloced_range_buf far_buf;
+	NTSTATUS status;
+	enum ndr_err_code ndr_ret;
+	TALLOC_CTX *tmp_ctx = talloc_new(tree);
+	bool ok;
+	size_t old_len;
+
+	/* zero length file, shouldn't have any ranges */
+	ok = test_setup_create_fill(torture, tree, tmp_ctx,
+				    FNAME, &fh, 0, SEC_RIGHTS_FILE_ALL,
+				    FILE_ATTRIBUTE_NORMAL);
+	torture_assert(torture, ok, "setup file");
+
+	status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
+						&ok);
+	torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
+	if (!ok) {
+		smb2_util_close(tree, fh);
+		torture_skip(torture, "Sparse files not supported\n");
+	}
+
+	/* no allocated ranges, no space for range response, should pass */
+	ZERO_STRUCT(ioctl);
+	ioctl.smb2.level = RAW_IOCTL_SMB2;
+	ioctl.smb2.in.file.handle = fh;
+	ioctl.smb2.in.function = FSCTL_QUERY_ALLOCATED_RANGES;
+	ioctl.smb2.in.max_response_size = 0;
+	ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+	far_buf.file_off = 0;
+	far_buf.len = 1024;
+	ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+				       &far_buf,
+			(ndr_push_flags_fn_t)ndr_push_file_alloced_range_buf);
+	torture_assert_ndr_success(torture, ndr_ret, "push far ndr buf");
+
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_ok(torture, status, "FSCTL_QUERY_ALLOCATED_RANGES");
+
+	/* write into the file at 4k offset */
+	ok = write_pattern(torture, tree, tmp_ctx, fh,
+			   0,		/* off */
+			   1024,	/* len */
+			   0);		/* pattern offset */
+	torture_assert(torture, ok, "write pattern");
+
+	/* allocated range, no space for range response, should fail */
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_equal(torture, status,
+				      NT_STATUS_BUFFER_TOO_SMALL, "qar no space");
+
+	/* oversize (2x) file_alloced_range_buf in request, should pass */
+	ioctl.smb2.in.max_response_size = 1024;
+	old_len = ioctl.smb2.in.out.length;
+	ok = data_blob_realloc(tmp_ctx, &ioctl.smb2.in.out,
+			       (ioctl.smb2.in.out.length * 2));
+	torture_assert(torture, ok, "2x data buffer");
+	memcpy(ioctl.smb2.in.out.data + old_len, ioctl.smb2.in.out.data,
+	       old_len);
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_ok(torture, status, "qar too big");
+
+	/* no file_alloced_range_buf in request, should fail */
+	data_blob_free(&ioctl.smb2.in.out);
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_equal(torture, status,
+				      NT_STATUS_INVALID_PARAMETER, "qar empty");
+
+	return true;
+}
+
+/*
+ * 2.3.57 FSCTL_SET_ZERO_DATA Request
+ *
+ * How an implementation zeros data within a file is implementation-dependent.
+ * A file system MAY choose to deallocate regions of disk space that have been
+ * zeroed.<50>
+ * <50>
+ * ... NTFS might deallocate disk space in the file if the file is stored on an
+ * NTFS volume, and the file is sparse or compressed. It will free any allocated
+ * space in chunks of 64 kilobytes that begin at an offset that is a multiple of
+ * 64 kilobytes. Other bytes in the file (prior to the first freed 64-kilobyte
+ * chunk and after the last freed 64-kilobyte chunk) will be zeroed but not
+ * deallocated.
+ */
+static NTSTATUS test_ioctl_zdata_req(struct torture_context *torture,
+				     TALLOC_CTX *mem_ctx,
+				     struct smb2_tree *tree,
+				     struct smb2_handle fh,
+				     int64_t off,
+				     int64_t beyond_final_zero)
+{
+	union smb_ioctl ioctl;
+	NTSTATUS status;
+	enum ndr_err_code ndr_ret;
+	struct file_zero_data_info zdata_info;
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ZERO_STRUCT(ioctl);
+	ioctl.smb2.level = RAW_IOCTL_SMB2;
+	ioctl.smb2.in.file.handle = fh;
+	ioctl.smb2.in.function = FSCTL_SET_ZERO_DATA;
+	ioctl.smb2.in.max_response_size = 0;
+	ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+	zdata_info.file_off = off;
+	zdata_info.beyond_final_zero = beyond_final_zero;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list