1*a90cf9f2SGordon Ross /*
2*a90cf9f2SGordon Ross * This file and its contents are supplied under the terms of the
3*a90cf9f2SGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
4*a90cf9f2SGordon Ross * You may only use this file in accordance with the terms of version
5*a90cf9f2SGordon Ross * 1.0 of the CDDL.
6*a90cf9f2SGordon Ross *
7*a90cf9f2SGordon Ross * A full copy of the text of the CDDL should have accompanied this
8*a90cf9f2SGordon Ross * source. A copy of the CDDL is also available via the Internet at
9*a90cf9f2SGordon Ross * http://www.illumos.org/license/CDDL.
10*a90cf9f2SGordon Ross */
11*a90cf9f2SGordon Ross
12*a90cf9f2SGordon Ross /*
13*a90cf9f2SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
14*a90cf9f2SGordon Ross */
15*a90cf9f2SGordon Ross
16*a90cf9f2SGordon Ross /*
17*a90cf9f2SGordon Ross * Dispatch function for SMB2_CANCEL
18*a90cf9f2SGordon Ross */
19*a90cf9f2SGordon Ross
20*a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
21*a90cf9f2SGordon Ross
22*a90cf9f2SGordon Ross static void smb2sr_cancel_async(smb_request_t *);
23*a90cf9f2SGordon Ross static void smb2sr_cancel_sync(smb_request_t *);
24*a90cf9f2SGordon Ross
25*a90cf9f2SGordon Ross /*
26*a90cf9f2SGordon Ross * This handles an SMB2_CANCEL request when seen in the reader.
27*a90cf9f2SGordon Ross * (See smb2sr_newrq) Handle this immediately, rather than
28*a90cf9f2SGordon Ross * going through the normal taskq dispatch mechanism.
29*a90cf9f2SGordon Ross * Note that Cancel does NOT get a response.
30*a90cf9f2SGordon Ross */
31*a90cf9f2SGordon Ross int
smb2sr_newrq_cancel(smb_request_t * sr)32*a90cf9f2SGordon Ross smb2sr_newrq_cancel(smb_request_t *sr)
33*a90cf9f2SGordon Ross {
34*a90cf9f2SGordon Ross int rc;
35*a90cf9f2SGordon Ross
36*a90cf9f2SGordon Ross /*
37*a90cf9f2SGordon Ross * Decode the header
38*a90cf9f2SGordon Ross */
39*a90cf9f2SGordon Ross if ((rc = smb2_decode_header(sr)) != 0)
40*a90cf9f2SGordon Ross return (rc);
41*a90cf9f2SGordon Ross
42*a90cf9f2SGordon Ross if (sr->smb2_hdr_flags & SMB2_FLAGS_ASYNC_COMMAND)
43*a90cf9f2SGordon Ross smb2sr_cancel_async(sr);
44*a90cf9f2SGordon Ross else
45*a90cf9f2SGordon Ross smb2sr_cancel_sync(sr);
46*a90cf9f2SGordon Ross
47*a90cf9f2SGordon Ross return (0);
48*a90cf9f2SGordon Ross }
49*a90cf9f2SGordon Ross
50*a90cf9f2SGordon Ross static void
smb2sr_cancel_sync(smb_request_t * sr)51*a90cf9f2SGordon Ross smb2sr_cancel_sync(smb_request_t *sr)
52*a90cf9f2SGordon Ross {
53*a90cf9f2SGordon Ross struct smb_request *req;
54*a90cf9f2SGordon Ross struct smb_session *session = sr->session;
55*a90cf9f2SGordon Ross int cnt = 0;
56*a90cf9f2SGordon Ross
57*a90cf9f2SGordon Ross smb_slist_enter(&session->s_req_list);
58*a90cf9f2SGordon Ross req = smb_slist_head(&session->s_req_list);
59*a90cf9f2SGordon Ross while (req) {
60*a90cf9f2SGordon Ross ASSERT(req->sr_magic == SMB_REQ_MAGIC);
61*a90cf9f2SGordon Ross if ((req != sr) &&
62*a90cf9f2SGordon Ross (req->smb2_messageid == sr->smb2_messageid)) {
63*a90cf9f2SGordon Ross smb_request_cancel(req);
64*a90cf9f2SGordon Ross cnt++;
65*a90cf9f2SGordon Ross }
66*a90cf9f2SGordon Ross req = smb_slist_next(&session->s_req_list, req);
67*a90cf9f2SGordon Ross }
68*a90cf9f2SGordon Ross if (cnt != 1) {
69*a90cf9f2SGordon Ross DTRACE_PROBE2(smb2__cancel__error,
70*a90cf9f2SGordon Ross uint64_t, sr->smb2_messageid, int, cnt);
71*a90cf9f2SGordon Ross }
72*a90cf9f2SGordon Ross smb_slist_exit(&session->s_req_list);
73*a90cf9f2SGordon Ross }
74*a90cf9f2SGordon Ross
75*a90cf9f2SGordon Ross static void
smb2sr_cancel_async(smb_request_t * sr)76*a90cf9f2SGordon Ross smb2sr_cancel_async(smb_request_t *sr)
77*a90cf9f2SGordon Ross {
78*a90cf9f2SGordon Ross struct smb_request *req;
79*a90cf9f2SGordon Ross struct smb_session *session = sr->session;
80*a90cf9f2SGordon Ross int cnt = 0;
81*a90cf9f2SGordon Ross
82*a90cf9f2SGordon Ross smb_slist_enter(&session->s_req_list);
83*a90cf9f2SGordon Ross req = smb_slist_head(&session->s_req_list);
84*a90cf9f2SGordon Ross while (req) {
85*a90cf9f2SGordon Ross ASSERT(req->sr_magic == SMB_REQ_MAGIC);
86*a90cf9f2SGordon Ross if ((req != sr) &&
87*a90cf9f2SGordon Ross (req->smb2_async_id == sr->smb2_async_id)) {
88*a90cf9f2SGordon Ross smb_request_cancel(req);
89*a90cf9f2SGordon Ross cnt++;
90*a90cf9f2SGordon Ross }
91*a90cf9f2SGordon Ross req = smb_slist_next(&session->s_req_list, req);
92*a90cf9f2SGordon Ross }
93*a90cf9f2SGordon Ross if (cnt != 1) {
94*a90cf9f2SGordon Ross DTRACE_PROBE2(smb2__cancel__error,
95*a90cf9f2SGordon Ross uint64_t, sr->smb2_async_id, int, cnt);
96*a90cf9f2SGordon Ross }
97*a90cf9f2SGordon Ross smb_slist_exit(&session->s_req_list);
98*a90cf9f2SGordon Ross }
99