UNMAP: propagate request to backing store
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user