> +ssize_t iov_iter_pin_pages(struct iov_iter *i, > + struct page **pages, size_t maxsize, unsigned int maxpages, > + size_t *start) > +{ > + size_t len; > + int n, res; > + > + if (maxsize > i->count) > + maxsize = i->count; > + if (!maxsize) > + return 0; > + > + WARN_ON_ONCE(!iter_is_iovec(i)); > + > + if (likely(iter_is_iovec(i))) { > + unsigned int gup_flags = 0; > + unsigned long addr; > + > + if (iov_iter_rw(i) != WRITE) > + gup_flags |= FOLL_WRITE; > + if (i->nofault) > + gup_flags |= FOLL_NOFAULT; > + > + addr = first_iovec_segment(i, &len, start, maxsize, maxpages); > + n = DIV_ROUND_UP(len, PAGE_SIZE); > + res = pin_user_pages_fast(addr, n, gup_flags, pages); > + if (unlikely(res <= 0)) > + return res; > + return (res == n ? len : res * PAGE_SIZE) - *start; Trying to be clever like that just makes the code a lot less readable. I should not have to reason about a return value. Same in the other function. -- Jens Axboe