diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 5787a5dde..bef27a3cf 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -2142,11 +2142,11 @@ out: return; } -static void dev_user_unjam_dev(struct scst_user_dev *dev) +static int dev_user_unjam_dev(struct scst_user_dev *dev) __releases(&dev->cmd_lists.cmd_list_lock) __acquires(&dev->cmd_lists.cmd_list_lock) { - int i; + int i, res = 0; struct scst_user_cmd *ucmd; TRACE_ENTRY(); @@ -2160,6 +2160,8 @@ repeat: struct list_head *head = &dev->ucmd_hash[i]; list_for_each_entry(ucmd, head, hash_list_entry) { + res++; + if (!ucmd->sent_to_user) continue; @@ -2184,8 +2186,8 @@ repeat: spin_unlock_irq(&dev->cmd_lists.cmd_list_lock); - TRACE_EXIT(); - return; + TRACE_EXIT_RES(res); + return res; } static int dev_user_process_reply_tm_exec(struct scst_user_cmd *ucmd, @@ -3081,8 +3083,8 @@ static int dev_user_release(struct inode *inode, struct file *file) scst_unregister_virtual_device(dev->virt_id); scst_unregister_virtual_dev_driver(&dev->devtype); - sgv_pool_destroy(dev->pool_clust); - sgv_pool_destroy(dev->pool); + sgv_pool_flush(dev->pool_clust); + sgv_pool_flush(dev->pool); TRACE_DBG("Unregistering finished (dev %p)", dev); @@ -3093,6 +3095,9 @@ static int dev_user_release(struct inode *inode, struct file *file) wait_for_completion(&dev->cleanup_cmpl); + sgv_pool_destroy(dev->pool_clust); + sgv_pool_destroy(dev->pool); + up_write(&dev->dev_rwsem); /* to make the debug check happy */ TRACE_DBG("Releasing completed (dev %p)", dev); @@ -3109,7 +3114,7 @@ out: static int dev_user_process_cleanup(struct scst_user_dev *dev) { struct scst_user_cmd *ucmd; - int rc, res = 1; + int rc = 0, res = 1; TRACE_ENTRY(); @@ -3117,9 +3122,13 @@ static int dev_user_process_cleanup(struct scst_user_dev *dev) wake_up_all(&dev->cmd_lists.cmd_list_waitQ); /* just in case */ while (1) { + int rc1; + TRACE_DBG("Cleanuping dev %p", dev); - dev_user_unjam_dev(dev); + rc1 = dev_user_unjam_dev(dev); + if ((rc1 == 0) && (rc == -EAGAIN) && dev->cleanup_done) + break; spin_lock_irq(&dev->cmd_lists.cmd_list_lock); @@ -3130,9 +3139,7 @@ static int dev_user_process_cleanup(struct scst_user_dev *dev) spin_unlock_irq(&dev->cmd_lists.cmd_list_lock); if (rc == -EAGAIN) { - if (dev->cleanup_done) - break; - else { + if (!dev->cleanup_done) { TRACE_DBG("No more commands (dev %p)", dev); goto out; }