aboutsummaryrefslogtreecommitdiffstats
path: root/lib/scatterlist.c
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2013-07-08 19:01:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 13:33:30 -0400
commit1105200480b4faeb673d1b23658650b003302c06 (patch)
tree546433c5f8c403c296fa7e1f8929030b902514ed /lib/scatterlist.c
parent0ea8530dcf762526459b29ac713a623b51fd691f (diff)
lib/scatterlist: factor out sg_miter_get_next_page() from sg_miter_next()
This patchset introduces sg_pcopy_from_buffer() and sg_pcopy_to_buffer(), which copy data between a linear buffer and an SG list. The only difference between sg_pcopy_{from,to}_buffer() and sg_copy_{from,to}_buffer() is an additional argument that specifies the number of bytes to skip the SG list before copying. The main reason for introducing these functions is to fix a problem in scsi_debug module. And there is a local function in crypto/talitos module, which can be replaced by sg_pcopy_to_buffer(). This patch: sg_miter_get_next_page() is used to proceed page iterator to the next page if necessary, and will be used to implement the variants of sg_copy_{from,to}_buffer() later. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Acked-by: Tejun Heo <tj@kernel.org> Cc: Tejun Heo <tj@kernel.org> Cc: Imre Deak <imre.deak@intel.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "David S. Miller" <davem@davemloft.net> Cc: "James E.J. Bottomley" <JBottomley@parallels.com> Cc: Douglas Gilbert <dgilbert@interlog.com> Cc: Horia Geanta <horia.geanta@freescale.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/scatterlist.c')
-rw-r--r--lib/scatterlist.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index a1cf8cae60e7..c35b929435f3 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -453,6 +453,28 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
453} 453}
454EXPORT_SYMBOL(sg_miter_start); 454EXPORT_SYMBOL(sg_miter_start);
455 455
456static bool sg_miter_get_next_page(struct sg_mapping_iter *miter)
457{
458 if (!miter->__remaining) {
459 struct scatterlist *sg;
460 unsigned long pgoffset;
461
462 if (!__sg_page_iter_next(&miter->piter))
463 return false;
464
465 sg = miter->piter.sg;
466 pgoffset = miter->piter.sg_pgoffset;
467
468 miter->__offset = pgoffset ? 0 : sg->offset;
469 miter->__remaining = sg->offset + sg->length -
470 (pgoffset << PAGE_SHIFT) - miter->__offset;
471 miter->__remaining = min_t(unsigned long, miter->__remaining,
472 PAGE_SIZE - miter->__offset);
473 }
474
475 return true;
476}
477
456/** 478/**
457 * sg_miter_next - proceed mapping iterator to the next mapping 479 * sg_miter_next - proceed mapping iterator to the next mapping
458 * @miter: sg mapping iter to proceed 480 * @miter: sg mapping iter to proceed
@@ -478,22 +500,9 @@ bool sg_miter_next(struct sg_mapping_iter *miter)
478 * Get to the next page if necessary. 500 * Get to the next page if necessary.
479 * __remaining, __offset is adjusted by sg_miter_stop 501 * __remaining, __offset is adjusted by sg_miter_stop
480 */ 502 */
481 if (!miter->__remaining) { 503 if (!sg_miter_get_next_page(miter))
482 struct scatterlist *sg; 504 return false;
483 unsigned long pgoffset;
484
485 if (!__sg_page_iter_next(&miter->piter))
486 return false;
487
488 sg = miter->piter.sg;
489 pgoffset = miter->piter.sg_pgoffset;
490 505
491 miter->__offset = pgoffset ? 0 : sg->offset;
492 miter->__remaining = sg->offset + sg->length -
493 (pgoffset << PAGE_SHIFT) - miter->__offset;
494 miter->__remaining = min_t(unsigned long, miter->__remaining,
495 PAGE_SIZE - miter->__offset);
496 }
497 miter->page = sg_page_iter_page(&miter->piter); 506 miter->page = sg_page_iter_page(&miter->piter);
498 miter->consumed = miter->length = miter->__remaining; 507 miter->consumed = miter->length = miter->__remaining;
499 508