do_iterative_fd_io_iterate(): Support sparse files
* Check whether the vectors we get are sparse file vectors and satisfy them immediately instead of creating a subrequest. Untested, since the API isn't used by ext2 as it should be. * Add error == B_OK to the condition of the outer loop.
This commit is contained in:
@@ -165,12 +165,33 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request,
|
|||||||
|
|
||||||
// create subrequests for the file vecs we've got
|
// create subrequests for the file vecs we've got
|
||||||
size_t subRequestCount = 0;
|
size_t subRequestCount = 0;
|
||||||
for (size_t i = 0; i < vecCount && subRequestCount < kMaxSubRequests; i++) {
|
for (size_t i = 0;
|
||||||
|
i < vecCount && subRequestCount < kMaxSubRequests && error == B_OK;
|
||||||
|
i++) {
|
||||||
off_t vecOffset = vecs[i].offset;
|
off_t vecOffset = vecs[i].offset;
|
||||||
off_t vecLength = min_c(vecs[i].length, (off_t)requestLength);
|
off_t vecLength = min_c(vecs[i].length, (off_t)requestLength);
|
||||||
TRACE_RIO("[%ld] vec %lu offset: %lld, length: %lld\n",
|
TRACE_RIO("[%ld] vec %lu offset: %lld, length: %lld\n",
|
||||||
find_thread(NULL), i, vecOffset, vecLength);
|
find_thread(NULL), i, vecOffset, vecLength);
|
||||||
|
|
||||||
|
// Special offset -1 means that this is part of sparse file that is
|
||||||
|
// zero. We fill it in right here.
|
||||||
|
if (vecOffset == -1) {
|
||||||
|
if (request->IsWrite()) {
|
||||||
|
panic("do_iterative_fd_io_iterate(): write to sparse file "
|
||||||
|
"vector");
|
||||||
|
error = B_BAD_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = request->ClearData(requestOffset, vecLength);
|
||||||
|
if (error != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
requestOffset += vecLength;
|
||||||
|
requestLength -= vecLength;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (vecLength > 0 && subRequestCount < kMaxSubRequests) {
|
while (vecLength > 0 && subRequestCount < kMaxSubRequests) {
|
||||||
TRACE_RIO("[%ld] creating subrequest: offset: %lld, length: "
|
TRACE_RIO("[%ld] creating subrequest: offset: %lld, length: "
|
||||||
"%lld\n", find_thread(NULL), vecOffset, vecLength);
|
"%lld\n", find_thread(NULL), vecOffset, vecLength);
|
||||||
@@ -200,6 +221,14 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request,
|
|||||||
request->Advance(requestOffset - cookie->request_offset);
|
request->Advance(requestOffset - cookie->request_offset);
|
||||||
cookie->request_offset = requestOffset;
|
cookie->request_offset = requestOffset;
|
||||||
|
|
||||||
|
// If we don't have any sub requests at this point, that means all that
|
||||||
|
// remained were zeroed sparse file vectors. So the request is done now.
|
||||||
|
if (subRequestCount == 0) {
|
||||||
|
ASSERT(request->RemainingBytes() == 0);
|
||||||
|
request->SetStatusAndNotify(B_OK);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule the subrequests.
|
// Schedule the subrequests.
|
||||||
IORequest* nextSubRequest = request->FirstSubRequest();
|
IORequest* nextSubRequest = request->FirstSubRequest();
|
||||||
while (nextSubRequest != NULL) {
|
while (nextSubRequest != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user