⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 initiator_rx.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
					     " 0x%02x, expected 0x%02x\n",					     nopout_cmd->opcode & ISCSI_OPCODE,					     ISCSI_INIT_NOP_OUT);				}				if (size != ntohl(nopout_cmd->length)) {					TRACE_ERROR					    ("NopIn DSL is %u, expected %u\n",					     size, ntohl(nopout_cmd->length));				} else if (size > 0					   && memcmp(*buffer,						     related_command->tx_iov[1].						     iov_base, size) != 0) {					TRACE_ERROR					    ("NopIn Data \"%s\", "					     "expected \"%s\"\n", *buffer,					     (char *) related_command->							tx_iov[1].iov_base);				} else {					TRACE(TRACE_ISCSI_FULL,					      "%u byte NopIn matches NopOut\n",					      size);				}				/* in any case, free up the related command */				related_command->cmd_state |= CMD_STATE_RXDONE;				free_pending_command(related_command,						     current_connection);			}		}	} else {		/* sent by target on its own to provoke a "ping"		 * response from us		 */		if (unlikely(local_itt != ALL_ONES)) {			TRACE_ERROR("Invalid NopIn ITT %u when TTT is %u\n",				    local_itt, ntohl(header->target_xfer_tag));		}		/* Draft 20, Section 10.19.3 Lun		 * "A LUN MUST be set to a correct value when the		 * Target Transfer Tag is valid (not the reserved		 * value 0xffffffff)."		 */		lun = unpack_lun((__u8 *) & header->lun);		if (unlikely(!(related_session->lun_bits & (1 << lun)))) {			TRACE(TRACE_ISCSI, "Invalid NopIn LUN %u\n", lun);		}		/* Now send a NopOut PDU in response to this NopIn */		if (unlikely(current_connection->connection_flags						& SEND_NO_REPLY_TO_NOP_PING)) {			TRACE(TRACE_ISCSI,			      "Not replying to NopIn ping from target\n");		} else {			tx_nopout(current_connection, 0, header, buffer, size);		}	}	TRACE(TRACE_ENTER_LEAVE, "Leave rx_nopin\n");	return 1;		/* only success here */}/* * print out all keys sent by target in a text response * returns 1 on success, 0 on error (unterminated key) */static inttext_key_dump(char *buffer, __u32 size, char *message){	int retval = 1;	char *ptr, *ptr2;	if (likely(buffer != NULL && size > 0)) {		/* print out the info sent by target */		for (ptr = buffer; size > 0; ptr = ptr2) {			for (ptr2 = ptr; *ptr2 != '\0' && size > 0;				ptr2++, size--) {				/* skip over key itself */			}			if (*ptr2 != '\0') {				*ptr2 = '\0';				TRACE_ERROR("Unterminated key %s\n", ptr);				retval = 0;			}			printk("%s %s %s\n", current->comm, message, ptr);			for (; *ptr2 == '\0' && size > 0; ptr2++, size--) {				/* skip over nulls between keys */			}		}	} else {		TRACE(TRACE_ISCSI_FULL, "%s empty text response\n",		      current->comm);	}	return retval;}/* called only by rx_text_rsp() * Returns 1 if need reset due to error, 0 if all ok */static int __attribute__ ((no_instrument_function))accumulate_text(struct command *command, char *buffer, __u32 size){	int retval, total;	if ((total = size) > 0) {		/* buffer contains some data, must accumulate it */		if (command->buffer_to_free == NULL) {			command->buffer_to_free = my_kmalloc(MAX_TEXT_LEN,							     "Text data");			if (command->buffer_to_free == NULL) {				retval = 1;				goto out;			}		}		total += command->data_offset;		if (total > MAX_TEXT_LEN) {			TRACE_ERROR("%s too many total bytes %u in text data, "				    " max %u\n", current->comm, total,				    MAX_TEXT_LEN);			retval = 1;			goto out;		}		memcpy(command->buffer_to_free + command->data_offset, buffer,		       size);		command->data_offset = total;	}	retval = 0;out:	return retval;}/*************************************************************************** * executed only by rx thread. * the session->sess_lock MUST be held by the calling process/thread. * Called only by iscsi_initiator_rx_thread(). * This function processes the TextResponse header. * * Parameters: current_connection which is a ptr to the connection struct *			  where the TextResponse header was received. * Return Value: >0 success; ==0 on fatal error ***************************************************************************/static intrx_text_rsp(struct connection *current_connection,	    __u32 local_itt,	    struct command *related_command, __u32 size, char *buffer){	struct iscsi_targ_text_rsp *header;	struct session *related_session;	struct iscsi_init_text_cmnd *text_cmd;	int retval = 1, need_reset = 0;	TRACE(TRACE_ENTER_LEAVE, "Enter rx_text_rsp, current_connection %p\n",	      current_connection);	header = (struct iscsi_targ_text_rsp *)current_connection->rx_buf;	if (related_command == NULL) {		TRACE_ERROR("%s ignoring Text Response that matches no "			    "command\n", current->comm);		print_targ_text_rsp(header);		goto out;	}	related_session = current_connection->my_session;#ifdef ISCSI_CHECK_PDU_FORMAT	/* Check if reserved fields are zero or not */	if (unlikely(!((header->flags & ~(F_BIT | C_BIT)) == 0	      && header->rsvd2 == 0	      && header->rsvd4 == 0 && header->rsvd5 == 0))) {		reserved_not_0("Text Response");	}#endif	if (unlikely(header->flags & C_BIT)) {		/* C bit is set in Text Response		 *		 * RFC 3720 Section 10.11.2 C (Continue) Bit (in Text Response)		 * "A Text Response with the C bit set to 1 MUST have the		 * F bit set to 0."		 */		if (unlikely(header->flags & F_BIT)) {			/* have C=1 and F=1 -- try to guess which is wrong */						if (header->target_xfer_tag == ALL_ONES) {				/* this is ok when F=1, bad when C=1 */				TRACE_ERROR("Text Response with ITT %u has F=1 "					    "and C=1, expected C=0\n",					    local_itt);				header->flags &= ~C_BIT;			} else {				TRACE_ERROR("Text Response with ITT %u has C=1 "					    "and F=1, expected F=0\n",					    local_itt);				need_reset = 1;				header->flags &= ~F_BIT;			}		}	}	if (!(header->flags & C_BIT)) {		/* this pdu completes one full data payload */		if (related_command->data_offset) {			/* previous response pdus were continued to this one.			 * append this new buffer, then dump the whole payload.			 */			need_reset = accumulate_text(related_command, buffer,						     size);			buffer = related_command->buffer_to_free;			size = related_command->data_offset;		}		if (!need_reset) {			if (related_session->oper_param->SessionType) {				text_key_dump(buffer, size, "discovery");			} else {				text_key_dump(buffer, size, "text negotiation");			}		}		/* finished with any accumulated data payload */		related_command->data_offset = 0;	} else {		/* this pdu contains only part of the complete data payload */		if (related_command->data_offset == 0) {			/* this is first continued pdu, free original request */			my_kfree((void **)&related_command->buffer_to_free,				 "Text data");		}		need_reset = accumulate_text(related_command, buffer, size);	}	if (header->flags & F_BIT) {		/* F Bit is 1, Target is finished sending everything */		if (unlikely(header->target_xfer_tag != ALL_ONES)) {			/* RFC 3720 Section 10.11.1 F (Final) Bit in Text Resp			 * "A Text Response with the F bit set to 1			 * MUST have a Target Transfer Tag field set to			 * the reserved value of 0xffffffff."			 */			TRACE_ERROR("Text Response with ITT %u has F=1 TTT=%u, "				    "expected 0xffffffff\n", local_itt,				    ntohl(header->target_xfer_tag));			/* ignore this since F=1 so we close it down anyway */		}		/* in any case, free up the related command */		related_command->cmd_state |= CMD_STATE_RXDONE;		free_pending_command(related_command, current_connection);		if (related_session->oper_param->SessionType) {			/* in a discovery session, shut it down with a logout */			drive_logout(related_session, current_connection,				     LOGOUT_CLOSE_SESSION);		}	} else {		/* F bit is 0, target has more to send after this		 * RFC 3720 Section 10.11.4 Target Transfer Tag		 * "When a target has more work to do (e.g., cannot transfer all		 * the remaining text data in a single Text Response or has to		 * continue the negotiation) and has enough resources to		 * proceed, it MUST set the Target Transfer Tag to a value other		 * than the reserved value of 0xffffffff.  Otherwise, the Target		 * Transfer Tag MUST be set to 0xffffffff.		 * ...		 * The initiator MUST copy the Target Transfer Tag and LUN in		 * its next request to indicate that it wants the rest of the		 * data."		 */		if (unlikely(header->target_xfer_tag == ALL_ONES)) {			/* RFC 3720 Section 10.11.1 F (Final) Bit in Text Resp			 * "A text response with the F bit set to 0 MUST			 * have a Target Transfer Tag field set to a value			 * other than the reserved 0xffffffff."			 */			TRACE_ERROR("Text Response with ITT %u F=0 has TTT="				    "0x%8x, expected unreserved TTT\n",				    local_itt, ALL_ONES);			need_reset = 1;		}		/* queue up an empty TextRequest to keep Target going */		text_cmd = (struct iscsi_init_text_cmnd *)						&related_command->iscsi_cmd;		if (need_reset) {			text_cmd->target_xfer_tag = ALL_ONES;			text_cmd->lun = 0;		} else {			text_cmd->target_xfer_tag = header->target_xfer_tag;			text_cmd->lun = header->lun;		}		/* this follow-on TextRequest pdu has no data attached,		 * reset iov and msghdr so only header is sent		 */		text_cmd->length = 0;		related_command->tx_iov->iov_len = related_command->tx_size					= current_connection->basic_hdr_len;		related_command->tx_iovlen = 1;		/* reattach the existing Text Request command to end of		 * pending commands list.  this also sets the CmdSN		 */		attach_pending_command(related_command, current_connection, 2);	}out:	TRACE(TRACE_ENTER_LEAVE, "Leave rx_text_rsp, retval %d\n", retval);	return retval;}/*************************************************************************** * executed only by rx thread. * the session->sess_lock MUST be held by the calling process/thread. * Called only by iscsi_initiator_rx_thread(). * This function processes the LogoutResponse header. * * Parameters: current_connection which is a ptr to the connection struct *			  where the LogoutResponse header was received. * Return Value: =0 terminate connection on return, (session lock still locked) *		 <0 terminate connection on return, (session lock not locked) *		 >0 do not terminate connection (session lock still locked) ***************************************************************************/static intrx_logout_rsp(struct connection *conn,	      __u32 local_itt, struct command *related_command){	int reason, response = 1;	struct iscsi_init_logout_cmnd *logout_cmd;	struct iscsi_targ_logout_rsp *header;	struct session *sess = NULL;	struct semaphore rec_wait_sem;	TRACE(TRACE_ENTER_LEAVE, "Enter rx_logout_rsp, current_connection %p\n",	      conn);	header = (struct iscsi_targ_logout_rsp *)conn->rx_buf;	/* store the session pointer - SAI */	sess = conn->my_session;#ifdef ISCSI_CHECK_PDU_FORMAT	/* Check if reserved fields are zero or not */	if (unlikely(!((header->flags & ~F_BIT) == 0	      && header->rsvd1 == 0	      && header->rsvd3 == 0	      && header->rsvd4 == 0 && header->rsvd5 == 0))) {		reserved_not_0("Logout Response");	}#endif	/* this PDU should be a response to a LogoutRequest sent	 * earlier by us.	 */	if (likely(related_command != NULL)) {		/* found the corresponding LogoutRequest command */		response = header->response;		/* If connection recovery, start a Wait timer - SAI */		logout_cmd = (struct iscsi_init_logout_cmnd *)						& (related_command->iscsi_cmd);		reason = logout_cmd->flags & LOGOUT_REASON;		related_command->cmd_state |= CMD_STATE_RXDONE;		free_pending_command(related_command, conn);		switch (reason) {		case LOGOUT_CLOSE_SESSION:			if (response == 0) {				sess->session_state = SESSION_LOGGED_OUT;			} else {				TRACE_ERROR("Logout to close session failed"					    ", response %u\n", response);			}			break;		case LOGOUT_CLOSE_CONNECTION:			if (response == 0) {				/* stop using logged-out connection */				conn->connection_state = CONNECTION_LOGGED_OUT;			} else {				TRACE_ERROR("Logout to close connection failed"					    ", response %u\n", response);			}			break;		case LOGOUT_REMOVE_CONN_FOR_RECOVERY:			/* If the response is zero and ErrorRecoveryLevel > 1,			 * then wait until Time2Wait and then recover - SAI			 */			if (response == 0			    && sess->oper_param->ErrorRecoveryLevel > 1) {				UNH_UNLOCK(&sess->sess_lock,					   conn->rx_lock_flags);				if (be16_to_cpu(header->time2wait) > 0) {					init_MUTEX_LOCKED(&rec_wait_sem);					start_connrec_timer(sess,							    &rec_wait_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -