|
@@ -117,7 +117,7 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
|
|
struct se_node_acl *, struct se_session *);
|
|
struct se_node_acl *, struct se_session *);
|
|
static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
|
|
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_session *se_sess = cmd->se_sess;
|
|
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
|
|
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
|
|
@@ -127,7 +127,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
|
|
int conflict = 0;
|
|
int conflict = 0;
|
|
|
|
|
|
if (!crh)
|
|
if (!crh)
|
|
- return false;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
|
|
pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
|
|
se_sess);
|
|
se_sess);
|
|
@@ -155,16 +155,14 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
|
|
*/
|
|
*/
|
|
if (pr_reg->pr_res_holder) {
|
|
if (pr_reg->pr_res_holder) {
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
- *ret = 0;
|
|
|
|
- return false;
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
|
|
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_EXCLUSIVE_ACCESS_REGONLY) ||
|
|
(pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
|
|
(pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
|
|
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
|
|
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
- *ret = 0;
|
|
|
|
- return true;
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
core_scsi3_put_pr_reg(pr_reg);
|
|
conflict = 1;
|
|
conflict = 1;
|
|
@@ -189,10 +187,10 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
|
|
" while active SPC-3 registrations exist,"
|
|
" while active SPC-3 registrations exist,"
|
|
" returning RESERVATION_CONFLICT\n");
|
|
" returning RESERVATION_CONFLICT\n");
|
|
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
|
|
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
|
|
- return true;
|
|
|
|
|
|
+ return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
- return false;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
int target_scsi2_reservation_release(struct se_task *task)
|
|
int target_scsi2_reservation_release(struct se_task *task)
|
|
@@ -201,12 +199,18 @@ int target_scsi2_reservation_release(struct se_task *task)
|
|
struct se_device *dev = cmd->se_dev;
|
|
struct se_device *dev = cmd->se_dev;
|
|
struct se_session *sess = cmd->se_sess;
|
|
struct se_session *sess = cmd->se_sess;
|
|
struct se_portal_group *tpg = sess->se_tpg;
|
|
struct se_portal_group *tpg = sess->se_tpg;
|
|
- int ret = 0;
|
|
|
|
|
|
+ int ret = 0, rc;
|
|
|
|
|
|
if (!sess || !tpg)
|
|
if (!sess || !tpg)
|
|
goto out;
|
|
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;
|
|
goto out;
|
|
|
|
+ }
|
|
|
|
|
|
ret = 0;
|
|
ret = 0;
|
|
spin_lock(&dev->dev_reservation_lock);
|
|
spin_lock(&dev->dev_reservation_lock);
|
|
@@ -243,7 +247,7 @@ int target_scsi2_reservation_reserve(struct se_task *task)
|
|
struct se_device *dev = cmd->se_dev;
|
|
struct se_device *dev = cmd->se_dev;
|
|
struct se_session *sess = cmd->se_sess;
|
|
struct se_session *sess = cmd->se_sess;
|
|
struct se_portal_group *tpg = sess->se_tpg;
|
|
struct se_portal_group *tpg = sess->se_tpg;
|
|
- int ret = 0;
|
|
|
|
|
|
+ int ret = 0, rc;
|
|
|
|
|
|
if ((cmd->t_task_cdb[1] & 0x01) &&
|
|
if ((cmd->t_task_cdb[1] & 0x01) &&
|
|
(cmd->t_task_cdb[1] & 0x02)) {
|
|
(cmd->t_task_cdb[1] & 0x02)) {
|
|
@@ -259,8 +263,14 @@ int target_scsi2_reservation_reserve(struct se_task *task)
|
|
*/
|
|
*/
|
|
if (!sess || !tpg)
|
|
if (!sess || !tpg)
|
|
goto out;
|
|
goto out;
|
|
- if (target_check_scsi2_reservation_conflict(cmd, &ret))
|
|
|
|
|
|
+ rc = target_check_scsi2_reservation_conflict(cmd);
|
|
|
|
+ if (rc == 1)
|
|
goto out;
|
|
goto out;
|
|
|
|
+ else if (rc < 0) {
|
|
|
|
+ cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
|
|
|
|
+ ret = -EINVAL;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
|
|
ret = 0;
|
|
ret = 0;
|
|
spin_lock(&dev->dev_reservation_lock);
|
|
spin_lock(&dev->dev_reservation_lock);
|