/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* * Dispatch function for SMB2_CANCEL */ #include static void smb2sr_cancel_async(smb_request_t *); static void smb2sr_cancel_sync(smb_request_t *); /* * This handles an SMB2_CANCEL request when seen in the reader. * (See smb2sr_newrq) Handle this immediately, rather than * going through the normal taskq dispatch mechanism. * Note that Cancel does NOT get a response. */ int smb2sr_newrq_cancel(smb_request_t *sr) { int rc; /* * Decode the header */ if ((rc = smb2_decode_header(sr)) != 0) return (rc); if (sr->smb2_hdr_flags & SMB2_FLAGS_ASYNC_COMMAND) smb2sr_cancel_async(sr); else smb2sr_cancel_sync(sr); return (0); } static void smb2sr_cancel_sync(smb_request_t *sr) { struct smb_request *req; struct smb_session *session = sr->session; int cnt = 0; smb_slist_enter(&session->s_req_list); req = smb_slist_head(&session->s_req_list); while (req) { ASSERT(req->sr_magic == SMB_REQ_MAGIC); if ((req != sr) && (req->smb2_messageid == sr->smb2_messageid)) { smb_request_cancel(req); cnt++; } req = smb_slist_next(&session->s_req_list, req); } if (cnt != 1) { DTRACE_PROBE2(smb2__cancel__error, uint64_t, sr->smb2_messageid, int, cnt); } smb_slist_exit(&session->s_req_list); } static void smb2sr_cancel_async(smb_request_t *sr) { struct smb_request *req; struct smb_session *session = sr->session; int cnt = 0; smb_slist_enter(&session->s_req_list); req = smb_slist_head(&session->s_req_list); while (req) { ASSERT(req->sr_magic == SMB_REQ_MAGIC); if ((req != sr) && (req->smb2_async_id == sr->smb2_async_id)) { smb_request_cancel(req); cnt++; } req = smb_slist_next(&session->s_req_list, req); } if (cnt != 1) { DTRACE_PROBE2(smb2__cancel__error, uint64_t, sr->smb2_async_id, int, cnt); } smb_slist_exit(&session->s_req_list); }