Merge pull request #51 from openebs/dev

Send data in dataIn PDUs splitted by maxRecvDataSegment Length
This commit is contained in:
Lei Xue
2017-04-23 19:35:38 +08:00
committed by GitHub
4 changed files with 69 additions and 17 deletions

View File

@@ -33,6 +33,11 @@ const (
OpReject = 0x3f
)
const (
MaxBurstLength uint32 = 262144
MaxRecvDataSegmentLength uint32 = 65536
)
var opCodeMap = map[OpCode]string{
OpNoopOut: "NOP-Out",
OpSCSICmd: "SCSI Command",
@@ -62,6 +67,7 @@ type ISCSICommand struct {
DataLen int
RawData []byte
Final bool
FinalInSeq bool
Immediate bool
TaskTag uint32
ExpCmdSN, MaxCmdSN uint32
@@ -276,23 +282,26 @@ func (m *ISCSICommand) dataInBytes() []byte {
buf := &bytes.Buffer{}
buf.WriteByte(byte(OpSCSIIn))
var b byte
b = 0x80
if m.HasStatus {
b = 0x0
if m.FinalInSeq || m.Final == true {
b |= 0x80
}
if m.HasStatus && m.Final == true {
b |= 0x01
}
buf.WriteByte(b)
buf.WriteByte(0x00)
if m.HasStatus {
if m.HasStatus && m.Final == true {
b = byte(m.Status)
}
buf.WriteByte(b)
buf.WriteByte(0x00) // 4
buf.Write(util.MarshalUint64(uint64(len(m.RawData)))[5:]) // 5-8
// Skip through to byte 16
buf.Write(util.MarshalUint64(uint64(m.DataLen))[5:]) // 5-8
// Skip through to byte 16 Since A bit is not set 11.7.4
for i := 0; i < 8; i++ {
buf.WriteByte(byte(m.LUN[i]))
buf.WriteByte(0x00)
}
buf.Write(util.MarshalUint64(uint64(m.TaskTag))[4:])
for i := 0; i < 4; i++ {
@@ -307,8 +316,8 @@ func (m *ISCSICommand) dataInBytes() []byte {
for i := 0; i < 4; i++ {
buf.WriteByte(0x00)
}
buf.Write(m.RawData)
dl := len(m.RawData)
buf.Write(m.RawData[m.BufferOffset : m.BufferOffset+uint32(m.DataLen)])
dl := m.DataLen
for dl%4 > 0 {
dl++
buf.WriteByte(0x00)

View File

@@ -77,7 +77,10 @@ type iscsiConnection struct {
// ExpCmdSN - the next expected command sequence number at the target
expCmdSN uint32
// MaxCmdSN - the maximum CmdSN acceptable at the target from this initiator
maxCmdSN uint32
maxCmdSN uint32
maxRecvDataSegmentLength uint32
maxBurstLength uint32
maxSeqCount uint32
rxTask *iscsiTask
txTask *iscsiTask

View File

@@ -330,6 +330,9 @@ func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error {
conn.loginParam.isid = cmd.ISID
conn.loginParam.tsih = cmd.TSIH
conn.expCmdSN = cmd.CmdSN
conn.maxBurstLength = MaxBurstLength
conn.maxRecvDataSegmentLength = MaxRecvDataSegmentLength
conn.maxSeqCount = conn.maxBurstLength / conn.maxRecvDataSegmentLength
if conn.loginParam.iniCSG == SecurityNegotiation {
conn.state = CONN_STATE_EXIT
@@ -428,9 +431,11 @@ func iscsiExecR2T(conn *iscsiConnection) error {
func (s *ISCSITargetDriver) txHandler(conn *iscsiConnection) {
var (
hdigest uint = 0
ddigest uint = 0
final bool = false
hdigest uint = 0
ddigest uint = 0
offset uint32 = 0
final bool = false
count uint32 = 0
)
if conn.state == CONN_STATE_SCSI {
hdigest = conn.loginParam.sessionParam[ISCSI_PARAM_HDRDGST_EN].Value & DIGEST_CRC32C
@@ -443,14 +448,42 @@ func (s *ISCSITargetDriver) txHandler(conn *iscsiConnection) {
return
}
}
resp := conn.resp
segmentLen := conn.maxRecvDataSegmentLength
transferLen := len(resp.RawData)
resp.DataSN = 0
maxCount := conn.maxSeqCount
/* send data splitted by segmentLen */
SendRemainingData:
if resp.OpCode == OpSCSIIn {
resp.BufferOffset = offset
if int(offset+segmentLen) < transferLen {
count += 1
if count < maxCount {
resp.FinalInSeq = false
resp.Final = false
} else {
count = 0
resp.FinalInSeq = true
resp.Final = false
}
offset = offset + segmentLen
resp.DataLen = int(segmentLen)
} else {
resp.FinalInSeq = true
resp.Final = true
resp.DataLen = transferLen - int(offset)
}
}
for {
switch conn.txIOState {
case IOSTATE_TX_BHS:
log.Debug("ready to write response")
log.Debugf("%s", conn.resp.String())
log.Debugf("length of RawData is %d", len(conn.resp.RawData))
log.Debugf("length of resp is %d", len(conn.resp.Bytes()))
if l, err := conn.write(conn.resp.Bytes()); err != nil {
log.Debugf("%s", resp.String())
log.Debugf("length of RawData is %d", len(resp.RawData))
log.Debugf("length of resp is %d", len(resp.Bytes()))
if l, err := conn.write(resp.Bytes()); err != nil {
log.Error(err)
return
} else {
@@ -479,7 +512,13 @@ func (s *ISCSITargetDriver) txHandler(conn *iscsiConnection) {
}
if final {
break
if resp.OpCode == OpSCSIIn && resp.Final != true {
resp.DataSN++
conn.txIOState = IOSTATE_TX_BHS
goto SendRemainingData
} else {
break
}
}
}

View File

@@ -16,6 +16,7 @@ var (
{"InitialR2T", "Yes"},
{"MaxBurstLength", "262144"},
{"FirstBurstLength", "65536"},
{"MaxRecvDataSegmentLength", "65536"},
{"DefaultTime2Wait", "2"},
{"DefaultTime2Retain", "0"},
{"MaxOutstandingR2T", "1"},