aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-21 04:58:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:32:53 -0400
commit91f79c43d1b54d7154b118860d81b39bad07dfff (patch)
treea5b142ba57fdabf835476b6dbca24288a78f0c53
parentf67da30c1d5fc9e341bc8121708874bfd7b31e45 (diff)
new helper: iov_iter_get_pages_alloc()
same as iov_iter_get_pages(), except that pages array is allocated (kmalloc if possible, vmalloc if that fails) and left for caller to free. Lustre and NFS ->direct_IO() switched to it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/staging/lustre/lustre/llite/rw26.c92
-rw-r--r--fs/nfs/direct.c290
-rw-r--r--include/linux/uio.h2
-rw-r--r--mm/iov_iter.c40
4 files changed, 167 insertions, 257 deletions
diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c
index f718585c9e08..6b5994577b6b 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -218,14 +218,11 @@ static void ll_free_user_pages(struct page **pages, int npages, int do_dirty)
218 int i; 218 int i;
219 219
220 for (i = 0; i < npages; i++) { 220 for (i = 0; i < npages; i++) {
221 if (pages[i] == NULL)
222 break;
223 if (do_dirty) 221 if (do_dirty)
224 set_page_dirty_lock(pages[i]); 222 set_page_dirty_lock(pages[i]);
225 page_cache_release(pages[i]); 223 page_cache_release(pages[i]);
226 } 224 }
227 225 kvfree(pages);
228 OBD_FREE_LARGE(pages, npages * sizeof(*pages));
229} 226}
230 227
231ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, 228ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
@@ -370,10 +367,9 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb,
370 struct file *file = iocb->ki_filp; 367 struct file *file = iocb->ki_filp;
371 struct inode *inode = file->f_mapping->host; 368 struct inode *inode = file->f_mapping->host;
372 struct ccc_object *obj = cl_inode2ccc(inode); 369 struct ccc_object *obj = cl_inode2ccc(inode);
373 long count = iov_iter_count(iter); 370 ssize_t count = iov_iter_count(iter);
374 long tot_bytes = 0, result = 0; 371 ssize_t tot_bytes = 0, result = 0;
375 struct ll_inode_info *lli = ll_i2info(inode); 372 struct ll_inode_info *lli = ll_i2info(inode);
376 unsigned long seg = 0;
377 long size = MAX_DIO_SIZE; 373 long size = MAX_DIO_SIZE;
378 int refcheck; 374 int refcheck;
379 375
@@ -407,63 +403,49 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb,
407 mutex_lock(&inode->i_mutex); 403 mutex_lock(&inode->i_mutex);
408 404
409 LASSERT(obj->cob_transient_pages == 0); 405 LASSERT(obj->cob_transient_pages == 0);
410 for (seg = 0; seg < iter->nr_segs; seg++) { 406 while (iov_iter_count(iter)) {
411 long iov_left = iter->iov[seg].iov_len; 407 struct page **pages;
412 unsigned long user_addr = (unsigned long)iter->iov[seg].iov_base; 408 size_t offs;
413 409
410 count = min_t(size_t, iov_iter_count(iter), size);
414 if (rw == READ) { 411 if (rw == READ) {
415 if (file_offset >= i_size_read(inode)) 412 if (file_offset >= i_size_read(inode))
416 break; 413 break;
417 if (file_offset + iov_left > i_size_read(inode)) 414 if (file_offset + count > i_size_read(inode))
418 iov_left = i_size_read(inode) - file_offset; 415 count = i_size_read(inode) - file_offset;
419 } 416 }
420 417
421 while (iov_left > 0) { 418 result = iov_iter_get_pages_alloc(iter, &pages, count, &offs);
422 struct page **pages; 419 if (likely(result > 0)) {
423 int page_count, max_pages = 0; 420 int n = (result + offs + PAGE_SIZE - 1) / PAGE_SIZE;
424 long bytes; 421 result = ll_direct_IO_26_seg(env, io, rw, inode,
425 422 file->f_mapping,
426 bytes = min(size, iov_left); 423 result, file_offset,
427 page_count = ll_get_user_pages(rw, user_addr, bytes, 424 pages, n);
428 &pages, &max_pages); 425 ll_free_user_pages(pages, n, rw==READ);
429 if (likely(page_count > 0)) { 426 }
430 if (unlikely(page_count < max_pages)) 427 if (unlikely(result <= 0)) {
431 bytes = page_count << PAGE_CACHE_SHIFT; 428 /* If we can't allocate a large enough buffer
432 result = ll_direct_IO_26_seg(env, io, rw, inode, 429 * for the request, shrink it to a smaller
433 file->f_mapping, 430 * PAGE_SIZE multiple and try again.
434 bytes, file_offset, 431 * We should always be able to kmalloc for a
435 pages, page_count); 432 * page worth of page pointers = 4MB on i386. */
436 ll_free_user_pages(pages, max_pages, rw==READ); 433 if (result == -ENOMEM &&
437 } else if (page_count == 0) { 434 size > (PAGE_CACHE_SIZE / sizeof(*pages)) *
438 GOTO(out, result = -EFAULT); 435 PAGE_CACHE_SIZE) {
439 } else { 436 size = ((((size / 2) - 1) |
440 result = page_count; 437 ~CFS_PAGE_MASK) + 1) &
441 } 438 CFS_PAGE_MASK;
442 if (unlikely(result <= 0)) { 439 CDEBUG(D_VFSTRACE,"DIO size now %lu\n",
443 /* If we can't allocate a large enough buffer 440 size);
444 * for the request, shrink it to a smaller 441 continue;
445 * PAGE_SIZE multiple and try again.
446 * We should always be able to kmalloc for a
447 * page worth of page pointers = 4MB on i386. */
448 if (result == -ENOMEM &&
449 size > (PAGE_CACHE_SIZE / sizeof(*pages)) *
450 PAGE_CACHE_SIZE) {
451 size = ((((size / 2) - 1) |
452 ~CFS_PAGE_MASK) + 1) &
453 CFS_PAGE_MASK;
454 CDEBUG(D_VFSTRACE,"DIO size now %lu\n",
455 size);
456 continue;
457 }
458
459 GOTO(out, result);
460 } 442 }
461 443
462 tot_bytes += result; 444 GOTO(out, result);
463 file_offset += result;
464 iov_left -= result;
465 user_addr += result;
466 } 445 }
446 iov_iter_advance(iter, result);
447 tot_bytes += result;
448 file_offset += result;
467 } 449 }
468out: 450out:
469 LASSERT(obj->cob_transient_pages == 0); 451 LASSERT(obj->cob_transient_pages == 0);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 1d34f454989e..b122fe21fea0 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -322,60 +322,37 @@ static const struct nfs_pgio_completion_ops nfs_direct_read_completion_ops = {
322 * handled automatically by nfs_direct_read_result(). Otherwise, if 322 * handled automatically by nfs_direct_read_result(). Otherwise, if
323 * no requests have been sent, just return an error. 323 * no requests have been sent, just return an error.
324 */ 324 */
325static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *desc,
326 const struct iovec *iov,
327 loff_t pos, bool uio)
328{
329 struct nfs_direct_req *dreq = desc->pg_dreq;
330 struct nfs_open_context *ctx = dreq->ctx;
331 struct inode *inode = ctx->dentry->d_inode;
332 unsigned long user_addr = (unsigned long)iov->iov_base;
333 size_t count = iov->iov_len;
334 size_t rsize = NFS_SERVER(inode)->rsize;
335 unsigned int pgbase;
336 int result;
337 ssize_t started = 0;
338 struct page **pagevec = NULL;
339 unsigned int npages;
340
341 do {
342 size_t bytes;
343 int i;
344 325
345 pgbase = user_addr & ~PAGE_MASK; 326static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
346 bytes = min(max_t(size_t, rsize, PAGE_SIZE), count); 327 struct iov_iter *iter,
328 loff_t pos)
329{
330 struct nfs_pageio_descriptor desc;
331 struct inode *inode = dreq->inode;
332 ssize_t result = -EINVAL;
333 size_t requested_bytes = 0;
334 size_t rsize = max_t(size_t, NFS_SERVER(inode)->rsize, PAGE_SIZE);
347 335
348 result = -ENOMEM; 336 NFS_PROTO(dreq->inode)->read_pageio_init(&desc, dreq->inode,
349 npages = nfs_page_array_len(pgbase, bytes); 337 &nfs_direct_read_completion_ops);
350 if (!pagevec) 338 get_dreq(dreq);
351 pagevec = kmalloc(npages * sizeof(struct page *), 339 desc.pg_dreq = dreq;
352 GFP_KERNEL); 340 atomic_inc(&inode->i_dio_count);
353 if (!pagevec)
354 break;
355 if (uio) {
356 down_read(&current->mm->mmap_sem);
357 result = get_user_pages(current, current->mm, user_addr,
358 npages, 1, 0, pagevec, NULL);
359 up_read(&current->mm->mmap_sem);
360 if (result < 0)
361 break;
362 } else {
363 WARN_ON(npages != 1);
364 result = get_kernel_page(user_addr, 1, pagevec);
365 if (WARN_ON(result != 1))
366 break;
367 }
368 341
369 if ((unsigned)result < npages) { 342 while (iov_iter_count(iter)) {
370 bytes = result * PAGE_SIZE; 343 struct page **pagevec;
371 if (bytes <= pgbase) { 344 size_t bytes;
372 nfs_direct_release_pages(pagevec, result); 345 size_t pgbase;
373 break; 346 unsigned npages, i;
374 }
375 bytes -= pgbase;
376 npages = result;
377 }
378 347
348 result = iov_iter_get_pages_alloc(iter, &pagevec,
349 rsize, &pgbase);
350 if (result < 0)
351 break;
352
353 bytes = result;
354 iov_iter_advance(iter, bytes);
355 npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
379 for (i = 0; i < npages; i++) { 356 for (i = 0; i < npages; i++) {
380 struct nfs_page *req; 357 struct nfs_page *req;
381 unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase); 358 unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
@@ -389,55 +366,21 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
389 } 366 }
390 req->wb_index = pos >> PAGE_SHIFT; 367 req->wb_index = pos >> PAGE_SHIFT;
391 req->wb_offset = pos & ~PAGE_MASK; 368 req->wb_offset = pos & ~PAGE_MASK;
392 if (!nfs_pageio_add_request(desc, req)) { 369 if (!nfs_pageio_add_request(&desc, req)) {
393 result = desc->pg_error; 370 result = desc.pg_error;
394 nfs_release_request(req); 371 nfs_release_request(req);
395 break; 372 break;
396 } 373 }
397 pgbase = 0; 374 pgbase = 0;
398 bytes -= req_len; 375 bytes -= req_len;
399 started += req_len; 376 requested_bytes += req_len;
400 user_addr += req_len;
401 pos += req_len; 377 pos += req_len;
402 count -= req_len;
403 dreq->bytes_left -= req_len; 378 dreq->bytes_left -= req_len;
404 } 379 }
405 /* The nfs_page now hold references to these pages */
406 nfs_direct_release_pages(pagevec, npages); 380 nfs_direct_release_pages(pagevec, npages);
407 } while (count != 0 && result >= 0); 381 kvfree(pagevec);
408
409 kfree(pagevec);
410
411 if (started)
412 return started;
413 return result < 0 ? (ssize_t) result : -EFAULT;
414}
415
416static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
417 struct iov_iter *iter,
418 loff_t pos, bool uio)
419{
420 struct nfs_pageio_descriptor desc;
421 struct inode *inode = dreq->inode;
422 ssize_t result = -EINVAL;
423 size_t requested_bytes = 0;
424 unsigned long seg;
425
426 NFS_PROTO(dreq->inode)->read_pageio_init(&desc, dreq->inode,
427 &nfs_direct_read_completion_ops);
428 get_dreq(dreq);
429 desc.pg_dreq = dreq;
430 atomic_inc(&inode->i_dio_count);
431
432 for (seg = 0; seg < iter->nr_segs; seg++) {
433 const struct iovec *vec = &iter->iov[seg];
434 result = nfs_direct_read_schedule_segment(&desc, vec, pos, uio);
435 if (result < 0) 382 if (result < 0)
436 break; 383 break;
437 requested_bytes += result;
438 if ((size_t)result < vec->iov_len)
439 break;
440 pos += vec->iov_len;
441 } 384 }
442 385
443 nfs_pageio_complete(&desc); 386 nfs_pageio_complete(&desc);
@@ -521,7 +464,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
521 dreq->iocb = iocb; 464 dreq->iocb = iocb;
522 465
523 NFS_I(inode)->read_io += count; 466 NFS_I(inode)->read_io += count;
524 result = nfs_direct_read_schedule_iovec(dreq, iter, pos, uio); 467 result = nfs_direct_read_schedule_iovec(dreq, iter, pos);
525 468
526 mutex_unlock(&inode->i_mutex); 469 mutex_unlock(&inode->i_mutex);
527 470
@@ -677,109 +620,6 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
677} 620}
678#endif 621#endif
679 622
680/*
681 * NB: Return the value of the first error return code. Subsequent
682 * errors after the first one are ignored.
683 */
684/*
685 * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE
686 * operation. If nfs_writedata_alloc() or get_user_pages() fails,
687 * bail and stop sending more writes. Write length accounting is
688 * handled automatically by nfs_direct_write_result(). Otherwise, if
689 * no requests have been sent, just return an error.
690 */
691static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *desc,
692 const struct iovec *iov,
693 loff_t pos, bool uio)
694{
695 struct nfs_direct_req *dreq = desc->pg_dreq;
696 struct nfs_open_context *ctx = dreq->ctx;
697 struct inode *inode = ctx->dentry->d_inode;
698 unsigned long user_addr = (unsigned long)iov->iov_base;
699 size_t count = iov->iov_len;
700 size_t wsize = NFS_SERVER(inode)->wsize;
701 unsigned int pgbase;
702 int result;
703 ssize_t started = 0;
704 struct page **pagevec = NULL;
705 unsigned int npages;
706
707 do {
708 size_t bytes;
709 int i;
710
711 pgbase = user_addr & ~PAGE_MASK;
712 bytes = min(max_t(size_t, wsize, PAGE_SIZE), count);
713
714 result = -ENOMEM;
715 npages = nfs_page_array_len(pgbase, bytes);
716 if (!pagevec)
717 pagevec = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
718 if (!pagevec)
719 break;
720
721 if (uio) {
722 down_read(&current->mm->mmap_sem);
723 result = get_user_pages(current, current->mm, user_addr,
724 npages, 0, 0, pagevec, NULL);
725 up_read(&current->mm->mmap_sem);
726 if (result < 0)
727 break;
728 } else {
729 WARN_ON(npages != 1);
730 result = get_kernel_page(user_addr, 0, pagevec);
731 if (WARN_ON(result != 1))
732 break;
733 }
734
735 if ((unsigned)result < npages) {
736 bytes = result * PAGE_SIZE;
737 if (bytes <= pgbase) {
738 nfs_direct_release_pages(pagevec, result);
739 break;
740 }
741 bytes -= pgbase;
742 npages = result;
743 }
744
745 for (i = 0; i < npages; i++) {
746 struct nfs_page *req;
747 unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
748
749 req = nfs_create_request(dreq->ctx, dreq->inode,
750 pagevec[i],
751 pgbase, req_len);
752 if (IS_ERR(req)) {
753 result = PTR_ERR(req);
754 break;
755 }
756 nfs_lock_request(req);
757 req->wb_index = pos >> PAGE_SHIFT;
758 req->wb_offset = pos & ~PAGE_MASK;
759 if (!nfs_pageio_add_request(desc, req)) {
760 result = desc->pg_error;
761 nfs_unlock_and_release_request(req);
762 break;
763 }
764 pgbase = 0;
765 bytes -= req_len;
766 started += req_len;
767 user_addr += req_len;
768 pos += req_len;
769 count -= req_len;
770 dreq->bytes_left -= req_len;
771 }
772 /* The nfs_page now hold references to these pages */
773 nfs_direct_release_pages(pagevec, npages);
774 } while (count != 0 && result >= 0);
775
776 kfree(pagevec);
777
778 if (started)
779 return started;
780 return result < 0 ? (ssize_t) result : -EFAULT;
781}
782
783static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) 623static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
784{ 624{
785 struct nfs_direct_req *dreq = hdr->dreq; 625 struct nfs_direct_req *dreq = hdr->dreq;
@@ -859,15 +699,27 @@ static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
859 .completion = nfs_direct_write_completion, 699 .completion = nfs_direct_write_completion,
860}; 700};
861 701
702
703/*
704 * NB: Return the value of the first error return code. Subsequent
705 * errors after the first one are ignored.
706 */
707/*
708 * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE
709 * operation. If nfs_writedata_alloc() or get_user_pages() fails,
710 * bail and stop sending more writes. Write length accounting is
711 * handled automatically by nfs_direct_write_result(). Otherwise, if
712 * no requests have been sent, just return an error.
713 */
862static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, 714static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
863 struct iov_iter *iter, 715 struct iov_iter *iter,
864 loff_t pos, bool uio) 716 loff_t pos)
865{ 717{
866 struct nfs_pageio_descriptor desc; 718 struct nfs_pageio_descriptor desc;
867 struct inode *inode = dreq->inode; 719 struct inode *inode = dreq->inode;
868 ssize_t result = 0; 720 ssize_t result = 0;
869 size_t requested_bytes = 0; 721 size_t requested_bytes = 0;
870 unsigned long seg; 722 size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE);
871 723
872 NFS_PROTO(inode)->write_pageio_init(&desc, inode, FLUSH_COND_STABLE, 724 NFS_PROTO(inode)->write_pageio_init(&desc, inode, FLUSH_COND_STABLE,
873 &nfs_direct_write_completion_ops); 725 &nfs_direct_write_completion_ops);
@@ -875,16 +727,50 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
875 get_dreq(dreq); 727 get_dreq(dreq);
876 atomic_inc(&inode->i_dio_count); 728 atomic_inc(&inode->i_dio_count);
877 729
878 NFS_I(dreq->inode)->write_io += iov_iter_count(iter); 730 NFS_I(inode)->write_io += iov_iter_count(iter);
879 for (seg = 0; seg < iter->nr_segs; seg++) { 731 while (iov_iter_count(iter)) {
880 const struct iovec *vec = &iter->iov[seg]; 732 struct page **pagevec;
881 result = nfs_direct_write_schedule_segment(&desc, vec, pos, uio); 733 size_t bytes;
734 size_t pgbase;
735 unsigned npages, i;
736
737 result = iov_iter_get_pages_alloc(iter, &pagevec,
738 wsize, &pgbase);
882 if (result < 0) 739 if (result < 0)
883 break; 740 break;
884 requested_bytes += result; 741
885 if ((size_t)result < vec->iov_len) 742 bytes = result;
743 iov_iter_advance(iter, bytes);
744 npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
745 for (i = 0; i < npages; i++) {
746 struct nfs_page *req;
747 unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
748
749 req = nfs_create_request(dreq->ctx, inode,
750 pagevec[i],
751 pgbase, req_len);
752 if (IS_ERR(req)) {
753 result = PTR_ERR(req);
754 break;
755 }
756 nfs_lock_request(req);
757 req->wb_index = pos >> PAGE_SHIFT;
758 req->wb_offset = pos & ~PAGE_MASK;
759 if (!nfs_pageio_add_request(&desc, req)) {
760 result = desc.pg_error;
761 nfs_unlock_and_release_request(req);
762 break;
763 }
764 pgbase = 0;
765 bytes -= req_len;
766 requested_bytes += req_len;
767 pos += req_len;
768 dreq->bytes_left -= req_len;
769 }
770 nfs_direct_release_pages(pagevec, npages);
771 kvfree(pagevec);
772 if (result < 0)
886 break; 773 break;
887 pos += vec->iov_len;
888 } 774 }
889 nfs_pageio_complete(&desc); 775 nfs_pageio_complete(&desc);
890 776
@@ -985,7 +871,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
985 if (!is_sync_kiocb(iocb)) 871 if (!is_sync_kiocb(iocb))
986 dreq->iocb = iocb; 872 dreq->iocb = iocb;
987 873
988 result = nfs_direct_write_schedule_iovec(dreq, iter, pos, uio); 874 result = nfs_direct_write_schedule_iovec(dreq, iter, pos);
989 875
990 if (mapping->nrpages) { 876 if (mapping->nrpages) {
991 invalidate_inode_pages2_range(mapping, 877 invalidate_inode_pages2_range(mapping,
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 2f8825b06680..4876e9f2a58f 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -73,6 +73,8 @@ void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
73 unsigned long nr_segs, size_t count); 73 unsigned long nr_segs, size_t count);
74ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, 74ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
75 size_t maxsize, size_t *start); 75 size_t maxsize, size_t *start);
76ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
77 size_t maxsize, size_t *start);
76int iov_iter_npages(const struct iov_iter *i, int maxpages); 78int iov_iter_npages(const struct iov_iter *i, int maxpages);
77 79
78static inline size_t iov_iter_count(struct iov_iter *i) 80static inline size_t iov_iter_count(struct iov_iter *i)
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index 0b677f8f9bad..a5c691c1a283 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -1,6 +1,8 @@
1#include <linux/export.h> 1#include <linux/export.h>
2#include <linux/uio.h> 2#include <linux/uio.h>
3#include <linux/pagemap.h> 3#include <linux/pagemap.h>
4#include <linux/slab.h>
5#include <linux/vmalloc.h>
4 6
5size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, 7size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
6 struct iov_iter *i) 8 struct iov_iter *i)
@@ -263,6 +265,44 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
263} 265}
264EXPORT_SYMBOL(iov_iter_get_pages); 266EXPORT_SYMBOL(iov_iter_get_pages);
265 267
268ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
269 struct page ***pages, size_t maxsize,
270 size_t *start)
271{
272 size_t offset = i->iov_offset;
273 const struct iovec *iov = i->iov;
274 size_t len;
275 unsigned long addr;
276 void *p;
277 int n;
278 int res;
279
280 len = iov->iov_len - offset;
281 if (len > i->count)
282 len = i->count;
283 if (len > maxsize)
284 len = maxsize;
285 addr = (unsigned long)iov->iov_base + offset;
286 len += *start = addr & (PAGE_SIZE - 1);
287 addr &= ~(PAGE_SIZE - 1);
288 n = (len + PAGE_SIZE - 1) / PAGE_SIZE;
289
290 p = kmalloc(n * sizeof(struct page *), GFP_KERNEL);
291 if (!p)
292 p = vmalloc(n * sizeof(struct page *));
293 if (!p)
294 return -ENOMEM;
295
296 res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p);
297 if (unlikely(res < 0)) {
298 kvfree(p);
299 return res;
300 }
301 *pages = p;
302 return (res == n ? len : res * PAGE_SIZE) - *start;
303}
304EXPORT_SYMBOL(iov_iter_get_pages_alloc);
305
266int iov_iter_npages(const struct iov_iter *i, int maxpages) 306int iov_iter_npages(const struct iov_iter *i, int maxpages)
267{ 307{
268 size_t offset = i->iov_offset; 308 size_t offset = i->iov_offset;