summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2013-07-08 16:01:52 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 10:33:30 -0700
commit1105200480b4faeb673d1b23658650b003302c06 (patch)
tree546433c5f8c403c296fa7e1f8929030b902514ed
parent0ea8530dcf762526459b29ac713a623b51fd691f (diff)
downloadlwn-1105200480b4faeb673d1b23658650b003302c06.tar.gz
lwn-1105200480b4faeb673d1b23658650b003302c06.zip
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>
-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,
}
EXPORT_SYMBOL(sg_miter_start);
+static bool sg_miter_get_next_page(struct sg_mapping_iter *miter)
+{
+ if (!miter->__remaining) {
+ struct scatterlist *sg;
+ unsigned long pgoffset;
+
+ if (!__sg_page_iter_next(&miter->piter))
+ return false;
+
+ sg = miter->piter.sg;
+ pgoffset = miter->piter.sg_pgoffset;
+
+ miter->__offset = pgoffset ? 0 : sg->offset;
+ miter->__remaining = sg->offset + sg->length -
+ (pgoffset << PAGE_SHIFT) - miter->__offset;
+ miter->__remaining = min_t(unsigned long, miter->__remaining,
+ PAGE_SIZE - miter->__offset);
+ }
+
+ return true;
+}
+
/**
* sg_miter_next - proceed mapping iterator to the next mapping
* @miter: sg mapping iter to proceed
@@ -478,22 +500,9 @@ bool sg_miter_next(struct sg_mapping_iter *miter)
* Get to the next page if necessary.
* __remaining, __offset is adjusted by sg_miter_stop
*/
- if (!miter->__remaining) {
- struct scatterlist *sg;
- unsigned long pgoffset;
-
- if (!__sg_page_iter_next(&miter->piter))
- return false;
-
- sg = miter->piter.sg;
- pgoffset = miter->piter.sg_pgoffset;
+ if (!sg_miter_get_next_page(miter))
+ return false;
- miter->__offset = pgoffset ? 0 : sg->offset;
- miter->__remaining = sg->offset + sg->length -
- (pgoffset << PAGE_SHIFT) - miter->__offset;
- miter->__remaining = min_t(unsigned long, miter->__remaining,
- PAGE_SIZE - miter->__offset);
- }
miter->page = sg_page_iter_page(&miter->piter);
miter->consumed = miter->length = miter->__remaining;