target 和 iSCSI 介面指南¶
簡介和概述¶
待定
Target 核心裝置介面¶
本節為空,因為沒有 kerneldoc 註釋新增到 drivers/target/target_core_device.c。
Target 核心傳輸介面¶
-
void transport_init_session(struct se_session *se_sess)¶
初始化會話物件
引數
struct se_session *se_sess會話物件指標。
描述
呼叫者在呼叫此函式之前必須將 se_sess 歸零。
-
struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)¶
分配一個會話物件並初始化它
引數
enum target_prot_op sup_prot_ops定義支援哪些 T10-PI 模式的位掩碼。
-
int transport_alloc_session_tags(struct se_session *se_sess, unsigned int tag_num, unsigned int tag_size)¶
分配 target 驅動程式私有資料
引數
struct se_session *se_sess會話指標。
unsigned int tag_num發起方和 target 之間的最大未完成命令數。
unsigned int tag_sizetarget 驅動程式與每個命令關聯的私有資料的大小(以位元組為單位)。
-
int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags)¶
初始化 se_cmd
引數
struct se_cmd *se_cmd要初始化的命令描述符
struct se_session *se_sess端點關聯的 se_sess
unsigned char *sense指向 SCSI sense 緩衝區的指標
u64 unpacked_lun用於引用 struct se_lun 的解包 LUN
u32 data_lengthfabric 期望的資料傳輸長度
int task_attrSAM 任務屬性
int data_dirDMA 資料方向
int flags來自 target_sc_flags_tables 的命令提交標誌
描述
如果呼叫者設定了 se_cmd->tag,則支援任務標籤。
如果 fabric 驅動程式呼叫 target_stop_session,則它必須檢查返回值並處理故障。 對於其他驅動程式,這永遠不會失敗,並且可以忽略返回值。
返回
小於零表示活動 I/O 關閉失敗。
成功時返回零。
-
int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, struct scatterlist *sgl, u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count, struct scatterlist *sgl_prot, u32 sgl_prot_count, gfp_t gfp)¶
準備提交 cmd
引數
struct se_cmd *se_cmd要準備的命令描述符
unsigned char *cdb指向 SCSI CDB 的指標
struct scatterlist *sgl用於單向對映的 struct scatterlist 記憶體
u32 sgl_count用於單向對映的 scatterlist 計數
struct scatterlist *sgl_bidi用於雙向 READ 對映的 struct scatterlist 記憶體
u32 sgl_bidi_count用於雙向 READ 對映的 scatterlist 計數
struct scatterlist *sgl_protstruct scatterlist 記憶體保護資訊
u32 sgl_prot_count保護資訊的 scatterlist 計數
gfp_t gfpgfp 分配型別
返回
小於零表示失敗。
成功時返回零。
描述
如果返回失敗,lio 將呼叫 queue_status 來完成 cmd。
-
void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *cdb, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags)¶
查詢解包的 lun 並提交未初始化的 se_cmd
引數
struct se_cmd *se_cmd要提交的命令描述符
struct se_session *se_sess端點關聯的 se_sess
unsigned char *cdb指向 SCSI CDB 的指標
unsigned char *sense指向 SCSI sense 緩衝區的指標
u64 unpacked_lun用於引用 struct se_lun 的解包 LUN
u32 data_lengthfabric 期望的資料傳輸長度
int task_attrSAM 任務屬性
int data_dirDMA 資料方向
int flags來自 target_sc_flags_tables 的命令提交標誌
描述
如果呼叫者設定了 se_cmd->tag,則支援任務標籤。
這隻能從程序上下文中呼叫,並且當前還假設 target-core 內部分配 fabric 有效負載緩衝區。
它還假設內部 target 核心 SGL 記憶體分配。
此函式只能由在關閉期間執行自己的同步並且不使用 target_stop_session 的驅動程式使用。 如果發生故障,此函式將使用 CHECK_CONDITION 呼叫 fabric 驅動程式的 queue_status。
引數
struct se_cmd *se_cmd要提交的命令描述符
描述
必須已在 cmd 上呼叫 target_submit_prep 或類似的東西,並且必須從程序上下文中呼叫它。
-
int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t gfp, u64 tag, int flags)¶
查詢解包的 lun 並提交用於 TMR CDB 的未初始化 se_cmd
引數
struct se_cmd *se_cmd要提交的命令描述符
struct se_session *se_sess端點關聯的 se_sess
unsigned char *sense指向 SCSI sense 緩衝區的指標
u64 unpacked_lun用於引用 struct se_lun 的解包 LUN
void *fabric_tmr_ptrTMR 請求的 fabric 上下文
unsigned char tm_typeTM 請求的型別
gfp_t gfp呼叫者的 gfp 型別
u64 tagTMR_ABORT_TASK 的引用任務標籤
int flags提交 cmd 標誌
描述
可以從所有上下文呼叫。
引數
struct se_cmd *se_cmd要新增的命令描述符
bool ack_kref指示 fabric 將執行 ack
target_put_sess_cmd()
-
void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt)¶
停止向計數器新增新的 IO。
引數
struct target_cmd_counter *cmd_cnt要停止的計數器
-
void target_stop_session(struct se_session *se_sess)¶
停止在會話上排隊新的 IO。
引數
struct se_session *se_sess要停止的會話
-
void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt)¶
等待未完成的 cmds。
引數
struct target_cmd_counter *cmd_cnt要等待活動 I/O 的計數器。
-
void target_wait_for_sess_cmds(struct se_session *se_sess)¶
等待未完成的命令
引數
struct se_session *se_sess要等待活動 I/O 的會話
-
bool transport_wait_for_tasks(struct se_cmd *cmd)¶
設定 CMD_T_STOP 並等待 t_transport_stop_comp
引數
struct se_cmd *cmd要等待的命令
-
int target_send_busy(struct se_cmd *cmd)¶
將 SCSI BUSY 狀態傳送回啟動器
引數
struct se_cmd *cmd要為其傳送 BUSY 響應的 SCSI 命令。
注意
僅當 target_submit_cmd*() 失敗時才呼叫此函式。
Target 支援的使用者空間 I/O¶
使用者空間 I/O¶
定義 LIO 的共享記憶體介面,用於將 SCSI 命令和資料傳遞到使用者空間進行處理。 這是為了允許後端過於複雜,無法進行核心支援。
它使用 UIO 框架來為我們完成大量裝置建立和內省工作。
有關環的佈局,請參見 .h 檔案。 請注意,儘管定義了命令環,但資料區域的細節並未定義。 命令條目中的偏移值指向 mmap 區域內的其他位置。 在命令環之外有單獨的空間用於資料緩衝區。 這為移動緩衝區分配,甚至頁面翻轉或其他分配技術留下了最大的靈活性,而無需更改命令環佈局。
安全性:必須假定使用者程序是惡意的。 如果它願意,沒有辦法阻止它破壞命令環協議,但為了防止其他問題,我們必須始終僅從共享記憶體區域讀取*data*,而不是偏移量或大小。 這適用於命令環條目以及郵箱。 為此需要的額外程式碼可能帶有“UAM”註釋。
環設計¶
mmap 區域分為三個部分:1) 郵箱(下面的 struct tcmu_mailbox); 2) 命令環; 3) 命令環之外的所有內容(資料)。
郵箱告訴使用者空間命令環相對於共享記憶體區域起點的偏移量以及命令環的大小。
核心透過將 struct tcmu_cmd_entry 放入環中、更新 mailbox->cmd_head 並透過 UIO 的中斷機制來通知使用者空間,從而將 SCSI 命令傳遞給使用者空間。
tcmu_cmd_entry 包含一個標頭。 如果標頭型別為 PAD,則使用者空間應跳過 hdr->length 位元組(mod cmdr_size)以查詢下一個 cmd_entry。
否則,條目將包含到 mmap 區域中的偏移量,該區域包含 cdb 和資料緩衝區 - 後者可以透過 iov 陣列訪問。 iov 地址也是共享區域中的偏移量。
當用戶空間完成處理命令時,設定 entry->rsp.scsi_status,如果適用,填充 rsp.sense_buffer,並將 mailbox->cmd_tail 設定為舊 cmd_tail 加上 hdr->length,mod cmdr_size。 如果 cmd_tail 不等於 cmd_head,則它應該以相同的方式處理下一個資料包,依此類推。
iSCSI 輔助函式¶
-
void iscsi_prep_data_out_pdu(struct iscsi_task *task, struct iscsi_r2t_info *r2t, struct iscsi_data *hdr)¶
初始化 Data-Out
引數
struct iscsi_task *taskscsi 命令任務
struct iscsi_r2t_info *r2tR2T 資訊
struct iscsi_data *hdriscsi 資料在 pdu 中
註釋
在此 R2T 序列中初始化 Data-Out,並在此 SCSI 命令中查詢適當的 data_offset。
此函式在獲取連線鎖時呼叫。
-
void __iscsi_put_task(struct iscsi_task *task)¶
減少任務上的引用計數
引數
struct iscsi_task *task要減少引用計數的 iscsi_task
描述
呼叫時必須持有 back_lock,以防它釋放任務。
-
void iscsi_complete_scsi_task(struct iscsi_task *task, uint32_t exp_cmdsn, uint32_t max_cmdsn)¶
正常完成 scsi 任務
引數
struct iscsi_task *taskscsi cmd 的 iscsi 任務
uint32_t exp_cmdsncpu 格式的預期 cmd sn
uint32_t max_cmdsncpu 格式的最大 cmd sn
描述
當驅動程式不需要或無法執行較低級別的 pdu 處理時,將使用此選項。
使用會話 back_lock 呼叫
-
struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)¶
按 itt 查詢任務
引數
struct iscsi_conn *conniscsi 連線
itt_t ittitt
描述
這應該用於 mgmt 任務,例如登入和 nops,或者如果 LDD 的 itt 空間不包含會話期限。
必須持有會話 back_lock。
-
int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, int datalen)¶
完成 pdu
引數
struct iscsi_conn *conniscsi conn
struct iscsi_hdr *hdriscsi 標頭
char *data資料緩衝區
int datalen資料緩衝區的長度
描述
透過釋放 queuecommand 或傳送通用命令時分配的任何資源來完成 pdu 處理。 必須持有會話 back_lock,並且必須已呼叫 verify itt。
-
struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)¶
按 itt 查詢 ctask
引數
struct iscsi_conn *conniscsi 連線
itt_t ittitt
描述
這應該用於 cmd 任務。
必須持有會話 back_lock。
-
void iscsi_requeue_task(struct iscsi_task *task)¶
重新排隊任務以從會話工作佇列執行
引數
struct iscsi_task *task要重新排隊的任務
描述
呼叫方必須已獲取將要重新排隊的任務的引用。
-
void iscsi_suspend_queue(struct iscsi_conn *conn)¶
暫停 iscsi_queuecommand
引數
struct iscsi_conn *conn要停止在其上排隊 IO 的 iscsi conn
描述
這會獲取會話 frwd_lock 以確保沒有人位於 xmit_task/queuecommand 中,然後設定 suspend 以防止新命令排隊。 只有需要同步路徑的解除安裝驅動程式(例如 ep 斷開連線)才能使用 iscsi_queuecommand/xmit_task 呼叫此選項。 要再次啟動 IO,libiscsi 將在 FFP 中呼叫 iscsi_start_tx 和 iscsi_unblock_session。
-
void iscsi_suspend_tx(struct iscsi_conn *conn)¶
暫停 iscsi_data_xmit
引數
struct iscsi_conn *conniscsi conn 以停止處理 IO。
描述
此函式設定暫停位以防止 iscsi_data_xmit 傳送新的 IO,如果工作在 xmit 執行緒上排隊,它將等待它完成。
-
void iscsi_suspend_rx(struct iscsi_conn *conn)¶
阻止 recvwork 再次執行。
引數
struct iscsi_conn *conniscsi conn 以停止。
-
void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active)¶
防止排隊到 conn。
引數
struct iscsi_cls_conn *cls_conniscsi conn ep 繫結到。
bool is_activeconn 是否用於啟動,或者這是否用於 EH/終止
描述
實現 ep_disconnect callout 的驅動程式必須呼叫此選項。 它停用從 libiscsi 排隊到連線,以便準備 ep_disconnect 呼叫。
-
int iscsi_eh_session_reset(struct scsi_cmnd *sc)¶
刪除會話並嘗試重新登入
引數
struct scsi_cmnd *scscsi 命令
描述
此函式將等待重新登入、使用者空間的會話終止或恢復/替換超時。
-
int iscsi_eh_recover_target(struct scsi_cmnd *sc)¶
重置目標,並可能重置會話
引數
struct scsi_cmnd *scscsi 命令
描述
這將嘗試傳送熱目標重置。 如果失敗,我們將升級到 ERL0 會話恢復。
引數
struct Scsi_Host *shostscsi 主機
struct device *pdev父裝置
描述
部分解除安裝和軟體 iscsi 驅動程式應呼叫此選項以將主機新增到系統。
-
struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht, int dd_data_size, bool xmit_can_sleep)¶
分配主機和驅動程式資料
引數
const struct scsi_host_template *shtscsi 主機模板
int dd_data_size驅動程式主機資料大小
bool xmit_can_sleep布林值,指示 LLD 是否將從工作佇列排隊 IO
描述
部分解除安裝和軟體 iscsi 驅動程式應呼叫此選項。 要訪問驅動程式特定記憶體,請使用 iscsi_host_priv() 宏。
-
void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown)¶
刪除主機和會話
引數
struct Scsi_Host *shostscsi 主機
bool is_shutdown如果從驅動程式關閉 callout 呼叫,則為 true
描述
如果剩下任何會話,這將啟動刪除並等待完成。
-
struct iscsi_cls_session *iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, uint16_t cmds_max, int dd_size, int cmd_task_size, uint32_t initial_cmdsn, unsigned int id)¶
建立 iscsi cls 會話以及主機和會話
引數
struct iscsi_transport *iscsitiscsi 傳輸模板
struct Scsi_Host *shostscsi 主機
uint16_t cmds_max會話可以排隊的命令數量
int dd_size私有驅動程式資料大小,新增到會話分配大小
int cmd_task_sizeLLD 任務私有資料大小
uint32_t initial_cmdsn初始 CmdSN
unsigned int id要新增到此會話的目標 ID
描述
這可以被每個 SCSI 主機分配一個會話的軟體 iscsi_transports 使用。
呼叫者應將 cmds_max 設定為它們支援的最大總任務數(管理 + SCSI)。 iscsi 層為 nop 處理和登入/登出請求保留 ISCSI_MGMT_CMDS_MAX 個任務。
-
void iscsi_session_free(struct iscsi_cls_session *cls_session)¶
釋放 iscsi 會話及其資源
引數
struct iscsi_cls_session *cls_sessioniscsi 會話
-
void iscsi_session_teardown(struct iscsi_cls_session *cls_session)¶
銷燬會話和 cls_session
引數
struct iscsi_cls_session *cls_sessioniscsi 會話
-
struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, uint32_t conn_idx)¶
建立 iscsi_cls_conn 和 iscsi_conn
引數
struct iscsi_cls_session *cls_sessioniscsi_cls_session
int dd_size私有驅動程式資料大小
uint32_t conn_idxcid
-
void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)¶
拆卸 iscsi 連線
引數
struct iscsi_cls_conn *cls_conniscsi 類連線
描述
TODO: 我們可能需要將其變成一個兩步過程,例如 scsi-mls remove + put host
iSCSI 啟動資訊¶
-
struct iscsi_boot_kobj *iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, void *data, ssize_t (*show)(void *data, int type, char *buf), umode_t (*is_visible)(void *data, int type), void (*release)(void *data))¶
建立啟動目標 sysfs 目錄
引數
struct iscsi_boot_kset *boot_kset啟動 kset
int index目標 ID
void *data目標的驅動程式特定資料
ssize_t (*show) (void *data, int type, char *buf)屬性顯示函式
umode_t (*is_visible) (void *data, int type)屬性可見性函式
void (*release) (void *data)釋放函式
注意
當對目標 kobject 的所有引用都已釋放時,啟動 sysfs 庫將釋放為呼叫者傳入的資料。
-
struct iscsi_boot_kobj *iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, void *data, ssize_t (*show)(void *data, int type, char *buf), umode_t (*is_visible)(void *data, int type), void (*release)(void *data))¶
建立啟動器 sysfs 目錄
引數
struct iscsi_boot_kset *boot_kset啟動 kset
int index啟動器 ID
void *data驅動程式特定資料
ssize_t (*show) (void *data, int type, char *buf)屬性顯示函式
umode_t (*is_visible) (void *data, int type)屬性可見性函式
void (*release) (void *data)釋放函式
注意
當對啟動器 kobject 的所有引用都已釋放時,啟動 sysfs 庫將釋放為呼叫者傳入的資料。
-
struct iscsi_boot_kobj *iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, void *data, ssize_t (*show)(void *data, int type, char *buf), umode_t (*is_visible)(void *data, int type), void (*release)(void *data))¶
建立啟動乙太網 sysfs 目錄
引數
struct iscsi_boot_kset *boot_kset啟動 kset
int index乙太網裝置 ID
void *data驅動程式特定資料
ssize_t (*show) (void *data, int type, char *buf)屬性顯示函式
umode_t (*is_visible) (void *data, int type)屬性可見性函式
void (*release) (void *data)釋放函式
注意
當對乙太網 kobject 的所有引用都已釋放時,啟動 sysfs 庫將釋放為呼叫者傳入的資料。
-
struct iscsi_boot_kobj *iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index, void *data, ssize_t (*show)(void *data, int type, char *buf), umode_t (*is_visible)(void *data, int type), void (*release)(void *data))¶
建立啟動 acpi 表 sysfs 目錄
引數
struct iscsi_boot_kset *boot_kset啟動 kset
int index未使用
void *data驅動程式特定資料
ssize_t (*show)(void *data, int type, char *buf)屬性顯示函式
umode_t (*is_visible)(void *data, int type)屬性可見性函式
void (*release)(void *data)釋放函式
注意
當對 acpitbl kobject 的所有引用都已釋放時,啟動 sysfs 庫將釋放為呼叫者傳入的資料。
-
struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name)¶
建立根 sysfs 樹
引數
const char *set_name根目錄的名稱
-
struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno)¶
為 SCSI 主機建立根 sysfs 樹
引數
unsigned int hostnoSCSI 主機的 host number
-
void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset)¶
銷燬 kset 及其下的 kobject
引數
struct iscsi_boot_kset *boot_kset啟動 kset
描述
這將刪除 kset、kobject 及其下的屬性。
iSCSI TCP 介面¶
-
int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)¶
以 sendfile 方式進行 TCP 接收
引數
read_descriptor_t *rd_desc讀取描述符
struct sk_buff *skb套接字緩衝區
unsigned int offsetskb中的偏移量
size_t lenskb->len - offset
引數
struct sock *sk套接字
描述
如果套接字處於CLOSE或CLOSE_WAIT狀態,如果仍有一些資料未處理,我們不應關閉連線。
必須使用sk_callback_lock呼叫。
引數
struct sock *sk套接字空間可用於
-
int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn, struct iscsi_segment *segment)¶
傳輸段
引數
struct iscsi_tcp_conn *tcp_conniSCSI TCP連線
struct iscsi_segment *segment要傳輸的緩衝區
描述
此函式傳輸網路層將接受的儘可能多的緩衝區,並返回傳輸的位元組數。
如果啟用了CRC雜湊,該函式將計算雜湊值。 當整個段已傳輸時,它將檢索雜湊值併發送它。
-
int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)¶
TCP傳輸
引數
struct iscsi_conn *conniscsi 連線
-
int iscsi_sw_tcp_xmit_qlen(struct iscsi_conn *conn)¶
返回為xmit排隊的位元組數
引數
struct iscsi_conn *conniscsi 連線
-
int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, struct iscsi_segment *segment, int recv, unsigned copied)¶
檢查段是否完整
引數
struct iscsi_tcp_conn *tcp_conniscsi tcp 連線
struct iscsi_segment *segment要檢查的iscsi段
int recv如果從recv路徑呼叫,則設定為1
unsigned copied複製的位元組數
描述
檢查我們是否已完成接收此段。 如果接收緩衝區已滿,但我們希望有更多資料,則移至散列表中的下一個條目。
如果我們收到的資料量不是4的倍數,我們也會透明地接收填充位元組。
此函式必須是可重入的。
-
void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn)¶
準備段以進行hdr接收
引數
struct iscsi_tcp_conn *tcp_conn要準備的iscsi連線
描述
此函式總是為crcp引數傳遞NULL,因為當呼叫此函式時,我們還不知道header的最終大小,並希望延遲摘要處理,直到我們知道為止。
-
void iscsi_tcp_cleanup_task(struct iscsi_task *task)¶
釋放tcp_task資源
引數
struct iscsi_task *taskiscsi任務
描述
必須使用會話back_lock呼叫
-
int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn)¶
測試我們是否正在讀取header
引數
struct iscsi_tcp_conn *tcp_conniscsi tcp 連線
描述
如果我們當前正在處理或設定為處理header,則返回非零值。
-
int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, unsigned int offset, bool offloaded, int *status)¶
處理 skb
引數
struct iscsi_conn *conniscsi 連線
struct sk_buff *skb帶有header和/或資料段的網路緩衝區
unsigned int offsetskb中的偏移量
bool offloaded指示傳輸是否已解除安裝的布林值
int *statusiscsi TCP狀態結果
描述
將在 **status** 中返回傳輸狀態。 並將返回複製的位元組數。
-
int iscsi_tcp_task_init(struct iscsi_task *task)¶
初始化iSCSI SCSI_READ或SCSI_WRITE命令
引數
struct iscsi_task *taskscsi 命令任務
-
int iscsi_tcp_task_xmit(struct iscsi_task *task)¶
xmit正常PDU任務
引數
struct iscsi_task *taskiscsi命令任務
描述
如果一切都成功傳輸,我們應該返回0;如果佇列中仍然有資料,則返回-EAGAIN;對於任何其他型別的錯誤,則返回!= 0。