aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_pr.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2012-11-06 15:24:09 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 23:55:46 -0500
commitde103c93aff0bed0ae984274e5dc8b95899badab (patch)
tree7db9bba755fa95772052e8d31285a38ba48f1a84 /drivers/target/target_core_pr.c
parentfecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (diff)
target: pass sense_reason as a return value
Pass the sense reason as an explicit return value from the I/O submission path instead of storing it in struct se_cmd and using negative return values. This cleans up a lot of the code pathes, and with the sparse annotations for the new sense_reason_t type allows for much better error checking. (nab: Convert spc_emulate_modesense + spc_emulate_modeselect to use sense_reason_t with Roland's MODE SELECT changes) Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_pr.c')
-rw-r--r--drivers/target/target_core_pr.c918
1 files changed, 411 insertions, 507 deletions
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index f561a08ff8e5..ffbe0ea9bbad 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -68,7 +68,8 @@ int core_pr_dump_initiator_port(
68static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, 68static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
69 struct t10_pr_registration *, int); 69 struct t10_pr_registration *, int);
70 70
71static int target_scsi2_reservation_check(struct se_cmd *cmd) 71static sense_reason_t
72target_scsi2_reservation_check(struct se_cmd *cmd)
72{ 73{
73 struct se_device *dev = cmd->se_dev; 74 struct se_device *dev = cmd->se_dev;
74 struct se_session *sess = cmd->se_sess; 75 struct se_session *sess = cmd->se_sess;
@@ -86,11 +87,11 @@ static int target_scsi2_reservation_check(struct se_cmd *cmd)
86 return 0; 87 return 0;
87 88
88 if (dev->dev_reserved_node_acl != sess->se_node_acl) 89 if (dev->dev_reserved_node_acl != sess->se_node_acl)
89 return -EBUSY; 90 return TCM_RESERVATION_CONFLICT;
90 91
91 if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { 92 if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
92 if (dev->dev_res_bin_isid != sess->sess_bin_isid) 93 if (dev->dev_res_bin_isid != sess->sess_bin_isid)
93 return -EBUSY; 94 return TCM_RESERVATION_CONFLICT;
94 } 95 }
95 96
96 return 0; 97 return 0;
@@ -165,32 +166,28 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
165 pr_err("Received legacy SPC-2 RESERVE/RELEASE" 166 pr_err("Received legacy SPC-2 RESERVE/RELEASE"
166 " while active SPC-3 registrations exist," 167 " while active SPC-3 registrations exist,"
167 " returning RESERVATION_CONFLICT\n"); 168 " returning RESERVATION_CONFLICT\n");
168 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
169 return -EBUSY; 169 return -EBUSY;
170 } 170 }
171 171
172 return 0; 172 return 0;
173} 173}
174 174
175int target_scsi2_reservation_release(struct se_cmd *cmd) 175sense_reason_t
176target_scsi2_reservation_release(struct se_cmd *cmd)
176{ 177{
177 struct se_device *dev = cmd->se_dev; 178 struct se_device *dev = cmd->se_dev;
178 struct se_session *sess = cmd->se_sess; 179 struct se_session *sess = cmd->se_sess;
179 struct se_portal_group *tpg; 180 struct se_portal_group *tpg;
180 int ret = 0, rc; 181 int rc;
181 182
182 if (!sess || !sess->se_tpg) 183 if (!sess || !sess->se_tpg)
183 goto out; 184 goto out;
184 rc = target_check_scsi2_reservation_conflict(cmd); 185 rc = target_check_scsi2_reservation_conflict(cmd);
185 if (rc == 1) 186 if (rc == 1)
186 goto out; 187 goto out;
187 else if (rc < 0) { 188 if (rc < 0)
188 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 189 return TCM_RESERVATION_CONFLICT;
189 ret = -EINVAL;
190 goto out;
191 }
192 190
193 ret = 0;
194 spin_lock(&dev->dev_reservation_lock); 191 spin_lock(&dev->dev_reservation_lock);
195 if (!dev->dev_reserved_node_acl || !sess) 192 if (!dev->dev_reserved_node_acl || !sess)
196 goto out_unlock; 193 goto out_unlock;
@@ -216,25 +213,24 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
216out_unlock: 213out_unlock:
217 spin_unlock(&dev->dev_reservation_lock); 214 spin_unlock(&dev->dev_reservation_lock);
218out: 215out:
219 if (!ret) 216 target_complete_cmd(cmd, GOOD);
220 target_complete_cmd(cmd, GOOD); 217 return 0;
221 return ret;
222} 218}
223 219
224int target_scsi2_reservation_reserve(struct se_cmd *cmd) 220sense_reason_t
221target_scsi2_reservation_reserve(struct se_cmd *cmd)
225{ 222{
226 struct se_device *dev = cmd->se_dev; 223 struct se_device *dev = cmd->se_dev;
227 struct se_session *sess = cmd->se_sess; 224 struct se_session *sess = cmd->se_sess;
228 struct se_portal_group *tpg; 225 struct se_portal_group *tpg;
229 int ret = 0, rc; 226 sense_reason_t ret = 0;
227 int rc;
230 228
231 if ((cmd->t_task_cdb[1] & 0x01) && 229 if ((cmd->t_task_cdb[1] & 0x01) &&
232 (cmd->t_task_cdb[1] & 0x02)) { 230 (cmd->t_task_cdb[1] & 0x02)) {
233 pr_err("LongIO and Obselete Bits set, returning" 231 pr_err("LongIO and Obselete Bits set, returning"
234 " ILLEGAL_REQUEST\n"); 232 " ILLEGAL_REQUEST\n");
235 cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; 233 return TCM_UNSUPPORTED_SCSI_OPCODE;
236 ret = -EINVAL;
237 goto out;
238 } 234 }
239 /* 235 /*
240 * This is currently the case for target_core_mod passthrough struct se_cmd 236 * This is currently the case for target_core_mod passthrough struct se_cmd
@@ -245,13 +241,10 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
245 rc = target_check_scsi2_reservation_conflict(cmd); 241 rc = target_check_scsi2_reservation_conflict(cmd);
246 if (rc == 1) 242 if (rc == 1)
247 goto out; 243 goto out;
248 else if (rc < 0) {
249 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
250 ret = -EINVAL;
251 goto out;
252 }
253 244
254 ret = 0; 245 if (rc < 0)
246 return TCM_RESERVATION_CONFLICT;
247
255 tpg = sess->se_tpg; 248 tpg = sess->se_tpg;
256 spin_lock(&dev->dev_reservation_lock); 249 spin_lock(&dev->dev_reservation_lock);
257 if (dev->dev_reserved_node_acl && 250 if (dev->dev_reserved_node_acl &&
@@ -265,8 +258,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
265 " from %s \n", cmd->se_lun->unpacked_lun, 258 " from %s \n", cmd->se_lun->unpacked_lun,
266 cmd->se_deve->mapped_lun, 259 cmd->se_deve->mapped_lun,
267 sess->se_node_acl->initiatorname); 260 sess->se_node_acl->initiatorname);
268 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 261 ret = TCM_RESERVATION_CONFLICT;
269 ret = -EINVAL;
270 goto out_unlock; 262 goto out_unlock;
271 } 263 }
272 264
@@ -536,7 +528,8 @@ static int core_scsi3_pr_seq_non_holder(
536 return 1; /* Conflict by default */ 528 return 1; /* Conflict by default */
537} 529}
538 530
539static int target_scsi3_pr_reservation_check(struct se_cmd *cmd) 531static sense_reason_t
532target_scsi3_pr_reservation_check(struct se_cmd *cmd)
540{ 533{
541 struct se_device *dev = cmd->se_dev; 534 struct se_device *dev = cmd->se_dev;
542 struct se_session *sess = cmd->se_sess; 535 struct se_session *sess = cmd->se_sess;
@@ -562,7 +555,7 @@ static int target_scsi3_pr_reservation_check(struct se_cmd *cmd)
562 555
563check_nonholder: 556check_nonholder:
564 if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type)) 557 if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type))
565 return -EBUSY; 558 return TCM_RESERVATION_CONFLICT;
566 return 0; 559 return 0;
567} 560}
568 561
@@ -1435,7 +1428,8 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
1435 smp_mb__after_atomic_dec(); 1428 smp_mb__after_atomic_dec();
1436} 1429}
1437 1430
1438static int core_scsi3_decode_spec_i_port( 1431static sense_reason_t
1432core_scsi3_decode_spec_i_port(
1439 struct se_cmd *cmd, 1433 struct se_cmd *cmd,
1440 struct se_portal_group *tpg, 1434 struct se_portal_group *tpg,
1441 unsigned char *l_isid, 1435 unsigned char *l_isid,
@@ -1457,8 +1451,9 @@ static int core_scsi3_decode_spec_i_port(
1457 unsigned char *buf; 1451 unsigned char *buf;
1458 unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; 1452 unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident;
1459 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; 1453 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
1454 sense_reason_t ret;
1460 u32 tpdl, tid_len = 0; 1455 u32 tpdl, tid_len = 0;
1461 int ret, dest_local_nexus, prf_isid; 1456 int dest_local_nexus, prf_isid;
1462 u32 dest_rtpi = 0; 1457 u32 dest_rtpi = 0;
1463 1458
1464 memset(dest_iport, 0, 64); 1459 memset(dest_iport, 0, 64);
@@ -1473,8 +1468,7 @@ static int core_scsi3_decode_spec_i_port(
1473 tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); 1468 tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL);
1474 if (!tidh_new) { 1469 if (!tidh_new) {
1475 pr_err("Unable to allocate tidh_new\n"); 1470 pr_err("Unable to allocate tidh_new\n");
1476 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1471 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1477 return -EINVAL;
1478 } 1472 }
1479 INIT_LIST_HEAD(&tidh_new->dest_list); 1473 INIT_LIST_HEAD(&tidh_new->dest_list);
1480 tidh_new->dest_tpg = tpg; 1474 tidh_new->dest_tpg = tpg;
@@ -1486,8 +1480,7 @@ static int core_scsi3_decode_spec_i_port(
1486 sa_res_key, all_tg_pt, aptpl); 1480 sa_res_key, all_tg_pt, aptpl);
1487 if (!local_pr_reg) { 1481 if (!local_pr_reg) {
1488 kfree(tidh_new); 1482 kfree(tidh_new);
1489 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1483 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1490 return -ENOMEM;
1491 } 1484 }
1492 tidh_new->dest_pr_reg = local_pr_reg; 1485 tidh_new->dest_pr_reg = local_pr_reg;
1493 /* 1486 /*
@@ -1501,12 +1494,16 @@ static int core_scsi3_decode_spec_i_port(
1501 if (cmd->data_length < 28) { 1494 if (cmd->data_length < 28) {
1502 pr_warn("SPC-PR: Received PR OUT parameter list" 1495 pr_warn("SPC-PR: Received PR OUT parameter list"
1503 " length too small: %u\n", cmd->data_length); 1496 " length too small: %u\n", cmd->data_length);
1504 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1497 ret = TCM_INVALID_PARAMETER_LIST;
1505 ret = -EINVAL;
1506 goto out; 1498 goto out;
1507 } 1499 }
1508 1500
1509 buf = transport_kmap_data_sg(cmd); 1501 buf = transport_kmap_data_sg(cmd);
1502 if (!buf) {
1503 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1504 goto out;
1505 }
1506
1510 /* 1507 /*
1511 * For a PERSISTENT RESERVE OUT specify initiator ports payload, 1508 * For a PERSISTENT RESERVE OUT specify initiator ports payload,
1512 * first extract TransportID Parameter Data Length, and make sure 1509 * first extract TransportID Parameter Data Length, and make sure
@@ -1521,9 +1518,8 @@ static int core_scsi3_decode_spec_i_port(
1521 pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" 1518 pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header"
1522 " does not equal CDB data_length: %u\n", tpdl, 1519 " does not equal CDB data_length: %u\n", tpdl,
1523 cmd->data_length); 1520 cmd->data_length);
1524 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1521 ret = TCM_INVALID_PARAMETER_LIST;
1525 ret = -EINVAL; 1522 goto out_unmap;
1526 goto out;
1527 } 1523 }
1528 /* 1524 /*
1529 * Start processing the received transport IDs using the 1525 * Start processing the received transport IDs using the
@@ -1566,16 +1562,13 @@ static int core_scsi3_decode_spec_i_port(
1566 smp_mb__after_atomic_inc(); 1562 smp_mb__after_atomic_inc();
1567 spin_unlock(&dev->se_port_lock); 1563 spin_unlock(&dev->se_port_lock);
1568 1564
1569 ret = core_scsi3_tpg_depend_item(tmp_tpg); 1565 if (core_scsi3_tpg_depend_item(tmp_tpg)) {
1570 if (ret != 0) {
1571 pr_err(" core_scsi3_tpg_depend_item()" 1566 pr_err(" core_scsi3_tpg_depend_item()"
1572 " for tmp_tpg\n"); 1567 " for tmp_tpg\n");
1573 atomic_dec(&tmp_tpg->tpg_pr_ref_count); 1568 atomic_dec(&tmp_tpg->tpg_pr_ref_count);
1574 smp_mb__after_atomic_dec(); 1569 smp_mb__after_atomic_dec();
1575 cmd->scsi_sense_reason = 1570 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1576 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1571 goto out_unmap;
1577 ret = -EINVAL;
1578 goto out;
1579 } 1572 }
1580 /* 1573 /*
1581 * Locate the destination initiator ACL to be registered 1574 * Locate the destination initiator ACL to be registered
@@ -1597,17 +1590,14 @@ static int core_scsi3_decode_spec_i_port(
1597 continue; 1590 continue;
1598 } 1591 }
1599 1592
1600 ret = core_scsi3_nodeacl_depend_item(dest_node_acl); 1593 if (core_scsi3_nodeacl_depend_item(dest_node_acl)) {
1601 if (ret != 0) {
1602 pr_err("configfs_depend_item() failed" 1594 pr_err("configfs_depend_item() failed"
1603 " for dest_node_acl->acl_group\n"); 1595 " for dest_node_acl->acl_group\n");
1604 atomic_dec(&dest_node_acl->acl_pr_ref_count); 1596 atomic_dec(&dest_node_acl->acl_pr_ref_count);
1605 smp_mb__after_atomic_dec(); 1597 smp_mb__after_atomic_dec();
1606 core_scsi3_tpg_undepend_item(tmp_tpg); 1598 core_scsi3_tpg_undepend_item(tmp_tpg);
1607 cmd->scsi_sense_reason = 1599 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1608 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1600 goto out_unmap;
1609 ret = -EINVAL;
1610 goto out;
1611 } 1601 }
1612 1602
1613 dest_tpg = tmp_tpg; 1603 dest_tpg = tmp_tpg;
@@ -1624,9 +1614,8 @@ static int core_scsi3_decode_spec_i_port(
1624 if (!dest_tpg) { 1614 if (!dest_tpg) {
1625 pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" 1615 pr_err("SPC-3 PR SPEC_I_PT: Unable to locate"
1626 " dest_tpg\n"); 1616 " dest_tpg\n");
1627 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1617 ret = TCM_INVALID_PARAMETER_LIST;
1628 ret = -EINVAL; 1618 goto out_unmap;
1629 goto out;
1630 } 1619 }
1631 1620
1632 pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" 1621 pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u"
@@ -1639,9 +1628,8 @@ static int core_scsi3_decode_spec_i_port(
1639 " %u for Transport ID: %s\n", tid_len, ptr); 1628 " %u for Transport ID: %s\n", tid_len, ptr);
1640 core_scsi3_nodeacl_undepend_item(dest_node_acl); 1629 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1641 core_scsi3_tpg_undepend_item(dest_tpg); 1630 core_scsi3_tpg_undepend_item(dest_tpg);
1642 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1631 ret = TCM_INVALID_PARAMETER_LIST;
1643 ret = -EINVAL; 1632 goto out_unmap;
1644 goto out;
1645 } 1633 }
1646 /* 1634 /*
1647 * Locate the desintation struct se_dev_entry pointer for matching 1635 * Locate the desintation struct se_dev_entry pointer for matching
@@ -1658,23 +1646,19 @@ static int core_scsi3_decode_spec_i_port(
1658 1646
1659 core_scsi3_nodeacl_undepend_item(dest_node_acl); 1647 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1660 core_scsi3_tpg_undepend_item(dest_tpg); 1648 core_scsi3_tpg_undepend_item(dest_tpg);
1661 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1649 ret = TCM_INVALID_PARAMETER_LIST;
1662 ret = -EINVAL; 1650 goto out_unmap;
1663 goto out;
1664 } 1651 }
1665 1652
1666 ret = core_scsi3_lunacl_depend_item(dest_se_deve); 1653 if (core_scsi3_lunacl_depend_item(dest_se_deve)) {
1667 if (ret < 0) {
1668 pr_err("core_scsi3_lunacl_depend_item()" 1654 pr_err("core_scsi3_lunacl_depend_item()"
1669 " failed\n"); 1655 " failed\n");
1670 atomic_dec(&dest_se_deve->pr_ref_count); 1656 atomic_dec(&dest_se_deve->pr_ref_count);
1671 smp_mb__after_atomic_dec(); 1657 smp_mb__after_atomic_dec();
1672 core_scsi3_nodeacl_undepend_item(dest_node_acl); 1658 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1673 core_scsi3_tpg_undepend_item(dest_tpg); 1659 core_scsi3_tpg_undepend_item(dest_tpg);
1674 cmd->scsi_sense_reason = 1660 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1675 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1661 goto out_unmap;
1676 ret = -EINVAL;
1677 goto out;
1678 } 1662 }
1679 1663
1680 pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" 1664 pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s"
@@ -1710,10 +1694,8 @@ static int core_scsi3_decode_spec_i_port(
1710 core_scsi3_lunacl_undepend_item(dest_se_deve); 1694 core_scsi3_lunacl_undepend_item(dest_se_deve);
1711 core_scsi3_nodeacl_undepend_item(dest_node_acl); 1695 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1712 core_scsi3_tpg_undepend_item(dest_tpg); 1696 core_scsi3_tpg_undepend_item(dest_tpg);
1713 cmd->scsi_sense_reason = 1697 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1714 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1698 goto out_unmap;
1715 ret = -ENOMEM;
1716 goto out;
1717 } 1699 }
1718 INIT_LIST_HEAD(&tidh_new->dest_list); 1700 INIT_LIST_HEAD(&tidh_new->dest_list);
1719 tidh_new->dest_tpg = dest_tpg; 1701 tidh_new->dest_tpg = dest_tpg;
@@ -1744,9 +1726,8 @@ static int core_scsi3_decode_spec_i_port(
1744 core_scsi3_nodeacl_undepend_item(dest_node_acl); 1726 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1745 core_scsi3_tpg_undepend_item(dest_tpg); 1727 core_scsi3_tpg_undepend_item(dest_tpg);
1746 kfree(tidh_new); 1728 kfree(tidh_new);
1747 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 1729 ret = TCM_INVALID_PARAMETER_LIST;
1748 ret = -EINVAL; 1730 goto out_unmap;
1749 goto out;
1750 } 1731 }
1751 tidh_new->dest_pr_reg = dest_pr_reg; 1732 tidh_new->dest_pr_reg = dest_pr_reg;
1752 list_add_tail(&tidh_new->dest_list, &tid_dest_list); 1733 list_add_tail(&tidh_new->dest_list, &tid_dest_list);
@@ -1804,8 +1785,9 @@ static int core_scsi3_decode_spec_i_port(
1804 } 1785 }
1805 1786
1806 return 0; 1787 return 0;
1807out: 1788out_unmap:
1808 transport_kunmap_data_sg(cmd); 1789 transport_kunmap_data_sg(cmd);
1790out:
1809 /* 1791 /*
1810 * For the failure case, release everything from tid_dest_list 1792 * For the failure case, release everything from tid_dest_list
1811 * including *dest_pr_reg and the configfs dependances.. 1793 * including *dest_pr_reg and the configfs dependances..
@@ -2020,14 +2002,15 @@ static int __core_scsi3_write_aptpl_to_file(
2020 return 0; 2002 return 0;
2021} 2003}
2022 2004
2023static int core_scsi3_update_and_write_aptpl( 2005static int
2024 struct se_device *dev, 2006core_scsi3_update_and_write_aptpl(struct se_device *dev, unsigned char *in_buf,
2025 unsigned char *in_buf, 2007 u32 in_pr_aptpl_buf_len)
2026 u32 in_pr_aptpl_buf_len)
2027{ 2008{
2028 unsigned char null_buf[64], *buf; 2009 unsigned char null_buf[64], *buf;
2029 u32 pr_aptpl_buf_len; 2010 u32 pr_aptpl_buf_len;
2030 int ret, clear_aptpl_metadata = 0; 2011 int clear_aptpl_metadata = 0;
2012 int ret;
2013
2031 /* 2014 /*
2032 * Can be called with a NULL pointer from PROUT service action CLEAR 2015 * Can be called with a NULL pointer from PROUT service action CLEAR
2033 */ 2016 */
@@ -2049,25 +2032,17 @@ static int core_scsi3_update_and_write_aptpl(
2049 clear_aptpl_metadata); 2032 clear_aptpl_metadata);
2050 if (ret != 0) 2033 if (ret != 0)
2051 return ret; 2034 return ret;
2035
2052 /* 2036 /*
2053 * __core_scsi3_write_aptpl_to_file() will call strlen() 2037 * __core_scsi3_write_aptpl_to_file() will call strlen()
2054 * on the passed buf to determine pr_aptpl_buf_len. 2038 * on the passed buf to determine pr_aptpl_buf_len.
2055 */ 2039 */
2056 ret = __core_scsi3_write_aptpl_to_file(dev, buf, 0); 2040 return __core_scsi3_write_aptpl_to_file(dev, buf, 0);
2057 if (ret != 0)
2058 return ret;
2059
2060 return ret;
2061} 2041}
2062 2042
2063static int core_scsi3_emulate_pro_register( 2043static sense_reason_t
2064 struct se_cmd *cmd, 2044core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
2065 u64 res_key, 2045 int aptpl, int all_tg_pt, int spec_i_pt, int ignore_key)
2066 u64 sa_res_key,
2067 int aptpl,
2068 int all_tg_pt,
2069 int spec_i_pt,
2070 int ignore_key)
2071{ 2046{
2072 struct se_session *se_sess = cmd->se_sess; 2047 struct se_session *se_sess = cmd->se_sess;
2073 struct se_device *dev = cmd->se_dev; 2048 struct se_device *dev = cmd->se_dev;
@@ -2079,12 +2054,12 @@ static int core_scsi3_emulate_pro_register(
2079 /* Used for APTPL metadata w/ UNREGISTER */ 2054 /* Used for APTPL metadata w/ UNREGISTER */
2080 unsigned char *pr_aptpl_buf = NULL; 2055 unsigned char *pr_aptpl_buf = NULL;
2081 unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; 2056 unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
2082 int pr_holder = 0, ret = 0, type; 2057 sense_reason_t ret;
2058 int pr_holder = 0, type;
2083 2059
2084 if (!se_sess || !se_lun) { 2060 if (!se_sess || !se_lun) {
2085 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); 2061 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
2086 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2062 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2087 return -EINVAL;
2088 } 2063 }
2089 se_tpg = se_sess->se_tpg; 2064 se_tpg = se_sess->se_tpg;
2090 se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; 2065 se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
@@ -2103,8 +2078,7 @@ static int core_scsi3_emulate_pro_register(
2103 if (res_key) { 2078 if (res_key) {
2104 pr_warn("SPC-3 PR: Reservation Key non-zero" 2079 pr_warn("SPC-3 PR: Reservation Key non-zero"
2105 " for SA REGISTER, returning CONFLICT\n"); 2080 " for SA REGISTER, returning CONFLICT\n");
2106 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2081 return TCM_RESERVATION_CONFLICT;
2107 return -EINVAL;
2108 } 2082 }
2109 /* 2083 /*
2110 * Do nothing but return GOOD status. 2084 * Do nothing but return GOOD status.
@@ -2118,15 +2092,13 @@ static int core_scsi3_emulate_pro_register(
2118 * Port Endpoint that the PRO was received from on the 2092 * Port Endpoint that the PRO was received from on the
2119 * Logical Unit of the SCSI device server. 2093 * Logical Unit of the SCSI device server.
2120 */ 2094 */
2121 ret = core_scsi3_alloc_registration(cmd->se_dev, 2095 if (core_scsi3_alloc_registration(cmd->se_dev,
2122 se_sess->se_node_acl, se_deve, isid_ptr, 2096 se_sess->se_node_acl, se_deve, isid_ptr,
2123 sa_res_key, all_tg_pt, aptpl, 2097 sa_res_key, all_tg_pt, aptpl,
2124 ignore_key, 0); 2098 ignore_key, 0)) {
2125 if (ret != 0) {
2126 pr_err("Unable to allocate" 2099 pr_err("Unable to allocate"
2127 " struct t10_pr_registration\n"); 2100 " struct t10_pr_registration\n");
2128 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 2101 return TCM_INVALID_PARAMETER_LIST;
2129 return -EINVAL;
2130 } 2102 }
2131 } else { 2103 } else {
2132 /* 2104 /*
@@ -2160,201 +2132,192 @@ static int core_scsi3_emulate_pro_register(
2160 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, 2132 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev,
2161 se_sess->se_node_acl, se_sess); 2133 se_sess->se_node_acl, se_sess);
2162 2134
2163 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 2135 if (core_scsi3_update_and_write_aptpl(cmd->se_dev,
2164 &pr_reg->pr_aptpl_buf[0], 2136 &pr_reg->pr_aptpl_buf[0],
2165 pr_tmpl->pr_aptpl_buf_len); 2137 pr_tmpl->pr_aptpl_buf_len)) {
2166 if (!ret) {
2167 pr_tmpl->pr_aptpl_active = 1; 2138 pr_tmpl->pr_aptpl_active = 1;
2168 pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); 2139 pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n");
2169 } 2140 }
2170 2141
2171 core_scsi3_put_pr_reg(pr_reg); 2142 goto out_put_pr_reg;
2172 return ret; 2143 }
2173 } else { 2144
2174 /* 2145 /*
2175 * Locate the existing *pr_reg via struct se_node_acl pointers 2146 * Locate the existing *pr_reg via struct se_node_acl pointers
2176 */ 2147 */
2177 pr_reg = pr_reg_e; 2148 pr_reg = pr_reg_e;
2178 type = pr_reg->pr_res_type; 2149 type = pr_reg->pr_res_type;
2179 2150
2180 if (!ignore_key) { 2151 if (!ignore_key) {
2181 if (res_key != pr_reg->pr_res_key) { 2152 if (res_key != pr_reg->pr_res_key) {
2182 pr_err("SPC-3 PR REGISTER: Received" 2153 pr_err("SPC-3 PR REGISTER: Received"
2183 " res_key: 0x%016Lx does not match" 2154 " res_key: 0x%016Lx does not match"
2184 " existing SA REGISTER res_key:" 2155 " existing SA REGISTER res_key:"
2185 " 0x%016Lx\n", res_key, 2156 " 0x%016Lx\n", res_key,
2186 pr_reg->pr_res_key); 2157 pr_reg->pr_res_key);
2187 core_scsi3_put_pr_reg(pr_reg); 2158 ret = TCM_RESERVATION_CONFLICT;
2188 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2159 goto out_put_pr_reg;
2189 return -EINVAL;
2190 }
2191 } 2160 }
2192 if (spec_i_pt) { 2161 }
2193 pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" 2162
2194 " set while sa_res_key=0\n"); 2163 if (spec_i_pt) {
2195 core_scsi3_put_pr_reg(pr_reg); 2164 pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT"
2196 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 2165 " set while sa_res_key=0\n");
2197 return -EINVAL; 2166 ret = TCM_INVALID_PARAMETER_LIST;
2167 goto out_put_pr_reg;
2168 }
2169
2170 /*
2171 * An existing ALL_TG_PT=1 registration being released
2172 * must also set ALL_TG_PT=1 in the incoming PROUT.
2173 */
2174 if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) {
2175 pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1"
2176 " registration exists, but ALL_TG_PT=1 bit not"
2177 " present in received PROUT\n");
2178 ret = TCM_INVALID_CDB_FIELD;
2179 goto out_put_pr_reg;
2180 }
2181
2182 /*
2183 * Allocate APTPL metadata buffer used for UNREGISTER ops
2184 */
2185 if (aptpl) {
2186 pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len,
2187 GFP_KERNEL);
2188 if (!pr_aptpl_buf) {
2189 pr_err("Unable to allocate"
2190 " pr_aptpl_buf\n");
2191 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2192 goto out_put_pr_reg;
2198 } 2193 }
2199 /* 2194 }
2200 * An existing ALL_TG_PT=1 registration being released 2195
2201 * must also set ALL_TG_PT=1 in the incoming PROUT. 2196 /*
2202 */ 2197 * sa_res_key=0 Unregister Reservation Key for registered I_T
2203 if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { 2198 * Nexus sa_res_key=1 Change Reservation Key for registered I_T
2204 pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" 2199 * Nexus.
2205 " registration exists, but ALL_TG_PT=1 bit not" 2200 */
2206 " present in received PROUT\n"); 2201 if (!sa_res_key) {
2207 core_scsi3_put_pr_reg(pr_reg); 2202 pr_holder = core_scsi3_check_implict_release(
2208 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 2203 cmd->se_dev, pr_reg);
2209 return -EINVAL; 2204 if (pr_holder < 0) {
2205 kfree(pr_aptpl_buf);
2206 ret = TCM_RESERVATION_CONFLICT;
2207 goto out_put_pr_reg;
2210 } 2208 }
2209
2210 spin_lock(&pr_tmpl->registration_lock);
2211 /* 2211 /*
2212 * Allocate APTPL metadata buffer used for UNREGISTER ops 2212 * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port
2213 * and matching pr_res_key.
2213 */ 2214 */
2214 if (aptpl) { 2215 if (pr_reg->pr_reg_all_tg_pt) {
2215 pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, 2216 list_for_each_entry_safe(pr_reg_p, pr_reg_tmp,
2216 GFP_KERNEL); 2217 &pr_tmpl->registration_list,
2217 if (!pr_aptpl_buf) { 2218 pr_reg_list) {
2218 pr_err("Unable to allocate" 2219
2219 " pr_aptpl_buf\n"); 2220 if (!pr_reg_p->pr_reg_all_tg_pt)
2220 core_scsi3_put_pr_reg(pr_reg); 2221 continue;
2221 cmd->scsi_sense_reason = 2222 if (pr_reg_p->pr_res_key != res_key)
2222 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2223 continue;
2223 return -EINVAL; 2224 if (pr_reg == pr_reg_p)
2225 continue;
2226 if (strcmp(pr_reg->pr_reg_nacl->initiatorname,
2227 pr_reg_p->pr_reg_nacl->initiatorname))
2228 continue;
2229
2230 __core_scsi3_free_registration(dev,
2231 pr_reg_p, NULL, 0);
2224 } 2232 }
2225 } 2233 }
2234
2226 /* 2235 /*
2227 * sa_res_key=0 Unregister Reservation Key for registered I_T 2236 * Release the calling I_T Nexus registration now..
2228 * Nexus sa_res_key=1 Change Reservation Key for registered I_T
2229 * Nexus.
2230 */ 2237 */
2231 if (!sa_res_key) { 2238 __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1);
2232 pr_holder = core_scsi3_check_implict_release(
2233 cmd->se_dev, pr_reg);
2234 if (pr_holder < 0) {
2235 kfree(pr_aptpl_buf);
2236 core_scsi3_put_pr_reg(pr_reg);
2237 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2238 return -EINVAL;
2239 }
2240
2241 spin_lock(&pr_tmpl->registration_lock);
2242 /*
2243 * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port
2244 * and matching pr_res_key.
2245 */
2246 if (pr_reg->pr_reg_all_tg_pt) {
2247 list_for_each_entry_safe(pr_reg_p, pr_reg_tmp,
2248 &pr_tmpl->registration_list,
2249 pr_reg_list) {
2250
2251 if (!pr_reg_p->pr_reg_all_tg_pt)
2252 continue;
2253 2239
2254 if (pr_reg_p->pr_res_key != res_key) 2240 /*
2255 continue; 2241 * From spc4r17, section 5.7.11.3 Unregistering
2256 2242 *
2257 if (pr_reg == pr_reg_p) 2243 * If the persistent reservation is a registrants only
2258 continue; 2244 * type, the device server shall establish a unit
2259 2245 * attention condition for the initiator port associated
2260 if (strcmp(pr_reg->pr_reg_nacl->initiatorname, 2246 * with every registered I_T nexus except for the I_T
2261 pr_reg_p->pr_reg_nacl->initiatorname)) 2247 * nexus on which the PERSISTENT RESERVE OUT command was
2262 continue; 2248 * received, with the additional sense code set to
2263 2249 * RESERVATIONS RELEASED.
2264 __core_scsi3_free_registration(dev, 2250 */
2265 pr_reg_p, NULL, 0); 2251 if (pr_holder &&
2266 } 2252 (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY ||
2267 } 2253 type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) {
2268 /* 2254 list_for_each_entry(pr_reg_p,
2269 * Release the calling I_T Nexus registration now.. 2255 &pr_tmpl->registration_list,
2270 */ 2256 pr_reg_list) {
2271 __core_scsi3_free_registration(cmd->se_dev, pr_reg, 2257
2272 NULL, 1); 2258 core_scsi3_ua_allocate(
2273 /* 2259 pr_reg_p->pr_reg_nacl,
2274 * From spc4r17, section 5.7.11.3 Unregistering 2260 pr_reg_p->pr_res_mapped_lun,
2275 * 2261 0x2A,
2276 * If the persistent reservation is a registrants only 2262 ASCQ_2AH_RESERVATIONS_RELEASED);
2277 * type, the device server shall establish a unit
2278 * attention condition for the initiator port associated
2279 * with every registered I_T nexus except for the I_T
2280 * nexus on which the PERSISTENT RESERVE OUT command was
2281 * received, with the additional sense code set to
2282 * RESERVATIONS RELEASED.
2283 */
2284 if (pr_holder &&
2285 ((type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
2286 (type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY))) {
2287 list_for_each_entry(pr_reg_p,
2288 &pr_tmpl->registration_list,
2289 pr_reg_list) {
2290
2291 core_scsi3_ua_allocate(
2292 pr_reg_p->pr_reg_nacl,
2293 pr_reg_p->pr_res_mapped_lun,
2294 0x2A,
2295 ASCQ_2AH_RESERVATIONS_RELEASED);
2296 }
2297 } 2263 }
2298 spin_unlock(&pr_tmpl->registration_lock); 2264 }
2265 spin_unlock(&pr_tmpl->registration_lock);
2299 2266
2300 if (!aptpl) { 2267 if (!aptpl) {
2301 pr_tmpl->pr_aptpl_active = 0; 2268 pr_tmpl->pr_aptpl_active = 0;
2302 core_scsi3_update_and_write_aptpl(dev, NULL, 0); 2269 core_scsi3_update_and_write_aptpl(dev, NULL, 0);
2303 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" 2270 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
2304 " for UNREGISTER\n"); 2271 " for UNREGISTER\n");
2305 return 0; 2272 return 0;
2306 } 2273 }
2307 2274
2308 ret = core_scsi3_update_and_write_aptpl(dev, 2275 if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0],
2309 &pr_aptpl_buf[0], 2276 pr_tmpl->pr_aptpl_buf_len)) {
2310 pr_tmpl->pr_aptpl_buf_len); 2277 pr_tmpl->pr_aptpl_active = 1;
2311 if (!ret) { 2278 pr_debug("SPC-3 PR: Set APTPL Bit Activated"
2312 pr_tmpl->pr_aptpl_active = 1; 2279 " for UNREGISTER\n");
2313 pr_debug("SPC-3 PR: Set APTPL Bit Activated" 2280 }
2314 " for UNREGISTER\n");
2315 }
2316 2281
2317 kfree(pr_aptpl_buf); 2282 goto out_free_aptpl_buf;
2318 return ret; 2283 }
2319 } else {
2320 /*
2321 * Increment PRgeneration counter for struct se_device"
2322 * upon a successful REGISTER, see spc4r17 section 6.3.2
2323 * READ_KEYS service action.
2324 */
2325 pr_reg->pr_res_generation = core_scsi3_pr_generation(
2326 cmd->se_dev);
2327 pr_reg->pr_res_key = sa_res_key;
2328 pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
2329 " Key for %s to: 0x%016Lx PRgeneration:"
2330 " 0x%08x\n", cmd->se_tfo->get_fabric_name(),
2331 (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "",
2332 pr_reg->pr_reg_nacl->initiatorname,
2333 pr_reg->pr_res_key, pr_reg->pr_res_generation);
2334
2335 if (!aptpl) {
2336 pr_tmpl->pr_aptpl_active = 0;
2337 core_scsi3_update_and_write_aptpl(dev, NULL, 0);
2338 core_scsi3_put_pr_reg(pr_reg);
2339 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
2340 " for REGISTER\n");
2341 return 0;
2342 }
2343 2284
2344 ret = core_scsi3_update_and_write_aptpl(dev, 2285 /*
2345 &pr_aptpl_buf[0], 2286 * Increment PRgeneration counter for struct se_device"
2346 pr_tmpl->pr_aptpl_buf_len); 2287 * upon a successful REGISTER, see spc4r17 section 6.3.2
2347 if (!ret) { 2288 * READ_KEYS service action.
2348 pr_tmpl->pr_aptpl_active = 1; 2289 */
2349 pr_debug("SPC-3 PR: Set APTPL Bit Activated" 2290 pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev);
2350 " for REGISTER\n"); 2291 pr_reg->pr_res_key = sa_res_key;
2351 } 2292 pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
2293 " Key for %s to: 0x%016Lx PRgeneration:"
2294 " 0x%08x\n", cmd->se_tfo->get_fabric_name(),
2295 (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "",
2296 pr_reg->pr_reg_nacl->initiatorname,
2297 pr_reg->pr_res_key, pr_reg->pr_res_generation);
2352 2298
2353 kfree(pr_aptpl_buf); 2299 if (!aptpl) {
2354 core_scsi3_put_pr_reg(pr_reg); 2300 pr_tmpl->pr_aptpl_active = 0;
2355 } 2301 core_scsi3_update_and_write_aptpl(dev, NULL, 0);
2302 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
2303 " for REGISTER\n");
2304 ret = 0;
2305 goto out_put_pr_reg;
2356 } 2306 }
2357 return 0; 2307
2308 if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0],
2309 pr_tmpl->pr_aptpl_buf_len)) {
2310 pr_tmpl->pr_aptpl_active = 1;
2311 pr_debug("SPC-3 PR: Set APTPL Bit Activated"
2312 " for REGISTER\n");
2313 }
2314
2315out_free_aptpl_buf:
2316 kfree(pr_aptpl_buf);
2317 ret = 0;
2318out_put_pr_reg:
2319 core_scsi3_put_pr_reg(pr_reg);
2320 return ret;
2358} 2321}
2359 2322
2360unsigned char *core_scsi3_pr_dump_type(int type) 2323unsigned char *core_scsi3_pr_dump_type(int type)
@@ -2379,26 +2342,23 @@ unsigned char *core_scsi3_pr_dump_type(int type)
2379 return "Unknown SPC-3 PR Type"; 2342 return "Unknown SPC-3 PR Type";
2380} 2343}
2381 2344
2382static int core_scsi3_pro_reserve( 2345static sense_reason_t
2383 struct se_cmd *cmd, 2346core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
2384 struct se_device *dev,
2385 int type,
2386 int scope,
2387 u64 res_key)
2388{ 2347{
2348 struct se_device *dev = cmd->se_dev;
2389 struct se_session *se_sess = cmd->se_sess; 2349 struct se_session *se_sess = cmd->se_sess;
2390 struct se_lun *se_lun = cmd->se_lun; 2350 struct se_lun *se_lun = cmd->se_lun;
2391 struct t10_pr_registration *pr_reg, *pr_res_holder; 2351 struct t10_pr_registration *pr_reg, *pr_res_holder;
2392 struct t10_reservation *pr_tmpl = &dev->t10_pr; 2352 struct t10_reservation *pr_tmpl = &dev->t10_pr;
2393 char i_buf[PR_REG_ISID_ID_LEN]; 2353 char i_buf[PR_REG_ISID_ID_LEN];
2394 int ret, prf_isid; 2354 sense_reason_t ret;
2355 int prf_isid;
2395 2356
2396 memset(i_buf, 0, PR_REG_ISID_ID_LEN); 2357 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
2397 2358
2398 if (!se_sess || !se_lun) { 2359 if (!se_sess || !se_lun) {
2399 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); 2360 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
2400 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2361 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2401 return -EINVAL;
2402 } 2362 }
2403 /* 2363 /*
2404 * Locate the existing *pr_reg via struct se_node_acl pointers 2364 * Locate the existing *pr_reg via struct se_node_acl pointers
@@ -2408,8 +2368,7 @@ static int core_scsi3_pro_reserve(
2408 if (!pr_reg) { 2368 if (!pr_reg) {
2409 pr_err("SPC-3 PR: Unable to locate" 2369 pr_err("SPC-3 PR: Unable to locate"
2410 " PR_REGISTERED *pr_reg for RESERVE\n"); 2370 " PR_REGISTERED *pr_reg for RESERVE\n");
2411 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2371 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2412 return -EINVAL;
2413 } 2372 }
2414 /* 2373 /*
2415 * From spc4r17 Section 5.7.9: Reserving: 2374 * From spc4r17 Section 5.7.9: Reserving:
@@ -2424,9 +2383,8 @@ static int core_scsi3_pro_reserve(
2424 pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx" 2383 pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx"
2425 " does not match existing SA REGISTER res_key:" 2384 " does not match existing SA REGISTER res_key:"
2426 " 0x%016Lx\n", res_key, pr_reg->pr_res_key); 2385 " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
2427 core_scsi3_put_pr_reg(pr_reg); 2386 ret = TCM_RESERVATION_CONFLICT;
2428 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2387 goto out_put_pr_reg;
2429 return -EINVAL;
2430 } 2388 }
2431 /* 2389 /*
2432 * From spc4r17 Section 5.7.9: Reserving: 2390 * From spc4r17 Section 5.7.9: Reserving:
@@ -2440,9 +2398,8 @@ static int core_scsi3_pro_reserve(
2440 */ 2398 */
2441 if (scope != PR_SCOPE_LU_SCOPE) { 2399 if (scope != PR_SCOPE_LU_SCOPE) {
2442 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); 2400 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
2443 core_scsi3_put_pr_reg(pr_reg); 2401 ret = TCM_INVALID_PARAMETER_LIST;
2444 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 2402 goto out_put_pr_reg;
2445 return -EINVAL;
2446 } 2403 }
2447 /* 2404 /*
2448 * See if we have an existing PR reservation holder pointer at 2405 * See if we have an existing PR reservation holder pointer at
@@ -2473,9 +2430,8 @@ static int core_scsi3_pro_reserve(
2473 pr_res_holder->pr_reg_nacl->initiatorname); 2430 pr_res_holder->pr_reg_nacl->initiatorname);
2474 2431
2475 spin_unlock(&dev->dev_reservation_lock); 2432 spin_unlock(&dev->dev_reservation_lock);
2476 core_scsi3_put_pr_reg(pr_reg); 2433 ret = TCM_RESERVATION_CONFLICT;
2477 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2434 goto out_put_pr_reg;
2478 return -EINVAL;
2479 } 2435 }
2480 /* 2436 /*
2481 * From spc4r17 Section 5.7.9: Reserving: 2437 * From spc4r17 Section 5.7.9: Reserving:
@@ -2497,9 +2453,8 @@ static int core_scsi3_pro_reserve(
2497 pr_res_holder->pr_reg_nacl->initiatorname); 2453 pr_res_holder->pr_reg_nacl->initiatorname);
2498 2454
2499 spin_unlock(&dev->dev_reservation_lock); 2455 spin_unlock(&dev->dev_reservation_lock);
2500 core_scsi3_put_pr_reg(pr_reg); 2456 ret = TCM_RESERVATION_CONFLICT;
2501 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2457 goto out_put_pr_reg;
2502 return -EINVAL;
2503 } 2458 }
2504 /* 2459 /*
2505 * From spc4r17 Section 5.7.9: Reserving: 2460 * From spc4r17 Section 5.7.9: Reserving:
@@ -2512,8 +2467,8 @@ static int core_scsi3_pro_reserve(
2512 * shall completethe command with GOOD status. 2467 * shall completethe command with GOOD status.
2513 */ 2468 */
2514 spin_unlock(&dev->dev_reservation_lock); 2469 spin_unlock(&dev->dev_reservation_lock);
2515 core_scsi3_put_pr_reg(pr_reg); 2470 ret = 0;
2516 return 0; 2471 goto out_put_pr_reg;
2517 } 2472 }
2518 /* 2473 /*
2519 * Otherwise, our *pr_reg becomes the PR reservation holder for said 2474 * Otherwise, our *pr_reg becomes the PR reservation holder for said
@@ -2537,27 +2492,24 @@ static int core_scsi3_pro_reserve(
2537 spin_unlock(&dev->dev_reservation_lock); 2492 spin_unlock(&dev->dev_reservation_lock);
2538 2493
2539 if (pr_tmpl->pr_aptpl_active) { 2494 if (pr_tmpl->pr_aptpl_active) {
2540 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 2495 if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
2541 &pr_reg->pr_aptpl_buf[0], 2496 &pr_reg->pr_aptpl_buf[0],
2542 pr_tmpl->pr_aptpl_buf_len); 2497 pr_tmpl->pr_aptpl_buf_len)) {
2543 if (!ret)
2544 pr_debug("SPC-3 PR: Updated APTPL metadata" 2498 pr_debug("SPC-3 PR: Updated APTPL metadata"
2545 " for RESERVE\n"); 2499 " for RESERVE\n");
2500 }
2546 } 2501 }
2547 2502
2503 ret = 0;
2504out_put_pr_reg:
2548 core_scsi3_put_pr_reg(pr_reg); 2505 core_scsi3_put_pr_reg(pr_reg);
2549 return 0; 2506 return ret;
2550} 2507}
2551 2508
2552static int core_scsi3_emulate_pro_reserve( 2509static sense_reason_t
2553 struct se_cmd *cmd, 2510core_scsi3_emulate_pro_reserve(struct se_cmd *cmd, int type, int scope,
2554 int type, 2511 u64 res_key)
2555 int scope,
2556 u64 res_key)
2557{ 2512{
2558 struct se_device *dev = cmd->se_dev;
2559 int ret = 0;
2560
2561 switch (type) { 2513 switch (type) {
2562 case PR_TYPE_WRITE_EXCLUSIVE: 2514 case PR_TYPE_WRITE_EXCLUSIVE:
2563 case PR_TYPE_EXCLUSIVE_ACCESS: 2515 case PR_TYPE_EXCLUSIVE_ACCESS:
@@ -2565,16 +2517,12 @@ static int core_scsi3_emulate_pro_reserve(
2565 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: 2517 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
2566 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: 2518 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
2567 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: 2519 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
2568 ret = core_scsi3_pro_reserve(cmd, dev, type, scope, res_key); 2520 return core_scsi3_pro_reserve(cmd, type, scope, res_key);
2569 break;
2570 default: 2521 default:
2571 pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" 2522 pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:"
2572 " 0x%02x\n", type); 2523 " 0x%02x\n", type);
2573 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 2524 return TCM_INVALID_CDB_FIELD;
2574 return -EINVAL;
2575 } 2525 }
2576
2577 return ret;
2578} 2526}
2579 2527
2580/* 2528/*
@@ -2612,23 +2560,21 @@ static void __core_scsi3_complete_pro_release(
2612 pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0; 2560 pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0;
2613} 2561}
2614 2562
2615static int core_scsi3_emulate_pro_release( 2563static sense_reason_t
2616 struct se_cmd *cmd, 2564core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope,
2617 int type, 2565 u64 res_key)
2618 int scope,
2619 u64 res_key)
2620{ 2566{
2621 struct se_device *dev = cmd->se_dev; 2567 struct se_device *dev = cmd->se_dev;
2622 struct se_session *se_sess = cmd->se_sess; 2568 struct se_session *se_sess = cmd->se_sess;
2623 struct se_lun *se_lun = cmd->se_lun; 2569 struct se_lun *se_lun = cmd->se_lun;
2624 struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; 2570 struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder;
2625 struct t10_reservation *pr_tmpl = &dev->t10_pr; 2571 struct t10_reservation *pr_tmpl = &dev->t10_pr;
2626 int ret, all_reg = 0; 2572 int all_reg = 0;
2573 sense_reason_t ret = 0;
2627 2574
2628 if (!se_sess || !se_lun) { 2575 if (!se_sess || !se_lun) {
2629 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); 2576 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
2630 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2577 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2631 return -EINVAL;
2632 } 2578 }
2633 /* 2579 /*
2634 * Locate the existing *pr_reg via struct se_node_acl pointers 2580 * Locate the existing *pr_reg via struct se_node_acl pointers
@@ -2637,8 +2583,7 @@ static int core_scsi3_emulate_pro_release(
2637 if (!pr_reg) { 2583 if (!pr_reg) {
2638 pr_err("SPC-3 PR: Unable to locate" 2584 pr_err("SPC-3 PR: Unable to locate"
2639 " PR_REGISTERED *pr_reg for RELEASE\n"); 2585 " PR_REGISTERED *pr_reg for RELEASE\n");
2640 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2586 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2641 return -EINVAL;
2642 } 2587 }
2643 /* 2588 /*
2644 * From spc4r17 Section 5.7.11.2 Releasing: 2589 * From spc4r17 Section 5.7.11.2 Releasing:
@@ -2659,7 +2604,6 @@ static int core_scsi3_emulate_pro_release(
2659 * No persistent reservation, return GOOD status. 2604 * No persistent reservation, return GOOD status.
2660 */ 2605 */
2661 spin_unlock(&dev->dev_reservation_lock); 2606 spin_unlock(&dev->dev_reservation_lock);
2662 core_scsi3_put_pr_reg(pr_reg);
2663 return 0; 2607 return 0;
2664 } 2608 }
2665 if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || 2609 if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
@@ -2673,9 +2617,9 @@ static int core_scsi3_emulate_pro_release(
2673 * persistent reservation holder. return GOOD status. 2617 * persistent reservation holder. return GOOD status.
2674 */ 2618 */
2675 spin_unlock(&dev->dev_reservation_lock); 2619 spin_unlock(&dev->dev_reservation_lock);
2676 core_scsi3_put_pr_reg(pr_reg); 2620 goto out_put_pr_reg;
2677 return 0;
2678 } 2621 }
2622
2679 /* 2623 /*
2680 * From spc4r17 Section 5.7.11.2 Releasing: 2624 * From spc4r17 Section 5.7.11.2 Releasing:
2681 * 2625 *
@@ -2695,9 +2639,8 @@ static int core_scsi3_emulate_pro_release(
2695 " does not match existing SA REGISTER res_key:" 2639 " does not match existing SA REGISTER res_key:"
2696 " 0x%016Lx\n", res_key, pr_reg->pr_res_key); 2640 " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
2697 spin_unlock(&dev->dev_reservation_lock); 2641 spin_unlock(&dev->dev_reservation_lock);
2698 core_scsi3_put_pr_reg(pr_reg); 2642 ret = TCM_RESERVATION_CONFLICT;
2699 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2643 goto out_put_pr_reg;
2700 return -EINVAL;
2701 } 2644 }
2702 /* 2645 /*
2703 * From spc4r17 Section 5.7.11.2 Releasing and above: 2646 * From spc4r17 Section 5.7.11.2 Releasing and above:
@@ -2718,9 +2661,8 @@ static int core_scsi3_emulate_pro_release(
2718 pr_res_holder->pr_reg_nacl->initiatorname); 2661 pr_res_holder->pr_reg_nacl->initiatorname);
2719 2662
2720 spin_unlock(&dev->dev_reservation_lock); 2663 spin_unlock(&dev->dev_reservation_lock);
2721 core_scsi3_put_pr_reg(pr_reg); 2664 ret = TCM_RESERVATION_CONFLICT;
2722 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2665 goto out_put_pr_reg;
2723 return -EINVAL;
2724 } 2666 }
2725 /* 2667 /*
2726 * In response to a persistent reservation release request from the 2668 * In response to a persistent reservation release request from the
@@ -2773,20 +2715,18 @@ static int core_scsi3_emulate_pro_release(
2773 2715
2774write_aptpl: 2716write_aptpl:
2775 if (pr_tmpl->pr_aptpl_active) { 2717 if (pr_tmpl->pr_aptpl_active) {
2776 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 2718 if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
2777 &pr_reg->pr_aptpl_buf[0], 2719 &pr_reg->pr_aptpl_buf[0], pr_tmpl->pr_aptpl_buf_len)) {
2778 pr_tmpl->pr_aptpl_buf_len);
2779 if (!ret)
2780 pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); 2720 pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n");
2721 }
2781 } 2722 }
2782 2723out_put_pr_reg:
2783 core_scsi3_put_pr_reg(pr_reg); 2724 core_scsi3_put_pr_reg(pr_reg);
2784 return 0; 2725 return ret;
2785} 2726}
2786 2727
2787static int core_scsi3_emulate_pro_clear( 2728static sense_reason_t
2788 struct se_cmd *cmd, 2729core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key)
2789 u64 res_key)
2790{ 2730{
2791 struct se_device *dev = cmd->se_dev; 2731 struct se_device *dev = cmd->se_dev;
2792 struct se_node_acl *pr_reg_nacl; 2732 struct se_node_acl *pr_reg_nacl;
@@ -2803,8 +2743,7 @@ static int core_scsi3_emulate_pro_clear(
2803 if (!pr_reg_n) { 2743 if (!pr_reg_n) {
2804 pr_err("SPC-3 PR: Unable to locate" 2744 pr_err("SPC-3 PR: Unable to locate"
2805 " PR_REGISTERED *pr_reg for CLEAR\n"); 2745 " PR_REGISTERED *pr_reg for CLEAR\n");
2806 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2746 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2807 return -EINVAL;
2808 } 2747 }
2809 /* 2748 /*
2810 * From spc4r17 section 5.7.11.6, Clearing: 2749 * From spc4r17 section 5.7.11.6, Clearing:
@@ -2823,8 +2762,7 @@ static int core_scsi3_emulate_pro_clear(
2823 " existing SA REGISTER res_key:" 2762 " existing SA REGISTER res_key:"
2824 " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); 2763 " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
2825 core_scsi3_put_pr_reg(pr_reg_n); 2764 core_scsi3_put_pr_reg(pr_reg_n);
2826 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2765 return TCM_RESERVATION_CONFLICT;
2827 return -EINVAL;
2828 } 2766 }
2829 /* 2767 /*
2830 * a) Release the persistent reservation, if any; 2768 * a) Release the persistent reservation, if any;
@@ -2948,13 +2886,9 @@ static void core_scsi3_release_preempt_and_abort(
2948 } 2886 }
2949} 2887}
2950 2888
2951static int core_scsi3_pro_preempt( 2889static sense_reason_t
2952 struct se_cmd *cmd, 2890core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
2953 int type, 2891 u64 sa_res_key, int abort)
2954 int scope,
2955 u64 res_key,
2956 u64 sa_res_key,
2957 int abort)
2958{ 2892{
2959 struct se_device *dev = cmd->se_dev; 2893 struct se_device *dev = cmd->se_dev;
2960 struct se_node_acl *pr_reg_nacl; 2894 struct se_node_acl *pr_reg_nacl;
@@ -2964,12 +2898,10 @@ static int core_scsi3_pro_preempt(
2964 struct t10_reservation *pr_tmpl = &dev->t10_pr; 2898 struct t10_reservation *pr_tmpl = &dev->t10_pr;
2965 u32 pr_res_mapped_lun = 0; 2899 u32 pr_res_mapped_lun = 0;
2966 int all_reg = 0, calling_it_nexus = 0, released_regs = 0; 2900 int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
2967 int prh_type = 0, prh_scope = 0, ret; 2901 int prh_type = 0, prh_scope = 0;
2968 2902
2969 if (!se_sess) { 2903 if (!se_sess)
2970 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2904 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2971 return -EINVAL;
2972 }
2973 2905
2974 pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, 2906 pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
2975 se_sess); 2907 se_sess);
@@ -2977,19 +2909,16 @@ static int core_scsi3_pro_preempt(
2977 pr_err("SPC-3 PR: Unable to locate" 2909 pr_err("SPC-3 PR: Unable to locate"
2978 " PR_REGISTERED *pr_reg for PREEMPT%s\n", 2910 " PR_REGISTERED *pr_reg for PREEMPT%s\n",
2979 (abort) ? "_AND_ABORT" : ""); 2911 (abort) ? "_AND_ABORT" : "");
2980 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2912 return TCM_RESERVATION_CONFLICT;
2981 return -EINVAL;
2982 } 2913 }
2983 if (pr_reg_n->pr_res_key != res_key) { 2914 if (pr_reg_n->pr_res_key != res_key) {
2984 core_scsi3_put_pr_reg(pr_reg_n); 2915 core_scsi3_put_pr_reg(pr_reg_n);
2985 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 2916 return TCM_RESERVATION_CONFLICT;
2986 return -EINVAL;
2987 } 2917 }
2988 if (scope != PR_SCOPE_LU_SCOPE) { 2918 if (scope != PR_SCOPE_LU_SCOPE) {
2989 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); 2919 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
2990 core_scsi3_put_pr_reg(pr_reg_n); 2920 core_scsi3_put_pr_reg(pr_reg_n);
2991 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 2921 return TCM_INVALID_PARAMETER_LIST;
2992 return -EINVAL;
2993 } 2922 }
2994 2923
2995 spin_lock(&dev->dev_reservation_lock); 2924 spin_lock(&dev->dev_reservation_lock);
@@ -3002,8 +2931,7 @@ static int core_scsi3_pro_preempt(
3002 if (!all_reg && !sa_res_key) { 2931 if (!all_reg && !sa_res_key) {
3003 spin_unlock(&dev->dev_reservation_lock); 2932 spin_unlock(&dev->dev_reservation_lock);
3004 core_scsi3_put_pr_reg(pr_reg_n); 2933 core_scsi3_put_pr_reg(pr_reg_n);
3005 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 2934 return TCM_INVALID_PARAMETER_LIST;
3006 return -EINVAL;
3007 } 2935 }
3008 /* 2936 /*
3009 * From spc4r17, section 5.7.11.4.4 Removing Registrations: 2937 * From spc4r17, section 5.7.11.4.4 Removing Registrations:
@@ -3097,8 +3025,7 @@ static int core_scsi3_pro_preempt(
3097 if (!released_regs) { 3025 if (!released_regs) {
3098 spin_unlock(&dev->dev_reservation_lock); 3026 spin_unlock(&dev->dev_reservation_lock);
3099 core_scsi3_put_pr_reg(pr_reg_n); 3027 core_scsi3_put_pr_reg(pr_reg_n);
3100 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 3028 return TCM_RESERVATION_CONFLICT;
3101 return -EINVAL;
3102 } 3029 }
3103 /* 3030 /*
3104 * For an existing all registrants type reservation 3031 * For an existing all registrants type reservation
@@ -3117,13 +3044,13 @@ static int core_scsi3_pro_preempt(
3117 spin_unlock(&dev->dev_reservation_lock); 3044 spin_unlock(&dev->dev_reservation_lock);
3118 3045
3119 if (pr_tmpl->pr_aptpl_active) { 3046 if (pr_tmpl->pr_aptpl_active) {
3120 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 3047 if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
3121 &pr_reg_n->pr_aptpl_buf[0], 3048 &pr_reg_n->pr_aptpl_buf[0],
3122 pr_tmpl->pr_aptpl_buf_len); 3049 pr_tmpl->pr_aptpl_buf_len)) {
3123 if (!ret)
3124 pr_debug("SPC-3 PR: Updated APTPL" 3050 pr_debug("SPC-3 PR: Updated APTPL"
3125 " metadata for PREEMPT%s\n", (abort) ? 3051 " metadata for PREEMPT%s\n", (abort) ?
3126 "_AND_ABORT" : ""); 3052 "_AND_ABORT" : "");
3053 }
3127 } 3054 }
3128 3055
3129 core_scsi3_put_pr_reg(pr_reg_n); 3056 core_scsi3_put_pr_reg(pr_reg_n);
@@ -3253,12 +3180,12 @@ static int core_scsi3_pro_preempt(
3253 } 3180 }
3254 3181
3255 if (pr_tmpl->pr_aptpl_active) { 3182 if (pr_tmpl->pr_aptpl_active) {
3256 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 3183 if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
3257 &pr_reg_n->pr_aptpl_buf[0], 3184 &pr_reg_n->pr_aptpl_buf[0],
3258 pr_tmpl->pr_aptpl_buf_len); 3185 pr_tmpl->pr_aptpl_buf_len)) {
3259 if (!ret)
3260 pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" 3186 pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT"
3261 "%s\n", (abort) ? "_AND_ABORT" : ""); 3187 "%s\n", abort ? "_AND_ABORT" : "");
3188 }
3262 } 3189 }
3263 3190
3264 core_scsi3_put_pr_reg(pr_reg_n); 3191 core_scsi3_put_pr_reg(pr_reg_n);
@@ -3266,16 +3193,10 @@ static int core_scsi3_pro_preempt(
3266 return 0; 3193 return 0;
3267} 3194}
3268 3195
3269static int core_scsi3_emulate_pro_preempt( 3196static sense_reason_t
3270 struct se_cmd *cmd, 3197core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope,
3271 int type, 3198 u64 res_key, u64 sa_res_key, int abort)
3272 int scope,
3273 u64 res_key,
3274 u64 sa_res_key,
3275 int abort)
3276{ 3199{
3277 int ret = 0;
3278
3279 switch (type) { 3200 switch (type) {
3280 case PR_TYPE_WRITE_EXCLUSIVE: 3201 case PR_TYPE_WRITE_EXCLUSIVE:
3281 case PR_TYPE_EXCLUSIVE_ACCESS: 3202 case PR_TYPE_EXCLUSIVE_ACCESS:
@@ -3283,26 +3204,19 @@ static int core_scsi3_emulate_pro_preempt(
3283 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: 3204 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
3284 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: 3205 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
3285 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: 3206 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
3286 ret = core_scsi3_pro_preempt(cmd, type, scope, 3207 return core_scsi3_pro_preempt(cmd, type, scope, res_key,
3287 res_key, sa_res_key, abort); 3208 sa_res_key, abort);
3288 break;
3289 default: 3209 default:
3290 pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" 3210 pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
3291 " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); 3211 " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type);
3292 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3212 return TCM_INVALID_CDB_FIELD;
3293 return -EINVAL;
3294 } 3213 }
3295
3296 return ret;
3297} 3214}
3298 3215
3299 3216
3300static int core_scsi3_emulate_pro_register_and_move( 3217static sense_reason_t
3301 struct se_cmd *cmd, 3218core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
3302 u64 res_key, 3219 u64 sa_res_key, int aptpl, int unreg)
3303 u64 sa_res_key,
3304 int aptpl,
3305 int unreg)
3306{ 3220{
3307 struct se_session *se_sess = cmd->se_sess; 3221 struct se_session *se_sess = cmd->se_sess;
3308 struct se_device *dev = cmd->se_dev; 3222 struct se_device *dev = cmd->se_dev;
@@ -3318,15 +3232,16 @@ static int core_scsi3_emulate_pro_register_and_move(
3318 unsigned char *initiator_str; 3232 unsigned char *initiator_str;
3319 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; 3233 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
3320 u32 tid_len, tmp_tid_len; 3234 u32 tid_len, tmp_tid_len;
3321 int new_reg = 0, type, scope, ret, matching_iname, prf_isid; 3235 int new_reg = 0, type, scope, matching_iname, prf_isid;
3236 sense_reason_t ret;
3322 unsigned short rtpi; 3237 unsigned short rtpi;
3323 unsigned char proto_ident; 3238 unsigned char proto_ident;
3324 3239
3325 if (!se_sess || !se_lun) { 3240 if (!se_sess || !se_lun) {
3326 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); 3241 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
3327 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3242 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3328 return -EINVAL;
3329 } 3243 }
3244
3330 memset(dest_iport, 0, 64); 3245 memset(dest_iport, 0, 64);
3331 memset(i_buf, 0, PR_REG_ISID_ID_LEN); 3246 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
3332 se_tpg = se_sess->se_tpg; 3247 se_tpg = se_sess->se_tpg;
@@ -3342,8 +3257,7 @@ static int core_scsi3_emulate_pro_register_and_move(
3342 if (!pr_reg) { 3257 if (!pr_reg) {
3343 pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" 3258 pr_err("SPC-3 PR: Unable to locate PR_REGISTERED"
3344 " *pr_reg for REGISTER_AND_MOVE\n"); 3259 " *pr_reg for REGISTER_AND_MOVE\n");
3345 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3260 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3346 return -EINVAL;
3347 } 3261 }
3348 /* 3262 /*
3349 * The provided reservation key much match the existing reservation key 3263 * The provided reservation key much match the existing reservation key
@@ -3353,9 +3267,8 @@ static int core_scsi3_emulate_pro_register_and_move(
3353 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received" 3267 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received"
3354 " res_key: 0x%016Lx does not match existing SA REGISTER" 3268 " res_key: 0x%016Lx does not match existing SA REGISTER"
3355 " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); 3269 " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key);
3356 core_scsi3_put_pr_reg(pr_reg); 3270 ret = TCM_RESERVATION_CONFLICT;
3357 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 3271 goto out_put_pr_reg;
3358 return -EINVAL;
3359 } 3272 }
3360 /* 3273 /*
3361 * The service active reservation key needs to be non zero 3274 * The service active reservation key needs to be non zero
@@ -3363,9 +3276,8 @@ static int core_scsi3_emulate_pro_register_and_move(
3363 if (!sa_res_key) { 3276 if (!sa_res_key) {
3364 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" 3277 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero"
3365 " sa_res_key\n"); 3278 " sa_res_key\n");
3366 core_scsi3_put_pr_reg(pr_reg); 3279 ret = TCM_INVALID_PARAMETER_LIST;
3367 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3280 goto out_put_pr_reg;
3368 return -EINVAL;
3369 } 3281 }
3370 3282
3371 /* 3283 /*
@@ -3374,6 +3286,11 @@ static int core_scsi3_emulate_pro_register_and_move(
3374 * information. 3286 * information.
3375 */ 3287 */
3376 buf = transport_kmap_data_sg(cmd); 3288 buf = transport_kmap_data_sg(cmd);
3289 if (!buf) {
3290 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3291 goto out_put_pr_reg;
3292 }
3293
3377 rtpi = (buf[18] & 0xff) << 8; 3294 rtpi = (buf[18] & 0xff) << 8;
3378 rtpi |= buf[19] & 0xff; 3295 rtpi |= buf[19] & 0xff;
3379 tid_len = (buf[20] & 0xff) << 24; 3296 tid_len = (buf[20] & 0xff) << 24;
@@ -3387,9 +3304,8 @@ static int core_scsi3_emulate_pro_register_and_move(
3387 pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header" 3304 pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header"
3388 " does not equal CDB data_length: %u\n", tid_len, 3305 " does not equal CDB data_length: %u\n", tid_len,
3389 cmd->data_length); 3306 cmd->data_length);
3390 core_scsi3_put_pr_reg(pr_reg); 3307 ret = TCM_INVALID_PARAMETER_LIST;
3391 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3308 goto out_put_pr_reg;
3392 return -EINVAL;
3393 } 3309 }
3394 3310
3395 spin_lock(&dev->se_port_lock); 3311 spin_lock(&dev->se_port_lock);
@@ -3407,15 +3323,13 @@ static int core_scsi3_emulate_pro_register_and_move(
3407 smp_mb__after_atomic_inc(); 3323 smp_mb__after_atomic_inc();
3408 spin_unlock(&dev->se_port_lock); 3324 spin_unlock(&dev->se_port_lock);
3409 3325
3410 ret = core_scsi3_tpg_depend_item(dest_se_tpg); 3326 if (core_scsi3_tpg_depend_item(dest_se_tpg)) {
3411 if (ret != 0) {
3412 pr_err("core_scsi3_tpg_depend_item() failed" 3327 pr_err("core_scsi3_tpg_depend_item() failed"
3413 " for dest_se_tpg\n"); 3328 " for dest_se_tpg\n");
3414 atomic_dec(&dest_se_tpg->tpg_pr_ref_count); 3329 atomic_dec(&dest_se_tpg->tpg_pr_ref_count);
3415 smp_mb__after_atomic_dec(); 3330 smp_mb__after_atomic_dec();
3416 core_scsi3_put_pr_reg(pr_reg); 3331 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3417 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3332 goto out_put_pr_reg;
3418 return -EINVAL;
3419 } 3333 }
3420 3334
3421 spin_lock(&dev->se_port_lock); 3335 spin_lock(&dev->se_port_lock);
@@ -3427,12 +3341,15 @@ static int core_scsi3_emulate_pro_register_and_move(
3427 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" 3341 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
3428 " fabric ops from Relative Target Port Identifier:" 3342 " fabric ops from Relative Target Port Identifier:"
3429 " %hu\n", rtpi); 3343 " %hu\n", rtpi);
3430 core_scsi3_put_pr_reg(pr_reg); 3344 ret = TCM_INVALID_PARAMETER_LIST;
3431 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3345 goto out_put_pr_reg;
3432 return -EINVAL;
3433 } 3346 }
3434 3347
3435 buf = transport_kmap_data_sg(cmd); 3348 buf = transport_kmap_data_sg(cmd);
3349 if (!buf) {
3350 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3351 goto out_put_pr_reg;
3352 }
3436 proto_ident = (buf[24] & 0x0f); 3353 proto_ident = (buf[24] & 0x0f);
3437 3354
3438 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" 3355 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
@@ -3444,16 +3361,14 @@ static int core_scsi3_emulate_pro_register_and_move(
3444 " from fabric: %s\n", proto_ident, 3361 " from fabric: %s\n", proto_ident,
3445 dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), 3362 dest_tf_ops->get_fabric_proto_ident(dest_se_tpg),
3446 dest_tf_ops->get_fabric_name()); 3363 dest_tf_ops->get_fabric_name());
3447 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3364 ret = TCM_INVALID_PARAMETER_LIST;
3448 ret = -EINVAL;
3449 goto out; 3365 goto out;
3450 } 3366 }
3451 if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { 3367 if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) {
3452 pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" 3368 pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not"
3453 " containg a valid tpg_parse_pr_out_transport_id" 3369 " containg a valid tpg_parse_pr_out_transport_id"
3454 " function pointer\n"); 3370 " function pointer\n");
3455 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3371 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3456 ret = -EINVAL;
3457 goto out; 3372 goto out;
3458 } 3373 }
3459 initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, 3374 initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg,
@@ -3461,8 +3376,7 @@ static int core_scsi3_emulate_pro_register_and_move(
3461 if (!initiator_str) { 3376 if (!initiator_str) {
3462 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" 3377 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
3463 " initiator_str from Transport ID\n"); 3378 " initiator_str from Transport ID\n");
3464 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3379 ret = TCM_INVALID_PARAMETER_LIST;
3465 ret = -EINVAL;
3466 goto out; 3380 goto out;
3467 } 3381 }
3468 3382
@@ -3491,8 +3405,7 @@ static int core_scsi3_emulate_pro_register_and_move(
3491 pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" 3405 pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s"
3492 " matches: %s on received I_T Nexus\n", initiator_str, 3406 " matches: %s on received I_T Nexus\n", initiator_str,
3493 pr_reg_nacl->initiatorname); 3407 pr_reg_nacl->initiatorname);
3494 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3408 ret = TCM_INVALID_PARAMETER_LIST;
3495 ret = -EINVAL;
3496 goto out; 3409 goto out;
3497 } 3410 }
3498 if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { 3411 if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) {
@@ -3500,8 +3413,7 @@ static int core_scsi3_emulate_pro_register_and_move(
3500 " matches: %s %s on received I_T Nexus\n", 3413 " matches: %s %s on received I_T Nexus\n",
3501 initiator_str, iport_ptr, pr_reg_nacl->initiatorname, 3414 initiator_str, iport_ptr, pr_reg_nacl->initiatorname,
3502 pr_reg->pr_reg_isid); 3415 pr_reg->pr_reg_isid);
3503 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3416 ret = TCM_INVALID_PARAMETER_LIST;
3504 ret = -EINVAL;
3505 goto out; 3417 goto out;
3506 } 3418 }
3507after_iport_check: 3419after_iport_check:
@@ -3521,19 +3433,17 @@ after_iport_check:
3521 pr_err("Unable to locate %s dest_node_acl for" 3433 pr_err("Unable to locate %s dest_node_acl for"
3522 " TransportID%s\n", dest_tf_ops->get_fabric_name(), 3434 " TransportID%s\n", dest_tf_ops->get_fabric_name(),
3523 initiator_str); 3435 initiator_str);
3524 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3436 ret = TCM_INVALID_PARAMETER_LIST;
3525 ret = -EINVAL;
3526 goto out; 3437 goto out;
3527 } 3438 }
3528 ret = core_scsi3_nodeacl_depend_item(dest_node_acl); 3439
3529 if (ret != 0) { 3440 if (core_scsi3_nodeacl_depend_item(dest_node_acl)) {
3530 pr_err("core_scsi3_nodeacl_depend_item() for" 3441 pr_err("core_scsi3_nodeacl_depend_item() for"
3531 " dest_node_acl\n"); 3442 " dest_node_acl\n");
3532 atomic_dec(&dest_node_acl->acl_pr_ref_count); 3443 atomic_dec(&dest_node_acl->acl_pr_ref_count);
3533 smp_mb__after_atomic_dec(); 3444 smp_mb__after_atomic_dec();
3534 dest_node_acl = NULL; 3445 dest_node_acl = NULL;
3535 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3446 ret = TCM_INVALID_PARAMETER_LIST;
3536 ret = -EINVAL;
3537 goto out; 3447 goto out;
3538 } 3448 }
3539 3449
@@ -3549,19 +3459,16 @@ after_iport_check:
3549 if (!dest_se_deve) { 3459 if (!dest_se_deve) {
3550 pr_err("Unable to locate %s dest_se_deve from RTPI:" 3460 pr_err("Unable to locate %s dest_se_deve from RTPI:"
3551 " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); 3461 " %hu\n", dest_tf_ops->get_fabric_name(), rtpi);
3552 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3462 ret = TCM_INVALID_PARAMETER_LIST;
3553 ret = -EINVAL;
3554 goto out; 3463 goto out;
3555 } 3464 }
3556 3465
3557 ret = core_scsi3_lunacl_depend_item(dest_se_deve); 3466 if (core_scsi3_lunacl_depend_item(dest_se_deve)) {
3558 if (ret < 0) {
3559 pr_err("core_scsi3_lunacl_depend_item() failed\n"); 3467 pr_err("core_scsi3_lunacl_depend_item() failed\n");
3560 atomic_dec(&dest_se_deve->pr_ref_count); 3468 atomic_dec(&dest_se_deve->pr_ref_count);
3561 smp_mb__after_atomic_dec(); 3469 smp_mb__after_atomic_dec();
3562 dest_se_deve = NULL; 3470 dest_se_deve = NULL;
3563 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3471 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3564 ret = -EINVAL;
3565 goto out; 3472 goto out;
3566 } 3473 }
3567 3474
@@ -3580,8 +3487,7 @@ after_iport_check:
3580 pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" 3487 pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation"
3581 " currently held\n"); 3488 " currently held\n");
3582 spin_unlock(&dev->dev_reservation_lock); 3489 spin_unlock(&dev->dev_reservation_lock);
3583 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3490 ret = TCM_INVALID_CDB_FIELD;
3584 ret = -EINVAL;
3585 goto out; 3491 goto out;
3586 } 3492 }
3587 /* 3493 /*
@@ -3594,8 +3500,7 @@ after_iport_check:
3594 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" 3500 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T"
3595 " Nexus is not reservation holder\n"); 3501 " Nexus is not reservation holder\n");
3596 spin_unlock(&dev->dev_reservation_lock); 3502 spin_unlock(&dev->dev_reservation_lock);
3597 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 3503 ret = TCM_RESERVATION_CONFLICT;
3598 ret = -EINVAL;
3599 goto out; 3504 goto out;
3600 } 3505 }
3601 /* 3506 /*
@@ -3613,8 +3518,7 @@ after_iport_check:
3613 " reservation for type: %s\n", 3518 " reservation for type: %s\n",
3614 core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); 3519 core_scsi3_pr_dump_type(pr_res_holder->pr_res_type));
3615 spin_unlock(&dev->dev_reservation_lock); 3520 spin_unlock(&dev->dev_reservation_lock);
3616 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 3521 ret = TCM_RESERVATION_CONFLICT;
3617 ret = -EINVAL;
3618 goto out; 3522 goto out;
3619 } 3523 }
3620 pr_res_nacl = pr_res_holder->pr_reg_nacl; 3524 pr_res_nacl = pr_res_holder->pr_reg_nacl;
@@ -3646,13 +3550,11 @@ after_iport_check:
3646 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, 3550 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
3647 iport_ptr); 3551 iport_ptr);
3648 if (!dest_pr_reg) { 3552 if (!dest_pr_reg) {
3649 ret = core_scsi3_alloc_registration(cmd->se_dev, 3553 if (core_scsi3_alloc_registration(cmd->se_dev,
3650 dest_node_acl, dest_se_deve, iport_ptr, 3554 dest_node_acl, dest_se_deve, iport_ptr,
3651 sa_res_key, 0, aptpl, 2, 1); 3555 sa_res_key, 0, aptpl, 2, 1)) {
3652 if (ret != 0) {
3653 spin_unlock(&dev->dev_reservation_lock); 3556 spin_unlock(&dev->dev_reservation_lock);
3654 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3557 ret = TCM_INVALID_PARAMETER_LIST;
3655 ret = -EINVAL;
3656 goto out; 3558 goto out;
3657 } 3559 }
3658 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, 3560 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
@@ -3723,12 +3625,12 @@ after_iport_check:
3723 " REGISTER_AND_MOVE\n"); 3625 " REGISTER_AND_MOVE\n");
3724 } else { 3626 } else {
3725 pr_tmpl->pr_aptpl_active = 1; 3627 pr_tmpl->pr_aptpl_active = 1;
3726 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, 3628 if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
3727 &dest_pr_reg->pr_aptpl_buf[0], 3629 &dest_pr_reg->pr_aptpl_buf[0],
3728 pr_tmpl->pr_aptpl_buf_len); 3630 pr_tmpl->pr_aptpl_buf_len)) {
3729 if (!ret)
3730 pr_debug("SPC-3 PR: Set APTPL Bit Activated for" 3631 pr_debug("SPC-3 PR: Set APTPL Bit Activated for"
3731 " REGISTER_AND_MOVE\n"); 3632 " REGISTER_AND_MOVE\n");
3633 }
3732 } 3634 }
3733 3635
3734 transport_kunmap_data_sg(cmd); 3636 transport_kunmap_data_sg(cmd);
@@ -3743,6 +3645,8 @@ out:
3743 if (dest_node_acl) 3645 if (dest_node_acl)
3744 core_scsi3_nodeacl_undepend_item(dest_node_acl); 3646 core_scsi3_nodeacl_undepend_item(dest_node_acl);
3745 core_scsi3_tpg_undepend_item(dest_se_tpg); 3647 core_scsi3_tpg_undepend_item(dest_se_tpg);
3648
3649out_put_pr_reg:
3746 core_scsi3_put_pr_reg(pr_reg); 3650 core_scsi3_put_pr_reg(pr_reg);
3747 return ret; 3651 return ret;
3748} 3652}
@@ -3760,14 +3664,15 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
3760/* 3664/*
3761 * See spc4r17 section 6.14 Table 170 3665 * See spc4r17 section 6.14 Table 170
3762 */ 3666 */
3763int target_scsi3_emulate_pr_out(struct se_cmd *cmd) 3667sense_reason_t
3668target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3764{ 3669{
3765 unsigned char *cdb = &cmd->t_task_cdb[0]; 3670 unsigned char *cdb = &cmd->t_task_cdb[0];
3766 unsigned char *buf; 3671 unsigned char *buf;
3767 u64 res_key, sa_res_key; 3672 u64 res_key, sa_res_key;
3768 int sa, scope, type, aptpl; 3673 int sa, scope, type, aptpl;
3769 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; 3674 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
3770 int ret; 3675 sense_reason_t ret;
3771 3676
3772 /* 3677 /*
3773 * Following spc2r20 5.5.1 Reservations overview: 3678 * Following spc2r20 5.5.1 Reservations overview:
@@ -3782,28 +3687,22 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3782 pr_err("Received PERSISTENT_RESERVE CDB while legacy" 3687 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
3783 " SPC-2 reservation is held, returning" 3688 " SPC-2 reservation is held, returning"
3784 " RESERVATION_CONFLICT\n"); 3689 " RESERVATION_CONFLICT\n");
3785 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 3690 return TCM_RESERVATION_CONFLICT;
3786 ret = -EINVAL;
3787 goto out;
3788 } 3691 }
3789 3692
3790 /* 3693 /*
3791 * FIXME: A NULL struct se_session pointer means an this is not coming from 3694 * FIXME: A NULL struct se_session pointer means an this is not coming from
3792 * a $FABRIC_MOD's nexus, but from internal passthrough ops. 3695 * a $FABRIC_MOD's nexus, but from internal passthrough ops.
3793 */ 3696 */
3794 if (!cmd->se_sess) { 3697 if (!cmd->se_sess)
3795 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 3698 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3796 ret = -EINVAL;
3797 goto out;
3798 }
3799 3699
3800 if (cmd->data_length < 24) { 3700 if (cmd->data_length < 24) {
3801 pr_warn("SPC-PR: Received PR OUT parameter list" 3701 pr_warn("SPC-PR: Received PR OUT parameter list"
3802 " length too small: %u\n", cmd->data_length); 3702 " length too small: %u\n", cmd->data_length);
3803 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3703 return TCM_INVALID_PARAMETER_LIST;
3804 ret = -EINVAL;
3805 goto out;
3806 } 3704 }
3705
3807 /* 3706 /*
3808 * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) 3707 * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB)
3809 */ 3708 */
@@ -3812,6 +3711,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3812 type = (cdb[2] & 0x0f); 3711 type = (cdb[2] & 0x0f);
3813 3712
3814 buf = transport_kmap_data_sg(cmd); 3713 buf = transport_kmap_data_sg(cmd);
3714 if (!buf)
3715 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3716
3815 /* 3717 /*
3816 * From PERSISTENT_RESERVE_OUT parameter list (payload) 3718 * From PERSISTENT_RESERVE_OUT parameter list (payload)
3817 */ 3719 */
@@ -3835,11 +3737,8 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3835 /* 3737 /*
3836 * SPEC_I_PT=1 is only valid for Service action: REGISTER 3738 * SPEC_I_PT=1 is only valid for Service action: REGISTER
3837 */ 3739 */
3838 if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { 3740 if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER))
3839 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3741 return TCM_INVALID_PARAMETER_LIST;
3840 ret = -EINVAL;
3841 goto out;
3842 }
3843 3742
3844 /* 3743 /*
3845 * From spc4r17 section 6.14: 3744 * From spc4r17 section 6.14:
@@ -3854,10 +3753,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3854 (cmd->data_length != 24)) { 3753 (cmd->data_length != 24)) {
3855 pr_warn("SPC-PR: Received PR OUT illegal parameter" 3754 pr_warn("SPC-PR: Received PR OUT illegal parameter"
3856 " list length: %u\n", cmd->data_length); 3755 " list length: %u\n", cmd->data_length);
3857 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; 3756 return TCM_INVALID_PARAMETER_LIST;
3858 ret = -EINVAL;
3859 goto out;
3860 } 3757 }
3758
3861 /* 3759 /*
3862 * (core_scsi3_emulate_pro_* function parameters 3760 * (core_scsi3_emulate_pro_* function parameters
3863 * are defined by spc4r17 Table 174: 3761 * are defined by spc4r17 Table 174:
@@ -3896,12 +3794,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3896 default: 3794 default:
3897 pr_err("Unknown PERSISTENT_RESERVE_OUT service" 3795 pr_err("Unknown PERSISTENT_RESERVE_OUT service"
3898 " action: 0x%02x\n", cdb[1] & 0x1f); 3796 " action: 0x%02x\n", cdb[1] & 0x1f);
3899 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3797 return TCM_INVALID_CDB_FIELD;
3900 ret = -EINVAL;
3901 break;
3902 } 3798 }
3903 3799
3904out:
3905 if (!ret) 3800 if (!ret)
3906 target_complete_cmd(cmd, GOOD); 3801 target_complete_cmd(cmd, GOOD);
3907 return ret; 3802 return ret;
@@ -3912,7 +3807,8 @@ out:
3912 * 3807 *
3913 * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160 3808 * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160
3914 */ 3809 */
3915static int core_scsi3_pri_read_keys(struct se_cmd *cmd) 3810static sense_reason_t
3811core_scsi3_pri_read_keys(struct se_cmd *cmd)
3916{ 3812{
3917 struct se_device *dev = cmd->se_dev; 3813 struct se_device *dev = cmd->se_dev;
3918 struct t10_pr_registration *pr_reg; 3814 struct t10_pr_registration *pr_reg;
@@ -3922,11 +3818,13 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
3922 if (cmd->data_length < 8) { 3818 if (cmd->data_length < 8) {
3923 pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" 3819 pr_err("PRIN SA READ_KEYS SCSI Data Length: %u"
3924 " too small\n", cmd->data_length); 3820 " too small\n", cmd->data_length);
3925 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3821 return TCM_INVALID_CDB_FIELD;
3926 return -EINVAL;
3927 } 3822 }
3928 3823
3929 buf = transport_kmap_data_sg(cmd); 3824 buf = transport_kmap_data_sg(cmd);
3825 if (!buf)
3826 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3827
3930 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); 3828 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
3931 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); 3829 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
3932 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); 3830 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -3970,7 +3868,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
3970 * 3868 *
3971 * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162 3869 * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162
3972 */ 3870 */
3973static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) 3871static sense_reason_t
3872core_scsi3_pri_read_reservation(struct se_cmd *cmd)
3974{ 3873{
3975 struct se_device *dev = cmd->se_dev; 3874 struct se_device *dev = cmd->se_dev;
3976 struct t10_pr_registration *pr_reg; 3875 struct t10_pr_registration *pr_reg;
@@ -3981,11 +3880,13 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
3981 if (cmd->data_length < 8) { 3880 if (cmd->data_length < 8) {
3982 pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" 3881 pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
3983 " too small\n", cmd->data_length); 3882 " too small\n", cmd->data_length);
3984 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3883 return TCM_INVALID_CDB_FIELD;
3985 return -EINVAL;
3986 } 3884 }
3987 3885
3988 buf = transport_kmap_data_sg(cmd); 3886 buf = transport_kmap_data_sg(cmd);
3887 if (!buf)
3888 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3889
3989 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); 3890 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
3990 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); 3891 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
3991 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); 3892 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -4054,7 +3955,8 @@ err:
4054 * 3955 *
4055 * See spc4r17 section 6.13.4 Table 165 3956 * See spc4r17 section 6.13.4 Table 165
4056 */ 3957 */
4057static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) 3958static sense_reason_t
3959core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
4058{ 3960{
4059 struct se_device *dev = cmd->se_dev; 3961 struct se_device *dev = cmd->se_dev;
4060 struct t10_reservation *pr_tmpl = &dev->t10_pr; 3962 struct t10_reservation *pr_tmpl = &dev->t10_pr;
@@ -4064,11 +3966,12 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
4064 if (cmd->data_length < 6) { 3966 if (cmd->data_length < 6) {
4065 pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" 3967 pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
4066 " %u too small\n", cmd->data_length); 3968 " %u too small\n", cmd->data_length);
4067 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 3969 return TCM_INVALID_CDB_FIELD;
4068 return -EINVAL;
4069 } 3970 }
4070 3971
4071 buf = transport_kmap_data_sg(cmd); 3972 buf = transport_kmap_data_sg(cmd);
3973 if (!buf)
3974 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
4072 3975
4073 buf[0] = ((add_len << 8) & 0xff); 3976 buf[0] = ((add_len << 8) & 0xff);
4074 buf[1] = (add_len & 0xff); 3977 buf[1] = (add_len & 0xff);
@@ -4110,7 +4013,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
4110 * 4013 *
4111 * See spc4r17 section 6.13.5 Table 168 and 169 4014 * See spc4r17 section 6.13.5 Table 168 and 169
4112 */ 4015 */
4113static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) 4016static sense_reason_t
4017core_scsi3_pri_read_full_status(struct se_cmd *cmd)
4114{ 4018{
4115 struct se_device *dev = cmd->se_dev; 4019 struct se_device *dev = cmd->se_dev;
4116 struct se_node_acl *se_nacl; 4020 struct se_node_acl *se_nacl;
@@ -4125,11 +4029,12 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
4125 if (cmd->data_length < 8) { 4029 if (cmd->data_length < 8) {
4126 pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" 4030 pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
4127 " too small\n", cmd->data_length); 4031 " too small\n", cmd->data_length);
4128 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 4032 return TCM_INVALID_CDB_FIELD;
4129 return -EINVAL;
4130 } 4033 }
4131 4034
4132 buf = transport_kmap_data_sg(cmd); 4035 buf = transport_kmap_data_sg(cmd);
4036 if (!buf)
4037 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
4133 4038
4134 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); 4039 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
4135 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); 4040 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
@@ -4255,9 +4160,10 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
4255 return 0; 4160 return 0;
4256} 4161}
4257 4162
4258int target_scsi3_emulate_pr_in(struct se_cmd *cmd) 4163sense_reason_t
4164target_scsi3_emulate_pr_in(struct se_cmd *cmd)
4259{ 4165{
4260 int ret; 4166 sense_reason_t ret;
4261 4167
4262 /* 4168 /*
4263 * Following spc2r20 5.5.1 Reservations overview: 4169 * Following spc2r20 5.5.1 Reservations overview:
@@ -4272,8 +4178,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
4272 pr_err("Received PERSISTENT_RESERVE CDB while legacy" 4178 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
4273 " SPC-2 reservation is held, returning" 4179 " SPC-2 reservation is held, returning"
4274 " RESERVATION_CONFLICT\n"); 4180 " RESERVATION_CONFLICT\n");
4275 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; 4181 return TCM_RESERVATION_CONFLICT;
4276 return -EINVAL;
4277 } 4182 }
4278 4183
4279 switch (cmd->t_task_cdb[1] & 0x1f) { 4184 switch (cmd->t_task_cdb[1] & 0x1f) {
@@ -4292,9 +4197,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
4292 default: 4197 default:
4293 pr_err("Unknown PERSISTENT_RESERVE_IN service" 4198 pr_err("Unknown PERSISTENT_RESERVE_IN service"
4294 " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); 4199 " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
4295 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 4200 return TCM_INVALID_CDB_FIELD;
4296 ret = -EINVAL;
4297 break;
4298 } 4201 }
4299 4202
4300 if (!ret) 4203 if (!ret)
@@ -4302,10 +4205,11 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
4302 return ret; 4205 return ret;
4303} 4206}
4304 4207
4305int target_check_reservation(struct se_cmd *cmd) 4208sense_reason_t
4209target_check_reservation(struct se_cmd *cmd)
4306{ 4210{
4307 struct se_device *dev = cmd->se_dev; 4211 struct se_device *dev = cmd->se_dev;
4308 int ret; 4212 sense_reason_t ret;
4309 4213
4310 if (!cmd->se_sess) 4214 if (!cmd->se_sess)
4311 return 0; 4215 return 0;