UNMAP: propagate request to backing store
This commit is contained in:
@@ -351,7 +351,7 @@ type BackingStore interface {
|
|||||||
Write([]byte, int64) error
|
Write([]byte, int64) error
|
||||||
DataSync() error
|
DataSync() error
|
||||||
DataAdvise(int64, int64, uint32) error
|
DataAdvise(int64, int64, uint32) error
|
||||||
Unmap() error
|
Unmap([]UnmapBlockDescriptor) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SCSIDeviceProtocol interface {
|
type SCSIDeviceProtocol interface {
|
||||||
@@ -401,3 +401,8 @@ type SCSILu struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LUNMap map[uint64]*SCSILu
|
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
|
rbuf, wbuf []byte
|
||||||
tl int64 = int64(cmd.TL)
|
tl int64 = int64(cmd.TL)
|
||||||
)
|
)
|
||||||
|
|
||||||
key = HARDWARE_ERROR
|
key = HARDWARE_ERROR
|
||||||
asc = ASC_INTERNAL_TGT_FAILURE
|
asc = ASC_INTERNAL_TGT_FAILURE
|
||||||
switch opcode {
|
switch opcode {
|
||||||
@@ -134,12 +135,6 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
|
|||||||
}
|
}
|
||||||
doVerify = true
|
doVerify = true
|
||||||
goto verify
|
goto verify
|
||||||
case api.UNMAP:
|
|
||||||
err = bs.Unmap()
|
|
||||||
if err != nil {
|
|
||||||
key = MEDIUM_ERROR
|
|
||||||
asc = NO_ADDITIONAL_SENSE
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,6 @@ func (bs *CephBackingStore) DataAdvise(offset, length int64, advise uint32) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *CephBackingStore) Unmap() error {
|
func (bs *CephBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,6 @@ func (bs *FileBackingStore) DataAdvise(offset, length int64, advise uint32) erro
|
|||||||
return util.Fadvise(bs.file, offset, length, advise)
|
return util.Fadvise(bs.file, offset, length, advise)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *FileBackingStore) Unmap() error {
|
func (bs *FileBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,6 @@ func (bs *NullBackingStore) DataAdvise(offset, length int64, advise uint32) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *NullBackingStore) Unmap() error {
|
func (bs *NullBackingStore) Unmap([]api.UnmapBlockDescriptor) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ limitations under the License.
|
|||||||
package scsi
|
package scsi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -295,13 +296,34 @@ sense:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SBCUnmap(host int, cmd *api.SCSICommand) api.SAMStat {
|
func SBCUnmap(host int, cmd *api.SCSICommand) api.SAMStat {
|
||||||
err, key, asc := bsPerformCommand(cmd.Device.Storage, cmd)
|
// check ANCHOR
|
||||||
if err == nil {
|
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
|
return api.SAMStatGood
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildSenseData(cmd, key, asc)
|
if err := cmd.Device.Storage.Unmap(blockDescs); err != nil {
|
||||||
return api.SAMStatCheckCondition
|
BuildSenseData(cmd, MEDIUM_ERROR, NO_ADDITIONAL_SENSE)
|
||||||
|
return api.SAMStatCheckCondition
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.SAMStatGood
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user