From 47b237f775ec0397af948ecc2493f20eb35e5e2e Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 22 Jun 2016 02:07:58 +0000 Subject: [PATCH] Merged revisions 6902 via svnmerge from svn+ssh://svn.code.sf.net/p/scst/svn/trunk ........ r6902 | vlnb | 2016-06-21 19:02:41 -0700 (Tue, 21 Jun 2016) | 12 lines We found this bug when we add ZFS zvol to vdisk_blockio, remove it from copy manager, and change ALUA state. After that the zvol would be in constant busy state, even if we remove all scst modules. The problem is that blockio_on_alua_state_change_finish will unconditionally vdisk_open_fd. But for the above mentioned case, tgt_dev_cnt will be zero, so the fd is permanently leaked. We fix this by only do vdisk_open_fd when tgt_dev_cnt is not zero. Signed-off-by: Chunwei Chen ........ git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.1.x@6903 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_vdisk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index c551da8aa..4229a6ff3 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -7343,13 +7343,19 @@ static void blockio_on_alua_state_change_finish(struct scst_device *dev, if ((new_state == SCST_TG_STATE_OPTIMIZED) || (new_state == SCST_TG_STATE_NONOPTIMIZED)) { /* Try non-optimized as well, it might be new redirection device */ - int rc; + int rc = 0; TRACE_MGMT_DBG("ALUA state change from %s to %s finished (dev %s), " "reopenning FD", scst_alua_state_name(old_state), scst_alua_state_name(new_state), dev->virt_name); - rc = vdisk_open_fd(virt_dev, dev->dev_rd_only); + /* + * only reopen fd if tgt_dev_cnt is not zero, otherwise we will + * leak reference. + */ + if (virt_dev->tgt_dev_cnt) + rc = vdisk_open_fd(virt_dev, dev->dev_rd_only); + if (rc == 0) { if (virt_dev->reexam_pending) { rc = vdisk_reexamine(virt_dev);