提交 b6932ee3 编写于 作者: S Steven Allen 提交者: Nicholas Bellinger

target: return CONFLICT only when SA key unmatched

PREEMPT (and PREEMPT AND ABORT) should return CONFLICT iff a specified
SERVICE ACTION RESERVATION KEY is specified and matches no existing
persistent reservation.

Without this patch, a PREEMPT will return CONFLICT if either all
reservations are held by the initiator (self preemption) or there is
nothing to preempt. According to the spec, both of these cases should
succeed.
Signed-off-by: NSteven Allen <steven.allen@purestorage.com>
Signed-off-by: NNicholas Bellinger <nab@linux-iscsi.org>
上级 3b726ae2
...@@ -2738,7 +2738,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2738,7 +2738,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
struct t10_reservation *pr_tmpl = &dev->t10_pr; struct t10_reservation *pr_tmpl = &dev->t10_pr;
u32 pr_res_mapped_lun = 0; u32 pr_res_mapped_lun = 0;
int all_reg = 0, calling_it_nexus = 0, released_regs = 0; int all_reg = 0, calling_it_nexus = 0;
bool sa_res_key_unmatched = sa_res_key != 0;
int prh_type = 0, prh_scope = 0; int prh_type = 0, prh_scope = 0;
if (!se_sess) if (!se_sess)
...@@ -2813,6 +2814,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2813,6 +2814,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
if (!all_reg) { if (!all_reg) {
if (pr_reg->pr_res_key != sa_res_key) if (pr_reg->pr_res_key != sa_res_key)
continue; continue;
sa_res_key_unmatched = false;
calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
pr_reg_nacl = pr_reg->pr_reg_nacl; pr_reg_nacl = pr_reg->pr_reg_nacl;
...@@ -2820,7 +2822,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2820,7 +2822,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
__core_scsi3_free_registration(dev, pr_reg, __core_scsi3_free_registration(dev, pr_reg,
(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
NULL, calling_it_nexus); NULL, calling_it_nexus);
released_regs++;
} else { } else {
/* /*
* Case for any existing all registrants type * Case for any existing all registrants type
...@@ -2838,6 +2839,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2838,6 +2839,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
if ((sa_res_key) && if ((sa_res_key) &&
(pr_reg->pr_res_key != sa_res_key)) (pr_reg->pr_res_key != sa_res_key))
continue; continue;
sa_res_key_unmatched = false;
calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
if (calling_it_nexus) if (calling_it_nexus)
...@@ -2848,7 +2850,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2848,7 +2850,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
__core_scsi3_free_registration(dev, pr_reg, __core_scsi3_free_registration(dev, pr_reg,
(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
NULL, 0); NULL, 0);
released_regs++;
} }
if (!calling_it_nexus) if (!calling_it_nexus)
core_scsi3_ua_allocate(pr_reg_nacl, core_scsi3_ua_allocate(pr_reg_nacl,
...@@ -2863,7 +2864,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, ...@@ -2863,7 +2864,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
* registered reservation key, then the device server shall * registered reservation key, then the device server shall
* complete the command with RESERVATION CONFLICT status. * complete the command with RESERVATION CONFLICT status.
*/ */
if (!released_regs) { if (sa_res_key_unmatched) {
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return TCM_RESERVATION_CONFLICT; return TCM_RESERVATION_CONFLICT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册