struct se_node_acl *, struct se_session *);
static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
-static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
+static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
{
struct se_session *se_sess = cmd->se_sess;
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
int conflict = 0;
if (!crh)
- return false;
+ return -EINVAL;
pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
se_sess);
*/
if (pr_reg->pr_res_holder) {
core_scsi3_put_pr_reg(pr_reg);
- *ret = 0;
- return false;
+ return 1;
}
if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
(pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
core_scsi3_put_pr_reg(pr_reg);
- *ret = 0;
- return true;
+ return 1;
}
core_scsi3_put_pr_reg(pr_reg);
conflict = 1;
" while active SPC-3 registrations exist,"
" returning RESERVATION_CONFLICT\n");
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
- return true;
+ return -EBUSY;
}
- return false;
+ return 0;
}
int target_scsi2_reservation_release(struct se_task *task)
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
struct se_portal_group *tpg = sess->se_tpg;
- int ret = 0;
+ int ret = 0, rc;
if (!sess || !tpg)
goto out;
- if (target_check_scsi2_reservation_conflict(cmd, &ret))
+ rc = target_check_scsi2_reservation_conflict(cmd);
+ if (rc == 1)
goto out;
+ else if (rc < 0) {
+ cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+ ret = -EINVAL;
+ goto out;
+ }
ret = 0;
spin_lock(&dev->dev_reservation_lock);
if (dev->dev_reserved_node_acl != sess->se_node_acl)
goto out_unlock;
+ if (dev->dev_res_bin_isid != sess->sess_bin_isid)
+ goto out_unlock;
+
dev->dev_reserved_node_acl = NULL;
dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
struct se_portal_group *tpg = sess->se_tpg;
- int ret = 0;
+ int ret = 0, rc;
if ((cmd->t_task_cdb[1] & 0x01) &&
(cmd->t_task_cdb[1] & 0x02)) {
*/
if (!sess || !tpg)
goto out;
- if (target_check_scsi2_reservation_conflict(cmd, &ret))
+ rc = target_check_scsi2_reservation_conflict(cmd);
+ if (rc == 1)
+ goto out;
+ else if (rc < 0) {
+ cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+ ret = -EINVAL;
goto out;
+ }
ret = 0;
spin_lock(&dev->dev_reservation_lock);
case READ_MEDIA_SERIAL_NUMBER:
case REPORT_LUNS:
case REQUEST_SENSE:
+ case PERSISTENT_RESERVE_IN:
ret = 0; /*/ Allowed CDBs */
break;
default:
tidh_new->dest_local_nexus = 1;
list_add_tail(&tidh_new->dest_list, &tid_dest_list);
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
/*
* For a PERSISTENT RESERVE OUT specify initiator ports payload,
* first extract TransportID Parameter Data Length, and make sure
}
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
/*
* Go ahead and create a registrations from tid_dest_list for the
return 0;
out:
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
/*
* For the failure case, release everything from tid_dest_list
* including *dest_pr_reg and the configfs dependances..
if (IS_ERR(file) || !file || !file->f_dentry) {
pr_err("filp_open(%s) for APTPL metadata"
" failed\n", path);
- return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT);
+ return IS_ERR(file) ? PTR_ERR(file) : -ENOENT;
}
iov[0].iov_base = &buf[0];
if (!calling_it_nexus)
core_scsi3_ua_allocate(pr_reg_nacl,
pr_res_mapped_lun, 0x2A,
- ASCQ_2AH_RESERVATIONS_PREEMPTED);
+ ASCQ_2AH_REGISTRATIONS_PREEMPTED);
}
spin_unlock(&pr_tmpl->registration_lock);
/*
* additional sense code set to REGISTRATIONS PREEMPTED;
*/
core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A,
- ASCQ_2AH_RESERVATIONS_PREEMPTED);
+ ASCQ_2AH_REGISTRATIONS_PREEMPTED);
}
spin_unlock(&pr_tmpl->registration_lock);
/*
* will be moved to for the TransportID containing SCSI initiator WWN
* information.
*/
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
rtpi = (buf[18] & 0xff) << 8;
rtpi |= buf[19] & 0xff;
tid_len = (buf[20] & 0xff) << 24;
tid_len |= (buf[21] & 0xff) << 16;
tid_len |= (buf[22] & 0xff) << 8;
tid_len |= buf[23] & 0xff;
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
buf = NULL;
if ((tid_len + 24) != cmd->data_length) {
return -EINVAL;
}
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
proto_ident = (buf[24] & 0x0f);
#if 0
pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
goto out;
}
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
buf = NULL;
pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s"
" REGISTER_AND_MOVE\n");
}
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
core_scsi3_put_pr_reg(dest_pr_reg);
return 0;
out:
if (buf)
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
if (dest_se_deve)
core_scsi3_lunacl_undepend_item(dest_se_deve);
if (dest_node_acl)
" SPC-2 reservation is held, returning"
" RESERVATION_CONFLICT\n");
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
- ret = EINVAL;
+ ret = -EINVAL;
goto out;
}
*/
if (!cmd->se_sess) {
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (cmd->data_length < 24) {
scope = (cdb[2] & 0xf0);
type = (cdb[2] & 0x0f);
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
/*
* From PERSISTENT_RESERVE_OUT parameter list (payload)
*/
aptpl = (buf[17] & 0x01);
unreg = (buf[17] & 0x02);
}
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
buf = NULL;
/*
return -EINVAL;
}
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
buf[6] = ((add_len >> 8) & 0xff);
buf[7] = (add_len & 0xff);
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
return 0;
}
return -EINVAL;
}
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
err:
spin_unlock(&se_dev->dev_reservation_lock);
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
return 0;
}
return -EINVAL;
}
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
buf[0] = ((add_len << 8) & 0xff);
buf[1] = (add_len & 0xff);
buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
return 0;
}
return -EINVAL;
}
- buf = transport_kmap_first_data_page(cmd);
+ buf = transport_kmap_data_sg(cmd);
buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
buf[6] = ((add_len >> 8) & 0xff);
buf[7] = (add_len & 0xff);
- transport_kunmap_first_data_page(cmd);
+ transport_kunmap_data_sg(cmd);
return 0;
}