diff options
Diffstat (limited to 'net/9p/trans_virtio.c')
-rw-r--r-- | net/9p/trans_virtio.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index d8e376a5f0f1..36a1a739ad68 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -658,14 +658,30 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
658 | static void p9_virtio_remove(struct virtio_device *vdev) | 658 | static void p9_virtio_remove(struct virtio_device *vdev) |
659 | { | 659 | { |
660 | struct virtio_chan *chan = vdev->priv; | 660 | struct virtio_chan *chan = vdev->priv; |
661 | 661 | unsigned long warning_time; | |
662 | if (chan->inuse) | ||
663 | p9_virtio_close(chan->client); | ||
664 | vdev->config->del_vqs(vdev); | ||
665 | 662 | ||
666 | mutex_lock(&virtio_9p_lock); | 663 | mutex_lock(&virtio_9p_lock); |
664 | |||
665 | /* Remove self from list so we don't get new users. */ | ||
667 | list_del(&chan->chan_list); | 666 | list_del(&chan->chan_list); |
667 | warning_time = jiffies; | ||
668 | |||
669 | /* Wait for existing users to close. */ | ||
670 | while (chan->inuse) { | ||
671 | mutex_unlock(&virtio_9p_lock); | ||
672 | msleep(250); | ||
673 | if (time_after(jiffies, warning_time + 10 * HZ)) { | ||
674 | dev_emerg(&vdev->dev, | ||
675 | "p9_virtio_remove: waiting for device in use.\n"); | ||
676 | warning_time = jiffies; | ||
677 | } | ||
678 | mutex_lock(&virtio_9p_lock); | ||
679 | } | ||
680 | |||
668 | mutex_unlock(&virtio_9p_lock); | 681 | mutex_unlock(&virtio_9p_lock); |
682 | |||
683 | vdev->config->del_vqs(vdev); | ||
684 | |||
669 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | 685 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); |
670 | kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE); | 686 | kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE); |
671 | kfree(chan->tag); | 687 | kfree(chan->tag); |