Implemented support for the recently introduced I/O request calls
io_request_{offset,length}(), {read_from,write_to}_io_request().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34137 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -106,6 +106,10 @@ KernelRequestHandler::HandleRequest(Request* request)
|
||||
// I/O
|
||||
case DO_ITERATIVE_FD_IO_REQUEST:
|
||||
return _HandleRequest((DoIterativeFDIORequest*)request);
|
||||
case READ_FROM_IO_REQUEST_REQUEST:
|
||||
return _HandleRequest((ReadFromIORequestRequest*)request);
|
||||
case WRITE_TO_IO_REQUEST_REQUEST:
|
||||
return _HandleRequest((WriteToIORequestRequest*)request);
|
||||
case NOTIFY_IO_REQUEST_REQUEST:
|
||||
return _HandleRequest((NotifyIORequestRequest*)request);
|
||||
}
|
||||
@@ -747,6 +751,72 @@ KernelRequestHandler::_HandleRequest(DoIterativeFDIORequest* request)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KernelRequestHandler::_HandleRequest(ReadFromIORequestRequest* request)
|
||||
{
|
||||
// check the request
|
||||
Volume* volume = NULL;
|
||||
status_t result = _GetVolume(request->nsid, &volume);
|
||||
VolumePutter _(volume);
|
||||
|
||||
size_t size = request->size;
|
||||
|
||||
// allocate the reply
|
||||
RequestAllocator allocator(fPort->GetPort());
|
||||
ReadFromIORequestReply* reply;
|
||||
status_t error = AllocateRequest(allocator, &reply);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
void* buffer;
|
||||
if (result == B_OK) {
|
||||
result = allocator.AllocateAddress(reply->buffer, size, 1, &buffer,
|
||||
true);
|
||||
}
|
||||
|
||||
// execute the request
|
||||
if (result == B_OK)
|
||||
result = volume->ReadFromIORequest(request->request, buffer, size);
|
||||
|
||||
// prepare the reply
|
||||
reply->error = result;
|
||||
|
||||
// send the reply
|
||||
if (reply->error == B_OK && size > 0) {
|
||||
SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY);
|
||||
return fPort->SendRequest(&allocator, &handler);
|
||||
}
|
||||
|
||||
return fPort->SendRequest(&allocator);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KernelRequestHandler::_HandleRequest(WriteToIORequestRequest* request)
|
||||
{
|
||||
// check and execute the request
|
||||
Volume* volume = NULL;
|
||||
status_t result = _GetVolume(request->nsid, &volume);
|
||||
VolumePutter _(volume);
|
||||
|
||||
if (result == B_OK) {
|
||||
result = volume->WriteToIORequest(request->request,
|
||||
request->buffer.GetData(), request->buffer.GetSize());
|
||||
}
|
||||
|
||||
// prepare the reply
|
||||
RequestAllocator allocator(fPort->GetPort());
|
||||
WriteToIORequestReply* reply;
|
||||
status_t error = AllocateRequest(allocator, &reply);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
reply->error = result;
|
||||
|
||||
// send the reply
|
||||
return fPort->SendRequest(&allocator);
|
||||
}
|
||||
|
||||
|
||||
// _HandleRequest
|
||||
status_t
|
||||
KernelRequestHandler::_HandleRequest(NotifyIORequestRequest* request)
|
||||
|
||||
@@ -75,6 +75,10 @@ private:
|
||||
status_t _HandleRequest(FileCacheWriteRequest* request);
|
||||
// I/O
|
||||
status_t _HandleRequest(DoIterativeFDIORequest* request);
|
||||
status_t _HandleRequest(
|
||||
ReadFromIORequestRequest* request);
|
||||
status_t _HandleRequest(
|
||||
WriteToIORequestRequest* request);
|
||||
status_t _HandleRequest(NotifyIORequestRequest* request);
|
||||
|
||||
status_t _GetVolume(dev_t id, Volume** volume);
|
||||
|
||||
@@ -690,6 +690,32 @@ Volume::WriteFileCache(ino_t vnodeID, void* cookie,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::ReadFromIORequest(int32 requestID, void* buffer, size_t size)
|
||||
{
|
||||
// get the request
|
||||
io_request* request;
|
||||
status_t error = _FindIORequest(requestID, &request);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
return read_from_io_request(request, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::WriteToIORequest(int32 requestID, const void* buffer, size_t size)
|
||||
{
|
||||
// get the request
|
||||
io_request* request;
|
||||
status_t error = _FindIORequest(requestID, &request);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
return write_to_io_request(request, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
// DoIterativeFDIO
|
||||
status_t
|
||||
Volume::DoIterativeFDIO(int fd, int32 requestID, void* clientCookie,
|
||||
@@ -838,6 +864,8 @@ Volume::Unmount()
|
||||
while (info != NULL) {
|
||||
IORequestInfo* nextInfo = info->structLink;
|
||||
delete info;
|
||||
// TODO: We should probably also notify the request, if that
|
||||
// hasn't happened yet.
|
||||
info = nextInfo;
|
||||
}
|
||||
delete fIORequestInfosByStruct;
|
||||
@@ -1199,6 +1227,7 @@ Volume::DoIO(void* _node, void* cookie, io_request* ioRequest)
|
||||
request->request = requestID;
|
||||
request->offset = ioRequest->Offset();
|
||||
request->length = ioRequest->Length();
|
||||
request->isWrite = ioRequest->IsWrite();
|
||||
|
||||
// send the request
|
||||
KernelRequestHandler handler(this, DO_IO_REPLY);
|
||||
|
||||
@@ -75,6 +75,10 @@ public:
|
||||
status_t DoIterativeFDIO(int fd, int32 requestID,
|
||||
void* cookie, const file_io_vec* vecs,
|
||||
uint32 vecCount);
|
||||
status_t ReadFromIORequest(int32 requestID, void* buffer,
|
||||
size_t size);
|
||||
status_t WriteToIORequest(int32 requestID,
|
||||
const void* buffer, size_t size);
|
||||
status_t NotifyIORequest(int32 requestID,
|
||||
status_t status);
|
||||
|
||||
|
||||
@@ -313,6 +313,22 @@ FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// ReadFromIORequestReply
|
||||
status_t
|
||||
ReadFromIORequestReply::GetAddressInfos(AddressInfo* infos, int32* count)
|
||||
{
|
||||
ADD_ADDRESS(buffer);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// WriteToIORequestRequest
|
||||
status_t
|
||||
WriteToIORequestRequest::GetAddressInfos(AddressInfo* infos, int32* count)
|
||||
{
|
||||
ADD_ADDRESS(buffer);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
@@ -720,10 +736,14 @@ UserlandFSUtil::is_kernel_request(uint32 type)
|
||||
return true;
|
||||
// I/O
|
||||
case DO_ITERATIVE_FD_IO_REQUEST:
|
||||
case READ_FROM_IO_REQUEST_REQUEST:
|
||||
case WRITE_TO_IO_REQUEST_REQUEST:
|
||||
case NOTIFY_IO_REQUEST_REQUEST:
|
||||
return false;
|
||||
case DO_ITERATIVE_FD_IO_REPLY:
|
||||
case NOTIFY_IO_REQUEST_REPLY:
|
||||
case READ_FROM_IO_REQUEST_REPLY:
|
||||
case WRITE_TO_IO_REQUEST_REPLY:
|
||||
return true;
|
||||
|
||||
// general reply
|
||||
@@ -964,9 +984,13 @@ UserlandFSUtil::is_userland_request(uint32 type)
|
||||
// I/O
|
||||
case DO_ITERATIVE_FD_IO_REQUEST:
|
||||
case NOTIFY_IO_REQUEST_REQUEST:
|
||||
case READ_FROM_IO_REQUEST_REQUEST:
|
||||
case WRITE_TO_IO_REQUEST_REQUEST:
|
||||
return true;
|
||||
case DO_ITERATIVE_FD_IO_REPLY:
|
||||
case NOTIFY_IO_REQUEST_REPLY:
|
||||
case READ_FROM_IO_REQUEST_REPLY:
|
||||
case WRITE_TO_IO_REQUEST_REPLY:
|
||||
return false;
|
||||
|
||||
// general reply
|
||||
|
||||
@@ -319,10 +319,46 @@ io_request_is_write(const io_request* request)
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
io_request_offset(const io_request* request)
|
||||
{
|
||||
return ((HaikuKernelIORequest*)request)->offset;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
io_request_length(const io_request* request)
|
||||
{
|
||||
return ((HaikuKernelIORequest*)request)->length;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
read_from_io_request(io_request* _request, void* buffer, size_t size)
|
||||
{
|
||||
HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request;
|
||||
|
||||
// send the request
|
||||
return UserlandFS::KernelEmu::read_from_io_request(request->volume->GetID(),
|
||||
request->id, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
write_to_io_request(io_request* _request, const void* buffer, size_t size)
|
||||
{
|
||||
HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request;
|
||||
|
||||
// send the request
|
||||
return UserlandFS::KernelEmu::write_to_io_request(request->volume->GetID(),
|
||||
request->id, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
notify_io_request(io_request* _request, status_t status)
|
||||
{
|
||||
HaikuKernelIORequest* request = (HaikuKernelIORequest*)request;
|
||||
HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request;
|
||||
|
||||
// send the request
|
||||
UserlandFS::KernelEmu::notify_io_request(request->volume->GetID(),
|
||||
|
||||
@@ -890,6 +890,90 @@ UserlandFS::KernelEmu::do_iterative_fd_io(dev_t volumeID, int fd,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UserlandFS::KernelEmu::read_from_io_request(dev_t volumeID, int32 requestID,
|
||||
void* buffer, size_t size)
|
||||
{
|
||||
// get the request port and the file system
|
||||
RequestPort* port;
|
||||
FileSystem* fileSystem;
|
||||
status_t error = get_port_and_fs(&port, &fileSystem);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// prepare the request
|
||||
RequestAllocator allocator(port->GetPort());
|
||||
ReadFromIORequestRequest* request;
|
||||
error = AllocateRequest(allocator, &request);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
request->nsid = volumeID;
|
||||
request->request = requestID;
|
||||
request->size = size;
|
||||
|
||||
// send the request
|
||||
UserlandRequestHandler handler(fileSystem, READ_FROM_IO_REQUEST_REPLY);
|
||||
ReadFromIORequestReply* reply;
|
||||
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
RequestReleaser requestReleaser(port, reply);
|
||||
|
||||
// process the reply
|
||||
if (reply->error != B_OK)
|
||||
return reply->error;
|
||||
|
||||
memcpy(buffer, reply->buffer.GetData(), reply->buffer.GetSize());
|
||||
|
||||
// send receipt-ack
|
||||
RequestAllocator receiptAckAllocator(port->GetPort());
|
||||
ReceiptAckReply* receiptAck;
|
||||
if (AllocateRequest(receiptAckAllocator, &receiptAck) == B_OK)
|
||||
port->SendRequest(&receiptAckAllocator);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UserlandFS::KernelEmu::write_to_io_request(dev_t volumeID, int32 requestID,
|
||||
const void* buffer, size_t size)
|
||||
{
|
||||
// get the request port and the file system
|
||||
RequestPort* port;
|
||||
FileSystem* fileSystem;
|
||||
status_t error = get_port_and_fs(&port, &fileSystem);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// prepare the request
|
||||
RequestAllocator allocator(port->GetPort());
|
||||
WriteToIORequestRequest* request;
|
||||
error = AllocateRequest(allocator, &request);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
request->nsid = volumeID;
|
||||
request->request = requestID;
|
||||
|
||||
error = allocator.AllocateData(request->buffer, buffer, size, 1, false);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// send the request
|
||||
UserlandRequestHandler handler(fileSystem, WRITE_TO_IO_REQUEST_REPLY);
|
||||
FileCacheWriteReply* reply;
|
||||
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
RequestReleaser requestReleaser(port, reply);
|
||||
|
||||
// process the reply
|
||||
return reply->error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UserlandFS::KernelEmu::notify_io_request(dev_t volumeID, int32 requestID,
|
||||
status_t status)
|
||||
|
||||
@@ -50,6 +50,10 @@ status_t file_cache_write(dev_t mountID, ino_t vnodeID, void *cookie,
|
||||
|
||||
status_t do_iterative_fd_io(dev_t volumeID, int fd, int32 requestID,
|
||||
void* cookie, const file_io_vec* vecs, uint32 vecCount);
|
||||
status_t read_from_io_request(dev_t volumeID, int32 requestID, void* buffer,
|
||||
size_t size);
|
||||
status_t write_to_io_request(dev_t volumeID, int32 requestID, const void* buffer,
|
||||
size_t size);
|
||||
status_t notify_io_request(dev_t volumeID, int32 requestID, status_t status);
|
||||
|
||||
void kernel_debugger(const char *message);
|
||||
|
||||
Reference in New Issue
Block a user