diff options
| -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); |
