@@ -571,6 +571,7 @@ static void target_pr_sync_cb(void *arg)
struct t10_pr_registration *pr_prev_res_holder = NULL;
struct pr_reg_lvb *pr_reg_data = NULL;
LIST_HEAD(to_be_deleted_list);
+ LIST_HEAD(preempt_and_abort_list);
struct async_group grp;
struct pr_lvb pr_data;
bool res_to_delete = false;
@@ -680,7 +681,9 @@ static void target_pr_sync_cb(void *arg)
pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
if (dev->dev_pr_res_holder != pr_reg)
- __core_scsi3_free_registration(dev, pr_reg, NULL, 0);
+ __core_scsi3_free_registration(dev, pr_reg,
+ (pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) ?
+ &preempt_and_abort_list : NULL, 0);
else
res_to_delete = true;
@@ -825,10 +828,20 @@ static void target_pr_sync_cb(void *arg)
if (res_to_delete) {
spin_lock(&dev->t10_pr.registration_lock);
- __core_scsi3_free_registration(dev, pr_prev_res_holder, NULL, 0);
+ __core_scsi3_free_registration(dev, pr_prev_res_holder,
+ (pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) ?
+ &preempt_and_abort_list : NULL, 0);
spin_unlock(&dev->t10_pr.registration_lock);
}
+ if (pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) {
+ core_local_lun_reset(dev, NULL, &preempt_and_abort_list, NULL);
+
+ core_scsi3_release_preempt_and_abort(
+ &preempt_and_abort_list,
+ pr_reg_res_holder);
+ }
+
core_scsi3_update_and_write_aptpl(dev, dev->t10_pr.pr_aptpl_active);
done:
@@ -119,8 +119,6 @@ int core_delete_hba(struct se_hba *);
void core_tmr_abort_task(struct se_device *, struct se_tmr_req *,
struct se_session *);
int core_tmr_lun_reset(struct se_device *dev, struct se_tmr_req *tmr);
-void core_local_lun_reset(struct se_device *swc, struct se_tmr_req *tmr,
- struct list_head *preempt_and_abort_list, struct se_cmd *prout_cmd);
/* target_core_tpg.c */
extern struct spinlock g_tpg_lock;
@@ -2725,7 +2725,7 @@ static void __core_scsi3_complete_pro_preempt(
preempt_and_abort_list);
}
-static void core_scsi3_release_preempt_and_abort(
+void core_scsi3_release_preempt_and_abort(
struct list_head *preempt_and_abort_list,
struct t10_pr_registration *pr_reg_holder)
{
@@ -2747,6 +2747,7 @@ static void core_scsi3_release_preempt_and_abort(
kmem_cache_free(t10_pr_reg_cache, pr_reg);
}
}
+EXPORT_SYMBOL(core_scsi3_release_preempt_and_abort);
static sense_reason_t
core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
@@ -99,6 +99,9 @@ void __core_scsi3_free_registration(struct se_device *dev,
struct t10_pr_registration *pr_reg,
struct list_head *preempt_and_abort_list,
int dec_holders);
+void core_scsi3_release_preempt_and_abort(
+ struct list_head *preempt_and_abort_list,
+ struct t10_pr_registration *pr_reg_holder);
#endif /* TARGET_CORE_PR_H */
@@ -394,6 +394,7 @@ void core_local_lun_reset(
(preempt_and_abort_list) ? "Preempt" : "TMR",
dev->transport->name);
}
+EXPORT_SYMBOL(core_local_lun_reset);
int core_tmr_lun_reset(
struct se_device *dev,
@@ -1010,5 +1010,8 @@ u32 target_parse_pr_out_transport_id(
int target_cmp_pr_transport_id(struct t10_pr_registration *pr_reg,
unsigned char *tid);
void target_pr_kref_release(struct kref *kref);
+void core_local_lun_reset(struct se_device *swc, struct se_tmr_req *tmr,
+ struct list_head *preempt_and_abort_list, struct se_cmd *prout_cmd);
+
#endif /* TARGET_CORE_BASE_H */
Abort commands in the preempted I_T nexuses on all nodes in cluster by PR OUT (PREEMPT AND ABORT) command. Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com> --- drivers/target/target_cluster_dlm.c | 17 +++++++++++++++-- drivers/target/target_core_internal.h | 2 -- drivers/target/target_core_pr.c | 3 ++- drivers/target/target_core_pr.h | 3 +++ drivers/target/target_core_tmr.c | 1 + include/target/target_core_base.h | 3 +++ 6 files changed, 24 insertions(+), 5 deletions(-)