From 24d0e21f51e88ab35cc3f1c1750741dfeb40933d Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 11 Nov 2013 18:58:09 +0100 Subject: [PATCH] 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. --- src/system/kernel/fs/vfs_request_io.cpp | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/fs/vfs_request_io.cpp b/src/system/kernel/fs/vfs_request_io.cpp index 4a7984d94a..8c42dbd1ab 100644 --- a/src/system/kernel/fs/vfs_request_io.cpp +++ b/src/system/kernel/fs/vfs_request_io.cpp @@ -165,12 +165,33 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request, // create subrequests for the file vecs we've got 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 vecLength = min_c(vecs[i].length, (off_t)requestLength); TRACE_RIO("[%ld] vec %lu offset: %lld, length: %lld\n", 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) { TRACE_RIO("[%ld] creating subrequest: offset: %lld, length: " "%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); 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. IORequest* nextSubRequest = request->FirstSubRequest(); while (nextSubRequest != NULL) {