Since LUN RESET clears SCSI2 Reservation (cluster wide data of persistence reservation status) make LUN RESET just one of reasons to update the Persistence Reservation status as well as Service Actions of PR OUT. Signed-off-by: Dmitry Bogdanov <d.bogdanov@xxxxxxxxx> --- drivers/target/target_cluster_dlm.c | 31 ++++++++++++++++++++++++++- drivers/target/target_core_device.c | 1 + drivers/target/target_core_internal.h | 1 - include/target/target_core_base.h | 2 +- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/target/target_cluster_dlm.c b/drivers/target/target_cluster_dlm.c index 91f8ffc7ad2f..546e28062b8f 100644 --- a/drivers/target/target_cluster_dlm.c +++ b/drivers/target/target_cluster_dlm.c @@ -99,6 +99,9 @@ struct async_group { struct completion compl; }; +#define PR_SYNC_REASON_RESERVE 10 +#define PR_SYNC_REASON_RESET 11 + static void target_pr_sync_cb(void *arg); static void target_nodeleft_cb(void *arg, int nodeid); static int pr_reg_realloc(struct target_cluster_data *cluster_data, @@ -842,6 +845,15 @@ static void target_pr_sync_cb(void *arg) pr_reg_res_holder); } + if (pr_data.pro_sa == PR_SYNC_REASON_RESET) { + core_local_lun_reset(dev, NULL, NULL, NULL); + + target_dev_ua_allocate(dev, 0x29, + ASCQ_29H_BUS_DEVICE_RESET_FUNCTION_OCCURRED); + + atomic_long_inc(&dev->num_resets); + } + core_scsi3_update_and_write_aptpl(dev, dev->t10_pr.pr_aptpl_active); done: @@ -863,7 +875,23 @@ target_spc2_reserve(struct se_device *dev, struct se_session *sess) cluster_data->reserved_node_id = 0; } - target_pr_sync_dlm(dev, -1); + target_pr_sync_dlm(dev, PR_SYNC_REASON_RESERVE); + target_pr_unlock_dlm(dev); +} + +static void +target_dlm_lun_reset(struct se_device *dev) +{ + struct target_cluster_data *cluster_data = dev->cluster_data; + + target_pr_lock_dlm(dev); + if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) { + target_release_reservation(dev); + cluster_data->reserved_node_id = 0; + pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); + } + + target_pr_sync_dlm(dev, PR_SYNC_REASON_RESET); target_pr_unlock_dlm(dev); } @@ -894,6 +922,7 @@ const struct target_cluster_ops dlm_cluster_ops = { .pr_unlock = target_pr_unlock_dlm, .pr_sync = target_pr_sync_dlm, .reserve = target_spc2_reserve, + .reset = target_dlm_lun_reset, }; static int __init target_cluster_dlm_module_init(void) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7d0d889961c2..6fe9f40b86f5 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -375,6 +375,7 @@ void target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq) } spin_unlock(&dev->se_port_lock); } +EXPORT_SYMBOL(target_dev_ua_allocate); static void target_luns_data_has_changed(struct se_node_acl *nacl, struct se_dev_entry *new, diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index fc7c2a9d9507..7c495dddcb4b 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -93,7 +93,6 @@ int target_configure_device(struct se_device *dev); void target_free_device(struct se_device *); int target_for_each_device(int (*fn)(struct se_device *dev, void *data), void *data); -void target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq); /* target_core_configfs.c */ extern struct configfs_item_operations target_core_dev_item_ops; diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index c8900da705b6..4dad7837f603 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -1013,6 +1013,6 @@ int target_cmp_pr_transport_id(struct t10_pr_registration *pr_reg, 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); - +void target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq); #endif /* TARGET_CORE_BASE_H */ -- 2.25.1