[Stgt-devel] [PATCH] head and data digest

Albert Pauw albert.pauw
Tue Apr 24 16:05:25 CEST 2007


Checked this patch (together with the FirstBurstLength patch)
and it seems to work fine again. But now with both digests.

Thanks,

Albert

FUJITA Tomonori wrote:
> From: Albert Pauw <albert.pauw at gmail.com>
> Subject: Re: [Stgt-devel] [PATCH] head and data digest
> Date: Mon, 23 Apr 2007 19:21:56 +0200
> 
>> FUJITA Tomonori wrote:
>>> From: Albert Pauw <albert.pauw at gmail.com>
>>> Subject: Re: [Stgt-devel] [PATCH] head and data digest
>>> Date: Sun, 22 Apr 2007 17:39:26 +0200
>>>
>>>   
>>>> I set HeaderDigest to CRC32C on the disk target:
>>>>     
>>> Do you enable the features? Here's an example:
>>>
>>> root at ac:~/git# ./tgt/usr/tgtadm --op show --mode target --tid 1
>>> MaxRecvDataSegmentLength=8192
>>> MaxXmitDataSegmentLength=8192
>>> HeaderDigest=None
>>> DataDigest=None
>>> InitialR2T=Yes
>>> MaxOutstandingR2T=1
>>> ImmediateData=Yes
>>> FirstBurstLength=65536
>>> MaxBurstLength=262144
>>> DataPDUInOrder=Yes
>>> DataSequenceInOrder=Yes
>>> ErrorRecoveryLevel=0
>>> IFMarker=No
>>> OFMarker=No
>>> DefaultTime2Wait=2
>>> DefaultTime2Retain=20
>>> OFMarkInt=Reject
>>> IFMarkInt=Reject
>>> MaxConnections=1
>>>
>>> root at ac:~/git# ./tgt/usr/tgtadm --op update --mode target --tid 1 -n HeaderDigest -v CRC32C
>>> root at ac:~/git# ./tgt/usr/tgtadm --op update --mode target --tid 1 -n DataDigest -v CRC32C
>>>
>>> root at ac:~/git# ./tgt/usr/tgtadm --op show --mode target --tid 1
>>> MaxRecvDataSegmentLength=8192
>>> MaxXmitDataSegmentLength=8192
>>> HeaderDigest=CRC32C
>>> DataDigest=CRC32C
>>> InitialR2T=Yes
>>> MaxOutstandingR2T=1
>>> ImmediateData=Yes
>>> FirstBurstLength=65536
>>> MaxBurstLength=262144
>>> DataPDUInOrder=Yes
>>> DataSequenceInOrder=Yes
>>> ErrorRecoveryLevel=0
>>> IFMarker=No
>>> OFMarker=No
>>> DefaultTime2Wait=2
>>> DefaultTime2Retain=20
>>> OFMarkInt=Reject
>>> IFMarkInt=Reject
>>> MaxConnections=1
>>>
>>> With this configuration, the target accepts CRC32C and
>>> None. Currently, there is no way to configure a target to accept only
>>> CRC32C.
>>>
>>> If it still doesn't work for you, please send the tcpdump log during a
>>> login process.
>>>
>>>   
>> Ok, login works fine, if I look with wireshark I can see that the digest
>> is ok.
> 
> Sorry, I put a silly bug in the patch. Here's a new one.
> 
> 
> diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c
> index e4e36aa..fcd2385 100644
> --- a/usr/iscsi/conn.c
> +++ b/usr/iscsi/conn.c
> @@ -176,18 +176,3 @@ int conn_take_fd(struct iscsi_connection
>  
>  	return 0;
>  }
> -
> -void conn_read_pdu(struct iscsi_connection *conn)
> -{
> -	conn->rx_iostate = IOSTATE_READ_BHS;
> -	conn->rx_buffer = (void *)&conn->req.bhs;
> -	conn->rx_size = BHS_SIZE;
> -}
> -
> -void conn_write_pdu(struct iscsi_connection *conn)
> -{
> -	conn->tx_iostate = IOSTATE_WRITE_BHS;
> -	memset(&conn->rsp, 0, sizeof(conn->rsp));
> -	conn->tx_buffer = (void *)&conn->rsp.bhs;
> -	conn->tx_size = BHS_SIZE;
> -}
> diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
> index 2377952..3d38ccc 100644
> --- a/usr/iscsi/iscsid.c
> +++ b/usr/iscsi/iscsid.c
> @@ -38,9 +38,53 @@ #include "iscsid.h"
>  #include "tgtd.h"
>  #include "util.h"
>  #include "driver.h"
> +#include "crc32c.h"
>  
>  #define MAX_QUEUE_CMD	32
>  
> +enum {
> +	IOSTATE_FREE,
> +
> +	IOSTATE_RX_BHS,
> +	IOSTATE_RX_INIT_AHS,
> +	IOSTATE_RX_AHS,
> +	IOSTATE_RX_INIT_HDIGEST,
> +	IOSTATE_RX_HDIGEST,
> +	IOSTATE_RX_CHECK_HDIGEST,
> +	IOSTATE_RX_INIT_DATA,
> +	IOSTATE_RX_DATA,
> +	IOSTATE_RX_INIT_DDIGEST,
> +	IOSTATE_RX_DDIGEST,
> +	IOSTATE_RX_CHECK_DDIGEST,
> +	IOSTATE_RX_END,
> +
> +	IOSTATE_TX_BHS,
> +	IOSTATE_TX_INIT_AHS,
> +	IOSTATE_TX_AHS,
> +	IOSTATE_TX_INIT_HDIGEST,
> +	IOSTATE_TX_HDIGEST,
> +	IOSTATE_TX_INIT_DATA,
> +	IOSTATE_TX_DATA,
> +	IOSTATE_TX_INIT_DDIGEST,
> +	IOSTATE_TX_DDIGEST,
> +	IOSTATE_TX_END,
> +};
> +
> +void conn_read_pdu(struct iscsi_connection *conn)
> +{
> +	conn->rx_iostate = IOSTATE_RX_BHS;
> +	conn->rx_buffer = (void *)&conn->req.bhs;
> +	conn->rx_size = BHS_SIZE;
> +}
> +
> +static void conn_write_pdu(struct iscsi_connection *conn)
> +{
> +	conn->tx_iostate = IOSTATE_TX_BHS;
> +	memset(&conn->rsp, 0, sizeof(conn->rsp));
> +	conn->tx_buffer = (void *)&conn->rsp.bhs;
> +	conn->tx_size = BHS_SIZE;
> +}
> +
>  static struct iscsi_key login_keys[] = {
>  	{"InitiatorName",},
>  	{"InitiatorAlias",},
> @@ -1265,9 +1309,7 @@ found:
>  		task->r2t_count,
>  		ntoh24(req->dlength), be32_to_cpu(req->offset));
>  
> -	conn->rx_buffer = task->data;
> -	conn->rx_buffer += be32_to_cpu(req->offset);
> -	conn->rx_size = roundup(ntoh24(req->dlength), 4);
> +	conn->req.data = task->data + be32_to_cpu(req->offset);
>  
>  	task->offset += ntoh24(req->dlength);
>  	task->r2t_count -= ntoh24(req->dlength);
> @@ -1357,12 +1399,10 @@ static int iscsi_scsi_cmd_rx_start(struc
>  	if (ahs_len) {
>  		task->ahs = task->data + sizeof(req->cdb);
>  		task->data = task->ahs + ahs_len;
> -		conn->rx_buffer = task->ahs;
> - 		conn->rx_size = ahs_len + imm_len;
> -	} else if (data_len) {
> - 		conn->rx_buffer = task->data;
> -		conn->rx_size = imm_len;
> - 	}
> +		conn->req.ahs = task->ahs;
> +		conn->req.data = task->data;
> +	} else if (data_len)
> +		conn->req.data = task->data;
>  
>  	if (req->flags & ISCSI_FLAG_CMD_WRITE) {
>  		task->offset = ntoh24(req->dlength);
> @@ -1414,9 +1454,8 @@ static int iscsi_noop_out_rx_start(struc
>  	}
>  
>  	if (len) {
> -		conn->rx_size = len;
>  		task->len = len;
> -		conn->rx_buffer = task->data;
> +		conn->req.data = task->data;
>  	}
>  out:
>  	return err;
> @@ -1662,167 +1701,314 @@ nodata:
>  	return -EAGAIN;
>  }
>  
> +static int do_recv(int fd, struct iscsi_connection *conn, int next_state)
> +{
> +	int ret;
> +
> +	ret = conn->tp->ep_read(fd, conn->rx_buffer, conn->rx_size);
> +	if (!ret) {
> +		conn->state = STATE_CLOSE;
> +		return 0;
> +	} else if (ret < 0) {
> +		if (errno == EINTR || errno == EAGAIN)
> +			return 0;
> +		else
> +			return -EIO;
> +	}
> +
> +	conn->rx_size -= ret;
> +	conn->rx_buffer += ret;
> +	if (!conn->rx_size)
> +		conn->rx_iostate = next_state;
> +
> +	return ret;
> +}
> +
>  static void iscsi_rx_handler(int fd, struct iscsi_connection *conn)
>  {
> -	int res;
> +	int ret = 0, hdigest, ddigest;
> +	uint32_t crc;
>  
> +	if (conn->state == STATE_SCSI) {
> +		struct param *p = conn->session_param;
> +		hdigest = p[ISCSI_PARAM_HDRDGST_EN].val & DIGEST_CRC32C;
> +		ddigest = p[ISCSI_PARAM_DATADGST_EN].val & DIGEST_CRC32C;
> +	} else
> +		hdigest = ddigest = 0;
> +again:
>  	switch (conn->rx_iostate) {
> -	case IOSTATE_READ_BHS:
> -	case IOSTATE_READ_AHS_DATA:
> -	read_again:
> -		res = conn->tp->ep_read(fd, conn->rx_buffer, conn->rx_size);
> -		if (!res) {
> -			conn->state = STATE_CLOSE;
> +	case IOSTATE_RX_BHS:
> +		ret = do_recv(fd, conn, IOSTATE_RX_INIT_AHS);
> +		if (ret <= 0 || conn->rx_iostate != IOSTATE_RX_INIT_AHS)
>  			break;
> -		} else if (res < 0) {
> -			if (errno == EINTR)
> -				goto read_again;
> -			else if (errno == EAGAIN)
> -				break;
> -			else {
> +	case IOSTATE_RX_INIT_AHS:
> +		if (conn->state == STATE_SCSI) {
> +			ret = iscsi_task_rx_start(conn);
> +			if (ret) {
>  				conn->state = STATE_CLOSE;
> -				dprintf("%d %d, %m\n", res, errno);
> +				break;
>  			}
> +		} else {
> +			conn->rx_buffer = conn->req_buffer;
> +			conn->req.ahs = conn->rx_buffer;
> +			conn->req.data = conn->rx_buffer + conn->rx_size;
> +		}
> +		conn->req.ahssize = conn->req.bhs.hlength * 4;
> +		conn->req.datasize = ntoh24(conn->req.bhs.dlength);
> +		conn->rx_size = roundup(conn->req.ahssize, 4);
> +		if (conn->rx_size) {
> +			ret = do_recv(fd, conn, IOSTATE_RX_AHS);
> +			if (ret <= 0)
> +				break;
> +		} else
> +			conn->rx_iostate = hdigest ?
> +				IOSTATE_RX_INIT_HDIGEST : IOSTATE_RX_INIT_DATA;
> +
> +		if (conn->rx_iostate == IOSTATE_RX_INIT_DATA)
> +			goto again;
> +		else if (conn->rx_iostate != IOSTATE_RX_AHS)
> +			break;
> +	case IOSTATE_RX_AHS:
> +		ret = do_recv(fd, conn, hdigest ?
> +			      IOSTATE_RX_INIT_HDIGEST : IOSTATE_RX_INIT_DATA);
> +		if (ret <= 0 || conn->rx_iostate != IOSTATE_RX_INIT_HDIGEST)
>  			break;
> +	case IOSTATE_RX_INIT_HDIGEST:
> +		conn->rx_buffer = conn->rx_digest;
> +		conn->rx_size = sizeof(conn->rx_digest);
> +		conn->rx_iostate = IOSTATE_RX_HDIGEST;
> +	case IOSTATE_RX_HDIGEST:
> +		ret = do_recv(fd, conn, IOSTATE_RX_CHECK_HDIGEST);
> +		if (ret <= 0 || conn->rx_iostate != IOSTATE_RX_CHECK_HDIGEST)
> +			break;
> +	case IOSTATE_RX_CHECK_HDIGEST:
> +		crc = ~0;
> +		crc = crc32c(crc, &conn->req.bhs, BHS_SIZE);
> +		if (conn->req.ahssize)
> +			crc = crc32c(crc, conn->req.ahs,
> +				     roundup(conn->req.ahssize, 4));
> +		crc = ~__cpu_to_le32(crc);
> +		if (*((uint32_t *)conn->rx_digest) != crc) {
> +			eprintf("rx hdr digest error 0x%x calc 0x%x\n",
> +				*((uint32_t *)conn->rx_digest), crc);
> +			conn->state = STATE_CLOSE;
>  		}
> -		conn->rx_size -= res;
> -		conn->rx_buffer += res;
> -		if (conn->rx_size)
> +		conn->rx_iostate = IOSTATE_RX_INIT_DATA;
> +	case IOSTATE_RX_INIT_DATA:
> +		conn->rx_size = roundup(conn->req.datasize, 4);
> +		if (conn->rx_size) {
> +			conn->rx_iostate = IOSTATE_RX_DATA;
> +			conn->rx_buffer = conn->req.data;
> +		} else {
> +			conn->rx_iostate = IOSTATE_RX_END;
> +			break;
> +		}
> +	case IOSTATE_RX_DATA:
> +		ret = do_recv(fd, conn, ddigest ?
> +			      IOSTATE_RX_INIT_DDIGEST : IOSTATE_RX_END);
> +		if (ret <= 0 || conn->rx_iostate != IOSTATE_RX_INIT_DDIGEST)
> +			break;
> +	case IOSTATE_RX_INIT_DDIGEST:
> +		conn->rx_buffer = conn->rx_digest;
> +		conn->rx_size = sizeof(conn->rx_digest);
> +		conn->rx_iostate = IOSTATE_RX_DDIGEST;
> +	case IOSTATE_RX_DDIGEST:
> +		ret = do_recv(fd, conn, IOSTATE_RX_CHECK_DDIGEST);
> +		if (ret <= 0 || conn->rx_iostate != IOSTATE_RX_CHECK_DDIGEST)
>  			break;
> +	case IOSTATE_RX_CHECK_DDIGEST:
> +		crc = ~0;
> +		crc = crc32c(crc, conn->req.data, roundup(conn->req.datasize, 4));
> +		crc = ~__cpu_to_le32(crc);
> +		conn->rx_iostate = IOSTATE_RX_END;
> +		if (*((uint32_t *)conn->rx_digest) != crc) {
> +			eprintf("rx hdr digest error 0x%x calc 0x%x\n",
> +				*((uint32_t *)conn->rx_digest), crc);
> +			conn->state = STATE_CLOSE;
> +		}
> +		break;
> +	default:
> +		eprintf("error %d %d\n", conn->state, conn->rx_iostate);
> +		exit(1);
> +	}
>  
> -		switch (conn->rx_iostate) {
> -		case IOSTATE_READ_BHS:
> -			conn->req.ahssize = conn->req.bhs.hlength * 4;
> -			conn->req.datasize = ntoh24(conn->req.bhs.dlength);
> +	if (ret < 0 ||
> +	    conn->rx_iostate != IOSTATE_RX_END ||
> +	    conn->state == STATE_CLOSE)
> +		return;
>  
> -			if (conn->state == STATE_SCSI) {
> -				res = iscsi_task_rx_start(conn);
> -				if (res) {
> -					conn->state = STATE_CLOSE;
> -					break;
> -				}
> -			} else {
> -				conn->rx_buffer = conn->req_buffer;
> -				conn->req.ahs = conn->rx_buffer;
> -				conn->rx_size = roundup(conn->req.ahssize, 4);
> -				conn->req.data = conn->rx_buffer + conn->rx_size;
> -				conn->rx_size += roundup(conn->req.datasize, 4);
> -			}
> +	if (conn->rx_size) {
> +		eprintf("error %d %d %d\n", conn->state, conn->rx_iostate,
> +			conn->rx_size);
> +		exit(1);
> +	}
>  
> -			if (conn->rx_size) {
> -				conn->rx_iostate = IOSTATE_READ_AHS_DATA;
> -				goto read_again;
> -			}
> +	if (conn->state == STATE_SCSI) {
> +		ret = iscsi_task_rx_done(conn);
> +		if (ret)
> +			conn->state = STATE_CLOSE;
> +		else
> +			conn_read_pdu(conn);
> +	} else {
> +		conn_write_pdu(conn);
> +		tgt_event_modify(fd, EPOLLOUT);
> +		ret = cmnd_execute(conn);
> +		if (ret)
> +			conn->state = STATE_CLOSE;
> +	}
> +}
>  
> -		case IOSTATE_READ_AHS_DATA:
> -			if (conn->state == STATE_SCSI) {
> -				res = iscsi_task_rx_done(conn);
> -				if (!res)
> -					conn_read_pdu(conn);
> -			} else {
> -				conn_write_pdu(conn);
> -				tgt_event_modify(fd, EPOLLOUT);
> -				res = cmnd_execute(conn);
> -			}
> +static int do_send(int fd, struct iscsi_connection *conn, int next_state)
> +{
> +	int ret;
> +again:
> +	ret = conn->tp->ep_write_begin(fd, conn->tx_buffer, conn->tx_size);
> +	if (ret < 0) {
> +		if (errno != EINTR && errno != EAGAIN)
> +			conn->state = STATE_CLOSE;
> +		else if (errno == EINTR || errno == EAGAIN)
> +			goto again;
>  
> -			if (res)
> -				conn->state = STATE_CLOSE;
> -			break;
> -		}
> -		break;
> +		return -EIO;
>  	}
> +
> +	conn->tx_size -= ret;
> +	conn->tx_buffer += ret;
> +	if (conn->tx_size)
> +		goto again;
> +	conn->tx_iostate = next_state;
> +
> +	return 0;
>  }
>  
>  static void iscsi_tx_handler(int fd, struct iscsi_connection *conn)
>  {
> -	int res;
> +	int ret = 0, hdigest, ddigest;
> +	uint32_t crc;
> +
> +	if (conn->state == STATE_SCSI) {
> +		struct param *p = conn->session_param;
> +		hdigest = p[ISCSI_PARAM_HDRDGST_EN].val & DIGEST_CRC32C;
> +		ddigest = p[ISCSI_PARAM_DATADGST_EN].val & DIGEST_CRC32C;
> +	} else
> +		hdigest = ddigest = 0;
>  
>  	if (conn->state == STATE_SCSI && !conn->tx_task) {
> -		res = iscsi_task_tx_start(conn);
> -		if (res)
> +		ret = iscsi_task_tx_start(conn);
> +		if (ret)
>  			return;
>  	}
>  
>  	switch (conn->tx_iostate) {
> -	case IOSTATE_WRITE_BHS:
> -	case IOSTATE_WRITE_AHS:
> -	case IOSTATE_WRITE_DATA:
> -	write_again:
> -		res = conn->tp->ep_write_begin(fd, conn->tx_buffer,
> -					       conn->tx_size);
> -		if (res < 0) {
> -			if (errno != EINTR && errno != EAGAIN)
> -				conn->state = STATE_CLOSE;
> -			else if (errno == EINTR)
> -				goto write_again;
> +	case IOSTATE_TX_BHS:
> +		ret = do_send(fd, conn, IOSTATE_TX_INIT_AHS);
> +		if (ret < 0)
>  			break;
> -		}
> +	case IOSTATE_TX_INIT_AHS:
> +		if (conn->rsp.ahssize) {
> +			conn->tx_iostate = IOSTATE_TX_AHS;
> +			conn->tx_buffer = conn->rsp.ahs;
> +			conn->tx_size = conn->rsp.ahssize;
>  
> -		conn->tx_size -= res;
> -		conn->tx_buffer += res;
> -		if (conn->tx_size)
> -			goto write_again;
> -
> -		switch (conn->tx_iostate) {
> -		case IOSTATE_WRITE_BHS:
> -			if (conn->rsp.ahssize) {
> -				conn->tx_iostate = IOSTATE_WRITE_AHS;
> -				conn->tx_buffer = conn->rsp.ahs;
> -				conn->tx_size = conn->rsp.ahssize;
> -				goto write_again;
> -			}
> -		case IOSTATE_WRITE_AHS:
> -			if (conn->rsp.datasize) {
> -				int pad;
> -
> -				conn->tx_iostate = IOSTATE_WRITE_DATA;
> -				conn->tx_buffer = conn->rsp.data;
> -				conn->tx_size = conn->rsp.datasize;
> -				pad = conn->tx_size & (PAD_WORD_LEN - 1);
> -				if (pad) {
> -					pad = PAD_WORD_LEN - pad;
> -					memset(conn->tx_buffer + conn->tx_size,
> -					       0, pad);
> -					conn->tx_size += pad;
> -				}
> -				goto write_again;
> -			}
> -		case IOSTATE_WRITE_DATA:
> -			conn->tp->ep_write_end(fd);
> -			cmnd_finish(conn);
> +			conn->tx_iostate = IOSTATE_TX_AHS;
> +		} else
> +			conn->tx_iostate = hdigest ?
> +				IOSTATE_TX_INIT_HDIGEST : IOSTATE_TX_INIT_DATA;
>  
> -			switch (conn->state) {
> -			case STATE_KERNEL:
> -				res = conn_take_fd(conn, fd);
> -				if (res)
> -					conn->state = STATE_CLOSE;
> -				else {
> -					conn->state = STATE_SCSI;
> -					conn_read_pdu(conn);
> -					tgt_event_modify(fd, EPOLLIN);
> -				}
> -				break;
> -			case STATE_EXIT:
> -			case STATE_CLOSE:
> -				break;
> -			case STATE_SCSI:
> -				iscsi_task_tx_done(conn);
> -				break;
> -			default:
> -				conn_read_pdu(conn);
> -				tgt_event_modify(fd, EPOLLIN);
> -				break;
> +		if (conn->tx_iostate != IOSTATE_TX_AHS)
> +			break;
> +	case IOSTATE_TX_AHS:
> +		conn->tx_iostate = hdigest ?
> +			IOSTATE_TX_INIT_HDIGEST : IOSTATE_TX_INIT_DATA;
> +		if (conn->tx_iostate != IOSTATE_TX_INIT_HDIGEST)
> +			break;
> +	case IOSTATE_TX_INIT_HDIGEST:
> +		crc = ~0;
> +		crc = crc32c(crc, &conn->rsp.bhs, BHS_SIZE);
> +		*(uint32_t *)conn->tx_digest = ~__cpu_to_le32(crc);
> +		conn->tx_iostate = IOSTATE_TX_HDIGEST;
> +		conn->tx_buffer = conn->tx_digest;
> +		conn->tx_size = sizeof(conn->tx_digest);
> +	case IOSTATE_TX_HDIGEST:
> +		ret = do_send(fd, conn, IOSTATE_TX_INIT_DATA);
> +		if (ret < 0)
> +			break;
> +	case IOSTATE_TX_INIT_DATA:
> +		if (conn->rsp.datasize) {
> +			int pad;
> +
> +			conn->tx_iostate = IOSTATE_TX_DATA;
> +			conn->tx_buffer = conn->rsp.data;
> +			conn->tx_size = conn->rsp.datasize;
> +			pad = conn->tx_size & (PAD_WORD_LEN - 1);
> +			if (pad) {
> +				pad = PAD_WORD_LEN - pad;
> +				memset(conn->tx_buffer + conn->tx_size, 0, pad);
> +				conn->tx_size += pad;
>  			}
> +		} else
> +			conn->tx_iostate = IOSTATE_TX_END;
> +		if (conn->tx_iostate != IOSTATE_TX_DATA)
>  			break;
> -		}
> -
> +	case IOSTATE_TX_DATA:
> +		ret = do_send(fd, conn, ddigest ?
> +			      IOSTATE_TX_INIT_DDIGEST : IOSTATE_TX_END);
> +		if (ret < 0)
> +			return;
> +		if (conn->tx_iostate != IOSTATE_TX_INIT_DDIGEST)
> +			break;
> +	case IOSTATE_TX_INIT_DDIGEST:
> +		crc = ~0;
> +		crc = crc32c(crc, conn->rsp.data,
> +			     roundup(conn->rsp.datasize, 4));
> +		*(uint32_t *)conn->tx_digest = ~__cpu_to_le32(crc);
> +		conn->tx_iostate = IOSTATE_TX_DDIGEST;
> +		conn->tx_buffer = conn->tx_digest;
> +		conn->tx_size = sizeof(conn->tx_digest);
> +	case IOSTATE_TX_DDIGEST:
> +		ret = do_send(fd, conn, IOSTATE_TX_END);
>  		break;
>  	default:
> -		eprintf("illegal iostate %d %d\n", conn->tx_iostate,
> -			conn->tx_iostate);
> -		conn->state = STATE_CLOSE;
> +		eprintf("error %d %d\n", conn->state, conn->tx_iostate);
> +		exit(1);
>  	}
>  
> +	if (ret < 0 ||
> +	    conn->tx_iostate != IOSTATE_TX_END ||
> +	    conn->state == STATE_CLOSE)
> +		return;
> +
> +	if (conn->tx_size) {
> +		eprintf("error %d %d %d\n", conn->state, conn->tx_iostate,
> +			conn->tx_size);
> +		exit(1);
> +	}
> +
> +	conn->tp->ep_write_end(fd);
> +	cmnd_finish(conn);
> +
> +	switch (conn->state) {
> +	case STATE_KERNEL:
> +		ret = conn_take_fd(conn, fd);
> +		if (ret)
> +			conn->state = STATE_CLOSE;
> +		else {
> +			conn->state = STATE_SCSI;
> +			conn_read_pdu(conn);
> +			tgt_event_modify(fd, EPOLLIN);
> +		}
> +		break;
> +	case STATE_EXIT:
> +	case STATE_CLOSE:
> +		break;
> +	case STATE_SCSI:
> +		iscsi_task_tx_done(conn);
> +		break;
> +	default:
> +		conn_read_pdu(conn);
> +		tgt_event_modify(fd, EPOLLIN);
> +		break;
> +	}
>  }
>  
>  void iscsi_event_handler(int fd, int events, void *data)
> @@ -1838,8 +2024,10 @@ void iscsi_event_handler(int fd, int eve
>  	if (conn->state != STATE_CLOSE && events & EPOLLOUT)
>  		iscsi_tx_handler(fd, conn);
>  
> -	if (conn->state == STATE_CLOSE)
> +	if (conn->state == STATE_CLOSE) {
>  		conn_close(conn, fd);
> +		dprintf("connection closed\n");
> +	}
>  }
>  
>  struct tgt_driver iscsi = {
> diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
> index 84d74f3..29abc5d 100644
> --- a/usr/iscsi/iscsid.h
> +++ b/usr/iscsi/iscsid.h
> @@ -174,6 +174,9 @@ struct iscsi_connection {
>  
>  	struct list_head tx_clist;
>  
> +	unsigned char rx_digest[4];
> +	unsigned char tx_digest[4];
> +
>  	int auth_state;
>  	union {
>  		struct {
> @@ -187,13 +190,6 @@ struct iscsi_connection {
>  	struct iscsi_transport *tp;
>  };
>  
> -#define IOSTATE_FREE		0
> -#define IOSTATE_READ_BHS	1
> -#define IOSTATE_READ_AHS_DATA	2
> -#define IOSTATE_WRITE_BHS	3
> -#define IOSTATE_WRITE_AHS	4
> -#define IOSTATE_WRITE_DATA	5
> -
>  #define STATE_FREE		0
>  #define STATE_SECURITY		1
>  #define STATE_SECURITY_AUTH	2
> @@ -263,14 +259,13 @@ extern void conn_put(struct iscsi_connec
>  extern int conn_get(struct iscsi_connection *conn);
>  extern struct iscsi_connection * conn_find(struct iscsi_session *session, uint32_t cid);
>  extern int conn_take_fd(struct iscsi_connection *conn, int fd);
> -extern void conn_read_pdu(struct iscsi_connection *conn);
> -extern void conn_write_pdu(struct iscsi_connection *conn);
>  extern void conn_add_to_session(struct iscsi_connection *conn, struct iscsi_session *session);
>  
>  /* iscsid.c */
>  extern void iscsi_event_handler(int fd, int events, void *data);
>  extern char *text_key_find(struct iscsi_connection *conn, char *searchKey);
>  extern void text_key_add(struct iscsi_connection *conn, char *key, char *value);
> +extern void conn_read_pdu(struct iscsi_connection *conn);
>  
>  /* iscsid.c iscsi_task */
>  extern void iscsi_free_task(struct iscsi_task *task);
> 
> 




More information about the stgt mailing list