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 <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
92ed372680
commit
50c7fbacb7
+41
-47
@@ -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
|
static status_t
|
||||||
write_to_file(file_cache_ref* ref, void* cookie, off_t offset, int32 pageOffset,
|
write_to_file(file_cache_ref* ref, void* cookie, off_t offset, int32 pageOffset,
|
||||||
addr_t buffer, size_t bufferSize, bool useBuffer,
|
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;
|
status_t status = B_OK;
|
||||||
|
|
||||||
if (!useBuffer) {
|
if (!useBuffer) {
|
||||||
while (bufferSize > 0) {
|
status = write_zeros_to_file(ref->vnode, cookie, offset + pageOffset,
|
||||||
generic_size_t written = min_c(bufferSize, kZeroVecSize);
|
&bufferSize);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
generic_io_vec vec;
|
generic_io_vec vec;
|
||||||
vec.base = buffer;
|
vec.base = buffer;
|
||||||
@@ -1312,7 +1339,6 @@ file_cache_write(void* _cacheRef, void* cookie, off_t offset,
|
|||||||
|
|
||||||
if (ref->disabled_count > 0) {
|
if (ref->disabled_count > 0) {
|
||||||
// Caching is disabled -- write directly to the file.
|
// Caching is disabled -- write directly to the file.
|
||||||
|
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
generic_io_vec vec;
|
generic_io_vec vec;
|
||||||
vec.base = (addr_t)buffer;
|
vec.base = (addr_t)buffer;
|
||||||
@@ -1322,40 +1348,8 @@ file_cache_write(void* _cacheRef, void* cookie, off_t offset,
|
|||||||
1, 0, &size);
|
1, 0, &size);
|
||||||
*_size = size;
|
*_size = size;
|
||||||
return error;
|
return error;
|
||||||
}
|
} else
|
||||||
|
return write_zeros_to_file(ref->vnode, cookie, offset, _size);
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t status = cache_io(ref, cookie, offset,
|
status_t status = cache_io(ref, cookie, offset,
|
||||||
|
|||||||
Reference in New Issue
Block a user