From d4e2c4b12ec110f902d8ce2fd766bab3beced3ef Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 22 Jun 2016 02:02:41 +0000 Subject: [PATCH] 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/trunk@6902 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 a4d286259..21b2383ba 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -7359,13 +7359,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)) && (virt_dev->fd == NULL)) { /* 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);