Skip to content

Commit fe83558

Browse files
committed
Merge branch '3.3-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull target fixes from Nicholas Bellinger: "This series addresses two recently reported regression bugs related to legacy SCSI reservation usage in target core, and iscsi-target reservation conflict handling. The second patch in particular addresses possible data-corruption with SCSI reservations that is specific to iscsi-target fabric LUNs with multiple client writers. Both patches need to go into v3.2 stable ASAP, and the branch based on the last target-pending/3.3-rc-fixes HEAD. Again, thanks to Martin Svec for his help to identify and address this regression bug with iscsi-target." * '3.3-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: iscsi-target: Fix reservation conflict -EBUSY response handling bug target: Fix compatible reservation handling (CRH=1) with legacy RESERVE/RELEASE
2 parents f1cbd03 + 00fdc6b commit fe83558

3 files changed

Lines changed: 24 additions & 13 deletions

File tree

‎drivers/target/iscsi/iscsi_target.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ static int iscsit_handle_scsi_cmd(
10281028
return iscsit_add_reject_from_cmd(
10291029
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
10301030
1, 1, buf, cmd);
1031-
} else if (transport_ret == -EINVAL) {
1031+
} else if (transport_ret < 0) {
10321032
/*
10331033
* Unsupported SAM Opcode. CHECK_CONDITION will be sent
10341034
* in iscsit_execute_cmd() during the CmdSN OOO Execution

‎drivers/target/target_core_pr.c‎

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
117117
struct se_node_acl *, struct se_session *);
118118
static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
119119

120-
static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
120+
static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
121121
{
122122
struct se_session *se_sess = cmd->se_sess;
123123
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)
127127
int conflict = 0;
128128

129129
if (!crh)
130-
return false;
130+
return -EINVAL;
131131

132132
pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
133133
se_sess);
@@ -155,16 +155,14 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
155155
*/
156156
if (pr_reg->pr_res_holder) {
157157
core_scsi3_put_pr_reg(pr_reg);
158-
*ret = 0;
159-
return false;
158+
return 1;
160159
}
161160
if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
162161
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
163162
(pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
164163
(pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
165164
core_scsi3_put_pr_reg(pr_reg);
166-
*ret = 0;
167-
return true;
165+
return 1;
168166
}
169167
core_scsi3_put_pr_reg(pr_reg);
170168
conflict = 1;
@@ -189,10 +187,10 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
189187
" while active SPC-3 registrations exist,"
190188
" returning RESERVATION_CONFLICT\n");
191189
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
192-
return true;
190+
return -EBUSY;
193191
}
194192

195-
return false;
193+
return 0;
196194
}
197195

198196
int target_scsi2_reservation_release(struct se_task *task)
@@ -201,12 +199,18 @@ int target_scsi2_reservation_release(struct se_task *task)
201199
struct se_device *dev = cmd->se_dev;
202200
struct se_session *sess = cmd->se_sess;
203201
struct se_portal_group *tpg = sess->se_tpg;
204-
int ret = 0;
202+
int ret = 0, rc;
205203

206204
if (!sess || !tpg)
207205
goto out;
208-
if (target_check_scsi2_reservation_conflict(cmd, &ret))
206+
rc = target_check_scsi2_reservation_conflict(cmd);
207+
if (rc == 1)
208+
goto out;
209+
else if (rc < 0) {
210+
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
211+
ret = -EINVAL;
209212
goto out;
213+
}
210214

211215
ret = 0;
212216
spin_lock(&dev->dev_reservation_lock);
@@ -243,7 +247,7 @@ int target_scsi2_reservation_reserve(struct se_task *task)
243247
struct se_device *dev = cmd->se_dev;
244248
struct se_session *sess = cmd->se_sess;
245249
struct se_portal_group *tpg = sess->se_tpg;
246-
int ret = 0;
250+
int ret = 0, rc;
247251

248252
if ((cmd->t_task_cdb[1] & 0x01) &&
249253
(cmd->t_task_cdb[1] & 0x02)) {
@@ -259,8 +263,14 @@ int target_scsi2_reservation_reserve(struct se_task *task)
259263
*/
260264
if (!sess || !tpg)
261265
goto out;
262-
if (target_check_scsi2_reservation_conflict(cmd, &ret))
266+
rc = target_check_scsi2_reservation_conflict(cmd);
267+
if (rc == 1)
263268
goto out;
269+
else if (rc < 0) {
270+
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
271+
ret = -EINVAL;
272+
goto out;
273+
}
264274

265275
ret = 0;
266276
spin_lock(&dev->dev_reservation_lock);

‎drivers/target/target_core_transport.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,7 @@ static int transport_generic_cmd_sequencer(
25392539
cmd, cdb, pr_reg_type) != 0) {
25402540
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
25412541
cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
2542+
cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
25422543
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
25432544
return -EBUSY;
25442545
}

0 commit comments

Comments
 (0)