mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
io_uring/rsrc: cleanup io_pin_pages()
This function is overly convoluted with a goto error path, and checks under the mmap_read_lock() that don't need to be at all. Rearrange it a bit so the checks and errors fall out naturally, rather than needing to jump around for it. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
93b8cc60c3
commit
922a2c78f1
@ -1037,39 +1037,36 @@ struct page **io_pin_pages(unsigned long ubuf, unsigned long len, int *npages)
|
||||
{
|
||||
unsigned long start, end, nr_pages;
|
||||
struct page **pages = NULL;
|
||||
int pret, ret = -ENOMEM;
|
||||
int ret;
|
||||
|
||||
end = (ubuf + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
start = ubuf >> PAGE_SHIFT;
|
||||
nr_pages = end - start;
|
||||
WARN_ON(!nr_pages);
|
||||
|
||||
pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
|
||||
if (!pages)
|
||||
goto done;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = 0;
|
||||
mmap_read_lock(current->mm);
|
||||
pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM,
|
||||
pages);
|
||||
if (pret == nr_pages)
|
||||
*npages = nr_pages;
|
||||
else
|
||||
ret = pret < 0 ? pret : -EFAULT;
|
||||
|
||||
ret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM, pages);
|
||||
mmap_read_unlock(current->mm);
|
||||
if (ret) {
|
||||
|
||||
/* success, mapped all pages */
|
||||
if (ret == nr_pages) {
|
||||
*npages = nr_pages;
|
||||
return pages;
|
||||
}
|
||||
|
||||
/* partial map, or didn't map anything */
|
||||
if (ret >= 0) {
|
||||
/* if we did partial map, release any pages we did get */
|
||||
if (pret > 0)
|
||||
unpin_user_pages(pages, pret);
|
||||
goto done;
|
||||
if (ret)
|
||||
unpin_user_pages(pages, ret);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
ret = 0;
|
||||
done:
|
||||
if (ret < 0) {
|
||||
kvfree(pages);
|
||||
pages = ERR_PTR(ret);
|
||||
}
|
||||
return pages;
|
||||
kvfree(pages);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
|
||||
|
Loading…
Reference in New Issue
Block a user