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 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 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 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