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 <[email protected]>
Haiku-Format: Haiku-format Bot <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-07-08 15:51:13 +00:00
committed by waddlesplash
parent ff91caf6e5
commit cf638bb14b
@@ -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) {