From daf6b59a01b2d1fb4173f8a85443085cae63893d Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 25 Jan 2022 14:58:47 +0200 Subject: Kernel: Make StorageDevice partial block writes OOM-fallible --- Kernel/Storage/StorageDevice.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Kernel') 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 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 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 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::Read, index + whole_blocks, 1, data_buffer, block_size())); auto result = read_request->wait(); @@ -151,7 +154,7 @@ ErrorOr 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::Write, index + whole_blocks, 1, data_buffer, block_size())); -- cgit v1.2.3