hrev54281 adds 1 changeset to branch 'master'
old head: 92ed37268072ab053b06d8e2f8b2e7320a495c57
new head: 50c7fbacb736a05dfc8306160e065f174cf34d1b
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=50c7fbacb736+%5E92ed37268072
----------------------------------------------------------------------------
50c7fbacb736: kernel/file_cache: Fix writing zeros in the cache_io case.
Should fix #16039 again.
Change-Id: I00c6566764a20e6ec5e8c99b0ebb2e304a5191ee
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2855
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54281
Commit: 50c7fbacb736a05dfc8306160e065f174cf34d1b
URL: https://git.haiku-os.org/haiku/commit/?id=50c7fbacb736
Author: Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date: Sun May 31 19:38:26 2020 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sun May 31 21:52:10 2020 UTC
Ticket: https://dev.haiku-os.org/ticket/16039
----------------------------------------------------------------------------
1 file changed, 41 insertions(+), 47 deletions(-)
src/system/kernel/cache/file_cache.cpp | 88 ++++++++++++++----------------
----------------------------------------------------------------------------
diff --git a/src/system/kernel/cache/file_cache.cpp
b/src/system/kernel/cache/file_cache.cpp
index eaa78acbd1..c765344fee 100644
--- a/src/system/kernel/cache/file_cache.cpp
+++ b/src/system/kernel/cache/file_cache.cpp
@@ -628,6 +628,43 @@ write_to_cache(file_cache_ref* ref, void* cookie, off_t
offset,
}
+static status_t
+write_zeros_to_file(struct vnode* vnode, void* cookie, off_t offset,
+ size_t* _size)
+{
+ size_t size = *_size;
+ status_t status = B_OK;
+ while (size > 0) {
+ generic_size_t length = min_c(size, kZeroVecSize);
+ generic_io_vec* vecs = sZeroVecs;
+ generic_io_vec vec;
+ size_t count = kZeroVecCount;
+ if (length != kZeroVecSize) {
+ if (length > B_PAGE_SIZE) {
+ length = ROUNDDOWN(length, B_PAGE_SIZE);
+ count = length / B_PAGE_SIZE;
+ } else {
+ vec.base = sZeroPage;
+ vec.length = length;
+ vecs = &vec;
+ count = 1;
+ }
+ }
+
+ status = vfs_write_pages(vnode, cookie, offset,
+ vecs, count, B_PHYSICAL_IO_REQUEST, &length);
+ if (status != B_OK || length == 0)
+ break;
+
+ offset += length;
+ size -= length;
+ }
+
+ *_size = *_size - size;
+ return status;
+}
+
+
static status_t
write_to_file(file_cache_ref* ref, void* cookie, off_t offset, int32
pageOffset,
addr_t buffer, size_t bufferSize, bool useBuffer,
@@ -640,18 +677,8 @@ write_to_file(file_cache_ref* ref, void* cookie, off_t
offset, int32 pageOffset,
status_t status = B_OK;
if (!useBuffer) {
- while (bufferSize > 0) {
- generic_size_t written = min_c(bufferSize,
kZeroVecSize);
- status = vfs_write_pages(ref->vnode, cookie, offset +
pageOffset,
- sZeroVecs, kZeroVecCount,
B_PHYSICAL_IO_REQUEST, &written);
- if (status != B_OK)
- return status;
- if (written == 0)
- return B_ERROR;
-
- bufferSize -= written;
- pageOffset += written;
- }
+ status = write_zeros_to_file(ref->vnode, cookie, offset +
pageOffset,
+ &bufferSize);
} else {
generic_io_vec vec;
vec.base = buffer;
@@ -1312,7 +1339,6 @@ file_cache_write(void* _cacheRef, void* cookie, off_t
offset,
if (ref->disabled_count > 0) {
// Caching is disabled -- write directly to the file.
-
if (buffer != NULL) {
generic_io_vec vec;
vec.base = (addr_t)buffer;
@@ -1322,40 +1348,8 @@ file_cache_write(void* _cacheRef, void* cookie, off_t
offset,
1, 0, &size);
*_size = size;
return error;
- }
-
- // NULL buffer -- use a dummy buffer to write zeroes
- size_t size = *_size;
- while (size > 0) {
- generic_size_t length = min_c(size, kZeroVecSize);
- generic_io_vec* vecs = sZeroVecs;
- generic_io_vec vec;
- size_t count = kZeroVecCount;
- if ((length % B_PAGE_SIZE) != 0) {
- if (length > B_PAGE_SIZE) {
- length = ROUNDDOWN(length, B_PAGE_SIZE);
- count = length / B_PAGE_SIZE;
- } else {
- vec.base = sZeroPage;
- vec.length = length;
- vecs = &vec;
- count = 1;
- }
- }
-
- status_t error = vfs_write_pages(ref->vnode, cookie,
offset,
- vecs, count, B_PHYSICAL_IO_REQUEST, &length);
- if (error != B_OK)
- return error;
- if (length == 0)
- break;
-
- offset += length;
- size -= length;
- }
-
- *_size -= size;
- return B_OK;
+ } else
+ return write_zeros_to_file(ref->vnode, cookie, offset,
_size);
}
status_t status = cache_io(ref, cookie, offset,