Skip to content

Commit

Permalink
Fix niova_io_iovs_advance() bug when iovs are completely used
Browse files Browse the repository at this point in the history
Calling niova_io_iovs_advance() with parameters that completely 'use'
the entire iov set caused the function to assert on an internal check
that verified the ensuing index was < the number of iovs.

The approach taken here is to detect the condition and return the error,
-EXFULL, rather than modify the last iov such that its base pointer
would be out of bounds and its length would be 0.
  • Loading branch information
00pauln00 committed Feb 29, 2024
1 parent c8e3777 commit 2b9e459
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,23 @@ niova_io_iovs_advance(struct iovec *iovs, size_t niovs,
break;
}

if (bytes_already_consumed > 0)
if (idx == niovs)
{
NIOVA_ASSERT(idx == niovs);
return -ERANGE;
if (bytes_already_consumed > 0)
{
NIOVA_ASSERT(idx == niovs);
return -ERANGE;
}
else
{
/* If this advance consumes all iov space, simply return w/out
* modifying any iov.
*/
NIOVA_ASSERT(bytes_already_consumed == 0);
return -EXFULL;
}
}

NIOVA_ASSERT(idx < niovs);

if (save_iov)
Expand Down
4 changes: 4 additions & 0 deletions test/io-iov-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ iov_test(void)
niova_io_iov_restore(iovs, n, idx, &save);
NIOVA_ASSERT(niova_io_iovs_total_size_get(iovs, n) == (n * n));

// Consume everything in one shot: niova-block issue #141
idx = niova_io_iovs_advance(iovs, n, n * n, NULL);
NIOVA_ASSERT(idx == -EXFULL);

off_t off = 0;
size_t niovs = n;

Expand Down

0 comments on commit 2b9e459

Please sign in to comment.