summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2022-01-25 14:58:47 +0200
committerIdan Horowitz <idan.horowitz@gmail.com>2022-01-26 02:37:03 +0200
commitdaf6b59a01b2d1fb4173f8a85443085cae63893d (patch)
treee03643a517761b77031dea0cabd84e333d7c8bf0
parent6f8e89a9055a0ca9e5465b26f69f137da85b14fd (diff)
downloadserenity-daf6b59a01b2d1fb4173f8a85443085cae63893d.zip
Kernel: Make StorageDevice partial block writes OOM-fallible
-rw-r--r--Kernel/Storage/StorageDevice.cpp13
1 files changed, 8 insertions, 5 deletions
diff --git a/Kernel/Storage/StorageDevice.cpp b/Kernel/Storage/StorageDevice.cpp
index ac1475abf3..67cc38bcd9 100644
--- a/Kernel/Storage/StorageDevice.cpp
+++ b/Kernel/Storage/StorageDevice.cpp
@@ -105,6 +105,12 @@ ErrorOr<size_t> StorageDevice::write(OpenFileDescription&, u64 offset, const Use
remaining = 0;
}
+ // We try to allocate the temporary block buffer for partial writes *before* we start any full block writes,
+ // to try and prevent partial writes
+ Optional<ByteBuffer> partial_write_block;
+ if (remaining > 0)
+ partial_write_block = TRY(ByteBuffer::create_zeroed(block_size()));
+
dbgln_if(STORAGE_DEVICE_DEBUG, "StorageDevice::write() index={}, whole_blocks={}, remaining={}", index, whole_blocks, remaining);
if (whole_blocks > 0) {
@@ -129,10 +135,7 @@ ErrorOr<size_t> StorageDevice::write(OpenFileDescription&, u64 offset, const Use
// partial write, we have to read the block's content first, modify it,
// then write the whole block back to the disk.
if (remaining > 0) {
- // FIXME: Do something sensible with this OOM scenario.
- auto data = ByteBuffer::create_zeroed(block_size()).release_value_but_fixme_should_propagate_errors();
- auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data.data());
-
+ auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(partial_write_block->data());
{
auto read_request = TRY(try_make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size()));
auto result = read_request->wait();
@@ -151,7 +154,7 @@ ErrorOr<size_t> StorageDevice::write(OpenFileDescription&, u64 offset, const Use
}
}
- TRY(inbuf.read(data.data(), pos, remaining));
+ TRY(inbuf.read(partial_write_block->data(), pos, remaining));
{
auto write_request = TRY(try_make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Write, index + whole_blocks, 1, data_buffer, block_size()));