當我們講到scsi命令這個概念時,需要根據上下文去理解。可能指代兩個概念:
- 一種含義指SCSI協議規劃中定義的SCSI 命令描述塊(Command descriptor block (CDB))。此描述塊定義了需要target處理的具體的操作。遵循特定的數據格式,其格式根據操作的不同而不同。SCSI規范中針對每個命令的CDB都有詳細的說明。描述塊會經過傳輸層完整的傳送到scsi target用于解析并執行。
- 另外一種含義指內核中定義的scsi_cmnd結構。該結構定義于linux/include/scsi/scsi_cmnd.h
中,描述了請求在SCSI子系統執行所需要的數據結構。每個請求都會創建一個scsi_cmnd數據結構。它創建于請求的初始化,結束于命令被正確的執行或者在操作中出現錯誤。其存儲的信息不僅僅包括了最終發送給scsi target的數據,也包括了在scsi子系統和scsi底層驅動執行中需要的運行時信息。
隨著技術的發展 ,存儲設備的容量持續增長。原有的SCSI指令的尋址空間不能滿足新的要求,于是就定了新的可支持更大空間的CBD格式。考慮到向前兼容,SCSI協議沒有取消原有的指令,而是重新定義操作碼。于是,針對一種服務(如讀、寫)定義了多種指令格式。
CBD格式分為定長格式和變長格式。
定長格式的CBD包括6、10、12、16四種格式,數字表示CBD的長度(單位:字節)。所有定長指令的第一個字節均為操作碼,最后一個字節為控制塊。其它域取決于指令。
變長格式,其長度取決于具體的指令。如READ(32)、WRITE(32)分別為32字節。變長格式第一個字節為操作碼,固定為操作碼(7Fh),其具體服務(如讀、寫)放在SERVICE ACTION
域,即CBD的第8、第9字節。變長格式的前10個字節是固定的。
無論是定長格式還是變長格式,都包括固定部分,即所有的指令都有的。這樣有利于程序設計。系統可以將CBD前幾個字節進行統一的解析,再進一步的根據操作碼判斷后面是否有數據段需要進一步解析。
CDB在內核中表現為一個連續的內存空間。通常它的存儲空間在請求初始化時被創建,隨著請求完成被釋放。請求初始化過程中給cmnd分配了16個字節。
當CDB長度大于32時,驅動程序它初始化時創建的專用緩存池sd_cdb_pool
上申請。
READ讀命令可以分成兩種格式。READ(10)、READ(12)、READ(16)格式一致,歸為第一類。READ32歸為第二類。
READ(10)、READ(12)、READ(16)所包括的屬性一致。兩者別在于LBA與數據傳輸字節數兩個字段的長度,這兩個字段長度決定了SCSI指令所能支持的最大容量和一次IO最大的數據長度。自SCSI-3始,規范建議實現方將READ(10-12)遷移到READ16上。
READ(16) CBD格式如下圖:
各個字段含義:
字段 | 含義 | 實現 |
---|---|---|
OPERATION CODE | 指令操作碼|調用sd_setup_read_write_cmnd 設定 | |
RDPROTECT | DIF支持相關屬性 | 調用sd_setup_read_write_cmnd 設定;設定值取決于磁盤DIF保護方式 |
DPO | 禁用頁面緩存(Disable Page Out)。 設定1意為執行此操作時,不進行緩存替換 設定為0意為讀取時同時在設備緩存中保留此數據 | Linux永遠設為0 |
FUA | 強制訪問介質。 如果設定為1,意味著target強制從介質中讀取數據,而非從緩存中 | 在構造IO請求(struct request )時根據應用要求設置; |
RARC | 重構輔助模式。 | scsi層未處理 |
LOGICAL BLOCK ADDRESS | 讀命令的起始地址 | 與請求的起始地址一致。以扇區(512字節)為單位 |
TRANSFER LENGTH | 讀寫數據長度 | 與請求的讀寫長度一致 |
CONTROL | 命令控制塊 | SCSI子系統未設定 |
變長由自第12字節始的8字節表示LBA,由第28字節始的4個字節表示數據長度。其支持的最大容量與最大扇區數與READ16相同。其它變量的含義與READ(16),不詳細解釋。
比定長CBD多出來的字節主要是用于數據校驗。T10是用于解決靜默錯誤的一種機制。
數據在讀寫環境中要經過多個部件、多個傳輸渠道和多層次的軟件系統,考慮到性能,系統設計過程中并非每層次都對數據進行檢測。如此,最終固化的到磁盤上的數據可能是不正確的。為避免此類錯誤存在,ANSI T10 定義了一種通過對每個數據塊加入保護信息(PI:Protection Information)也曾被稱作數據完整性域(DIF:Data Integrity Field)的方法來保護數據完整性。只有開啟T10信息檢驗且采用type2 保護信息時,才使用READ(10)命令格式。
P10在企業Oracle數據庫應用比較廣泛,且是存儲一大亮點,所以主流的存儲廠商都支持該特性,如EMC VNX系列支持自定義PI、VMAX支持標準的T10 PI,且支持DIX;HDS HUS系列支持自定義PI、HDS VSP支持PI;IBM DS8000支持標準的T10 PI,DS5000某些特定型號支持PI;HP P10000支持標準的T10 PI,華為 OceanStor 18000和V3全系列。 1
寫命令與讀命令在格式上非常相似,也分為多種格式。
不同的寫操作對應的服務是一致的。在Target端可對應于相同的實現。以WRITE(10)為例。其操作碼為24A。同時,也包括了用于DIF處理的WRPROTECT域,用于緩存控制的DPO、FUA域。
iscsi是什么。scsi_cmnd結構體記錄了scsi_cmnd需要處理的所有的上下文。系統在初始化request
時就為scsi_cmnd申請空間。當request
在子系統處理完成,scsi上層驅動根據request
創建scsi_cmnd
。面向IO的scsi_cmnd
與request
是一對一的關系。
scsi_cmnd
包含了scsi指令處理所需要的信息,包括CBD、數據、sense data等域。除此之外,還包括一些控制域。
scsi_cmnd
包含了scsi設備的相關信息,用于確定交scsi_cmnd針對于哪個設備。在
scsi_cmnd
流轉時,設備類型相關的邏輯處理完成,系統更加關注指令和數據在通信鏈路上的流轉。即關注總線、主機適配器、傳輸層等信息。
scsi_cmnd
生命周期中可能被掛接到多個不同的隊列,代表不同的控制面。大多數據情況,scsi_cmnd
鏈接到主機適配器的命令處理隊列中;在處理過程發生故障時,它又被錯誤處理相關的隊列中暫存,一旦故障恢復,再進行繼續處理;如果因為設備忙等原因,主機適配器不能接收scsi命令時,scsi_cmnd
將放到延時處理鏈表中,等合適的時機再行處理。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态