Commit fae43461 authored by Bart Van Assche's avatar Bart Van Assche Committed by Martin K. Petersen

scsi: target/core: Rework the SPC-2 reservation handling code

Instead of tracking the initiator that established an SPC-2 reservation,
track the session through which the SPC-2 reservation has been
established. This patch does not change any functionality.

Cc: Mike Christie <mchristi@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 63f74794
...@@ -1624,11 +1624,12 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, ...@@ -1624,11 +1624,12 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev,
static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev,
char *page) char *page)
{ {
struct se_session *sess = dev->reservation_holder;
struct se_node_acl *se_nacl; struct se_node_acl *se_nacl;
ssize_t len; ssize_t len;
se_nacl = dev->dev_reserved_node_acl; if (sess) {
if (se_nacl) { se_nacl = sess->se_node_acl;
len = sprintf(page, len = sprintf(page,
"SPC-2 Reservation: %s Initiator: %s\n", "SPC-2 Reservation: %s Initiator: %s\n",
se_nacl->se_tpg->se_tpg_tfo->fabric_name, se_nacl->se_tpg->se_tpg_tfo->fabric_name,
......
...@@ -111,10 +111,10 @@ target_scsi2_reservation_check(struct se_cmd *cmd) ...@@ -111,10 +111,10 @@ target_scsi2_reservation_check(struct se_cmd *cmd)
break; break;
} }
if (!dev->dev_reserved_node_acl || !sess) if (!dev->reservation_holder || !sess)
return 0; return 0;
if (dev->dev_reserved_node_acl != sess->se_node_acl) if (dev->reservation_holder->se_node_acl != sess->se_node_acl)
return TCM_RESERVATION_CONFLICT; return TCM_RESERVATION_CONFLICT;
if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
...@@ -200,6 +200,16 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) ...@@ -200,6 +200,16 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
return 0; return 0;
} }
void target_release_reservation(struct se_device *dev)
{
dev->reservation_holder = NULL;
dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
dev->dev_res_bin_isid = 0;
dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID;
}
}
sense_reason_t sense_reason_t
target_scsi2_reservation_release(struct se_cmd *cmd) target_scsi2_reservation_release(struct se_cmd *cmd)
{ {
...@@ -217,21 +227,16 @@ target_scsi2_reservation_release(struct se_cmd *cmd) ...@@ -217,21 +227,16 @@ target_scsi2_reservation_release(struct se_cmd *cmd)
return TCM_RESERVATION_CONFLICT; return TCM_RESERVATION_CONFLICT;
spin_lock(&dev->dev_reservation_lock); spin_lock(&dev->dev_reservation_lock);
if (!dev->dev_reserved_node_acl || !sess) if (!dev->reservation_holder || !sess)
goto out_unlock; goto out_unlock;
if (dev->dev_reserved_node_acl != sess->se_node_acl) if (dev->reservation_holder->se_node_acl != sess->se_node_acl)
goto out_unlock; goto out_unlock;
if (dev->dev_res_bin_isid != sess->sess_bin_isid) if (dev->dev_res_bin_isid != sess->sess_bin_isid)
goto out_unlock; goto out_unlock;
dev->dev_reserved_node_acl = NULL; target_release_reservation(dev);
dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
dev->dev_res_bin_isid = 0;
dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID;
}
tpg = sess->se_tpg; tpg = sess->se_tpg;
pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->" pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->"
" MAPPED LUN: %llu for %s\n", " MAPPED LUN: %llu for %s\n",
...@@ -275,13 +280,13 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) ...@@ -275,13 +280,13 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd)
tpg = sess->se_tpg; tpg = sess->se_tpg;
spin_lock(&dev->dev_reservation_lock); spin_lock(&dev->dev_reservation_lock);
if (dev->dev_reserved_node_acl && if (dev->reservation_holder &&
(dev->dev_reserved_node_acl != sess->se_node_acl)) { dev->reservation_holder->se_node_acl != sess->se_node_acl) {
pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n", pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n",
tpg->se_tpg_tfo->fabric_name); tpg->se_tpg_tfo->fabric_name);
pr_err("Original reserver LUN: %llu %s\n", pr_err("Original reserver LUN: %llu %s\n",
cmd->se_lun->unpacked_lun, cmd->se_lun->unpacked_lun,
dev->dev_reserved_node_acl->initiatorname); dev->reservation_holder->se_node_acl->initiatorname);
pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu" pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu"
" from %s \n", cmd->se_lun->unpacked_lun, " from %s \n", cmd->se_lun->unpacked_lun,
cmd->orig_fe_lun, cmd->orig_fe_lun,
...@@ -290,7 +295,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) ...@@ -290,7 +295,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd)
goto out_unlock; goto out_unlock;
} }
dev->dev_reserved_node_acl = sess->se_node_acl; dev->reservation_holder = sess;
dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS; dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS;
if (sess->sess_bin_isid != 0) { if (sess->sess_bin_isid != 0) {
dev->dev_res_bin_isid = sess->sess_bin_isid; dev->dev_res_bin_isid = sess->sess_bin_isid;
......
...@@ -58,6 +58,7 @@ extern struct kmem_cache *t10_pr_reg_cache; ...@@ -58,6 +58,7 @@ extern struct kmem_cache *t10_pr_reg_cache;
extern void core_pr_dump_initiator_port(struct t10_pr_registration *, extern void core_pr_dump_initiator_port(struct t10_pr_registration *,
char *, u32); char *, u32);
extern void target_release_reservation(struct se_device *dev);
extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *);
extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *);
extern int core_scsi3_alloc_aptpl_registration( extern int core_scsi3_alloc_aptpl_registration(
......
...@@ -390,7 +390,7 @@ int core_tmr_lun_reset( ...@@ -390,7 +390,7 @@ int core_tmr_lun_reset(
if (!preempt_and_abort_list && if (!preempt_and_abort_list &&
(dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) {
spin_lock(&dev->dev_reservation_lock); spin_lock(&dev->dev_reservation_lock);
dev->dev_reserved_node_acl = NULL; dev->reservation_holder = NULL;
dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); pr_debug("LUN_RESET: SCSI-2 Released reservation\n");
......
...@@ -795,8 +795,8 @@ struct se_device { ...@@ -795,8 +795,8 @@ struct se_device {
spinlock_t se_tmr_lock; spinlock_t se_tmr_lock;
spinlock_t qf_cmd_lock; spinlock_t qf_cmd_lock;
struct semaphore caw_sem; struct semaphore caw_sem;
/* Used for legacy SPC-2 reservationsa */ /* Used for legacy SPC-2 reservations */
struct se_node_acl *dev_reserved_node_acl; struct se_session *reservation_holder;
/* Used for ALUA Logical Unit Group membership */ /* Used for ALUA Logical Unit Group membership */
struct t10_alua_lu_gp_member *dev_alua_lu_gp_mem; struct t10_alua_lu_gp_member *dev_alua_lu_gp_mem;
/* Used for SPC-3 Persistent Reservations */ /* Used for SPC-3 Persistent Reservations */
......
...@@ -142,6 +142,7 @@ void transport_register_session(struct se_portal_group *, ...@@ -142,6 +142,7 @@ void transport_register_session(struct se_portal_group *,
struct se_node_acl *, struct se_session *, void *); struct se_node_acl *, struct se_session *, void *);
ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *); ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *);
void transport_free_session(struct se_session *); void transport_free_session(struct se_session *);
void target_spc2_release(struct se_node_acl *nacl);
void target_put_nacl(struct se_node_acl *); void target_put_nacl(struct se_node_acl *);
void transport_deregister_session_configfs(struct se_session *); void transport_deregister_session_configfs(struct se_session *);
void transport_deregister_session(struct se_session *); void transport_deregister_session(struct se_session *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment