mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
iovec: redo iovec_iterator_next_page
This commit is contained in:
@@ -64,8 +64,9 @@ size_t iovec_iterator_read_from_ringbuffer(iovec_iterator_t *iovec_iterator, rin
|
|||||||
size_t iovec_iterator_peek_from_ringbuffer(iovec_iterator_t *iovec_iterator, ringbuffer_t *ringbuffer, size_t byte_count, uintmax_t ringbuffer_offset);
|
size_t iovec_iterator_peek_from_ringbuffer(iovec_iterator_t *iovec_iterator, ringbuffer_t *ringbuffer, size_t byte_count, uintmax_t ringbuffer_offset);
|
||||||
|
|
||||||
// returns the physical address of the next page in the iovec_iterator, adding a reference count while at it
|
// returns the physical address of the next page in the iovec_iterator, adding a reference count while at it
|
||||||
// fails with EINVAL if the iterator does not currently point to the start of a page or there is not enough space for a page
|
// sets the page_offset to the offset in the page, page_remaining to the remaining number of bytes in the page and page to the physical address of the page
|
||||||
|
// if no more pages in iovec_iterator, returns success with page being set to NULL
|
||||||
// fails with EFAULT if the page is not mapped
|
// fails with EFAULT if the page is not mapped
|
||||||
int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, void **page);
|
int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, size_t *page_offset, size_t *page_remaining, void **page);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+11
-7
@@ -224,19 +224,23 @@ size_t iovec_iterator_read_from_ringbuffer(iovec_iterator_t *iovec_iterator, rin
|
|||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, void **page) {
|
int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, size_t *page_offset, size_t *page_remaining, void **page) {
|
||||||
void *addr = (void *)((uintptr_t)iovec_iterator->current->addr + iovec_iterator->current_offset);
|
void *addr = (void *)((uintptr_t)iovec_iterator->current->addr + iovec_iterator->current_offset);
|
||||||
if ((uintptr_t)addr % PAGE_SIZE)
|
size_t offset_in_page = ((uintptr_t)addr % PAGE_SIZE);
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
size_t remaining = iovec_iterator->current->len - iovec_iterator->current_offset;
|
size_t remaining = iovec_iterator->current->len - iovec_iterator->current_offset;
|
||||||
if (remaining < PAGE_SIZE)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
void *phys = vmm_getphysical(addr, true);
|
if (remaining == 0) {
|
||||||
|
*page = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *phys = vmm_getphysical((void *)((uintptr_t)addr - offset_in_page), true);
|
||||||
if (phys == NULL)
|
if (phys == NULL)
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
|
|
||||||
|
*page_offset = offset_in_page;
|
||||||
|
*page_remaining = min(PAGE_SIZE, remaining);
|
||||||
*page = phys;
|
*page = phys;
|
||||||
|
iovec_iterator_skip(iovec_iterator, *page_remaining);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user