void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out) { for (;;) { unsigned int len_this_page = scatterwalk_pagelen(walk); u8 *vaddr; if (len_this_page > nbytes) len_this_page = nbytes; if (out != 2) { vaddr = scatterwalk_map(walk); memcpy_dir(buf, vaddr, len_this_page, out); scatterwalk_unmap(vaddr); } scatterwalk_advance(walk, len_this_page); if (nbytes == len_this_page) break; buf += len_this_page; nbytes -= len_this_page; scatterwalk_pagedone(walk, out & 1, 1); } }
/* * Do not call this unless the total length of all of the fragments * has been verified as multiple of the block size. */ int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out) { if (buf != walk->data) { while (nbytes > walk->len_this_page) { memcpy_dir(buf, walk->data, walk->len_this_page, out); buf += walk->len_this_page; nbytes -= walk->len_this_page; crypto_kunmap(walk->data, out); scatterwalk_pagedone(walk, out, 1); scatterwalk_map(walk, out); } memcpy_dir(buf, walk->data, nbytes, out); } walk->offset += nbytes; walk->len_this_page -= nbytes; walk->len_this_segment -= nbytes; return 0; }