* Implemented forwarding the do_iterative_fd_io() callbacks to userland.

* Pass the request offset and length with the DoIORequest. This allows us to
  already get the first vecs for do_iterative_fd_io() in userland, saving a
  trip back and forth.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29546 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-03-15 18:24:14 +00:00
parent 2bb8b19f08
commit c76e8d36fb
14 changed files with 415 additions and 45 deletions

View File

@ -59,6 +59,10 @@ enum {
DO_IO_REPLY,
CANCEL_IO_REQUEST,
CANCEL_IO_REPLY,
ITERATIVE_IO_GET_VECS_REQUEST,
ITERATIVE_IO_GET_VECS_REPLY,
ITERATIVE_IO_FINISHED_REQUEST,
ITERATIVE_IO_FINISHED_REPLY,
// nodes
IOCTL_REQUEST,
@ -547,6 +551,8 @@ class DoIORequest : public FileRequest {
public:
DoIORequest() : FileRequest(DO_IO_REQUEST) {}
off_t offset;
size_t length;
int32 request;
bool isWrite;
};
@ -571,6 +577,49 @@ public:
CancelIOReply() : ReplyRequest(CANCEL_IO_REPLY) {}
};
// IterativeIOGetVecsRequest
class IterativeIOGetVecsRequest : public VolumeRequest {
public:
IterativeIOGetVecsRequest()
: VolumeRequest(ITERATIVE_IO_GET_VECS_REQUEST) {}
void* cookie;
off_t offset;
int32 request;
size_t size;
uint32 vecCount;
};
// IterativeIOGetVecsReply
class IterativeIOGetVecsReply : public ReplyRequest {
public:
IterativeIOGetVecsReply() : ReplyRequest(ITERATIVE_IO_GET_VECS_REPLY) {}
enum { MAX_VECS = 8 };
file_io_vec vecs[MAX_VECS];
uint32 vecCount;
};
// IterativeIOFinishedRequest
class IterativeIOFinishedRequest : public VolumeRequest {
public:
IterativeIOFinishedRequest()
: VolumeRequest(ITERATIVE_IO_FINISHED_REQUEST) {}
void* cookie;
int32 request;
status_t status;
bool partialTransfer;
size_t bytesTransferred;
};
// IterativeIOFinishedReply
class IterativeIOFinishedReply : public ReplyRequest {
public:
IterativeIOFinishedReply() : ReplyRequest(ITERATIVE_IO_FINISHED_REPLY) {}
};
// #pragma mark - nodes
@ -1751,13 +1800,14 @@ public:
class DoIterativeFDIORequest : public Request {
public:
DoIterativeFDIORequest() : Request(DO_ITERATIVE_FD_IO_REQUEST) {}
status_t GetAddressInfos(AddressInfo* infos, int32* count);
enum { MAX_VECS = 8 };
dev_t nsid;
int fd;
int32 request;
void* cookie;
Address vecs;
file_io_vec vecs[MAX_VECS];
uint32 vecCount;
};
@ -1853,6 +1903,14 @@ do_for_request(Request* request, Task& task)
return task((CancelIORequest*)request);
case CANCEL_IO_REPLY:
return task((CancelIOReply*)request);
case ITERATIVE_IO_GET_VECS_REQUEST:
return task((IterativeIOGetVecsRequest*)request);
case ITERATIVE_IO_GET_VECS_REPLY:
return task((IterativeIOGetVecsReply*)request);
case ITERATIVE_IO_FINISHED_REQUEST:
return task((IterativeIOFinishedRequest*)request);
case ITERATIVE_IO_FINISHED_REPLY:
return task((IterativeIOFinishedReply*)request);
// nodes
case IOCTL_REQUEST:
return task((IOCtlRequest*)request);
@ -2217,6 +2275,10 @@ using UserlandFSUtil::DoIORequest;
using UserlandFSUtil::DoIOReply;
using UserlandFSUtil::CancelIORequest;
using UserlandFSUtil::CancelIOReply;
using UserlandFSUtil::IterativeIOGetVecsRequest;
using UserlandFSUtil::IterativeIOGetVecsReply;
using UserlandFSUtil::IterativeIOFinishedRequest;
using UserlandFSUtil::IterativeIOFinishedReply;
// nodes
using UserlandFSUtil::IOCtlRequest;
using UserlandFSUtil::IOCtlReply;

View File

@ -1,13 +1,15 @@
SubDir HAIKU_TOP src add-ons kernel file_systems userlandfs kernel_add_on ;
local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems
userlandfs ] ;
userlandfs ] ;
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
UsePrivateHeaders shared ;
UsePrivateKernelHeaders ;
SubDirHdrs [ FDirName $(userlandFSIncludes) private ] ;
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
SubDirHdrs [ FDirName $(HAIKU_TOP) src system kernel device_manager ] ;
# for IORequest.h
SEARCH_SOURCE += [ FDirName $(userlandFSTop) private ] ;
SEARCH_SOURCE += [ FDirName $(userlandFSTop) shared ] ;

View File

@ -716,16 +716,13 @@ KernelRequestHandler::_HandleRequest(DoIterativeFDIORequest* request)
status_t result = _GetVolume(request->nsid, &volume);
VolumePutter _(volume);
const file_io_vec* vecs = (const file_io_vec*)request->vecs.GetData();
size_t vecsSize = request->vecs.GetSize();
uint32 vecCount = request->vecCount;
if (result == B_OK && vecsSize / sizeof(file_io_vec) < vecCount)
if (result == B_OK && vecCount > DoIterativeFDIORequest::MAX_VECS)
result = B_BAD_VALUE;
if (result == B_OK) {
result = volume->DoIterativeFDIO(request->fd, request->request,
request->cookie, vecs, vecCount);
request->cookie, request->vecs, vecCount);
}
// prepare the reply

View File

@ -10,6 +10,8 @@
#include <unistd.h>
#include <sys/stat.h>
#include <algorithm>
#include <fs_cache.h>
#include <util/AutoLock.h>
@ -17,6 +19,8 @@
#include <fs/fd.h> // kernel private
#include "IORequest.h" // kernel internal
#include "Compatibility.h"
#include "Debug.h"
#include "FileSystem.h"
@ -157,20 +161,29 @@ struct Volume::IterativeFDIOCookie : public Referenceable {
int fd;
int32 requestID;
void* clientCookie;
off_t offset;
const file_io_vec* vecs;
uint32 vecCount;
IterativeFDIOCookie(Volume* volume, int fd, int32 requestID,
void* clientCookie, const file_io_vec* vecs, uint32 vecCount)
void* clientCookie, off_t offset, const file_io_vec* vecs,
uint32 vecCount)
:
volume(volume),
fd(fd),
requestID(requestID),
clientCookie(clientCookie),
offset(offset),
vecs(vecs),
vecCount(vecCount)
{
}
~IterativeFDIOCookie()
{
if (fd >= 0)
close(fd);
}
};
@ -621,7 +634,7 @@ Volume::DoIterativeFDIO(int fd, int32 requestID, void* clientCookie,
// create a cookie
IterativeFDIOCookie* cookie = new(std::nothrow) IterativeFDIOCookie(
this, fd, requestID, clientCookie, vecs, vecCount);
this, fd, requestID, clientCookie, request->Offset(), vecs, vecCount);
if (cookie == NULL) {
close(fd);
RETURN_ERROR(B_NO_MEMORY);
@ -630,6 +643,8 @@ Volume::DoIterativeFDIO(int fd, int32 requestID, void* clientCookie,
// we need another reference, so we can still access the cookie below
cookie->AddReference();
// TODO: Up to this point we're responsible for calling the finished hook on
// error!
// call the kernel function
error = do_iterative_fd_io(fd, request, &_IterativeFDIOGetVecs,
&_IterativeFDIOFinished, cookie);
@ -1067,6 +1082,8 @@ Volume::DoIO(void* _node, void* cookie, io_request* ioRequest)
request->node = vnode->clientNode;
request->fileCookie = cookie;
request->request = requestID;
request->offset = ioRequest->Offset();
request->length = ioRequest->Length();
// send the request
KernelRequestHandler handler(this, DO_IO_REPLY);
@ -4406,18 +4423,135 @@ Volume::_FindIORequest(io_request* request, int32* requestID)
/*static*/ status_t
Volume::_IterativeFDIOGetVecs(void* cookie, io_request* request, off_t offset,
size_t size, struct file_io_vec* vecs, size_t* _count)
Volume::_IterativeFDIOGetVecs(void* _cookie, io_request* ioRequest,
off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count)
{
// TODO: Implement!
return B_UNSUPPORTED;
IterativeFDIOCookie* cookie = (IterativeFDIOCookie*)_cookie;
Volume* volume = cookie->volume;
MutexLocker locker(volume->fLock);
// If there are vecs cached in the cookie and the offset matches, return
// those.
if (cookie->vecs != NULL) {
size_t vecCount = 0;
if (offset == cookie->offset) {
// good, copy the vecs
while (size > 0 && vecCount < cookie->vecCount
&& vecCount < *_count) {
off_t maxSize = std::min((off_t)size,
cookie->vecs[vecCount].length);
vecs[vecCount].offset = cookie->vecs[vecCount].offset;
vecs[vecCount].length = maxSize;
size -= maxSize;
vecCount++;
}
}
cookie->vecs = NULL;
cookie->vecCount = 0;
// got some vecs? -- then we're done
if (vecCount > 0) {
*_count = vecCount;
return B_OK;
}
}
// we have to ask the client FS
int32 requestID = cookie->requestID;
void* clientCookie = cookie->clientCookie;
locker.Unlock();
// get a free port
RequestPort* port = volume->fFileSystem->GetPortPool()->AcquirePort();
if (!port)
return B_ERROR;
PortReleaser _(volume->fFileSystem->GetPortPool(), port);
// prepare the request
RequestAllocator allocator(port->GetPort());
IterativeIOGetVecsRequest* request;
status_t error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->volume = volume->fUserlandVolume;
request->cookie = clientCookie;
request->offset = offset;
request->request = requestID;
request->size = size;
size_t maxVecs = std::min(*_count,
(size_t)IterativeIOGetVecsReply::MAX_VECS);
request->vecCount = maxVecs;
// send the request
KernelRequestHandler handler(volume, ITERATIVE_IO_GET_VECS_REPLY);
IterativeIOGetVecsReply* reply;
error = volume->_SendRequest(port, &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;
uint32 vecCount = reply->vecCount;
if (vecCount < 0 || vecCount > maxVecs)
return B_BAD_DATA;
memcpy(vecs, reply->vecs, vecCount * sizeof(file_io_vec));
*_count = vecCount;
return B_OK;
}
/*static*/ status_t
Volume::_IterativeFDIOFinished(void* cookie, io_request* request,
Volume::_IterativeFDIOFinished(void* _cookie, io_request* ioRequest,
status_t status, bool partialTransfer, size_t bytesTransferred)
{
// TODO: Implement!
return B_UNSUPPORTED;
IterativeFDIOCookie* cookie = (IterativeFDIOCookie*)_cookie;
Volume* volume = cookie->volume;
// At any rate, we're done with the cookie after this call -- it will not
// be used anymore.
Reference<IterativeFDIOCookie> _(cookie, true);
// We also want to dispose of the request.
IORequestRemover _2(volume, cookie->requestID);
// get a free port
RequestPort* port = volume->fFileSystem->GetPortPool()->AcquirePort();
if (!port)
return B_ERROR;
PortReleaser _3(volume->fFileSystem->GetPortPool(), port);
// prepare the request
RequestAllocator allocator(port->GetPort());
IterativeIOFinishedRequest* request;
status_t error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->volume = volume->fUserlandVolume;
request->cookie = cookie->clientCookie;
request->request = cookie->requestID;
request->status = status;
request->partialTransfer = partialTransfer;
request->bytesTransferred = bytesTransferred;
// send the request
KernelRequestHandler handler(volume, ITERATIVE_IO_FINISHED_REPLY);
IterativeIOFinishedReply* reply;
error = volume->_SendRequest(port, &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;
return B_OK;
}

View File

@ -313,14 +313,6 @@ FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
return B_OK;
}
// DoIterativeFDIORequest
status_t
DoIterativeFDIORequest::GetAddressInfos(AddressInfo* infos, int32* count)
{
ADD_ADDRESS(vecs);
return B_OK;
}
// #pragma mark -
@ -542,9 +534,13 @@ UserlandFSUtil::is_kernel_request(uint32 type)
// asynchronous I/O
case DO_IO_REQUEST:
case CANCEL_IO_REQUEST:
case ITERATIVE_IO_GET_VECS_REQUEST:
case ITERATIVE_IO_FINISHED_REQUEST:
return true;
case DO_IO_REPLY:
case CANCEL_IO_REPLY:
case ITERATIVE_IO_GET_VECS_REPLY:
case ITERATIVE_IO_FINISHED_REPLY:
return false;
// nodes
case IOCTL_REQUEST:
@ -779,9 +775,13 @@ UserlandFSUtil::is_userland_request(uint32 type)
// asynchronous I/O
case DO_IO_REQUEST:
case CANCEL_IO_REQUEST:
case ITERATIVE_IO_GET_VECS_REQUEST:
case ITERATIVE_IO_FINISHED_REQUEST:
return false;
case DO_IO_REPLY:
case CANCEL_IO_REPLY:
case ITERATIVE_IO_GET_VECS_REPLY:
case ITERATIVE_IO_FINISHED_REPLY:
return true;
// nodes
case IOCTL_REQUEST:

View File

@ -11,11 +11,15 @@
namespace UserlandFS {
struct IORequestInfo {
off_t offset;
size_t length;
int32 id;
bool isWrite;
IORequestInfo(int32 id, bool isWrite)
IORequestInfo(int32 id, bool isWrite, off_t offset, size_t length)
:
offset(offset),
length(length),
id(id),
isWrite(isWrite)
{
@ -23,6 +27,8 @@ struct IORequestInfo {
IORequestInfo(const IORequestInfo& other)
:
offset(other.offset),
length(other.length),
id(other.id),
isWrite(other.isWrite)
{

View File

@ -2,6 +2,8 @@
#include "UserlandRequestHandler.h"
#include <algorithm>
#include "AutoDeleter.h"
#include "Compatibility.h"
#include "Debug.h"
@ -13,6 +15,7 @@
#include "SingleReplyRequestHandler.h"
#include "Volume.h"
// constructor
UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem)
: RequestHandler(),
@ -75,6 +78,10 @@ UserlandRequestHandler::HandleRequest(Request* request)
return _HandleRequest((DoIORequest*)request);
case CANCEL_IO_REQUEST:
return _HandleRequest((CancelIORequest*)request);
case ITERATIVE_IO_GET_VECS_REQUEST:
return _HandleRequest((IterativeIOGetVecsRequest*)request);
case ITERATIVE_IO_FINISHED_REQUEST:
return _HandleRequest((IterativeIOFinishedRequest*)request);
// nodes
case IOCTL_REQUEST:
@ -552,7 +559,8 @@ UserlandRequestHandler::_HandleRequest(DoIORequest* request)
if (result == B_OK) {
RequestThreadContext context(volume);
IORequestInfo requestInfo(request->request, request->isWrite);
IORequestInfo requestInfo(request->request, request->isWrite,
request->offset, request->length);
result = volume->DoIO(request->node, request->fileCookie, requestInfo);
}
@ -599,6 +607,78 @@ UserlandRequestHandler::_HandleRequest(CancelIORequest* request)
}
// _HandleRequest
status_t
UserlandRequestHandler::_HandleRequest(IterativeIOGetVecsRequest* request)
{
// check and execute the request
status_t result = B_OK;
Volume* volume = (Volume*)request->volume;
if (!volume)
result = B_BAD_VALUE;
file_io_vec vecs[IterativeIOGetVecsReply::MAX_VECS];
size_t vecCount = IterativeIOGetVecsReply::MAX_VECS;
if (result == B_OK) {
RequestThreadContext context(volume);
result = volume->IterativeIOGetVecs(request->cookie, request->request,
request->offset, request->size, vecs, &vecCount);
if (result == B_OK) {
vecCount = std::min(vecCount,
(uint32)IterativeIOGetVecsReply::MAX_VECS);
}
}
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
IterativeIOGetVecsReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
RETURN_ERROR(error);
reply->error = result;
if (result == B_OK) {
memcpy(reply->vecs, vecs, vecCount * sizeof(file_io_vec));
reply->vecCount = vecCount;
} else
reply->vecCount = 0;
// send the reply
return _SendReply(allocator, false);
}
// _HandleRequest
status_t
UserlandRequestHandler::_HandleRequest(IterativeIOFinishedRequest* request)
{
// check and execute the request
status_t result = B_OK;
Volume* volume = (Volume*)request->volume;
if (!volume)
result = B_BAD_VALUE;
if (result == B_OK) {
RequestThreadContext context(volume);
result = volume->IterativeIOFinished(request->cookie, request->request,
request->status, request->partialTransfer,
request->bytesTransferred);
}
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
IterativeIOFinishedReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
RETURN_ERROR(error);
reply->error = result;
// send the reply
return _SendReply(allocator, false);
}
// #pragma mark - nodes

View File

@ -22,6 +22,8 @@ class FSRemoveVNodeRequest;
// asynchronous I/O
class DoIORequest;
class CancelIORequest;
class IterativeIOGetVecsRequest;
class IterativeIOFinishedRequest;
// nodes
class IOCtlRequest;
class SetFlagsRequest;
@ -121,6 +123,10 @@ private:
// asynchronous I/O
status_t _HandleRequest(DoIORequest* request);
status_t _HandleRequest(CancelIORequest* request);
status_t _HandleRequest(
IterativeIOGetVecsRequest* request);
status_t _HandleRequest(
IterativeIOFinishedRequest* request);
// nodes
status_t _HandleRequest(IOCtlRequest* request);

View File

@ -206,6 +206,22 @@ Volume::CancelIO(void* node, void* cookie, int32 ioRequestID)
}
status_t
Volume::IterativeIOGetVecs(void* cookie, int32 requestID, off_t offset,
size_t size, struct file_io_vec* vecs, size_t* _count)
{
return B_BAD_VALUE;
}
status_t
Volume::IterativeIOFinished(void* cookie, int32 requestID, status_t status,
bool partialTransfer, size_t bytesTransferred)
{
return B_BAD_VALUE;
}
// #pragma mark - nodes

View File

@ -58,6 +58,13 @@ public:
const IORequestInfo& requestInfo);
virtual status_t CancelIO(void* node, void* cookie,
int32 ioRequestID);
virtual status_t IterativeIOGetVecs(void* cookie,
int32 requestID, off_t offset, size_t size,
struct file_io_vec* vecs, size_t* _count);
virtual status_t IterativeIOFinished(void* cookie,
int32 requestID, status_t status,
bool partialTransfer,
size_t bytesTransferred);
// nodes
virtual status_t IOCtl(void* node, void* cookie,

View File

@ -406,6 +406,58 @@ HaikuKernelVolume::CancelIO(void* _node, void* cookie, int32 ioRequestID)
}
// IterativeIOGetVecs
status_t
HaikuKernelVolume::IterativeIOGetVecs(void* _cookie, int32 requestID,
off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count)
{
HaikuKernelIterativeFDIOCookie* cookie
= (HaikuKernelIterativeFDIOCookie*)_cookie;
// get the request
HaikuKernelIORequest* request = _FileSystem()->GetIORequest(requestID);
if (request == NULL)
RETURN_ERROR(B_BAD_VALUE);
// call the callback
status_t error = cookie->getVecs(cookie->cookie, (io_request*)request,
offset, size, vecs, _count);
// put the reference we got above
_FileSystem()->PutIORequest(request, 1);
return error;
}
// IterativeIOFinished
status_t
HaikuKernelVolume::IterativeIOFinished(void* _cookie, int32 requestID,
status_t status, bool partialTransfer, size_t bytesTransferred)
{
HaikuKernelIterativeFDIOCookie* cookie
= (HaikuKernelIterativeFDIOCookie*)_cookie;
// we're definitely done with the cookie, now
ObjectDeleter<HaikuKernelIterativeFDIOCookie> _(cookie);
// get the request
HaikuKernelIORequest* request = _FileSystem()->GetIORequest(requestID);
if (request == NULL)
RETURN_ERROR(B_BAD_VALUE);
// call the callback
status_t error = cookie->finished(cookie->cookie, (io_request*)request,
status, partialTransfer, bytesTransferred);
// We're done with the request, too, so put the reference we got above and
// the one added by DoIO().
_FileSystem()->PutIORequest(request, 2);
return error;
}
// #pragma mark - nodes

View File

@ -65,6 +65,13 @@ public:
const IORequestInfo& requestInfo);
virtual status_t CancelIO(void* node, void* cookie,
int32 ioRequestID);
virtual status_t IterativeIOGetVecs(void* cookie,
int32 requestID, off_t offset, size_t size,
struct file_io_vec* vecs, size_t* _count);
virtual status_t IterativeIOFinished(void* cookie,
int32 requestID, status_t status,
bool partialTransfer,
size_t bytesTransferred);
// nodes
virtual status_t IOCtl(void* node, void* cookie,

View File

@ -274,18 +274,17 @@ status_t
do_iterative_fd_io(int fd, io_request *_request, iterative_io_get_vecs getVecs,
iterative_io_finished finished, void *_cookie)
{
#if 0
// get some vecs already
file_io_vec fileVecs[8];
uint32 fileVecCount = 8;
status_t error = getVecs(_cookie, _request, offset, vecLength, fileVecs,
&fileVecCount);
// TODO: We don't have the offset here. We should pass it along in the
// DoIORequest.
#endif
HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request;
// get the first vecs already -- this saves a guaranteed trip back from
// kernel to userland
file_io_vec fileVecs[DoIterativeFDIORequest::MAX_VECS];
uint32 fileVecCount = DoIterativeFDIORequest::MAX_VECS;
status_t error = getVecs(_cookie, _request, request->offset,
request->length, fileVecs, &fileVecCount);
if (error != B_OK)
return error;
// create a cookie
HaikuKernelIterativeFDIOCookie* cookie
= new(std::nothrow) HaikuKernelIterativeFDIOCookie(fd, request, getVecs,
@ -296,8 +295,10 @@ do_iterative_fd_io(int fd, io_request *_request, iterative_io_get_vecs getVecs,
}
// send the request
status_t error = UserlandFS::KernelEmu::do_iterative_fd_io(
request->volume->GetID(), fd, request->id, cookie, NULL, 0);
// TODO: Up to this point we should call the finished hook on error!
error = UserlandFS::KernelEmu::do_iterative_fd_io(
request->volume->GetID(), fd, request->id, cookie, fileVecs,
fileVecCount);
if (error != B_OK) {
delete cookie;
return error;

View File

@ -6,6 +6,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include "FileSystem.h"
#include "RequestPort.h"
#include "Requests.h"
@ -862,14 +864,12 @@ UserlandFS::KernelEmu::do_iterative_fd_io(dev_t volumeID, int fd,
request->fd = fd;
request->request = requestID;
request->cookie = cookie;
request->vecCount = vecCount;
if (vecCount > 0) {
error = allocator.AllocateData(request->vecs, vecs,
vecCount * sizeof(file_io_vec), sizeof(off_t), false);
if (error != B_OK)
return error;
vecCount = std::min(vecCount, (uint32)DoIterativeFDIORequest::MAX_VECS);
memcpy(request->vecs, vecs, sizeof(file_io_vec) * vecCount);
}
request->vecCount = vecCount;
// send the request
UserlandRequestHandler handler(fileSystem, DO_ITERATIVE_FD_IO_REPLY);
@ -877,7 +877,7 @@ UserlandFS::KernelEmu::do_iterative_fd_io(dev_t volumeID, int fd,
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK)
return error;
// TODO: Up to this point we should call the finished hook or error!
// TODO: Up to this point we should call the finished hook on error!
RequestReleaser requestReleaser(port, reply);
// process the reply