diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 503171e7e..1c40ffac3 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -618,6 +618,17 @@ void scst_unregister_target(struct scst_tgt *tgt) TRACE_ENTRY(); + /* + * Remove the sysfs attributes of a target before invoking + * tgt->tgtt->release(tgt) such that the "enabled" attribute can't be + * accessed during or after the tgt->tgtt->release(tgt) call. + */ +#ifdef CONFIG_SCST_PROC + scst_cleanup_proc_target_entries(tgt); +#else + scst_tgt_sysfs_del(tgt); +#endif + TRACE_DBG("%s", "Calling target driver's release()"); tgt->tgtt->release(tgt); TRACE_DBG("%s", "Target driver's release() returned"); @@ -653,9 +664,7 @@ again: scst_tg_tgt_remove_by_tgt(tgt); -#ifdef CONFIG_SCST_PROC - scst_cleanup_proc_target_entries(tgt); -#else +#ifndef CONFIG_SCST_PROC scst_del_free_acg(tgt->default_acg); list_for_each_entry_safe(acg, acg_tmp, &tgt->tgt_acg_list, @@ -668,7 +677,7 @@ again: scst_resume_activity(); #ifndef CONFIG_SCST_PROC - scst_tgt_sysfs_del(tgt); + scst_tgt_sysfs_put(tgt); #endif PRINT_INFO("Target %s for template %s unregistered successfully", diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index e60d5ba50..9da084aee 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -415,6 +415,7 @@ void scst_tg_tgt_remove_by_tgt(struct scst_tgt *tgt); #ifndef CONFIG_SCST_PROC int scst_dg_sysfs_add(struct kobject *parent, struct scst_dev_group *dg); void scst_dg_sysfs_del(struct scst_dev_group *dg); +void scst_tgt_sysfs_put(struct scst_tgt *tgt); int scst_dg_dev_sysfs_add(struct scst_dev_group *dg, struct scst_dg_dev *dgdev); void scst_dg_dev_sysfs_del(struct scst_dev_group *dg, struct scst_dg_dev *dgdev); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 809f0c227..3dcba8bff 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -2399,13 +2399,8 @@ out_err: */ void scst_tgt_sysfs_del(struct scst_tgt *tgt) { - int rc; - DECLARE_COMPLETION_ONSTACK(c); - TRACE_ENTRY(); - tgt->tgt_kobj_release_cmpl = &c; - kobject_del(tgt->tgt_sess_kobj); kobject_del(tgt->tgt_luns_kobj); kobject_del(tgt->tgt_ini_grp_kobj); @@ -2414,6 +2409,20 @@ void scst_tgt_sysfs_del(struct scst_tgt *tgt) kobject_put(tgt->tgt_sess_kobj); kobject_put(tgt->tgt_luns_kobj); kobject_put(tgt->tgt_ini_grp_kobj); + + TRACE_EXIT(); + return; +} + +void scst_tgt_sysfs_put(struct scst_tgt *tgt) +{ + int rc; + DECLARE_COMPLETION_ONSTACK(c); + + TRACE_ENTRY(); + + tgt->tgt_kobj_release_cmpl = &c; + kobject_put(&tgt->tgt_kobj); rc = wait_for_completion_timeout(tgt->tgt_kobj_release_cmpl, HZ);