|
@@ -3834,7 +3834,8 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
|
|
unsigned char *buf;
|
|
|
u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
|
|
|
u32 off = 8; /* off into first Full Status descriptor */
|
|
|
- int format_code = 0;
|
|
|
+ int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
|
|
|
+ bool all_reg = false;
|
|
|
|
|
|
if (cmd->data_length < 8) {
|
|
|
pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
|
|
@@ -3851,6 +3852,19 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
|
|
buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
|
|
|
buf[3] = (dev->t10_pr.pr_generation & 0xff);
|
|
|
|
|
|
+ spin_lock(&dev->dev_reservation_lock);
|
|
|
+ if (dev->dev_pr_res_holder) {
|
|
|
+ struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder;
|
|
|
+
|
|
|
+ if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
|
|
|
+ pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
|
|
|
+ all_reg = true;
|
|
|
+ pr_res_type = pr_holder->pr_res_type;
|
|
|
+ pr_res_scope = pr_holder->pr_res_scope;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ spin_unlock(&dev->dev_reservation_lock);
|
|
|
+
|
|
|
spin_lock(&pr_tmpl->registration_lock);
|
|
|
list_for_each_entry_safe(pr_reg, pr_reg_tmp,
|
|
|
&pr_tmpl->registration_list, pr_reg_list) {
|
|
@@ -3898,14 +3912,20 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
|
|
* reservation holder for PR_HOLDER bit.
|
|
|
*
|
|
|
* Also, if this registration is the reservation
|
|
|
- * holder, fill in SCOPE and TYPE in the next byte.
|
|
|
+ * holder or there is an All Registrants reservation
|
|
|
+ * active, fill in SCOPE and TYPE in the next byte.
|
|
|
*/
|
|
|
if (pr_reg->pr_res_holder) {
|
|
|
buf[off++] |= 0x01;
|
|
|
buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
|
|
|
(pr_reg->pr_res_type & 0x0f);
|
|
|
- } else
|
|
|
+ } else if (all_reg) {
|
|
|
+ buf[off++] |= 0x01;
|
|
|
+ buf[off++] = (pr_res_scope & 0xf0) |
|
|
|
+ (pr_res_type & 0x0f);
|
|
|
+ } else {
|
|
|
off += 2;
|
|
|
+ }
|
|
|
|
|
|
off += 4; /* Skip over reserved area */
|
|
|
/*
|