* 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:
parent
2bb8b19f08
commit
c76e8d36fb
@ -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;
|
||||
|
@ -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 ] ;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user