From 66e933c7de32a4207d7a6b25e3f31ed8353d7414 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 02:03:28 +0100 Subject: [PATCH 1/7] libcli: add smbXcli_req_endtime Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 94ad5ee662a5bfe1c79d8a9c3fcf51d0a1d652c7) --- libcli/smb/smbXcli_base.c | 10 ++++++++++ libcli/smb/smbXcli_base.h | 1 + 2 files changed, 11 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index ad1b67b8476..09bee755f80 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -227,6 +227,8 @@ struct smbXcli_req_state { struct tevent_req *write_req; + struct timeval endtime; + struct { /* Space for the header including the wct */ uint8_t hdr[HDR_VWV]; @@ -2892,6 +2894,14 @@ static void smb2cli_req_cancel_done(struct tevent_req *subreq) TALLOC_FREE(subreq); } +struct timeval smbXcli_req_endtime(struct tevent_req *req) +{ + struct smbXcli_req_state *state = tevent_req_data( + req, struct smbXcli_req_state); + + return state->endtime; +} + struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbXcli_conn *conn, diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 20ef26e3353..536c7ab60f4 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -74,6 +74,7 @@ NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn, void smbXcli_req_unset_pending(struct tevent_req *req); bool smbXcli_req_set_pending(struct tevent_req *req); +struct timeval smbXcli_req_endtime(struct tevent_req *req); uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn); uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn); -- 2.17.2 From 6c6e1c2a61de54ca179156e8aecc080e37a1d0eb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 02:04:51 +0100 Subject: [PATCH 2/7] libcli: fill endtime if smbXcli_req_create() timeout is non-zero Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit e7eec24d27b8694fd7626577a2aca05e99045964) --- libcli/smb/smbXcli_base.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 09bee755f80..2c6c7d9bcfd 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -1585,10 +1585,8 @@ struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx, state->smb1.iov_count = iov_count + 4; if (timeout_msec > 0) { - struct timeval endtime; - - endtime = timeval_current_ofs_msec(timeout_msec); - if (!tevent_req_set_endtime(req, ev, endtime)) { + state->endtime = timeval_current_ofs_msec(timeout_msec); + if (!tevent_req_set_endtime(req, ev, state->endtime)) { return req; } } @@ -3051,10 +3049,8 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, } if (timeout_msec > 0) { - struct timeval endtime; - - endtime = timeval_current_ofs_msec(timeout_msec); - if (!tevent_req_set_endtime(req, ev, endtime)) { + state->endtime = timeval_current_ofs_msec(timeout_msec); + if (!tevent_req_set_endtime(req, ev, state->endtime)) { return req; } } -- 2.17.2 From 0a5687155447fe08c0f6ea0990d9d65c35da5001 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 02:05:45 +0100 Subject: [PATCH 3/7] s4:libcli/smb2: reapply request endtime tevent_req_finish() removed a possible request timeout, make sure to reinstall it. This happened when an interim SMB2 response was received. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit a6de555c51ca34ef24ac4b4cb672cd748d3197a1) --- source4/libcli/smb2/transport.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 1d08289341b..18cc490be48 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -293,7 +293,24 @@ static void smb2_request_done(struct tevent_req *subreq) req->status = smb2cli_req_recv(req->subreq, req, &req->recv_iov, NULL, 0); if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { + struct timeval endtime = smbXcli_req_endtime(subreq); + bool ok; + req->cancel.can_cancel = true; + if (timeval_is_zero(&endtime)) { + return; + } + + ok = tevent_req_set_endtime( + subreq, req->transport->ev, endtime); + if (!ok) { + req->status = NT_STATUS_INTERNAL_ERROR; + req->state = SMB2_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + return; + } return; } TALLOC_FREE(req->subreq); -- 2.17.2 From 2564f25ed0a68c9d4728d9a381b8c939c26feae5 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 19:28:42 +0100 Subject: [PATCH 4/7] vfs_delay_inject: implement pread_send and pwrite_send Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 35f9bc06722fb07143c832442d784beb204bd367) --- source3/modules/vfs_delay_inject.c | 262 +++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) diff --git a/source3/modules/vfs_delay_inject.c b/source3/modules/vfs_delay_inject.c index 21fea9b10f4..d561fadb03b 100644 --- a/source3/modules/vfs_delay_inject.c +++ b/source3/modules/vfs_delay_inject.c @@ -19,6 +19,7 @@ #include "includes.h" #include "smbd/smbd.h" +#include "lib/util/tevent_unix.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS @@ -46,8 +47,269 @@ static int vfs_delay_inject_ntimes(vfs_handle_struct *handle, return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft); } +struct vfs_delay_inject_pread_state { + struct tevent_context *ev; + struct vfs_handle_struct *handle; + struct files_struct *fsp; + void *data; + size_t n; + off_t offset; + ssize_t ret; + struct vfs_aio_state vfs_aio_state; +}; + +static void vfs_delay_inject_pread_wait_done(struct tevent_req *subreq); +static void vfs_delay_inject_pread_done(struct tevent_req *subreq); + +static struct tevent_req *vfs_delay_inject_pread_send( + struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *fsp, + void *data, + size_t n, + off_t offset) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct vfs_delay_inject_pread_state *state = NULL; + int delay; + struct timeval delay_tv; + + delay = lp_parm_int( + SNUM(handle->conn), "delay_inject", "pread_send", 0); + delay_tv = tevent_timeval_current_ofs(delay / 1000, + (delay * 1000) % 1000000); + + req = tevent_req_create(mem_ctx, &state, + struct vfs_delay_inject_pread_state); + if (req == NULL) { + return NULL; + } + *state = (struct vfs_delay_inject_pread_state) { + .ev = ev, + .handle = handle, + .fsp = fsp, + .data = data, + .n = n, + .offset = offset, + }; + + if (delay == 0) { + subreq = SMB_VFS_NEXT_PREAD_SEND(state, + state->ev, + state->handle, + state->fsp, + state->data, + state->n, + state->offset); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + vfs_delay_inject_pread_done, + req); + return req; + } + + subreq = tevent_wakeup_send(state, ev, delay_tv); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, vfs_delay_inject_pread_wait_done, req); + return req; +} + + +static void vfs_delay_inject_pread_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct vfs_delay_inject_pread_state *state = tevent_req_data( + req, struct vfs_delay_inject_pread_state); + bool ok; + + ok = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + tevent_req_error(req, EIO); + return; + } + + subreq = SMB_VFS_NEXT_PREAD_SEND(state, + state->ev, + state->handle, + state->fsp, + state->data, + state->n, + state->offset); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, vfs_delay_inject_pread_done, req); +} + +static void vfs_delay_inject_pread_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct vfs_delay_inject_pread_state *state = tevent_req_data( + req, struct vfs_delay_inject_pread_state); + + state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state); + TALLOC_FREE(subreq); + + tevent_req_done(req); +} + +static ssize_t vfs_delay_inject_pread_recv(struct tevent_req *req, + struct vfs_aio_state *vfs_aio_state) +{ + struct vfs_delay_inject_pread_state *state = tevent_req_data( + req, struct vfs_delay_inject_pread_state); + + if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { + return -1; + } + + *vfs_aio_state = state->vfs_aio_state; + return state->ret; +} + +struct vfs_delay_inject_pwrite_state { + struct tevent_context *ev; + struct vfs_handle_struct *handle; + struct files_struct *fsp; + const void *data; + size_t n; + off_t offset; + ssize_t ret; + struct vfs_aio_state vfs_aio_state; +}; + +static void vfs_delay_inject_pwrite_wait_done(struct tevent_req *subreq); +static void vfs_delay_inject_pwrite_done(struct tevent_req *subreq); + +static struct tevent_req *vfs_delay_inject_pwrite_send( + struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *fsp, + const void *data, + size_t n, + off_t offset) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct vfs_delay_inject_pwrite_state *state = NULL; + int delay; + struct timeval delay_tv; + + delay = lp_parm_int( + SNUM(handle->conn), "delay_inject", "pwrite_send", 0); + delay_tv = tevent_timeval_current_ofs(delay / 1000, + (delay * 1000) % 1000000); + + req = tevent_req_create(mem_ctx, &state, + struct vfs_delay_inject_pwrite_state); + if (req == NULL) { + return NULL; + } + *state = (struct vfs_delay_inject_pwrite_state) { + .ev = ev, + .handle = handle, + .fsp = fsp, + .data = data, + .n = n, + .offset = offset, + }; + + if (delay == 0) { + subreq = SMB_VFS_NEXT_PWRITE_SEND(state, + state->ev, + state->handle, + state->fsp, + state->data, + state->n, + state->offset); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + vfs_delay_inject_pwrite_done, + req); + return req; + } + + subreq = tevent_wakeup_send(state, ev, delay_tv); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback( + subreq, vfs_delay_inject_pwrite_wait_done, req); + return req; +} + + +static void vfs_delay_inject_pwrite_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct vfs_delay_inject_pwrite_state *state = tevent_req_data( + req, struct vfs_delay_inject_pwrite_state); + bool ok; + + ok = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + tevent_req_error(req, EIO); + return; + } + + subreq = SMB_VFS_NEXT_PWRITE_SEND(state, + state->ev, + state->handle, + state->fsp, + state->data, + state->n, + state->offset); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, vfs_delay_inject_pwrite_done, req); +} + +static void vfs_delay_inject_pwrite_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct vfs_delay_inject_pwrite_state *state = tevent_req_data( + req, struct vfs_delay_inject_pwrite_state); + + state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state); + TALLOC_FREE(subreq); + + tevent_req_done(req); +} + +static ssize_t vfs_delay_inject_pwrite_recv(struct tevent_req *req, + struct vfs_aio_state *vfs_aio_state) +{ + struct vfs_delay_inject_pwrite_state *state = tevent_req_data( + req, struct vfs_delay_inject_pwrite_state); + + if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { + return -1; + } + + *vfs_aio_state = state->vfs_aio_state; + return state->ret; +} + static struct vfs_fn_pointers vfs_delay_inject_fns = { .ntimes_fn = vfs_delay_inject_ntimes, + .pread_send_fn = vfs_delay_inject_pread_send, + .pread_recv_fn = vfs_delay_inject_pread_recv, + .pwrite_send_fn = vfs_delay_inject_pwrite_send, + .pwrite_recv_fn = vfs_delay_inject_pwrite_recv, }; static_decl_vfs; -- 2.17.2 From a13ce4dbf37f8865cd6a611171779138fe27639a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 19:29:26 +0100 Subject: [PATCH 5/7] s4:torture/smb2/read: add test for cancelling SMB aio Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit e37ff8c5fe18d400e378bf2591e209b30473d9f9) --- selftest/knownfail.d/samba3.smb2 | 1 + selftest/target/Samba3.pm | 6 ++ source3/selftest/tests.py | 2 + source4/selftest/tests.py | 1 + source4/torture/smb2/read.c | 116 +++++++++++++++++++++++++++++++ source4/torture/smb2/smb2.c | 1 + 6 files changed, 127 insertions(+) create mode 100644 selftest/knownfail.d/samba3.smb2 diff --git a/selftest/knownfail.d/samba3.smb2 b/selftest/knownfail.d/samba3.smb2 new file mode 100644 index 00000000000..f4e2ecf3da4 --- /dev/null +++ b/selftest/knownfail.d/samba3.smb2 @@ -0,0 +1 @@ +^samba3.smb2.aio_delay.aio_cancel\(nt4_dc\) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index a5835d2f309..50f579ade3e 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -2201,6 +2201,12 @@ sub provision($$$$$$$$$) kernel oplocks = no posix locking = no include = $libdir/delay_inject.conf + +[aio_delay_inject] + copy = tmp + vfs objects = delay_inject + delay_inject:pread_send = 2000 + delay_inject:pwrite_send = 2000 "; close(CONF); diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index ced19268611..9b665907395 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -583,6 +583,8 @@ tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/streams_xattr -U$USERNAME%$PASSWORD', 'streams_xattr') + elif t == "smb2.aio_delay": + plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/aio_delay_inject -U$USERNAME%$PASSWORD') else: plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3a07eee4750..855766dfc9b 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -316,6 +316,7 @@ smb2_s3only = [ "smb2.credits", "smb2.kernel-oplocks", "smb2.durable-v2-delay", + "smb2.aio_delay", ] smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only] diff --git a/source4/torture/smb2/read.c b/source4/torture/smb2/read.c index 4bf3bb74be0..b26bc18ddac 100644 --- a/source4/torture/smb2/read.c +++ b/source4/torture/smb2/read.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include #include "torture/torture.h" #include "torture/smb2/proto.h" @@ -317,3 +318,118 @@ struct torture_suite *torture_smb2_read_init(TALLOC_CTX *ctx) return suite; } +static bool test_aio_cancel(struct torture_context *tctx, + struct smb2_tree *tree) +{ + struct smb2_handle h; + uint8_t buf[64 * 1024]; + struct smb2_read r; + struct smb2_request *req = NULL; + int rc; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCT(buf); + + smb2_util_unlink(tree, FNAME); + + status = torture_smb2_testfile(tree, FNAME, &h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "torture_smb2_testfile failed\n"); + + status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf)); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_write failed\n"); + + status = smb2_util_close(tree, h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_close failed\n"); + + status = torture_smb2_testfile_access( + tree, FNAME, &h, SEC_RIGHTS_FILE_ALL); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "torture_smb2_testfile_access failed\n"); + + r = (struct smb2_read) { + .in.file.handle = h, + .in.length = 1, + .in.offset = 0, + .in.min_count = 1, + }; + + req = smb2_read_send(tree, &r); + torture_assert_goto( + tctx, + req != NULL, + ret, + done, + "smb2_read_send failed\n"); + + while (!req->cancel.can_cancel) { + rc = tevent_loop_once(tctx->ev); + torture_assert_goto( + tctx, + rc == 0, + ret, + done, + "tevent_loop_once failed\n"); + } + + status = smb2_cancel(req); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_cancel failed\n"); + + status = smb2_read_recv(req, tree, &r); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_read_recv failed\n"); + + status = smb2_util_close(tree, h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_close failed\n"); + +done: + smb2_util_unlink(tree, FNAME); + return ret; +} + +/* + * aio testing against share with VFS module "delay_inject" + */ +struct torture_suite *torture_smb2_aio_delay_init(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "aio_delay"); + + torture_suite_add_1smb2_test(suite, "aio_cancel", test_aio_cancel); + + suite->description = talloc_strdup(suite, "SMB2 delayed aio tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 12f7edf8f86..6f9884e3c27 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -152,6 +152,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "setinfo", torture_smb2_setinfo); torture_suite_add_suite(suite, torture_smb2_lock_init(suite)); torture_suite_add_suite(suite, torture_smb2_read_init(suite)); + torture_suite_add_suite(suite, torture_smb2_aio_delay_init(suite)); torture_suite_add_suite(suite, torture_smb2_create_init(suite)); torture_suite_add_suite(suite, torture_smb2_acls_init(suite)); torture_suite_add_suite(suite, torture_smb2_notify_init(suite)); -- 2.17.2 From bf518c3ad43ffc1fcb6fa4f37bc07afdb7c28c5b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 19:35:59 +0100 Subject: [PATCH 6/7] s3:smbd: fix SMB2 aio cancelling As we currently don't attempt to cancel the internal aio request, we must ignore the SMB2 cancel request and continue to process the SMB2 request, cf MS-SM2 3.3.5.16: If the target request is not successfully canceled, processing of the target request MUST continue and no response is sent to the cancel request. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 07eb805cde4db6ac74740e3cfbc56ab6f8e2118a) --- selftest/knownfail.d/samba3.smb2 | 1 - source3/smbd/aio.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) delete mode 100644 selftest/knownfail.d/samba3.smb2 diff --git a/selftest/knownfail.d/samba3.smb2 b/selftest/knownfail.d/samba3.smb2 deleted file mode 100644 index f4e2ecf3da4..00000000000 --- a/selftest/knownfail.d/samba3.smb2 +++ /dev/null @@ -1 +0,0 @@ -^samba3.smb2.aio_delay.aio_cancel\(nt4_dc\) diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index c066ea1a978..ffa2a683b46 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -622,12 +622,16 @@ bool cancel_smb2_aio(struct smb_request *smbreq) } /* - * We let the aio request run. Setting fsp to NULL has the - * effect that the _done routines don't send anything out. + * We let the aio request run and don't try to cancel it which means + * processing of the SMB2 request must continue as normal, cf MS-SMB2 + * 3.3.5.16: + * + * If the target request is not successfully canceled, processing of + * the target request MUST continue and no response is sent to the + * cancel request. */ - aio_ex->fsp = NULL; - return true; + return false; } static void aio_pread_smb2_done(struct tevent_req *req); -- 2.17.2 From dff721ec0f6b351e0df4f88af879f6520fd5cc60 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 31 Oct 2018 10:21:31 +0100 Subject: [PATCH 7/7] s3:smbd: remove now unused check if fsp is NULL This was used internally to mark an aio request as cancelled. As the aio cancellation functionality has been removed, we can now also remove this check. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 3fa45900c0ada6596daf09aa4c5054974f3394b0) --- source3/smbd/aio.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index ffa2a683b46..29723d23fa5 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -750,14 +750,6 @@ static void aio_pread_smb2_done(struct tevent_req *req) DEBUG(10, ("pread_recv returned %d, err = %s\n", (int)nread, (nread == -1) ? strerror(vfs_aio_state.error) : "no error")); - if (fsp == NULL) { - DEBUG(3, ("%s: request cancelled (mid[%ju])\n", - __func__, (uintmax_t)aio_ex->smbreq->mid)); - TALLOC_FREE(aio_ex); - tevent_req_nterror(subreq, NT_STATUS_INTERNAL_ERROR); - return; - } - /* Common error or success code processing for async or sync read returns. */ @@ -913,14 +905,6 @@ static void aio_pwrite_smb2_done(struct tevent_req *req) DEBUG(10, ("pwrite_recv returned %d, err = %s\n", (int)nwritten, (nwritten == -1) ? strerror(err) : "no error")); - if (fsp == NULL) { - DEBUG(3, ("%s: request cancelled (mid[%ju])\n", - __func__, (uintmax_t)aio_ex->smbreq->mid)); - TALLOC_FREE(aio_ex); - tevent_req_nterror(subreq, NT_STATUS_INTERNAL_ERROR); - return; - } - mark_file_modified(fsp); status = smb2_write_complete_nosync(subreq, nwritten, err); -- 2.17.2