From cf638bb14b55b9899dec57ad79515934f5411e05 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 28 Jun 2024 16:28:38 -0400 Subject: [PATCH] nvme_disk: Fix a few bugs in the get_memory_map logic. * If realloc returns NULL, we still need to free the original pointer. * If get_memory_map returns with B_BAD_VALUE and entries is 0, this is really the same as B_BUFFER_OVERFLOW. Fixes spurious I/O failures when writing the BFS journal directly with vectored I/O (as the next commit will enable.) Change-Id: I56b63ea2f6b82716719570f1e35d9b425a49b64e Reviewed-on: https://review.haiku-os.org/c/haiku/+/7823 Reviewed-by: Adrien Destugues Haiku-Format: Haiku-format Bot Tested-by: Commit checker robot Reviewed-by: waddlesplash --- src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp index f259f8a9b3..7ab6a4c9e5 100644 --- a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp @@ -667,20 +667,24 @@ nvme_disk_io(void* cookie, io_request* request) // Avoid copies by going straight into the vtophys array. status = get_memory_map_etc(request->TeamID(), (void*)virt.base, virt.length, vtophys + nvme_request.iovec_count, &entries); + + if (status == B_BAD_VALUE && entries == 0) + status = B_BUFFER_OVERFLOW; if (status == B_BUFFER_OVERFLOW) { TRACE("vtophys array was too small, reallocating\n"); - vtophysDeleter.Detach(); vtophys_length *= 2; nvme_request.iovecs = vtophys = (physical_entry*)realloc(vtophys, sizeof(physical_entry) * vtophys_length); - vtophysDeleter.SetTo(vtophys); - if (vtophys == NULL) { - status = B_NO_MEMORY; - } else { + if (vtophys != NULL) { + vtophysDeleter.Detach(); + vtophysDeleter.SetTo(vtophys); + // Try again, with the larger buffer this time. i--; continue; + } else { + status = B_NO_MEMORY; } } if (status != B_OK) {