/* Returns a pointer to the allocated buffer on success; otherwise, NULL.  */
void* mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
/* Returns a pointer to the allocated buffer on success; otherwise, NULL.  */
void* mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
{
	gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
		       __GFP_NORETRY | __GFP_NO_KSWAPD;
	size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
	void *kbuf;
	*size = min_t(size_t, *size, KMALLOC_MAX_SIZE);
	while (*size > min_alloc) {
		kbuf = kmalloc(*size, flags);
		if (kbuf)
			return kbuf;
		*size >>= 1;
		*size = ALIGN(*size, mtd->writesize);
	}
	return kmalloc(*size, GFP_KERNEL);
}