This commit introduces two helper functions that facilitate the conversion between the persistent reservation types used in the SCSI protocol and those used in the block layer.
Signed-off-by: Changqi Lu <luchangqi....@bytedance.com> Signed-off-by: zhenwei pi <pizhen...@bytedance.com> Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com> --- include/scsi/utils.h | 8 +++++ scsi/utils.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/include/scsi/utils.h b/include/scsi/utils.h index d5c8efa16e..89a0b082fb 100644 --- a/include/scsi/utils.h +++ b/include/scsi/utils.h @@ -1,6 +1,8 @@ #ifndef SCSI_UTILS_H #define SCSI_UTILS_H +#include "block/block-common.h" +#include "scsi/constants.h" #ifdef CONFIG_LINUX #include <scsi/sg.h> #endif @@ -135,6 +137,12 @@ uint32_t scsi_data_cdb_xfer(uint8_t *buf); uint32_t scsi_cdb_xfer(uint8_t *buf); int scsi_cdb_length(uint8_t *buf); +BlockPrType scsi_pr_type_to_block(SCSIPrType type); +SCSIPrType block_pr_type_to_scsi(BlockPrType type); + +uint8_t scsi_pr_cap_to_block(uint16_t scsi_pr_cap); +uint16_t block_pr_cap_to_scsi(uint8_t block_pr_cap); + /* Linux SG_IO interface. */ #ifdef CONFIG_LINUX #define SG_ERR_DRIVER_TIMEOUT 0x06 diff --git a/scsi/utils.c b/scsi/utils.c index 357b036671..0dfdeb499d 100644 --- a/scsi/utils.c +++ b/scsi/utils.c @@ -658,3 +658,84 @@ int scsi_sense_from_host_status(uint8_t host_status, } return GOOD; } + +BlockPrType scsi_pr_type_to_block(SCSIPrType type) +{ + switch (type) { + case SCSI_PR_WRITE_EXCLUSIVE: + return BLK_PR_WRITE_EXCLUSIVE; + case SCSI_PR_EXCLUSIVE_ACCESS: + return BLK_PR_EXCLUSIVE_ACCESS; + case SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY: + return BLK_PR_WRITE_EXCLUSIVE_REGS_ONLY; + case SCSI_PR_EXCLUSIVE_ACCESS_REGS_ONLY: + return BLK_PR_EXCLUSIVE_ACCESS_REGS_ONLY; + case SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS: + return BLK_PR_WRITE_EXCLUSIVE_ALL_REGS; + case SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS: + return BLK_PR_EXCLUSIVE_ACCESS_ALL_REGS; + } + + return 0; +} + +SCSIPrType block_pr_type_to_scsi(BlockPrType type) +{ + switch (type) { + case BLK_PR_WRITE_EXCLUSIVE: + return SCSI_PR_WRITE_EXCLUSIVE; + case BLK_PR_EXCLUSIVE_ACCESS: + return SCSI_PR_EXCLUSIVE_ACCESS; + case BLK_PR_WRITE_EXCLUSIVE_REGS_ONLY: + return SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY; + case BLK_PR_EXCLUSIVE_ACCESS_REGS_ONLY: + return SCSI_PR_EXCLUSIVE_ACCESS_REGS_ONLY; + case BLK_PR_WRITE_EXCLUSIVE_ALL_REGS: + return SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS; + case BLK_PR_EXCLUSIVE_ACCESS_ALL_REGS: + return SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS; + } + + return 0; +} + + +uint8_t scsi_pr_cap_to_block(uint16_t scsi_pr_cap) +{ + uint8_t res = 0; + + res |= (scsi_pr_cap & SCSI_PR_CAP_WR_EX) ? + BLK_PR_CAP_WR_EX : 0; + res |= (scsi_pr_cap & SCSI_PR_CAP_EX_AC) ? + BLK_PR_CAP_EX_AC : 0; + res |= (scsi_pr_cap & SCSI_PR_CAP_WR_EX_RO) ? + BLK_PR_CAP_WR_EX_RO : 0; + res |= (scsi_pr_cap & SCSI_PR_CAP_EX_AC_RO) ? + BLK_PR_CAP_EX_AC_RO : 0; + res |= (scsi_pr_cap & SCSI_PR_CAP_WR_EX_AR) ? + BLK_PR_CAP_WR_EX_AR : 0; + res |= (scsi_pr_cap & SCSI_PR_CAP_EX_AC_AR) ? + BLK_PR_CAP_EX_AC_AR : 0; + + return res; +} + +uint16_t block_pr_cap_to_scsi(uint8_t block_pr_cap) +{ + uint16_t res = 0; + + res |= (block_pr_cap & BLK_PR_CAP_WR_EX) ? + SCSI_PR_CAP_WR_EX : 0; + res |= (block_pr_cap & BLK_PR_CAP_EX_AC) ? + SCSI_PR_CAP_EX_AC : 0; + res |= (block_pr_cap & BLK_PR_CAP_WR_EX_RO) ? + SCSI_PR_CAP_WR_EX_RO : 0; + res |= (block_pr_cap & BLK_PR_CAP_EX_AC_RO) ? + SCSI_PR_CAP_EX_AC_RO : 0; + res |= (block_pr_cap & BLK_PR_CAP_WR_EX_AR) ? + SCSI_PR_CAP_WR_EX_AR : 0; + res |= (block_pr_cap & BLK_PR_CAP_EX_AC_AR) ? + SCSI_PR_CAP_EX_AC_AR : 0; + + return res; +} -- 2.20.1