static size_t msb_sg_copy()

in core/ms_block.c [36:87]


static size_t msb_sg_copy(struct scatterlist *sg_from,
	struct scatterlist *sg_to, int to_nents, size_t offset, size_t len)
{
	size_t copied = 0;

	while (offset > 0) {
		if (offset >= sg_from->length) {
			if (sg_is_last(sg_from))
				return 0;

			offset -= sg_from->length;
			sg_from = sg_next(sg_from);
			continue;
		}

		copied = min(len, sg_from->length - offset);
		sg_set_page(sg_to, sg_page(sg_from),
			copied, sg_from->offset + offset);

		len -= copied;
		offset = 0;

		if (sg_is_last(sg_from) || !len)
			goto out;

		sg_to = sg_next(sg_to);
		to_nents--;
		sg_from = sg_next(sg_from);
	}

	while (len > sg_from->length && to_nents--) {
		len -= sg_from->length;
		copied += sg_from->length;

		sg_set_page(sg_to, sg_page(sg_from),
				sg_from->length, sg_from->offset);

		if (sg_is_last(sg_from) || !len)
			goto out;

		sg_from = sg_next(sg_from);
		sg_to = sg_next(sg_to);
	}

	if (len && to_nents) {
		sg_set_page(sg_to, sg_page(sg_from), len, sg_from->offset);
		copied += len;
	}
out:
	sg_mark_end(sg_to);
	return copied;
}