UNMAP: propagate request to backing store

This commit is contained in:
chessman
2019-05-29 16:14:31 +03:00
parent 22d47a9212
commit 12b06c21ef
6 changed files with 36 additions and 14 deletions

View File

@@ -351,7 +351,7 @@ type BackingStore interface {
Write([]byte, int64) error
DataSync() error
DataAdvise(int64, int64, uint32) error
Unmap() error
Unmap([]UnmapBlockDescriptor) error
}
type SCSIDeviceProtocol interface {
@@ -401,3 +401,8 @@ type SCSILu struct {
}
type LUNMap map[uint64]*SCSILu
type UnmapBlockDescriptor struct {
Offset uint64
TL uint32
}

View File

@@ -64,6 +64,7 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
rbuf, wbuf []byte
tl int64 = int64(cmd.TL)
)
key = HARDWARE_ERROR
asc = ASC_INTERNAL_TGT_FAILURE
switch opcode {
@@ -134,12 +135,6 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
}
doVerify = true
goto verify
case api.UNMAP:
err = bs.Unmap()
if err != nil {
key = MEDIUM_ERROR
asc = NO_ADDITIONAL_SENSE
}
default:
break
}

View File

@@ -150,6 +150,6 @@ func (bs *CephBackingStore) DataAdvise(offset, length int64, advise uint32) erro
return nil
}
func (bs *CephBackingStore) Unmap() error {
func (bs *CephBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
return nil
}

View File

@@ -114,6 +114,6 @@ func (bs *FileBackingStore) DataAdvise(offset, length int64, advise uint32) erro
return util.Fadvise(bs.file, offset, length, advise)
}
func (bs *FileBackingStore) Unmap() error {
func (bs *FileBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
return nil
}

View File

@@ -75,6 +75,6 @@ func (bs *NullBackingStore) DataAdvise(offset, length int64, advise uint32) erro
return nil
}
func (bs *NullBackingStore) Unmap() error {
func (bs *NullBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
return nil
}

View File

@@ -18,6 +18,7 @@ limitations under the License.
package scsi
import (
"encoding/binary"
"fmt"
"unsafe"
@@ -295,13 +296,34 @@ sense:
}
func SBCUnmap(host int, cmd *api.SCSICommand) api.SAMStat {
err, key, asc := bsPerformCommand(cmd.Device.Storage, cmd)
if err == nil {
// check ANCHOR
if cmd.SCB[1]&0x01 != 0 {
BuildSenseData(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB)
return api.SAMStatCheckCondition
}
const blockDescLen = 16
var blockDescs []api.UnmapBlockDescriptor
for off := 8; uint32(off+blockDescLen) <= cmd.OutSDBBuffer.Length; off += blockDescLen {
lba := binary.BigEndian.Uint64(cmd.OutSDBBuffer.Buffer[off : off+8])
num := binary.BigEndian.Uint32(cmd.OutSDBBuffer.Buffer[off+8 : off+12])
blockDescs = append(blockDescs, api.UnmapBlockDescriptor{
Offset: lba << cmd.Device.BlockShift,
TL: num << cmd.Device.BlockShift,
})
}
if len(blockDescs) == 0 {
return api.SAMStatGood
}
BuildSenseData(cmd, key, asc)
return api.SAMStatCheckCondition
if err := cmd.Device.Storage.Unmap(blockDescs); err != nil {
BuildSenseData(cmd, MEDIUM_ERROR, NO_ADDITIONAL_SENSE)
return api.SAMStatCheckCondition
}
return api.SAMStatGood
}
/*