[PATCH 11/12] torture: add locking tests for copychunk
David Disseldorp
ddiss at samba.org
Wed Nov 7 17:19:45 MST 2012
---
selftest/knownfail | 2 +
source4/torture/smb2/ioctl.c | 200 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 202 insertions(+)
diff --git a/selftest/knownfail b/selftest/knownfail
index 8930baf..5c4ae5c 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -188,6 +188,8 @@
^samba4.smb2.ioctl.copy_chunk_overwrite\(dc\) # not supported by s4 ntvfs server
^samba4.smb2.ioctl.copy_chunk_append\(dc\) # not supported by s4 ntvfs server
^samba4.smb2.ioctl.copy_chunk_limits\(dc\) # not supported by s4 ntvfs server
+^samba4.smb2.ioctl.copy_chunk_src_lock\(dc\) # not supported by s4 ntvfs server
+^samba4.smb2.ioctl.copy_chunk_dest_lock\(dc\) # not supported by s4 ntvfs server
^samba3.smb2.dir.one
^samba3.smb2.dir.modify
^samba3.smb2.lease.request
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index ae727f0..6565be5 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -632,6 +632,202 @@ static bool test_ioctl_copy_chunk_limits(struct torture_context *torture,
return true;
}
+static bool test_ioctl_copy_chunk_src_lck(struct torture_context *torture,
+ struct smb2_tree *tree)
+{
+ struct smb2_handle src_h;
+ struct smb2_handle src_h2;
+ struct smb2_handle dest_h;
+ NTSTATUS status;
+ union smb_ioctl ioctl;
+ TALLOC_CTX *tmp_ctx = talloc_new(tree);
+ struct srv_copychunk_copy cc_copy;
+ struct srv_copychunk_rsp cc_rsp;
+ enum ndr_err_code ndr_ret;
+ bool ok;
+ struct smb2_lock lck;
+ struct smb2_lock_element el[1];
+
+ ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
+ 1, /* chunks */
+ &src_h, 4096, /* src file */
+ &dest_h, 0, /* dest file */
+ &cc_copy,
+ &ioctl);
+ if (!ok) {
+ return false;
+ }
+
+ cc_copy.chunks[0].source_off = 0;
+ cc_copy.chunks[0].target_off = 0;
+ cc_copy.chunks[0].length = 4096;
+
+ /* open and lock the copychunk src file */
+ status = torture_smb2_testfile(tree, FNAME, &src_h2);
+ torture_assert_ntstatus_ok(torture, status, "2nd src open");
+
+ lck.in.lock_count = 0x0001;
+ lck.in.lock_sequence = 0x00000000;
+ lck.in.file.handle = src_h2;
+ lck.in.locks = el;
+ el[0].offset = cc_copy.chunks[0].source_off;
+ el[0].length = cc_copy.chunks[0].length;
+ el[0].reserved = 0;
+ el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
+
+ status = smb2_lock(tree, &lck);
+ torture_assert_ntstatus_ok(torture, status, "lock");
+
+ ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+ &cc_copy,
+ (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
+ torture_assert_ndr_success(torture, ndr_ret,
+ "ndr_push_srv_copychunk_copy");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_equal(torture, status,
+ NT_STATUS_FILE_LOCK_CONFLICT,
+ "FSCTL_SRV_COPYCHUNK locked");
+
+ lck.in.lock_count = 0x0001;
+ lck.in.lock_sequence = 0x00000001;
+ lck.in.file.handle = src_h2;
+ lck.in.locks = el;
+ el[0].offset = cc_copy.chunks[0].source_off;
+ el[0].length = cc_copy.chunks[0].length;
+ el[0].reserved = 0;
+ el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
+ status = smb2_lock(tree, &lck);
+ torture_assert_ntstatus_ok(torture, status, "unlock");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_ok(torture, status,
+ "FSCTL_SRV_COPYCHUNK unlocked");
+
+ ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
+ &cc_rsp,
+ (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
+ torture_assert_ndr_success(torture, ndr_ret,
+ "ndr_pull_srv_copychunk_rsp");
+
+ ok = check_copy_chunk_rsp(torture, &cc_rsp,
+ 1, /* chunks written */
+ 0, /* chunk bytes unsuccessfully written */
+ 4096); /* total bytes written */
+ if (!ok) {
+ return false;
+ }
+
+ ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
+ if (!ok) {
+ return false;
+ }
+
+ smb2_util_close(tree, src_h2);
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+ talloc_free(tmp_ctx);
+ return true;
+}
+
+static bool test_ioctl_copy_chunk_dest_lck(struct torture_context *torture,
+ struct smb2_tree *tree)
+{
+ struct smb2_handle src_h;
+ struct smb2_handle dest_h;
+ struct smb2_handle dest_h2;
+ NTSTATUS status;
+ union smb_ioctl ioctl;
+ TALLOC_CTX *tmp_ctx = talloc_new(tree);
+ struct srv_copychunk_copy cc_copy;
+ struct srv_copychunk_rsp cc_rsp;
+ enum ndr_err_code ndr_ret;
+ bool ok;
+ struct smb2_lock lck;
+ struct smb2_lock_element el[1];
+
+ ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
+ 1, /* chunks */
+ &src_h, 4096, /* src file */
+ &dest_h, 4096, /* dest file */
+ &cc_copy,
+ &ioctl);
+ if (!ok) {
+ return false;
+ }
+
+ cc_copy.chunks[0].source_off = 0;
+ cc_copy.chunks[0].target_off = 0;
+ cc_copy.chunks[0].length = 4096;
+
+ /* open and lock the copychunk dest file */
+ status = torture_smb2_testfile(tree, FNAME2, &dest_h2);
+ torture_assert_ntstatus_ok(torture, status, "2nd src open");
+
+ lck.in.lock_count = 0x0001;
+ lck.in.lock_sequence = 0x00000000;
+ lck.in.file.handle = dest_h2;
+ lck.in.locks = el;
+ el[0].offset = cc_copy.chunks[0].target_off;
+ el[0].length = cc_copy.chunks[0].length;
+ el[0].reserved = 0;
+ el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
+
+ status = smb2_lock(tree, &lck);
+ torture_assert_ntstatus_ok(torture, status, "lock");
+
+ ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+ &cc_copy,
+ (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
+ torture_assert_ndr_success(torture, ndr_ret,
+ "ndr_push_srv_copychunk_copy");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_equal(torture, status,
+ NT_STATUS_FILE_LOCK_CONFLICT,
+ "FSCTL_SRV_COPYCHUNK locked");
+
+ lck.in.lock_count = 0x0001;
+ lck.in.lock_sequence = 0x00000001;
+ lck.in.file.handle = dest_h2;
+ lck.in.locks = el;
+ el[0].offset = cc_copy.chunks[0].target_off;
+ el[0].length = cc_copy.chunks[0].length;
+ el[0].reserved = 0;
+ el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
+ status = smb2_lock(tree, &lck);
+ torture_assert_ntstatus_ok(torture, status, "unlock");
+
+ status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+ torture_assert_ntstatus_ok(torture, status,
+ "FSCTL_SRV_COPYCHUNK unlocked");
+
+ ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
+ &cc_rsp,
+ (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
+ torture_assert_ndr_success(torture, ndr_ret,
+ "ndr_pull_srv_copychunk_rsp");
+
+ ok = check_copy_chunk_rsp(torture, &cc_rsp,
+ 1, /* chunks written */
+ 0, /* chunk bytes unsuccessfully written */
+ 4096); /* total bytes written */
+ if (!ok) {
+ return false;
+ }
+
+ ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
+ if (!ok) {
+ return false;
+ }
+
+ smb2_util_close(tree, dest_h2);
+ smb2_util_close(tree, src_h);
+ smb2_util_close(tree, dest_h);
+ talloc_free(tmp_ctx);
+ return true;
+}
+
/*
basic testing of SMB2 ioctls
*/
@@ -655,6 +851,10 @@ struct torture_suite *torture_smb2_ioctl_init(void)
test_ioctl_copy_chunk_append);
torture_suite_add_1smb2_test(suite, "copy_chunk_limits",
test_ioctl_copy_chunk_limits);
+ torture_suite_add_1smb2_test(suite, "copy_chunk_src_lock",
+ test_ioctl_copy_chunk_src_lck);
+ torture_suite_add_1smb2_test(suite, "copy_chunk_dest_lock",
+ test_ioctl_copy_chunk_dest_lck);
suite->description = talloc_strdup(suite, "SMB2-IOCTL tests");
--
1.7.10.4
More information about the samba-technical
mailing list