scst_sysfs: Introduce scst_kobject_put_and_wait()

This patch does not change any functionality other than the message
printed when it takes more than one second before the completion is
signalled.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5086 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2013-10-31 04:44:52 +00:00
parent 7fb71c06b4
commit 2d874f7cb8
4 changed files with 40 additions and 113 deletions

View File

@@ -237,7 +237,6 @@ static struct kobj_attribute iscsi_conn_state_attr =
static void conn_sysfs_del(struct iscsi_conn *conn)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -245,17 +244,8 @@ static void conn_sysfs_del(struct iscsi_conn *conn)
conn->conn_kobj_release_cmpl = &c;
kobject_del(&conn->conn_kobj);
kobject_put(&conn->conn_kobj);
rc = wait_for_completion_timeout(conn->conn_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for conn %p (%d refs)...", conn,
atomic_read(&conn->conn_kobj.kref.refcount));
wait_for_completion(conn->conn_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for conn %p", conn);
}
scst_kobject_put_and_wait(&conn->conn_kobj, "conn", &c);
TRACE_EXIT();
return;

View File

@@ -4210,6 +4210,9 @@ const struct sysfs_ops *scst_sysfs_get_sysfs_ops(void);
struct sysfs_ops *scst_sysfs_get_sysfs_ops(void);
#endif
void scst_kobject_put_and_wait(struct kobject *kobj, const char *category,
struct completion *c);
/*
* Returns target driver's root sysfs kobject.
* The driver can create own files/directories/links here.

View File

@@ -2077,7 +2077,6 @@ out:
static void scst_sgv_sysfs_del(struct sgv_pool *pool)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -2085,17 +2084,8 @@ static void scst_sgv_sysfs_del(struct sgv_pool *pool)
pool->sgv_kobj_release_cmpl = &c;
kobject_del(&pool->sgv_kobj);
kobject_put(&pool->sgv_kobj);
rc = wait_for_completion_timeout(pool->sgv_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for SGV pool %s (%d refs)...", pool->name,
atomic_read(&pool->sgv_kobj.kref.refcount));
wait_for_completion(pool->sgv_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for SGV pool %s", pool->name);
}
scst_kobject_put_and_wait(&pool->sgv_kobj, "SGV pool", &c);
TRACE_EXIT();
}

View File

@@ -1057,6 +1057,33 @@ out_del:
goto out;
}
void scst_kobject_put_and_wait(struct kobject *kobj, const char *category,
struct completion *c)
{
char *name;
TRACE_ENTRY();
name = kstrdup(kobject_name(kobj), GFP_KERNEL);
kobject_put(kobj);
if (wait_for_completion_timeout(c, HZ) > 0)
goto out_free;
PRINT_INFO("Waiting for release of sysfs entry for %s %s (%d refs)",
category, name ? : "(?)", atomic_read(&kobj->kref.refcount));
wait_for_completion(c);
PRINT_INFO("Finished waiting for release of %s %s sysfs entry",
category, name ? : "(?)");
out_free:
kfree(name);
TRACE_EXIT();
return;
}
/*
* Must not be called under scst_mutex, due to possible deadlock with
* sysfs ref counting in sysfs works (it is waiting for the last put, but
@@ -1064,7 +1091,6 @@ out_del:
*/
void scst_tgtt_sysfs_del(struct scst_tgt_template *tgtt)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -1072,17 +1098,8 @@ void scst_tgtt_sysfs_del(struct scst_tgt_template *tgtt)
tgtt->tgtt_kobj_release_cmpl = &c;
kobject_del(&tgtt->tgtt_kobj);
kobject_put(&tgtt->tgtt_kobj);
rc = wait_for_completion_timeout(tgtt->tgtt_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for target template %s (%d refs)...", tgtt->name,
atomic_read(&tgtt->tgtt_kobj.kref.refcount));
wait_for_completion(tgtt->tgtt_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for target template %s", tgtt->name);
}
scst_kobject_put_and_wait(&tgtt->tgtt_kobj, "target template", &c);
TRACE_EXIT();
return;
@@ -2473,24 +2490,13 @@ void scst_tgt_sysfs_del(struct scst_tgt *tgt)
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);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for target %s (%d refs)...", tgt->tgt_name,
atomic_read(&tgt->tgt_kobj.kref.refcount));
wait_for_completion(tgt->tgt_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for target %s", tgt->tgt_name);
}
scst_kobject_put_and_wait(&tgt->tgt_kobj, "target", &c);
TRACE_EXIT();
return;
@@ -2990,7 +2996,6 @@ out_del:
*/
void scst_dev_sysfs_del(struct scst_device *dev)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -3001,17 +3006,8 @@ void scst_dev_sysfs_del(struct scst_device *dev)
kobject_del(&dev->dev_kobj);
kobject_put(dev->dev_exp_kobj);
kobject_put(&dev->dev_kobj);
rc = wait_for_completion_timeout(dev->dev_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for device %s (%d refs)...", dev->virt_name,
atomic_read(&dev->dev_kobj.kref.refcount));
wait_for_completion(dev->dev_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for device %s", dev->virt_name);
}
scst_kobject_put_and_wait(&dev->dev_kobj, "device", &c);
TRACE_EXIT();
return;
@@ -3206,7 +3202,6 @@ out:
*/
void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -3214,19 +3209,8 @@ void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev)
tgt_dev->tgt_dev_kobj_release_cmpl = &c;
kobject_del(&tgt_dev->tgt_dev_kobj);
kobject_put(&tgt_dev->tgt_dev_kobj);
rc = wait_for_completion_timeout(
tgt_dev->tgt_dev_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for tgt_dev %lld (%d refs)...",
(unsigned long long)tgt_dev->lun,
atomic_read(&tgt_dev->tgt_dev_kobj.kref.refcount));
wait_for_completion(tgt_dev->tgt_dev_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs entry for "
"tgt_dev %lld", (unsigned long long)tgt_dev->lun);
}
scst_kobject_put_and_wait(&tgt_dev->tgt_dev_kobj, "tgt_dev", &c);
TRACE_EXIT();
return;
@@ -3765,7 +3749,6 @@ out_del:
*/
void scst_sess_sysfs_del(struct scst_session *sess)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -3779,17 +3762,8 @@ void scst_sess_sysfs_del(struct scst_session *sess)
sess->sess_kobj_release_cmpl = &c;
kobject_del(&sess->sess_kobj);
kobject_put(&sess->sess_kobj);
rc = wait_for_completion_timeout(sess->sess_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for session from %s (%d refs)...", sess->initiator_name,
atomic_read(&sess->sess_kobj.kref.refcount));
wait_for_completion(sess->sess_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for session %s", sess->initiator_name);
}
scst_kobject_put_and_wait(&sess->sess_kobj, "session", &c);
out:
TRACE_EXIT();
@@ -3851,7 +3825,6 @@ static struct kobj_type acg_dev_ktype = {
*/
void scst_acg_dev_sysfs_del(struct scst_acg_dev *acg_dev)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -3865,17 +3838,8 @@ void scst_acg_dev_sysfs_del(struct scst_acg_dev *acg_dev)
}
kobject_del(&acg_dev->acg_dev_kobj);
kobject_put(&acg_dev->acg_dev_kobj);
rc = wait_for_completion_timeout(acg_dev->acg_dev_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for acg_dev %p (%d refs)...", acg_dev,
atomic_read(&acg_dev->acg_dev_kobj.kref.refcount));
wait_for_completion(acg_dev->acg_dev_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for acg_dev %p", acg_dev);
}
scst_kobject_put_and_wait(&acg_dev->acg_dev_kobj, "acg_dev", &c);
TRACE_EXIT();
return;
@@ -4246,7 +4210,6 @@ static struct kobj_attribute scst_acg_cpu_mask =
*/
void scst_acg_sysfs_del(struct scst_acg *acg)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -4259,17 +4222,8 @@ void scst_acg_sysfs_del(struct scst_acg *acg)
kobject_put(acg->luns_kobj);
kobject_put(acg->initiators_kobj);
kobject_put(&acg->acg_kobj);
rc = wait_for_completion_timeout(acg->acg_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for acg %s (%d refs)...", acg->acg_name,
atomic_read(&acg->acg_kobj.kref.refcount));
wait_for_completion(acg->acg_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for acg %s", acg->acg_name);
}
scst_kobject_put_and_wait(&acg->acg_kobj, "acg", &c);
TRACE_EXIT();
return;
@@ -4901,7 +4855,6 @@ out_err:
void scst_devt_sysfs_del(struct scst_dev_type *devt)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
@@ -4909,17 +4862,8 @@ void scst_devt_sysfs_del(struct scst_dev_type *devt)
devt->devt_kobj_release_compl = &c;
kobject_del(&devt->devt_kobj);
kobject_put(&devt->devt_kobj);
rc = wait_for_completion_timeout(devt->devt_kobj_release_compl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing of sysfs entry "
"for dev handler template %s (%d refs)...", devt->name,
atomic_read(&devt->devt_kobj.kref.refcount));
wait_for_completion(devt->devt_kobj_release_compl);
PRINT_INFO("Done waiting for releasing sysfs entry "
"for dev handler template %s", devt->name);
}
scst_kobject_put_and_wait(&devt->devt_kobj, "dev handler template", &c);
TRACE_EXIT();
return;