On 11/15/17, 6:41 AM, "David Sterba" wrote: > The branch is now in a state that can be tested. Turns out the memory > requirements are too much for grub, so the boot fails with "not enough > memory". The calculated value > > ZSTD_BTRFS_MAX_INPUT: 131072 > ZSTD_DStreamWorkspaceBound with ZSTD_BTRFS_MAX_INPUT: 549424 > > This is not something I could fix easily, we'd probalby need a tuned > version of ZSTD for grub constraints. Adding Nick to CC. If I understand the grub code correctly, we only need to read, and we have the entire input and output buffer in one segment. In that case you can use ZSTD_initDCtx(), and ZSTD_decompressDCtx(). ZSTD_DCtxWorkspaceBound() is only 155984. See decompress_single() in https://patchwork.kernel.org/patch/9997909/ for an example. This (uncompiled and untested) code should work: ``` static grub_ssize_t grub_btrfs_zstd_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) { grub_size_t ret = 0; ZSTD_DCtx *ctx; void *wmem; grub_size_t wsize; wsize = ZSTD_DCtxWorkspaceBound(); wmem = grub_malloc(wsize); if (!wmem) { return -1; } ctx = ZSTD_initDCtx(wmem, wsize); if (!ctx) { grub_free(wmem); return -1; } /* This is only necessary if there is junk after the end of the zstd * compressed data in the input buffer. Otherwise the return value * should always be exactly isize. If you delete this, and it always works, * then there isn't junk data at the end. */ isize = ZSTD_findFrameCompressedSize(in_buf, in_len); if (ZSTD_isError(isize)) { grub_free(wmem); return -1; } ret = ZSTD_decompressDCtx(ctx, obuf, osize, ibuf, isize); grub_free(wmem); if (ZSTD_isError(ret)) { return -1; } return ret; } ``` {.n++%ݶw{.n+{k~^nrzh&zzޗ++zfh~iz_j:+v)ߣm