From owner-svn-src-head@FreeBSD.ORG Wed Oct 9 12:03:05 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 24F7CC90; Wed, 9 Oct 2013 12:03:05 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 02DB9212D; Wed, 9 Oct 2013 12:03:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r99C34xV040848; Wed, 9 Oct 2013 12:03:04 GMT (envelope-from trasz@svn.freebsd.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r99C34a1040846; Wed, 9 Oct 2013 12:03:04 GMT (envelope-from trasz@svn.freebsd.org) Message-Id: <201310091203.r99C34a1040846@svn.freebsd.org> From: Edward Tomasz Napierala Date: Wed, 9 Oct 2013 12:03:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r256187 - in head/sys: cam/ctl dev/iscsi X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Oct 2013 12:03:05 -0000 Author: trasz Date: Wed Oct 9 12:03:04 2013 New Revision: 256187 URL: http://svnweb.freebsd.org/changeset/base/256187 Log: Fix NOP-In/NOP-Out payload handling. Previous way didn't work at all; fortunately nothing seems to actually use this feature, but it's required by standard. Approved by: re (glebius) Sponsored by: FreeBSD Foundation Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c head/sys/dev/iscsi/iscsi.c Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c ============================================================================== --- head/sys/cam/ctl/ctl_frontend_iscsi.c Wed Oct 9 12:00:38 2013 (r256186) +++ head/sys/cam/ctl/ctl_frontend_iscsi.c Wed Oct 9 12:03:04 2013 (r256187) @@ -455,6 +455,9 @@ cfiscsi_pdu_handle_nop_out(struct icl_pd struct iscsi_bhs_nop_out *bhsno; struct iscsi_bhs_nop_in *bhsni; struct icl_pdu *response; + void *data = NULL; + size_t datasize; + int error; cs = PDU_SESSION(request); bhsno = (struct iscsi_bhs_nop_out *)request->ip_bhs; @@ -468,9 +471,26 @@ cfiscsi_pdu_handle_nop_out(struct icl_pd return; } + datasize = icl_pdu_data_segment_length(request); + if (datasize > 0) { + data = malloc(datasize, M_CFISCSI, M_NOWAIT | M_ZERO); + if (data == NULL) { + CFISCSI_SESSION_WARN(cs, "failed to allocate memory; " + "dropping connection"); + icl_pdu_free(request); + cfiscsi_session_terminate(cs); + return; + } + icl_pdu_get_data(request, 0, data, datasize); + } + response = cfiscsi_pdu_new_response(request, M_NOWAIT); if (response == NULL) { + CFISCSI_SESSION_WARN(cs, "failed to allocate memory; " + "droppping connection"); + free(data, M_CFISCSI); icl_pdu_free(request); + cfiscsi_session_terminate(cs); return; } bhsni = (struct iscsi_bhs_nop_in *)response->ip_bhs; @@ -478,14 +498,19 @@ cfiscsi_pdu_handle_nop_out(struct icl_pd bhsni->bhsni_flags = 0x80; bhsni->bhsni_initiator_task_tag = bhsno->bhsno_initiator_task_tag; bhsni->bhsni_target_transfer_tag = 0xffffffff; - -#if 0 - /* XXX */ - response->ip_data_len = request->ip_data_len; - response->ip_data_mbuf = request->ip_data_mbuf; - request->ip_data_len = 0; - request->ip_data_mbuf = NULL; -#endif + if (datasize > 0) { + error = icl_pdu_append_data(response, data, datasize, M_NOWAIT); + if (error != 0) { + CFISCSI_SESSION_WARN(cs, "failed to allocate memory; " + "dropping connection"); + free(data, M_CFISCSI); + icl_pdu_free(request); + icl_pdu_free(response); + cfiscsi_session_terminate(cs); + return; + } + free(data, M_CFISCSI); + } icl_pdu_free(request); cfiscsi_pdu_queue(response); Modified: head/sys/dev/iscsi/iscsi.c ============================================================================== --- head/sys/dev/iscsi/iscsi.c Wed Oct 9 12:00:38 2013 (r256186) +++ head/sys/dev/iscsi/iscsi.c Wed Oct 9 12:03:04 2013 (r256187) @@ -726,10 +726,15 @@ iscsi_error_callback(struct icl_conn *ic static void iscsi_pdu_handle_nop_in(struct icl_pdu *response) { + struct iscsi_session *is; struct iscsi_bhs_nop_out *bhsno; struct iscsi_bhs_nop_in *bhsni; struct icl_pdu *request; + void *data = NULL; + size_t datasize; + int error; + is = PDU_SESSION(response); bhsni = (struct iscsi_bhs_nop_in *)response->ip_bhs; if (bhsni->bhsni_target_transfer_tag == 0xffffffff) { @@ -741,22 +746,47 @@ iscsi_pdu_handle_nop_in(struct icl_pdu * return; } + datasize = icl_pdu_data_segment_length(response); + if (datasize > 0) { + data = malloc(datasize, M_ISCSI, M_NOWAIT | M_ZERO); + if (data == NULL) { + ISCSI_SESSION_WARN(is, "failed to allocate memory; " + "reconnecting"); + icl_pdu_free(response); + iscsi_session_reconnect(is); + return; + } + icl_pdu_get_data(response, 0, data, datasize); + } + request = icl_pdu_new_bhs(response->ip_conn, M_NOWAIT); if (request == NULL) { + ISCSI_SESSION_WARN(is, "failed to allocate memory; " + "reconnecting"); + free(data, M_ISCSI); icl_pdu_free(response); + iscsi_session_reconnect(is); return; } bhsno = (struct iscsi_bhs_nop_out *)request->ip_bhs; bhsno->bhsno_opcode = ISCSI_BHS_OPCODE_NOP_OUT | ISCSI_BHS_OPCODE_IMMEDIATE; bhsno->bhsno_flags = 0x80; - bhsno->bhsno_initiator_task_tag = 0xffffffff; /* XXX */ + bhsno->bhsno_initiator_task_tag = 0xffffffff; bhsno->bhsno_target_transfer_tag = bhsni->bhsni_target_transfer_tag; - - request->ip_data_len = response->ip_data_len; - request->ip_data_mbuf = response->ip_data_mbuf; - response->ip_data_len = 0; - response->ip_data_mbuf = NULL; + if (datasize > 0) { + error = icl_pdu_append_data(request, data, datasize, M_NOWAIT); + if (error != 0) { + ISCSI_SESSION_WARN(is, "failed to allocate memory; " + "reconnecting"); + free(data, M_ISCSI); + icl_pdu_free(request); + icl_pdu_free(response); + iscsi_session_reconnect(is); + return; + } + free(data, M_ISCSI); + } icl_pdu_free(response); iscsi_pdu_queue_locked(request);