/* Copies data into an arbitrary memory location from an array of pages The copy is assumed to be non-overlapping.  */
static void _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
/* Copies data into an arbitrary memory location from an array of pages The copy is assumed to be non-overlapping.  */
static void _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
{
	struct page **pgfrom;
	char *vfrom;
	size_t copy;
	pgfrom = pages + (pgbase >> PAGE_CACHE_SHIFT);
	pgbase &= ~PAGE_CACHE_MASK;
	do {
		copy = PAGE_CACHE_SIZE - pgbase;
		if (copy > len)
			copy = len;
		vfrom = kmap_atomic(*pgfrom, KM_USER0);
		memcpy(p, vfrom + pgbase, copy);
		kunmap_atomic(vfrom, KM_USER0);
		pgbase += copy;
		if (pgbase == PAGE_CACHE_SIZE) {
			pgbase = 0;
			pgfrom++;
		}
		p += copy;
	} while ((len -= copy) != 0);
}