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 <david.chen@osnexus.com>



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6902 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2016-06-22 02:02:41 +00:00
parent e7603fc7a7
commit d4e2c4b12e

View File

@@ -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);