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