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