diff options
Diffstat (limited to 'drivers/target/target_core_pr.c')
-rw-r--r-- | drivers/target/target_core_pr.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 2de6fb8cee8d..c1aa9655e96e 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -78,6 +78,22 @@ enum preempt_type { static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, struct t10_pr_registration *, int, int); +static int is_reservation_holder( + struct t10_pr_registration *pr_res_holder, + struct t10_pr_registration *pr_reg) +{ + int pr_res_type; + + if (pr_res_holder) { + pr_res_type = pr_res_holder->pr_res_type; + + return pr_res_holder == pr_reg || + pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG || + pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG; + } + return 0; +} + static sense_reason_t target_scsi2_reservation_check(struct se_cmd *cmd) { @@ -664,7 +680,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( struct se_dev_entry *deve_tmp; struct se_node_acl *nacl_tmp; struct se_port *port, *port_tmp; - struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; + const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; struct t10_pr_registration *pr_reg, *pr_reg_atp, *pr_reg_tmp, *pr_reg_tmp_safe; int ret; /* @@ -963,7 +979,7 @@ int core_scsi3_check_aptpl_registration( } static void __core_scsi3_dump_registration( - struct target_core_fabric_ops *tfo, + const struct target_core_fabric_ops *tfo, struct se_device *dev, struct se_node_acl *nacl, struct t10_pr_registration *pr_reg, @@ -1004,7 +1020,7 @@ static void __core_scsi3_add_registration( enum register_type register_type, int register_move) { - struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; + const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; struct t10_reservation *pr_tmpl = &dev->t10_pr; @@ -1220,8 +1236,10 @@ static void __core_scsi3_free_registration( struct t10_pr_registration *pr_reg, struct list_head *preempt_and_abort_list, int dec_holders) + __releases(&pr_tmpl->registration_lock) + __acquires(&pr_tmpl->registration_lock) { - struct target_core_fabric_ops *tfo = + const struct target_core_fabric_ops *tfo = pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; struct t10_reservation *pr_tmpl = &dev->t10_pr; char i_buf[PR_REG_ISID_ID_LEN]; @@ -1445,7 +1463,7 @@ core_scsi3_decode_spec_i_port( struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; LIST_HEAD(tid_dest_list); struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp; - struct target_core_fabric_ops *tmp_tf_ops; + const struct target_core_fabric_ops *tmp_tf_ops; unsigned char *buf; unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; @@ -2287,7 +2305,6 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) spin_lock(&dev->dev_reservation_lock); pr_res_holder = dev->dev_pr_res_holder; if (pr_res_holder) { - int pr_res_type = pr_res_holder->pr_res_type; /* * From spc4r17 Section 5.7.9: Reserving: * @@ -2298,9 +2315,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) * the logical unit, then the command shall be completed with * RESERVATION CONFLICT status. */ - if ((pr_res_holder != pr_reg) && - (pr_res_type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) && - (pr_res_type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { + if (!is_reservation_holder(pr_res_holder, pr_reg)) { struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; pr_err("SPC-3 PR: Attempted RESERVE from" " [%s]: %s while reservation already held by" @@ -2409,7 +2424,7 @@ static void __core_scsi3_complete_pro_release( int explicit, int unreg) { - struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; + const struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; char i_buf[PR_REG_ISID_ID_LEN]; int pr_res_type = 0, pr_res_scope = 0; @@ -2477,7 +2492,6 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, struct se_lun *se_lun = cmd->se_lun; struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; struct t10_reservation *pr_tmpl = &dev->t10_pr; - int all_reg = 0; sense_reason_t ret = 0; if (!se_sess || !se_lun) { @@ -2514,13 +2528,9 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, spin_unlock(&dev->dev_reservation_lock); goto out_put_pr_reg; } - if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || - (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) - all_reg = 1; - if ((all_reg == 0) && (pr_res_holder != pr_reg)) { + if (!is_reservation_holder(pr_res_holder, pr_reg)) { /* - * Non 'All Registrants' PR Type cases.. * Release request from a registered I_T nexus that is not a * persistent reservation holder. return GOOD status. */ @@ -2726,7 +2736,7 @@ static void __core_scsi3_complete_pro_preempt( enum preempt_type preempt_type) { struct se_node_acl *nacl = pr_reg->pr_reg_nacl; - struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; + const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; char i_buf[PR_REG_ISID_ID_LEN]; memset(i_buf, 0, PR_REG_ISID_ID_LEN); @@ -3111,7 +3121,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, struct se_node_acl *pr_res_nacl, *pr_reg_nacl, *dest_node_acl = NULL; struct se_port *se_port; struct se_portal_group *se_tpg, *dest_se_tpg = NULL; - struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; + const struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; struct t10_reservation *pr_tmpl = &dev->t10_pr; unsigned char *buf; @@ -3375,7 +3385,7 @@ after_iport_check: * From spc4r17 section 5.7.8 Table 50 -- * Register behaviors for a REGISTER AND MOVE service action */ - if (pr_res_holder != pr_reg) { + if (!is_reservation_holder(pr_res_holder, pr_reg)) { pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" " Nexus is not reservation holder\n"); spin_unlock(&dev->dev_reservation_lock); |