- for (seg = 0; seg < nr_segs; seg++) {
- size_t iov_left = iov[seg].iov_len;
- unsigned long user_addr = (unsigned long)iov[seg].iov_base;
-
- if (rw == READ) {
- if (file_offset >= i_size_read(inode))
- break;
- if (file_offset + iov_left > i_size_read(inode))
- iov_left = i_size_read(inode) - file_offset;
- }
-
- while (iov_left > 0) {
- struct page **pages;
- int page_count, max_pages = 0;
- size_t bytes;
-
- bytes = min(size, iov_left);
- page_count = ll_get_user_pages(rw, user_addr, bytes,
- &pages, &max_pages);
- if (likely(page_count > 0)) {
- if (unlikely(page_count < max_pages))
- bytes = page_count << PAGE_SHIFT;
- result = ll_direct_IO_seg(env, io, rw, inode,
- bytes, file_offset,
- pages, page_count);
- ll_free_user_pages(pages, max_pages, rw==READ);
- } else if (page_count == 0) {
- GOTO(out, result = -EFAULT);
- } else {
- result = page_count;
- }
- if (unlikely(result <= 0)) {
- /* If we can't allocate a large enough buffer
- * for the request, shrink it to a smaller
- * PAGE_SIZE multiple and try again.
- * We should always be able to kmalloc for a
- * page worth of page pointers = 4MB on i386. */
- if (result == -ENOMEM &&
- size > (PAGE_SIZE / sizeof(*pages)) *
- PAGE_SIZE) {
- size = ((((size / 2) - 1) |
- ~PAGE_MASK) + 1) &
- PAGE_MASK;
- CDEBUG(D_VFSTRACE, "DIO size now %zu\n",
- size);
- continue;
- }
-
- GOTO(out, result);
- }
-
- tot_bytes += result;
- file_offset += result;
- iov_left -= result;
- user_addr += result;
- }
- }
-out:
- if (tot_bytes > 0) {
- struct vvp_io *vio = vvp_env_io(env);