|
@@ -608,12 +608,20 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
|
|
struct request sreq;
|
|
|
|
|
|
dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
|
|
|
+ if (!nbd->sock)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
+ mutex_unlock(&nbd->tx_lock);
|
|
|
+ fsync_bdev(bdev);
|
|
|
+ mutex_lock(&nbd->tx_lock);
|
|
|
blk_rq_init(NULL, &sreq);
|
|
|
sreq.cmd_type = REQ_TYPE_SPECIAL;
|
|
|
nbd_cmd(&sreq) = NBD_CMD_DISC;
|
|
|
+
|
|
|
+ /* Check again after getting mutex back. */
|
|
|
if (!nbd->sock)
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
nbd_send_req(nbd, &sreq);
|
|
|
return 0;
|
|
|
}
|
|
@@ -627,6 +635,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
|
|
nbd_clear_que(nbd);
|
|
|
BUG_ON(!list_empty(&nbd->queue_head));
|
|
|
BUG_ON(!list_empty(&nbd->waiting_queue));
|
|
|
+ kill_bdev(bdev);
|
|
|
if (file)
|
|
|
fput(file);
|
|
|
return 0;
|
|
@@ -719,6 +728,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
|
|
nbd->file = NULL;
|
|
|
nbd_clear_que(nbd);
|
|
|
dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
|
|
|
+ kill_bdev(bdev);
|
|
|
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
|
|
|
if (file)
|
|
|
fput(file);
|