From 533cba7eff7465e14de98036c8a2a0aeeba2bdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 29 Jul 2009 12:16:15 +0000 Subject: [PATCH] bonefish + axeld: * Reverted r31809 as it introduced a race condition; if the I/O request had been notified, it could already been deleted at that point. * Instead, we need to notify the request in each file system/driver that uses it. Added new notify_io_request() function that does that exactly. * Added a TODO comment to the userlandfs where the request notification needs a bit more thought. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31903 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/io_requests.h | 3 +++ .../drivers/disk/scsi/scsi_cd/scsi_cd.cpp | 8 ++++++-- .../file_systems/bfs/kernel_interface.cpp | 10 ++++++++-- .../file_systems/iso9660/kernel_interface.cpp | 10 +++++++--- .../userlandfs/kernel_add_on/Volume.cpp | 17 +++++++++++++---- src/system/kernel/device_manager/IORequest.cpp | 1 - .../kernel/device_manager/IOScheduler.cpp | 5 ++++- .../kernel/device_manager/io_requests.cpp | 8 ++++++++ src/system/kernel/fs/vfs_request_io.cpp | 5 ----- 9 files changed, 49 insertions(+), 18 deletions(-) diff --git a/headers/os/drivers/io_requests.h b/headers/os/drivers/io_requests.h index 188af64908..9331eea925 100644 --- a/headers/os/drivers/io_requests.h +++ b/headers/os/drivers/io_requests.h @@ -5,6 +5,7 @@ #ifndef _IO_REQUESTS_H #define _IO_REQUESTS_H + /*! I/O request interface */ @@ -19,9 +20,11 @@ extern "C" { #endif bool io_request_is_write(const io_request* request); +void notify_io_request(io_request* request, status_t status); #ifdef __cplusplus } #endif + #endif /* _IO_REQUESTS_H */ diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp index 060e6fc40b..96630ecb29 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2008, Haiku, Inc. All rights reserved. + * Copyright 2004-2009, Haiku, Inc. All rights reserved. * Copyright 2002-2003, Thomas Kurschel. All rights reserved. * * Distributed under the terms of the MIT License. @@ -18,6 +18,8 @@ #include #include +#include + //#define TRACE_CD_DISK #ifdef TRACE_CD_DISK @@ -709,8 +711,10 @@ cd_io(void* cookie, io_request* request) { cd_handle* handle = (cd_handle*)cookie; - if (handle->info->capacity == 0) + if (handle->info->capacity == 0) { + notify_io_request(request, B_DEV_NO_MEDIA); return B_DEV_NO_MEDIA; + } return handle->info->io_scheduler->ScheduleRequest(request); } diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 92e1245444..10753c4990 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -485,12 +485,18 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request) Inode* inode = (Inode*)_node->private_node; #ifndef BFS_SHELL - if (io_request_is_write(request) && volume->IsReadOnly()) + if (io_request_is_write(request) && volume->IsReadOnly()) { + notify_io_request(request, B_READ_ONLY_DEVICE); return B_READ_ONLY_DEVICE; + } #endif - if (inode->FileCache() == NULL) + if (inode->FileCache() == NULL) { +#ifndef BFS_SHELL + notify_io_request(request, B_BAD_VALUE); +#endif RETURN_ERROR(B_BAD_VALUE); + } // We lock the node here and will unlock it in the "finished" hook. rw_lock_read_lock(&inode->Lock()); diff --git a/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp b/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp index b265c1a916..51decde7df 100644 --- a/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp @@ -456,11 +456,15 @@ fs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request) iso9660_volume* volume = (iso9660_volume*)_volume->private_volume; iso9660_inode* node = (iso9660_inode*)_node->private_node; - if (io_request_is_write(request)) + if (io_request_is_write(request)) { + notify_io_request(request, B_READ_ONLY_DEVICE); return B_READ_ONLY_DEVICE; + } - if ((node->flags & ISO_IS_DIR) != 0) - return EISDIR; + if ((node->flags & ISO_IS_DIR) != 0) { + notify_io_request(request, B_IS_A_DIRECTORY); + return B_IS_A_DIRECTORY; + } return do_iterative_fd_io(volume->fd, request, iterative_io_get_vecs_hook, iterative_io_finished_hook, node); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp index 7dbe15b0e3..e8c00d163d 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp @@ -18,6 +18,7 @@ #include #include // kernel private +#include #include #include "IORequest.h" // kernel internal @@ -1149,28 +1150,34 @@ Volume::DoIO(void* _node, void* cookie, io_request* ioRequest) // check capability if (!HasVNodeCapability(vnode, FS_VNODE_CAPABILITY_IO)) - return B_BAD_VALUE; + return B_UNSUPPORTED; // register the IO request int32 requestID; status_t error = _RegisterIORequest(ioRequest, &requestID); - if (error != B_OK) + if (error != B_OK) { + notify_io_request(ioRequest, error); return error; + } IORequestRemover requestRemover(this, requestID); // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) + if (!port) { + notify_io_request(ioRequest, B_ERROR); return B_ERROR; + } PortReleaser _(fFileSystem->GetPortPool(), port); // prepare the request RequestAllocator allocator(port->GetPort()); DoIORequest* request; error = AllocateRequest(allocator, &request); - if (error != B_OK) + if (error != B_OK) { + notify_io_request(ioRequest, error); return error; + } request->volume = fUserlandVolume; request->node = vnode->clientNode; @@ -1182,6 +1189,8 @@ Volume::DoIO(void* _node, void* cookie, io_request* ioRequest) // send the request KernelRequestHandler handler(this, DO_IO_REPLY); DoIOReply* reply; + + // TODO: when to notify the io_request? error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; diff --git a/src/system/kernel/device_manager/IORequest.cpp b/src/system/kernel/device_manager/IORequest.cpp index e686465d18..fe76c828c7 100644 --- a/src/system/kernel/device_manager/IORequest.cpp +++ b/src/system/kernel/device_manager/IORequest.cpp @@ -822,7 +822,6 @@ IORequest::NotifyFinished() if (fBuffer->IsMemoryLocked()) fBuffer->UnlockMemory(fTeam, fIsWrite); - // Cache the callbacks before we unblock waiters and unlock. Any of the // following could delete this request, so we don't want to touch it // once we have started telling others that it is done. diff --git a/src/system/kernel/device_manager/IOScheduler.cpp b/src/system/kernel/device_manager/IOScheduler.cpp index f961c21745..7833c462eb 100644 --- a/src/system/kernel/device_manager/IOScheduler.cpp +++ b/src/system/kernel/device_manager/IOScheduler.cpp @@ -227,8 +227,10 @@ IOScheduler::ScheduleRequest(IORequest* request) if (buffer->IsVirtual()) { status_t status = buffer->LockMemory(request->Team(), request->IsWrite()); - if (status != B_OK) + if (status != B_OK) { + request->SetStatusAndNotify(status); return status; + } } MutexLocker locker(fLock); @@ -240,6 +242,7 @@ IOScheduler::ScheduleRequest(IORequest* request) locker.Unlock(); if (buffer->IsVirtual()) buffer->UnlockMemory(request->Team(), request->IsWrite()); + request->SetStatusAndNotify(B_NO_MEMORY); return B_NO_MEMORY; } diff --git a/src/system/kernel/device_manager/io_requests.cpp b/src/system/kernel/device_manager/io_requests.cpp index 1372c7be20..7c3c79f679 100644 --- a/src/system/kernel/device_manager/io_requests.cpp +++ b/src/system/kernel/device_manager/io_requests.cpp @@ -13,3 +13,11 @@ io_request_is_write(const io_request* request) { return request->IsWrite(); } + + +void +notify_io_request(io_request* request, status_t status) +{ + request->SetStatusAndNotify(status); +} + diff --git a/src/system/kernel/fs/vfs_request_io.cpp b/src/system/kernel/fs/vfs_request_io.cpp index a2efa11a06..7c0d634e46 100644 --- a/src/system/kernel/fs/vfs_request_io.cpp +++ b/src/system/kernel/fs/vfs_request_io.cpp @@ -410,11 +410,6 @@ vfs_vnode_io(struct vnode* vnode, void* cookie, io_request* request) return synchronous_io(request, io); } - if (result != B_OK && !request->IsFinished()) { - // The request failed, but its owner has not been notified yet - request->SetStatusAndNotify(result); - } - return result; }