NVMe中对应SCSI 'VERIFY'的操作及无数据传输场景实现方法
把SCSI VERIFY(无数据传输)转成NVMe操作的正确姿势
刚好对SCSI和NVMe的命令映射比较熟,针对你说的这种仅指定起始LBA、验证长度,其余字段全0的无数据SCSI VERIFY操作,直接用NVMe的Verify命令就能完美对应,下面给你讲透细节:
核心对应逻辑
SCSI的VERIFY本质是让存储设备检查指定LBA范围内的介质完整性(比如ECC校验、内部数据一致性),全程不需要主机和设备之间传输数据。NVMe协议里专门设计了Verify命令(命令操作码为0x0F),就是用来实现这个需求的,完全匹配你的场景。
关键参数怎么配?
你需要在NVMe Verify命令的命令描述符字(CDW)里正确设置对应字段,和SCSI的参数一一对应:
- 起始LBA(SLBA):对应SCSI的
st lba,填在CDW10到CDW13组成的64位SLBA字段里 - 验证长度:SCSI里的验证长度是要检查的块数,NVMe里用
NLB(Number of Logical Blocks)字段,注意这个字段是块数减1(比如要验证10个LBA块,NLB就设为9),放在CDW14的低16位 - 无数据传输的关键设置:因为不需要传输任何数据,要确保命令的PRP(物理区域指针)或SGL(散列收集列表)字段留空,同时CDW0里的FUSE、PSDT等和数据传输相关的标志位都保持默认0
额外要注意的细节
- NVMe的Verify命令默认会做介质级别的完整性校验,如果要和你说的SCSI VERIFY(其余字段全0)的行为完全对齐,记得把CDW15里的
DW(Data Verify)和PI(Protection Information)位都设为0:PI=0表示不检查保护信息,对应SCSI里保护信息相关字段为0的情况DW=0表示只做介质校验,不需要验证数据内容(毕竟你也没传数据过来)
- 有些厂商的NVMe设备可能有自定义简化命令,但标准的
0x0FVerify命令是跨设备兼容的,优先用这个准没错
给你贴个伪代码形式的命令结构示例,更直观:
// NVMe Verify命令结构(对应无数据传输的SCSI VERIFY) struct nvme_verify_cmd { uint8_t opcode; // 固定为0x0F(Verify命令操作码) uint8_t flags; // 0x00,无特殊标志 uint16_t command_id; // 自定义的命令ID,用来区分不同命令 uint32_t cdw2; // 0x00,保留字段 uint32_t cdw3; // 0x00,保留字段 uint64_t slba; // 要验证的起始LBA(对应SCSI的st lba) uint32_t cdw14; // 低16位填NLB = 验证块数 - 1,高16位保留为0 uint32_t cdw15; // 0x00,DW=0、PI=0,不做额外校验 // PRP1、PRP2或SGL相关字段全部留空,无数据传输 };
总的来说,只要用NVMe的0x0F Verify命令,按上面的要求配置参数,就能实现和你描述的SCSI VERIFY完全一致的功能。
内容的提问来源于stack exchange,提问作者Parzival
相关产品推荐
相关产品推荐

