On Fri, Dec 04, 2020 at 06:45:54PM +0300, Konstantin Komarov wrote: > +/* external compression lzx/xpress */ > +static int decompress_lzx_xpress(struct ntfs_sb_info *sbi, const char *cmpr, > + size_t cmpr_size, void *unc, size_t unc_size, > + u32 frame_size) > +{ > + int err; > + void *ctx; > + > + if (cmpr_size == unc_size) { > + /* frame not compressed */ > + memcpy(unc, cmpr, unc_size); > + return 0; > + } > + > + err = 0; > + ctx = NULL; > + spin_lock(&sbi->compress.lock); > + if (frame_size == 0x8000) { > + /* LZX: frame compressed */ > + if (!sbi->compress.lzx) { > + /* Lazy initialize lzx decompress context */ > + spin_unlock(&sbi->compress.lock); > + ctx = lzx_allocate_decompressor(0x8000); > + if (!ctx) > + return -ENOMEM; > + if (IS_ERR(ctx)) { > + /* should never failed */ > + err = PTR_ERR(ctx); > + goto out; > + } > + > + spin_lock(&sbi->compress.lock); > + if (!sbi->compress.lzx) { > + sbi->compress.lzx = ctx; > + ctx = NULL; > + } > + } > + > + if (lzx_decompress(sbi->compress.lzx, cmpr, cmpr_size, unc, > + unc_size)) { > + err = -EINVAL; > + } > + } else { > + /* XPRESS: frame compressed */ > + if (!sbi->compress.xpress) { > + /* Lazy initialize xpress decompress context */ > + spin_unlock(&sbi->compress.lock); > + ctx = xpress_allocate_decompressor(); > + if (!ctx) > + return -ENOMEM; > + > + spin_lock(&sbi->compress.lock); > + if (!sbi->compress.xpress) { > + sbi->compress.xpress = ctx; > + ctx = NULL; > + } > + } > + > + if (xpress_decompress(sbi->compress.xpress, cmpr, cmpr_size, > + unc, unc_size)) { > + err = -EINVAL; > + } > + } > + spin_unlock(&sbi->compress.lock); > +out: > + ntfs_free(ctx); > + return err; > +} Decompression is a somewhat heavyweight operation. Not the type of thing that should be done while holding a spin lock. - Eric