Commit 4ec5bf0e authored by Bryant G. Ly's avatar Bryant G. Ly Committed by Nicholas Bellinger

target/user: PGR Support

This adds initial PGR support for just TCMU, since tcmu doesn't
have the necessary IT_NEXUS info to process PGR in userspace,
so have those commands be processed in kernel.

HA support is not available yet, we will work on it if this patch
is acceptable.
Signed-off-by: default avatarBryant G. Ly <bryantly@linux.vnet.ibm.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent c2d26f18
...@@ -1400,7 +1400,7 @@ static ssize_t target_pr_res_holder_show(struct config_item *item, char *page) ...@@ -1400,7 +1400,7 @@ static ssize_t target_pr_res_holder_show(struct config_item *item, char *page)
struct se_device *dev = pr_to_dev(item); struct se_device *dev = pr_to_dev(item);
int ret; int ret;
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return sprintf(page, "Passthrough\n"); return sprintf(page, "Passthrough\n");
spin_lock(&dev->dev_reservation_lock); spin_lock(&dev->dev_reservation_lock);
...@@ -1540,7 +1540,7 @@ static ssize_t target_pr_res_type_show(struct config_item *item, char *page) ...@@ -1540,7 +1540,7 @@ static ssize_t target_pr_res_type_show(struct config_item *item, char *page)
{ {
struct se_device *dev = pr_to_dev(item); struct se_device *dev = pr_to_dev(item);
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return sprintf(page, "SPC_PASSTHROUGH\n"); return sprintf(page, "SPC_PASSTHROUGH\n");
else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
return sprintf(page, "SPC2_RESERVATIONS\n"); return sprintf(page, "SPC2_RESERVATIONS\n");
...@@ -1553,7 +1553,7 @@ static ssize_t target_pr_res_aptpl_active_show(struct config_item *item, ...@@ -1553,7 +1553,7 @@ static ssize_t target_pr_res_aptpl_active_show(struct config_item *item,
{ {
struct se_device *dev = pr_to_dev(item); struct se_device *dev = pr_to_dev(item);
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return 0; return 0;
return sprintf(page, "APTPL Bit Status: %s\n", return sprintf(page, "APTPL Bit Status: %s\n",
...@@ -1565,7 +1565,7 @@ static ssize_t target_pr_res_aptpl_metadata_show(struct config_item *item, ...@@ -1565,7 +1565,7 @@ static ssize_t target_pr_res_aptpl_metadata_show(struct config_item *item,
{ {
struct se_device *dev = pr_to_dev(item); struct se_device *dev = pr_to_dev(item);
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return 0; return 0;
return sprintf(page, "Ready to process PR APTPL metadata..\n"); return sprintf(page, "Ready to process PR APTPL metadata..\n");
...@@ -1611,7 +1611,7 @@ static ssize_t target_pr_res_aptpl_metadata_store(struct config_item *item, ...@@ -1611,7 +1611,7 @@ static ssize_t target_pr_res_aptpl_metadata_store(struct config_item *item,
u16 tpgt = 0; u16 tpgt = 0;
u8 type = 0; u8 type = 0;
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return count; return count;
if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
return count; return count;
......
...@@ -1045,6 +1045,8 @@ passthrough_parse_cdb(struct se_cmd *cmd, ...@@ -1045,6 +1045,8 @@ passthrough_parse_cdb(struct se_cmd *cmd,
sense_reason_t (*exec_cmd)(struct se_cmd *cmd)) sense_reason_t (*exec_cmd)(struct se_cmd *cmd))
{ {
unsigned char *cdb = cmd->t_task_cdb; unsigned char *cdb = cmd->t_task_cdb;
struct se_device *dev = cmd->se_dev;
unsigned int size;
/* /*
* Clear a lun set in the cdb if the initiator talking to use spoke * Clear a lun set in the cdb if the initiator talking to use spoke
...@@ -1076,6 +1078,42 @@ passthrough_parse_cdb(struct se_cmd *cmd, ...@@ -1076,6 +1078,42 @@ passthrough_parse_cdb(struct se_cmd *cmd,
return TCM_NO_SENSE; return TCM_NO_SENSE;
} }
/*
* For PERSISTENT RESERVE IN/OUT, RELEASE, and RESERVE we need to
* emulate the response, since tcmu does not have the information
* required to process these commands.
*/
if (!(dev->transport->transport_flags &
TRANSPORT_FLAG_PASSTHROUGH_PGR)) {
if (cdb[0] == PERSISTENT_RESERVE_IN) {
cmd->execute_cmd = target_scsi3_emulate_pr_in;
size = (cdb[7] << 8) + cdb[8];
return target_cmd_size_check(cmd, size);
}
if (cdb[0] == PERSISTENT_RESERVE_OUT) {
cmd->execute_cmd = target_scsi3_emulate_pr_out;
size = (cdb[7] << 8) + cdb[8];
return target_cmd_size_check(cmd, size);
}
if (cdb[0] == RELEASE || cdb[0] == RELEASE_10) {
cmd->execute_cmd = target_scsi2_reservation_release;
if (cdb[0] == RELEASE_10)
size = (cdb[7] << 8) | cdb[8];
else
size = cmd->data_length;
return target_cmd_size_check(cmd, size);
}
if (cdb[0] == RESERVE || cdb[0] == RESERVE_10) {
cmd->execute_cmd = target_scsi2_reservation_reserve;
if (cdb[0] == RESERVE_10)
size = (cdb[7] << 8) | cdb[8];
else
size = cmd->data_length;
return target_cmd_size_check(cmd, size);
}
}
/* Set DATA_CDB flag for ops that should have it */ /* Set DATA_CDB flag for ops that should have it */
switch (cdb[0]) { switch (cdb[0]) {
case READ_6: case READ_6:
......
...@@ -4147,7 +4147,7 @@ target_check_reservation(struct se_cmd *cmd) ...@@ -4147,7 +4147,7 @@ target_check_reservation(struct se_cmd *cmd)
return 0; return 0;
if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)
return 0; return 0;
if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
return 0; return 0;
spin_lock(&dev->dev_reservation_lock); spin_lock(&dev->dev_reservation_lock);
......
...@@ -1081,7 +1081,8 @@ static const struct target_backend_ops pscsi_ops = { ...@@ -1081,7 +1081,8 @@ static const struct target_backend_ops pscsi_ops = {
.name = "pscsi", .name = "pscsi",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.transport_flags = TRANSPORT_FLAG_PASSTHROUGH | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH |
TRANSPORT_FLAG_PASSTHROUGH_ALUA, TRANSPORT_FLAG_PASSTHROUGH_ALUA |
TRANSPORT_FLAG_PASSTHROUGH_PGR,
.attach_hba = pscsi_attach_hba, .attach_hba = pscsi_attach_hba,
.detach_hba = pscsi_detach_hba, .detach_hba = pscsi_detach_hba,
.pmode_enable_hba = pscsi_pmode_enable_hba, .pmode_enable_hba = pscsi_pmode_enable_hba,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* backend module. * backend module.
*/ */
#define TRANSPORT_FLAG_PASSTHROUGH_ALUA 0x2 #define TRANSPORT_FLAG_PASSTHROUGH_ALUA 0x2
#define TRANSPORT_FLAG_PASSTHROUGH_PGR 0x4
struct request_queue; struct request_queue;
struct scatterlist; struct scatterlist;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment