From 86dd3875cd040344362f74e482e7dde63df48163 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 5 Apr 2008 16:42:34 +0000 Subject: [PATCH] * Updating device->removed must be protected by the device lock * Also updating device->open_count must be protected by the device list lock This fixes the (unlikely) case where a device was removed from usb_disk standpoint while it still had an open read/write/ioctl operation. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24811 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../drivers/disk/usb/usb_disk/usb_disk.cpp | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index c955045bcd..e56965232d 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -632,12 +632,14 @@ usb_disk_device_removed(void *cookie) } gLunCount -= device->lun_count; gDeviceCount--; - benaphore_unlock(&gDeviceListLock); - device->device = 0; + benaphore_lock(&device->lock); device->removed = true; + benaphore_unlock(&device->lock); if (device->open_count == 0) usb_disk_free_device_and_luns(device); + + benaphore_unlock(&gDeviceListLock); return B_OK; } @@ -799,12 +801,13 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) { device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; - if (device->removed) - return B_DEV_NOT_READY; - benaphore_lock(&device->lock); - status_t result = B_DEV_INVALID_IOCTL; + if (device->removed) { + benaphore_unlock(&device->lock); + return B_DEV_NOT_READY; + } + status_t result = B_DEV_INVALID_IOCTL; switch (op) { case B_GET_MEDIA_STATUS: { *(status_t *)buffer = usb_disk_test_unit_ready(lun); @@ -852,18 +855,19 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) static status_t usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length) { - TRACE("read(%lld, %ld)\n", position, *length); - device_lun *lun = (device_lun *)cookie; - disk_device *device = lun->device; - if (device->removed) { - *length = 0; - return B_DEV_NOT_READY; - } - if (buffer == NULL || length == NULL) return B_BAD_VALUE; + TRACE("read(%lld, %ld)\n", position, *length); + device_lun *lun = (device_lun *)cookie; + disk_device *device = lun->device; benaphore_lock(&device->lock); + if (device->removed) { + *length = 0; + benaphore_unlock(&device->lock); + return B_DEV_NOT_READY; + } + status_t result = B_ERROR; uint32 blockPosition = 0; uint16 blockCount = 0; @@ -899,18 +903,19 @@ static status_t usb_disk_write(void *cookie, off_t position, const void *buffer, size_t *length) { - TRACE("write(%lld, %ld)\n", position, *length); - device_lun *lun = (device_lun *)cookie; - disk_device *device = lun->device; - if (device->removed) { - *length = 0; - return B_DEV_NOT_READY; - } - if (buffer == NULL || length == NULL) return B_BAD_VALUE; + TRACE("write(%lld, %ld)\n", position, *length); + device_lun *lun = (device_lun *)cookie; + disk_device *device = lun->device; benaphore_lock(&device->lock); + if (device->removed) { + *length = 0; + benaphore_unlock(&device->lock); + return B_DEV_NOT_READY; + } + status_t result = B_ERROR; uint32 blockPosition = 0; uint16 blockCount = 0;