ReactOS  0.4.14-dev-358-gbef841c
compress.c File Reference
#include "btrfs_drv.h"
#include "zlib/zlib.h"
#include "zlib/inftrees.h"
#include "zlib/inflate.h"
#include "zstd/zstd.h"
Include dependency graph for compress.c:

Go to the source code of this file.

Classes

struct  lzo_stream
 

Macros

#define Z_SOLO
 
#define ZLIB_INTERNAL
 
#define ZSTD_STATIC_LINKING_ONLY
 
#define LZO_PAGE_SIZE   4096
 
#define LZO1X_MEM_COMPRESS   ((uint32_t) (16384L * sizeof(uint8_t*)))
 
#define M1_MAX_OFFSET   0x0400
 
#define M2_MAX_OFFSET   0x0800
 
#define M3_MAX_OFFSET   0x4000
 
#define M4_MAX_OFFSET   0xbfff
 
#define MX_MAX_OFFSET   (M1_MAX_OFFSET + M2_MAX_OFFSET)
 
#define M1_MARKER   0
 
#define M2_MARKER   64
 
#define M3_MARKER   32
 
#define M4_MARKER   16
 
#define _DV2(p, shift1, shift2)   (((( (uint32_t)(p[2]) << shift1) ^ p[1]) << shift2) ^ p[0])
 
#define DVAL_NEXT(dv, p)   dv ^= p[-1]; dv = (((dv) >> 5) ^ ((uint32_t)(p[2]) << (2*5)))
 
#define _DV(p, shift)   _DV2(p, shift, shift)
 
#define DVAL_FIRST(dv, p)   dv = _DV((p), 5)
 
#define _DINDEX(dv, p)   ((40799u * (dv)) >> 5)
 
#define DINDEX(dv, p)   (((_DINDEX(dv, p)) & 0x3fff) << 0)
 
#define UPDATE_D(dict, cycle, dv, p)   dict[DINDEX(dv, p)] = (p)
 
#define UPDATE_I(dict, cycle, index, p)   dict[index] = (p)
 
#define LZO_CHECK_MPOS_NON_DET(m_pos, m_off, in, ip, max_offset)
 
#define LZO_BYTE(x)   ((unsigned char) (x))
 
#define ZSTD_ALLOC_TAG   0x6474737a
 
#define ZSTD_BTRFS_MAX_WINDOWLOG   17
 

Functions

static voidzstd_malloc (void *opaque, size_t size)
 
static void zstd_free (void *opaque, void *address)
 
static uint8_t lzo_nextbyte (lzo_stream *stream)
 
static int lzo_len (lzo_stream *stream, int byte, int mask)
 
static void lzo_copy (lzo_stream *stream, int len)
 
static void lzo_copyback (lzo_stream *stream, uint32_t back, int len)
 
static NTSTATUS do_lzo_decompress (lzo_stream *stream)
 
NTSTATUS lzo_decompress (uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, uint32_t inpageoff)
 
static voidzlib_alloc (void *opaque, unsigned int items, unsigned int size)
 
static void zlib_free (void *opaque, void *ptr)
 
NTSTATUS zlib_decompress (uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
 
static NTSTATUS zlib_write_compressed_bit (fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
 
static NTSTATUS lzo_do_compress (const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len, void *wrkmem)
 
static NTSTATUS lzo1x_1_compress (lzo_stream *stream)
 
static __inline uint32_t lzo_max_outlen (uint32_t inlen)
 
static NTSTATUS lzo_write_compressed_bit (fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
 
static NTSTATUS zstd_write_compressed_bit (fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
 
NTSTATUS write_compressed_bit (fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
 
NTSTATUS zstd_decompress (uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
 

Variables

ZSTD_customMem zstd_mem = { .customAlloc = zstd_malloc, .customFree = zstd_free, .opaque = NULL }
 

Macro Definition Documentation

◆ _DINDEX

#define _DINDEX (   dv,
  p 
)    ((40799u * (dv)) >> 5)

Definition at line 77 of file compress.c.

◆ _DV

#define _DV (   p,
  shift 
)    _DV2(p, shift, shift)

Definition at line 75 of file compress.c.

◆ _DV2

#define _DV2 (   p,
  shift1,
  shift2 
)    (((( (uint32_t)(p[2]) << shift1) ^ p[1]) << shift2) ^ p[0])

Definition at line 73 of file compress.c.

◆ DINDEX

#define DINDEX (   dv,
  p 
)    (((_DINDEX(dv, p)) & 0x3fff) << 0)

Definition at line 78 of file compress.c.

◆ DVAL_FIRST

#define DVAL_FIRST (   dv,
  p 
)    dv = _DV((p), 5)

Definition at line 76 of file compress.c.

◆ DVAL_NEXT

#define DVAL_NEXT (   dv,
  p 
)    dv ^= p[-1]; dv = (((dv) >> 5) ^ ((uint32_t)(p[2]) << (2*5)))

Definition at line 74 of file compress.c.

◆ LZO1X_MEM_COMPRESS

#define LZO1X_MEM_COMPRESS   ((uint32_t) (16384L * sizeof(uint8_t*)))

Definition at line 59 of file compress.c.

◆ LZO_BYTE

#define LZO_BYTE (   x)    ((unsigned char) (x))

Definition at line 87 of file compress.c.

◆ LZO_CHECK_MPOS_NON_DET

#define LZO_CHECK_MPOS_NON_DET (   m_pos,
  m_off,
  in,
  ip,
  max_offset 
)
Value:
((void*) m_pos < (void*) in || \
(m_off = (uint8_t*) ip - (uint8_t*) m_pos) <= 0 || \
m_off > max_offset)
Definition: dhcpd.h:61
BYTE uint8_t
Definition: msvideo1.c:66
GLuint in
Definition: glext.h:9616

Definition at line 82 of file compress.c.

◆ LZO_PAGE_SIZE

#define LZO_PAGE_SIZE   4096

Definition at line 46 of file compress.c.

◆ M1_MARKER

#define M1_MARKER   0

Definition at line 68 of file compress.c.

◆ M1_MAX_OFFSET

#define M1_MAX_OFFSET   0x0400

Definition at line 61 of file compress.c.

◆ M2_MARKER

#define M2_MARKER   64

Definition at line 69 of file compress.c.

◆ M2_MAX_OFFSET

#define M2_MAX_OFFSET   0x0800

Definition at line 62 of file compress.c.

◆ M3_MARKER

#define M3_MARKER   32

Definition at line 70 of file compress.c.

◆ M3_MAX_OFFSET

#define M3_MAX_OFFSET   0x4000

Definition at line 63 of file compress.c.

◆ M4_MARKER

#define M4_MARKER   16

Definition at line 71 of file compress.c.

◆ M4_MAX_OFFSET

#define M4_MAX_OFFSET   0xbfff

Definition at line 64 of file compress.c.

◆ MX_MAX_OFFSET

#define MX_MAX_OFFSET   (M1_MAX_OFFSET + M2_MAX_OFFSET)

Definition at line 66 of file compress.c.

◆ UPDATE_D

#define UPDATE_D (   dict,
  cycle,
  dv,
  p 
)    dict[DINDEX(dv, p)] = (p)

Definition at line 79 of file compress.c.

◆ UPDATE_I

#define UPDATE_I (   dict,
  cycle,
  index,
  p 
)    dict[index] = (p)

Definition at line 80 of file compress.c.

◆ Z_SOLO

#define Z_SOLO

Definition at line 31 of file compress.c.

◆ ZLIB_INTERNAL

#define ZLIB_INTERNAL

Definition at line 32 of file compress.c.

◆ ZSTD_ALLOC_TAG

#define ZSTD_ALLOC_TAG   0x6474737a

Definition at line 89 of file compress.c.

◆ ZSTD_BTRFS_MAX_WINDOWLOG

#define ZSTD_BTRFS_MAX_WINDOWLOG   17

Definition at line 92 of file compress.c.

◆ ZSTD_STATIC_LINKING_ONLY

#define ZSTD_STATIC_LINKING_ONLY

Definition at line 42 of file compress.c.

Function Documentation

◆ do_lzo_decompress()

static NTSTATUS do_lzo_decompress ( lzo_stream stream)
static

Definition at line 170 of file compress.c.

170  {
171  uint8_t byte;
172  uint32_t len, back;
173  bool backcopy = false;
174 
175  stream->error = false;
176 
177  byte = lzo_nextbyte(stream);
178  if (stream->error) return STATUS_INTERNAL_ERROR;
179 
180  if (byte > 17) {
181  lzo_copy(stream, min((uint8_t)(byte - 17), (uint32_t)(stream->outlen - stream->outpos)));
182  if (stream->error) return STATUS_INTERNAL_ERROR;
183 
184  if (stream->outlen == stream->outpos)
185  return STATUS_SUCCESS;
186 
187  byte = lzo_nextbyte(stream);
188  if (stream->error) return STATUS_INTERNAL_ERROR;
189 
190  if (byte < 16) return STATUS_INTERNAL_ERROR;
191  }
192 
193  while (1) {
194  if (byte >> 4) {
195  backcopy = true;
196  if (byte >> 6) {
197  len = (byte >> 5) - 1;
198  back = (lzo_nextbyte(stream) << 3) + ((byte >> 2) & 7) + 1;
199  if (stream->error) return STATUS_INTERNAL_ERROR;
200  } else if (byte >> 5) {
201  len = lzo_len(stream, byte, 31);
202  if (stream->error) return STATUS_INTERNAL_ERROR;
203 
204  byte = lzo_nextbyte(stream);
205  if (stream->error) return STATUS_INTERNAL_ERROR;
206 
207  back = (lzo_nextbyte(stream) << 6) + (byte >> 2) + 1;
208  if (stream->error) return STATUS_INTERNAL_ERROR;
209  } else {
210  len = lzo_len(stream, byte, 7);
211  if (stream->error) return STATUS_INTERNAL_ERROR;
212 
213  back = (1 << 14) + ((byte & 8) << 11);
214 
215  byte = lzo_nextbyte(stream);
216  if (stream->error) return STATUS_INTERNAL_ERROR;
217 
218  back += (lzo_nextbyte(stream) << 6) + (byte >> 2);
219  if (stream->error) return STATUS_INTERNAL_ERROR;
220 
221  if (back == (1 << 14)) {
222  if (len != 1)
223  return STATUS_INTERNAL_ERROR;
224  break;
225  }
226  }
227  } else if (backcopy) {
228  len = 0;
229  back = (lzo_nextbyte(stream) << 2) + (byte >> 2) + 1;
230  if (stream->error) return STATUS_INTERNAL_ERROR;
231  } else {
232  len = lzo_len(stream, byte, 15);
233  if (stream->error) return STATUS_INTERNAL_ERROR;
234 
235  lzo_copy(stream, min(len + 3, stream->outlen - stream->outpos));
236  if (stream->error) return STATUS_INTERNAL_ERROR;
237 
238  if (stream->outlen == stream->outpos)
239  return STATUS_SUCCESS;
240 
241  byte = lzo_nextbyte(stream);
242  if (stream->error) return STATUS_INTERNAL_ERROR;
243 
244  if (byte >> 4)
245  continue;
246 
247  len = 1;
248  back = (1 << 11) + (lzo_nextbyte(stream) << 2) + (byte >> 2) + 1;
249  if (stream->error) return STATUS_INTERNAL_ERROR;
250 
251  break;
252  }
253 
254  lzo_copyback(stream, back, min(len + 2, stream->outlen - stream->outpos));
255  if (stream->error) return STATUS_INTERNAL_ERROR;
256 
257  if (stream->outlen == stream->outpos)
258  return STATUS_SUCCESS;
259 
260  len = byte & 3;
261 
262  if (len) {
263  lzo_copy(stream, min(len, stream->outlen - stream->outpos));
264  if (stream->error) return STATUS_INTERNAL_ERROR;
265 
266  if (stream->outlen == stream->outpos)
267  return STATUS_SUCCESS;
268  } else
269  backcopy = !backcopy;
270 
271  byte = lzo_nextbyte(stream);
272  if (stream->error) return STATUS_INTERNAL_ERROR;
273  }
274 
275  return STATUS_SUCCESS;
276 }
static void lzo_copy(lzo_stream *stream, int len)
Definition: compress.c:133
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
static void lzo_copyback(lzo_stream *stream, uint32_t back, int len)
Definition: compress.c:152
static uint8_t lzo_nextbyte(lzo_stream *stream)
Definition: compress.c:103
static int lzo_len(lzo_stream *stream, int byte, int mask)
Definition: compress.c:117
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722
BYTE uint8_t
Definition: msvideo1.c:66
#define byte(x, n)
Definition: tomcrypt.h:118
#define min(a, b)
Definition: monoChain.cc:55
UINT32 uint32_t
Definition: types.h:75
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by lzo_decompress().

◆ lzo1x_1_compress()

static NTSTATUS lzo1x_1_compress ( lzo_stream stream)
static

Definition at line 737 of file compress.c.

737  {
738  uint8_t *op = stream->out;
740 
741  if (stream->inlen <= 0)
742  stream->outlen = 0;
743  else if (stream->inlen <= 9 + 4) {
744  *op++ = LZO_BYTE(17 + stream->inlen);
745 
746  stream->inpos = 0;
747  do {
748  *op++ = stream->in[stream->inpos];
749  stream->inpos++;
750  } while (stream->inlen < stream->inpos);
751  stream->outlen = (uint32_t)(op - stream->out);
752  } else
753  Status = lzo_do_compress(stream->in, stream->inlen, stream->out, &stream->outlen, stream->wrkmem);
754 
755  if (Status == STATUS_SUCCESS) {
756  op = stream->out + stream->outlen;
757  *op++ = M4_MARKER | 1;
758  *op++ = 0;
759  *op++ = 0;
760  stream->outlen += 3;
761  }
762 
763  return Status;
764 }
LONG NTSTATUS
Definition: precomp.h:26
#define LZO_BYTE(x)
Definition: compress.c:87
Definition: parse.h:22
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
static NTSTATUS lzo_do_compress(const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len, void *wrkmem)
Definition: compress.c:529
UINT op
Definition: effect.c:223
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define M4_MARKER
Definition: compress.c:71

Referenced by lzo_write_compressed_bit().

◆ lzo_copy()

static void lzo_copy ( lzo_stream stream,
int  len 
)
static

Definition at line 133 of file compress.c.

133  {
134  if (stream->inpos + len > stream->inlen) {
135  stream->error = true;
136  return;
137  }
138 
139  if (stream->outpos + len > stream->outlen) {
140  stream->error = true;
141  return;
142  }
143 
144  do {
145  stream->out[stream->outpos] = stream->in[stream->inpos];
146  stream->inpos++;
147  stream->outpos++;
148  len--;
149  } while (len > 0);
150 }
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722

Referenced by do_lzo_decompress().

◆ lzo_copyback()

static void lzo_copyback ( lzo_stream stream,
uint32_t  back,
int  len 
)
static

Definition at line 152 of file compress.c.

152  {
153  if (stream->outpos < back) {
154  stream->error = true;
155  return;
156  }
157 
158  if (stream->outpos + len > stream->outlen) {
159  stream->error = true;
160  return;
161  }
162 
163  do {
164  stream->out[stream->outpos] = stream->out[stream->outpos - back];
165  stream->outpos++;
166  len--;
167  } while (len > 0);
168 }
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722

Referenced by do_lzo_decompress().

◆ lzo_decompress()

NTSTATUS lzo_decompress ( uint8_t inbuf,
uint32_t  inlen,
uint8_t outbuf,
uint32_t  outlen,
uint32_t  inpageoff 
)

Definition at line 278 of file compress.c.

278  {
280  uint32_t partlen, inoff, outoff;
282 
283  inoff = 0;
284  outoff = 0;
285 
286  do {
287  partlen = *(uint32_t*)&inbuf[inoff];
288 
289  if (partlen + inoff > inlen) {
290  ERR("overflow: %x + %x > %I64x\n", partlen, inoff, inlen);
291  return STATUS_INTERNAL_ERROR;
292  }
293 
294  inoff += sizeof(uint32_t);
295 
296  stream.in = &inbuf[inoff];
297  stream.inlen = partlen;
298  stream.inpos = 0;
299  stream.out = &outbuf[outoff];
300  stream.outlen = min(outlen, LZO_PAGE_SIZE);
301  stream.outpos = 0;
302 
304  if (!NT_SUCCESS(Status)) {
305  ERR("do_lzo_decompress returned %08x\n", Status);
306  return Status;
307  }
308 
309  if (stream.outpos < stream.outlen)
310  RtlZeroMemory(&stream.out[stream.outpos], stream.outlen - stream.outpos);
311 
312  inoff += partlen;
313  outoff += stream.outlen;
314 
315  if (LZO_PAGE_SIZE - ((inpageoff + inoff) % LZO_PAGE_SIZE) < sizeof(uint32_t))
316  inoff = ((((inpageoff + inoff) / LZO_PAGE_SIZE) + 1) * LZO_PAGE_SIZE) - inpageoff;
317 
318  outlen -= stream.outlen;
319  } while (inoff < inlen && outlen > 0);
320 
321  return STATUS_SUCCESS;
322 }
LONG NTSTATUS
Definition: precomp.h:26
static int inbuf
Definition: adnsresfilter.c:73
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS do_lzo_decompress(lzo_stream *stream)
Definition: compress.c:170
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
#define min(a, b)
Definition: monoChain.cc:55
UINT32 uint32_t
Definition: types.h:75
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define LZO_PAGE_SIZE
Definition: compress.c:46
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by flush_extents(), and read_file().

◆ lzo_do_compress()

static NTSTATUS lzo_do_compress ( const uint8_t in,
uint32_t  in_len,
uint8_t out,
uint32_t out_len,
void wrkmem 
)
static

Definition at line 529 of file compress.c.

529  {
530  const uint8_t* ip;
531  uint32_t dv;
532  uint8_t* op;
533  const uint8_t* in_end = in + in_len;
534  const uint8_t* ip_end = in + in_len - 9 - 4;
535  const uint8_t* ii;
536  const uint8_t** dict = (const uint8_t**)wrkmem;
537 
538  op = out;
539  ip = in;
540  ii = ip;
541 
542  DVAL_FIRST(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
543  DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
544  DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
545  DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
546 
547  while (1) {
548  const uint8_t* m_pos;
549  uint32_t m_len;
550  ptrdiff_t m_off;
551  uint32_t lit, dindex;
552 
553  dindex = DINDEX(dv, ip);
554  m_pos = dict[dindex];
555  UPDATE_I(dict, cycle, dindex, ip);
556 
557  if (!LZO_CHECK_MPOS_NON_DET(m_pos, m_off, in, ip, M4_MAX_OFFSET) && m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) {
558  lit = (uint32_t)(ip - ii);
559  m_pos += 3;
560  if (m_off <= M2_MAX_OFFSET)
561  goto match;
562 
563  if (lit == 3) { /* better compression, but slower */
564  if (op - 2 <= out)
565  return STATUS_INTERNAL_ERROR;
566 
567  op[-2] |= LZO_BYTE(3);
568  *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
569  goto code_match;
570  }
571 
572  if (*m_pos == ip[3])
573  goto match;
574  }
575 
576  /* a literal */
577  ++ip;
578  if (ip >= ip_end)
579  break;
580  DVAL_NEXT(dv, ip);
581  continue;
582 
583  /* a match */
584 match:
585  /* store current literal run */
586  if (lit > 0) {
587  uint32_t t = lit;
588 
589  if (t <= 3) {
590  if (op - 2 <= out)
591  return STATUS_INTERNAL_ERROR;
592 
593  op[-2] |= LZO_BYTE(t);
594  } else if (t <= 18)
595  *op++ = LZO_BYTE(t - 3);
596  else {
597  uint32_t tt = t - 18;
598 
599  *op++ = 0;
600  while (tt > 255) {
601  tt -= 255;
602  *op++ = 0;
603  }
604 
605  if (tt <= 0)
606  return STATUS_INTERNAL_ERROR;
607 
608  *op++ = LZO_BYTE(tt);
609  }
610 
611  do {
612  *op++ = *ii++;
613  } while (--t > 0);
614  }
615 
616 
617  /* code the match */
618 code_match:
619  if (ii != ip)
620  return STATUS_INTERNAL_ERROR;
621 
622  ip += 3;
623  if (*m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++ ||
624  *m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++) {
625  --ip;
626  m_len = (uint32_t)(ip - ii);
627 
628  if (m_len < 3 || m_len > 8)
629  return STATUS_INTERNAL_ERROR;
630 
631  if (m_off <= M2_MAX_OFFSET) {
632  m_off -= 1;
633  *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
634  *op++ = LZO_BYTE(m_off >> 3);
635  } else if (m_off <= M3_MAX_OFFSET) {
636  m_off -= 1;
637  *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
638  goto m3_m4_offset;
639  } else {
640  m_off -= 0x4000;
641 
642  if (m_off <= 0 || m_off > 0x7fff)
643  return STATUS_INTERNAL_ERROR;
644 
645  *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
646  goto m3_m4_offset;
647  }
648  } else {
649  const uint8_t* end;
650  end = in_end;
651  while (ip < end && *m_pos == *ip)
652  m_pos++, ip++;
653  m_len = (uint32_t)(ip - ii);
654 
655  if (m_len < 3)
656  return STATUS_INTERNAL_ERROR;
657 
658  if (m_off <= M3_MAX_OFFSET) {
659  m_off -= 1;
660  if (m_len <= 33)
661  *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
662  else {
663  m_len -= 33;
664  *op++ = M3_MARKER | 0;
665  goto m3_m4_len;
666  }
667  } else {
668  m_off -= 0x4000;
669 
670  if (m_off <= 0 || m_off > 0x7fff)
671  return STATUS_INTERNAL_ERROR;
672 
673  if (m_len <= 9)
674  *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
675  else {
676  m_len -= 9;
677  *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
678 m3_m4_len:
679  while (m_len > 255) {
680  m_len -= 255;
681  *op++ = 0;
682  }
683 
684  if (m_len <= 0)
685  return STATUS_INTERNAL_ERROR;
686 
687  *op++ = LZO_BYTE(m_len);
688  }
689  }
690 
691 m3_m4_offset:
692  *op++ = LZO_BYTE((m_off & 63) << 2);
693  *op++ = LZO_BYTE(m_off >> 6);
694  }
695 
696  ii = ip;
697  if (ip >= ip_end)
698  break;
699  DVAL_FIRST(dv, ip);
700  }
701 
702  /* store final literal run */
703  if (in_end - ii > 0) {
704  uint32_t t = (uint32_t)(in_end - ii);
705 
706  if (op == out && t <= 238)
707  *op++ = LZO_BYTE(17 + t);
708  else if (t <= 3)
709  op[-2] |= LZO_BYTE(t);
710  else if (t <= 18)
711  *op++ = LZO_BYTE(t - 3);
712  else {
713  uint32_t tt = t - 18;
714 
715  *op++ = 0;
716  while (tt > 255) {
717  tt -= 255;
718  *op++ = 0;
719  }
720 
721  if (tt <= 0)
722  return STATUS_INTERNAL_ERROR;
723 
724  *op++ = LZO_BYTE(tt);
725  }
726 
727  do {
728  *op++ = *ii++;
729  } while (--t > 0);
730  }
731 
732  *out_len = (uint32_t)(op - out);
733 
734  return STATUS_SUCCESS;
735 }
#define M4_MAX_OFFSET
Definition: compress.c:64
#define M3_MARKER
Definition: compress.c:70
#define LZO_CHECK_MPOS_NON_DET(m_pos, m_off, in, ip, max_offset)
Definition: compress.c:82
GLdouble GLdouble t
Definition: gl.h:2047
#define M2_MAX_OFFSET
Definition: compress.c:62
GLuint GLuint end
Definition: gl.h:1545
#define LZO_BYTE(x)
Definition: compress.c:87
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
int ip[4]
Definition: rtl.c:1176
struct match match
Definition: match.c:33
#define DVAL_FIRST(dv, p)
Definition: compress.c:76
Definition: dhcpd.h:61
static FILE * out
Definition: regtests2xml.c:44
BYTE uint8_t
Definition: msvideo1.c:66
#define DVAL_NEXT(dv, p)
Definition: compress.c:74
#define UPDATE_I(dict, cycle, index, p)
Definition: compress.c:80
#define M3_MAX_OFFSET
Definition: compress.c:63
GLuint in
Definition: glext.h:9616
#define DINDEX(dv, p)
Definition: compress.c:78
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
UINT32 uint32_t
Definition: types.h:75
UINT op
Definition: effect.c:223
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define M4_MARKER
Definition: compress.c:71
#define UPDATE_D(dict, cycle, dv, p)
Definition: compress.c:79

Referenced by lzo1x_1_compress().

◆ lzo_len()

static int lzo_len ( lzo_stream stream,
int  byte,
int  mask 
)
static

Definition at line 117 of file compress.c.

117  {
118  int len = byte & mask;
119 
120  if (len == 0) {
121  while (!(byte = lzo_nextbyte(stream))) {
122  if (stream->error) return 0;
123 
124  len += 255;
125  }
126 
127  len += mask + byte;
128  }
129 
130  return len;
131 }
GLenum GLint GLuint mask
Definition: glext.h:6028
static uint8_t lzo_nextbyte(lzo_stream *stream)
Definition: compress.c:103
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722
#define byte(x, n)
Definition: tomcrypt.h:118

Referenced by do_lzo_decompress().

◆ lzo_max_outlen()

static __inline uint32_t lzo_max_outlen ( uint32_t  inlen)
static

Definition at line 766 of file compress.c.

766  {
767  return inlen + (inlen / 16) + 64 + 3; // formula comes from LZO.FAQ
768 }

Referenced by lzo_write_compressed_bit().

◆ lzo_nextbyte()

static uint8_t lzo_nextbyte ( lzo_stream stream)
static

Definition at line 103 of file compress.c.

103  {
104  uint8_t c;
105 
106  if (stream->inpos >= stream->inlen) {
107  stream->error = true;
108  return 0;
109  }
110 
111  c = stream->in[stream->inpos];
112  stream->inpos++;
113 
114  return c;
115 }
const GLubyte * c
Definition: glext.h:8905
Definition: parse.h:22
BYTE uint8_t
Definition: msvideo1.c:66
#define c
Definition: ke_i.h:80

Referenced by do_lzo_decompress(), and lzo_len().

◆ lzo_write_compressed_bit()

static NTSTATUS lzo_write_compressed_bit ( fcb fcb,
uint64_t  start_data,
uint64_t  end_data,
void data,
bool compressed,
PIRP  Irp,
LIST_ENTRY rollback 
)
static

Definition at line 770 of file compress.c.

770  {
774  ULONG comp_data_len, num_pages, i;
775  uint8_t* comp_data;
776  bool skip_compression = false;
779  LIST_ENTRY* le;
780  chunk* c;
781 
782  num_pages = (ULONG)((sector_align(end_data - start_data, LZO_PAGE_SIZE)) / LZO_PAGE_SIZE);
783 
784  // Four-byte overall header
785  // Another four-byte header page
786  // Each page has a maximum size of lzo_max_outlen(LZO_PAGE_SIZE)
787  // Plus another four bytes for possible padding
788  comp_data_len = sizeof(uint32_t) + ((lzo_max_outlen(LZO_PAGE_SIZE) + (2 * sizeof(uint32_t))) * num_pages);
789 
790  comp_data = ExAllocatePoolWithTag(PagedPool, comp_data_len, ALLOC_TAG);
791  if (!comp_data) {
792  ERR("out of memory\n");
794  }
795 
797  if (!stream.wrkmem) {
798  ERR("out of memory\n");
799  ExFreePool(comp_data);
801  }
802 
804  if (!NT_SUCCESS(Status)) {
805  ERR("excise_extents returned %08x\n", Status);
806  ExFreePool(comp_data);
807  ExFreePool(stream.wrkmem);
808  return Status;
809  }
810 
811  out_size = (uint32_t*)comp_data;
812  *out_size = sizeof(uint32_t);
813 
814  stream.in = data;
815  stream.out = comp_data + (2 * sizeof(uint32_t));
816 
817  for (i = 0; i < num_pages; i++) {
818  uint32_t* pagelen = (uint32_t*)(stream.out - sizeof(uint32_t));
819 
820  stream.inlen = (uint32_t)min(LZO_PAGE_SIZE, end_data - start_data - (i * LZO_PAGE_SIZE));
821 
823  if (!NT_SUCCESS(Status)) {
824  ERR("lzo1x_1_compress returned %08x\n", Status);
825  skip_compression = true;
826  break;
827  }
828 
829  *pagelen = stream.outlen;
830  *out_size += stream.outlen + sizeof(uint32_t);
831 
832  stream.in += LZO_PAGE_SIZE;
833  stream.out += stream.outlen + sizeof(uint32_t);
834 
835  if (LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE) < sizeof(uint32_t)) {
839  }
840  }
841 
842  ExFreePool(stream.wrkmem);
843 
844  if (skip_compression || *out_size >= end_data - start_data - fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent
845  ExFreePool(comp_data);
846 
847  comp_length = end_data - start_data;
848  comp_data = data;
850 
851  *compressed = false;
852  } else {
854  comp_length = sector_align(*out_size, fcb->Vcb->superblock.sector_size);
855 
856  RtlZeroMemory(comp_data + *out_size, (ULONG)(comp_length - *out_size));
857 
858  *compressed = true;
859  }
860 
861  ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true);
862 
863  le = fcb->Vcb->chunks.Flink;
864  while (le != &fcb->Vcb->chunks) {
866 
867  if (!c->readonly && !c->reloc) {
869 
870  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
871  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
872  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
873 
875  ExFreePool(comp_data);
876 
877  return STATUS_SUCCESS;
878  }
879  }
880 
882  }
883 
884  le = le->Flink;
885  }
886 
887  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
888 
889  ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true);
890 
891  Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false);
892 
893  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
894 
895  if (!NT_SUCCESS(Status)) {
896  ERR("alloc_chunk returned %08x\n", Status);
897 
899  ExFreePool(comp_data);
900 
901  return Status;
902  }
903 
904  if (c) {
906 
907  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
908  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
910  ExFreePool(comp_data);
911 
912  return STATUS_SUCCESS;
913  }
914  }
915 
917  }
918 
919  WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length);
920 
922  ExFreePool(comp_data);
923 
924  return STATUS_DISK_FULL;
925 }
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static NTSTATUS lzo1x_1_compress(lzo_stream *stream)
Definition: compress.c:737
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:61
_In_ PIRP Irp
Definition: csq.h:116
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
release_chunk_lock(c, Vcb)
#define BTRFS_COMPRESSION_LZO
Definition: btrfs.h:63
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1314
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:91
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static DWORD comp_length(DWORD len, DWORD flags, WCHAR *comp)
Definition: url.c:345
const GLubyte * c
Definition: glext.h:8905
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define LZO1X_MEM_COMPRESS
Definition: compress.c:59
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:2368
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
static __inline uint32_t lzo_max_outlen(uint32_t inlen)
Definition: compress.c:766
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1314
Definition: typedefs.h:117
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
UINT64 uint64_t
Definition: types.h:77
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1104
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1314
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define LZO_PAGE_SIZE
Definition: compress.c:46
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size)
Definition: write.c:361
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by write_compressed_bit().

◆ write_compressed_bit()

NTSTATUS write_compressed_bit ( fcb fcb,
uint64_t  start_data,
uint64_t  end_data,
void data,
bool compressed,
PIRP  Irp,
LIST_ENTRY rollback 
)

Definition at line 1093 of file compress.c.

1093  {
1094  uint8_t type;
1095 
1096  if (fcb->Vcb->options.compress_type != 0 && fcb->prop_compression == PropCompression_None)
1097  type = fcb->Vcb->options.compress_type;
1098  else {
1099  if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD) && fcb->prop_compression == PropCompression_ZSTD)
1103  else if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO) && fcb->prop_compression == PropCompression_LZO)
1105  else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO && fcb->prop_compression != PropCompression_Zlib)
1107  else
1109  }
1110 
1111  if (type == BTRFS_COMPRESSION_ZSTD) {
1112  fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD;
1113  return zstd_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback);
1114  } else if (type == BTRFS_COMPRESSION_LZO) {
1115  fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO;
1116  return lzo_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback);
1117  } else
1118  return zlib_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback);
1119 }
_In_ PIRP Irp
Definition: csq.h:116
enum prop_compression_type prop_compression
Definition: btrfs_drv.h:303
static NTSTATUS zstd_write_compressed_bit(fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
Definition: compress.c:927
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static NTSTATUS zlib_write_compressed_bit(fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
Definition: compress.c:382
#define BTRFS_COMPRESSION_LZO
Definition: btrfs.h:63
#define BTRFS_COMPRESSION_ZSTD
Definition: btrfs.h:64
#define BTRFS_COMPRESSION_ZLIB
Definition: btrfs.h:62
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1314
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO
Definition: btrfs.h:109
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static NTSTATUS lzo_write_compressed_bit(fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, bool *compressed, PIRP Irp, LIST_ENTRY *rollback)
Definition: compress.c:770
BYTE uint8_t
Definition: msvideo1.c:66
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1314
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD
Definition: btrfs.h:110
struct _device_extension * Vcb
Definition: btrfs_drv.h:283

Referenced by write_compressed().

◆ zlib_alloc()

static void* zlib_alloc ( void opaque,
unsigned int  items,
unsigned int  size 
)
static

Definition at line 324 of file compress.c.

324  {
325  UNUSED(opaque);
326 
328 }
#define UNUSED(x)
Definition: btrfs_drv.h:86
GLsizeiptr size
Definition: glext.h:5919
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ALLOC_TAG_ZLIB
Definition: btrfs_drv.h:92
static TCHAR * items[]
Definition: page1.c:45

Referenced by zlib_decompress(), and zlib_write_compressed_bit().

◆ zlib_decompress()

NTSTATUS zlib_decompress ( uint8_t inbuf,
uint32_t  inlen,
uint8_t outbuf,
uint32_t  outlen 
)

Definition at line 336 of file compress.c.

336  {
337  z_stream c_stream;
338  int ret;
339 
340  c_stream.zalloc = zlib_alloc;
341  c_stream.zfree = zlib_free;
342  c_stream.opaque = (voidpf)0;
343 
344  ret = inflateInit(&c_stream);
345 
346  if (ret != Z_OK) {
347  ERR("inflateInit returned %08x\n", ret);
348  return STATUS_INTERNAL_ERROR;
349  }
350 
351  c_stream.next_in = inbuf;
352  c_stream.avail_in = inlen;
353 
354  c_stream.next_out = outbuf;
355  c_stream.avail_out = outlen;
356 
357  do {
358  ret = inflate(&c_stream, Z_NO_FLUSH);
359 
360  if (ret != Z_OK && ret != Z_STREAM_END) {
361  ERR("inflate returned %08x\n", ret);
362  inflateEnd(&c_stream);
363  return STATUS_INTERNAL_ERROR;
364  }
365 
366  if (c_stream.avail_out == 0)
367  break;
368  } while (ret != Z_STREAM_END);
369 
370  ret = inflateEnd(&c_stream);
371 
372  if (ret != Z_OK) {
373  ERR("inflateEnd returned %08x\n", ret);
374  return STATUS_INTERNAL_ERROR;
375  }
376 
377  // FIXME - if we're short, should we zero the end of outbuf so we don't leak information into userspace?
378 
379  return STATUS_SUCCESS;
380 }
static void zlib_free(void *opaque, void *ptr)
Definition: compress.c:330
int ZEXPORT inflateEnd(z_streamp strm)
Definition: inflate.c:1277
uInt avail_in
Definition: zlib.h:88
static int inbuf
Definition: adnsresfilter.c:73
static void * zlib_alloc(void *opaque, unsigned int items, unsigned int size)
Definition: compress.c:324
#define Z_STREAM_END
Definition: zlib.h:178
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
voidpf opaque
Definition: zlib.h:100
free_func zfree
Definition: zlib.h:99
#define Z_OK
Definition: zlib.h:177
alloc_func zalloc
Definition: zlib.h:98
#define Z_NO_FLUSH
Definition: zlib.h:168
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: inflate.c:622
int ret
#define inflateInit(strm)
Definition: zlib.h:1795
#define ERR(fmt,...)
Definition: debug.h:109
Byte FAR * voidpf
Definition: zconf.h:413
uInt avail_out
Definition: zlib.h:92
z_const Bytef * next_in
Definition: zlib.h:87
Bytef * next_out
Definition: zlib.h:91
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by flush_extents(), and read_file().

◆ zlib_free()

static void zlib_free ( void opaque,
void ptr 
)
static

Definition at line 330 of file compress.c.

330  {
331  UNUSED(opaque);
332 
333  ExFreePool(ptr);
334 }
static PVOID ptr
Definition: dispmode.c:27
#define UNUSED(x)
Definition: btrfs_drv.h:86
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by zlib_decompress(), and zlib_write_compressed_bit().

◆ zlib_write_compressed_bit()

static NTSTATUS zlib_write_compressed_bit ( fcb fcb,
uint64_t  start_data,
uint64_t  end_data,
void data,
bool compressed,
PIRP  Irp,
LIST_ENTRY rollback 
)
static

Definition at line 382 of file compress.c.

382  {
386  uint8_t* comp_data;
387  uint32_t out_left;
388  LIST_ENTRY* le;
389  chunk* c;
390  z_stream c_stream;
391  int ret;
392 
393  comp_data = ExAllocatePoolWithTag(PagedPool, (uint32_t)(end_data - start_data), ALLOC_TAG);
394  if (!comp_data) {
395  ERR("out of memory\n");
397  }
398 
400  if (!NT_SUCCESS(Status)) {
401  ERR("excise_extents returned %08x\n", Status);
402  ExFreePool(comp_data);
403  return Status;
404  }
405 
406  c_stream.zalloc = zlib_alloc;
407  c_stream.zfree = zlib_free;
408  c_stream.opaque = (voidpf)0;
409 
410  ret = deflateInit(&c_stream, fcb->Vcb->options.zlib_level);
411 
412  if (ret != Z_OK) {
413  ERR("deflateInit returned %08x\n", ret);
414  ExFreePool(comp_data);
415  return STATUS_INTERNAL_ERROR;
416  }
417 
418  c_stream.avail_in = (uint32_t)(end_data - start_data);
419  c_stream.next_in = data;
420  c_stream.avail_out = (uint32_t)(end_data - start_data);
421  c_stream.next_out = comp_data;
422 
423  do {
424  ret = deflate(&c_stream, Z_FINISH);
425 
426  if (ret == Z_STREAM_ERROR) {
427  ERR("deflate returned %x\n", ret);
428  ExFreePool(comp_data);
429  return STATUS_INTERNAL_ERROR;
430  }
431  } while (c_stream.avail_in > 0 && c_stream.avail_out > 0);
432 
433  out_left = c_stream.avail_out;
434 
435  ret = deflateEnd(&c_stream);
436 
437  if (ret != Z_OK) {
438  ERR("deflateEnd returned %08x\n", ret);
439  ExFreePool(comp_data);
440  return STATUS_INTERNAL_ERROR;
441  }
442 
443  if (out_left < fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent
444  ExFreePool(comp_data);
445 
446  comp_length = (uint32_t)(end_data - start_data);
447  comp_data = data;
449 
450  *compressed = false;
451  } else {
452  uint32_t cl;
453 
455  cl = (uint32_t)(end_data - start_data - out_left);
456  comp_length = (uint32_t)sector_align(cl, fcb->Vcb->superblock.sector_size);
457 
458  RtlZeroMemory(comp_data + cl, comp_length - cl);
459 
460  *compressed = true;
461  }
462 
463  ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true);
464 
465  le = fcb->Vcb->chunks.Flink;
466  while (le != &fcb->Vcb->chunks) {
468 
469  if (!c->readonly && !c->reloc) {
471 
472  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
473  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
474  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
475 
477  ExFreePool(comp_data);
478 
479  return STATUS_SUCCESS;
480  }
481  }
482 
484  }
485 
486  le = le->Flink;
487  }
488 
489  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
490 
491  ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true);
492 
493  Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false);
494 
495  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
496 
497  if (!NT_SUCCESS(Status)) {
498  ERR("alloc_chunk returned %08x\n", Status);
499 
501  ExFreePool(comp_data);
502 
503  return Status;
504  }
505 
506  if (c) {
508 
509  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
510  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
512  ExFreePool(comp_data);
513 
514  return STATUS_SUCCESS;
515  }
516  }
517 
519  }
520 
521  WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length);
522 
524  ExFreePool(comp_data);
525 
526  return STATUS_DISK_FULL;
527 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:61
static void zlib_free(void *opaque, void *ptr)
Definition: compress.c:330
_In_ PIRP Irp
Definition: csq.h:116
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
uInt avail_in
Definition: zlib.h:88
release_chunk_lock(c, Vcb)
static void * zlib_alloc(void *opaque, unsigned int items, unsigned int size)
Definition: compress.c:324
#define Z_STREAM_ERROR
Definition: zlib.h:181
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:1079
#define deflateInit(strm, level)
Definition: zlib.h:1793
#define BTRFS_COMPRESSION_ZLIB
Definition: btrfs.h:62
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1314
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define ALLOC_TAG
Definition: btrfs_drv.h:91
voidpf opaque
Definition: zlib.h:100
free_func zfree
Definition: zlib.h:99
#define Z_OK
Definition: zlib.h:177
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static DWORD comp_length(DWORD len, DWORD flags, WCHAR *comp)
Definition: url.c:345
#define Vcb
Definition: cdprocs.h:1425
const GLubyte * c
Definition: glext.h:8905
alloc_func zalloc
Definition: zlib.h:98
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
int ret
NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:2368
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1314
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.c:766
Definition: typedefs.h:117
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
Byte FAR * voidpf
Definition: zconf.h:413
#define Z_FINISH
Definition: zlib.h:172
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1104
Definition: list.h:27
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1314
uInt avail_out
Definition: zlib.h:92
z_const Bytef * next_in
Definition: zlib.h:87
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define c
Definition: ke_i.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
Bytef * next_out
Definition: zlib.h:91
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size)
Definition: write.c:361
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by write_compressed_bit().

◆ zstd_decompress()

NTSTATUS zstd_decompress ( uint8_t inbuf,
uint32_t  inlen,
uint8_t outbuf,
uint32_t  outlen 
)

Definition at line 1133 of file compress.c.

1133  {
1134  NTSTATUS Status;
1136  size_t init_res, read;
1139 
1141 
1142  if (!stream) {
1143  ERR("ZSTD_createDStream failed.\n");
1144  return STATUS_INTERNAL_ERROR;
1145  }
1146 
1147  init_res = ZSTD_initDStream(stream);
1148 
1149  if (ZSTD_isError(init_res)) {
1150  ERR("ZSTD_initDStream failed: %s\n", ZSTD_getErrorName(init_res));
1152  goto end;
1153  }
1154 
1155  input.src = inbuf;
1156  input.size = inlen;
1157  input.pos = 0;
1158 
1159  output.dst = outbuf;
1160  output.size = outlen;
1161  output.pos = 0;
1162 
1164 
1165  if (ZSTD_isError(read)) {
1166  ERR("ZSTD_decompressStream failed: %s\n", ZSTD_getErrorName(read));
1168  goto end;
1169  }
1170 
1172 
1173 end:
1175 
1176  return Status;
1177 }
ZSTDLIB_API const char * ZSTD_getErrorName(size_t code)
Definition: zstd_common.c:39
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
LONG NTSTATUS
Definition: precomp.h:26
static int inbuf
Definition: adnsresfilter.c:73
GLuint GLuint end
Definition: gl.h:1545
ZSTD_customMem zstd_mem
Definition: compress.c:98
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream *zds)
ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
ZSTD_DStream * ZSTD_createDStream_advanced(ZSTD_customMem customMem)
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
#define ZSTD_isError
GLenum GLenum GLenum input
Definition: glext.h:9031
return STATUS_SUCCESS
Definition: btrfs.c:2938
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream *zds)

Referenced by flush_extents(), and read_file().

◆ zstd_free()

static void zstd_free ( void opaque,
void address 
)
static

Definition at line 1127 of file compress.c.

1127  {
1128  UNUSED(opaque);
1129 
1131 }
#define UNUSED(x)
Definition: btrfs_drv.h:86
GLuint address
Definition: glext.h:9393
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ zstd_malloc()

static void * zstd_malloc ( void opaque,
size_t  size 
)
static

Definition at line 1121 of file compress.c.

1121  {
1122  UNUSED(opaque);
1123 
1125 }
#define ZSTD_ALLOC_TAG
Definition: compress.c:89
#define UNUSED(x)
Definition: btrfs_drv.h:86
GLsizeiptr size
Definition: glext.h:5919
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350

◆ zstd_write_compressed_bit()

static NTSTATUS zstd_write_compressed_bit ( fcb fcb,
uint64_t  start_data,
uint64_t  end_data,
void data,
bool compressed,
PIRP  Irp,
LIST_ENTRY rollback 
)
static

Definition at line 927 of file compress.c.

927  {
931  uint8_t* comp_data;
932  uint32_t out_left;
933  LIST_ENTRY* le;
934  chunk* c;
936  size_t init_res, written;
939  ZSTD_parameters params;
940 
941  comp_data = ExAllocatePoolWithTag(PagedPool, (uint32_t)(end_data - start_data), ALLOC_TAG);
942  if (!comp_data) {
943  ERR("out of memory\n");
945  }
946 
948  if (!NT_SUCCESS(Status)) {
949  ERR("excise_extents returned %08x\n", Status);
950  ExFreePool(comp_data);
951  return Status;
952  }
953 
955 
956  if (!stream) {
957  ERR("ZSTD_createCStream failed.\n");
958  ExFreePool(comp_data);
959  return STATUS_INTERNAL_ERROR;
960  }
961 
962  params = ZSTD_getParams(fcb->Vcb->options.zstd_level, (uint32_t)(end_data - start_data), 0);
963 
964  if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
965  params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
966 
967  init_res = ZSTD_initCStream_advanced(stream, NULL, 0, params, (uint32_t)(end_data - start_data));
968 
969  if (ZSTD_isError(init_res)) {
970  ERR("ZSTD_initCStream_advanced failed: %s\n", ZSTD_getErrorName(init_res));
972  ExFreePool(comp_data);
973  return STATUS_INTERNAL_ERROR;
974  }
975 
976  input.src = data;
977  input.size = (uint32_t)(end_data - start_data);
978  input.pos = 0;
979 
980  output.dst = comp_data;
981  output.size = (uint32_t)(end_data - start_data);
982  output.pos = 0;
983 
984  while (input.pos < input.size && output.pos < output.size) {
985  written = ZSTD_compressStream(stream, &output, &input);
986 
987  if (ZSTD_isError(written)) {
988  ERR("ZSTD_compressStream failed: %s\n", ZSTD_getErrorName(written));
990  ExFreePool(comp_data);
991  return STATUS_INTERNAL_ERROR;
992  }
993  }
994 
995  written = ZSTD_endStream(stream, &output);
996  if (ZSTD_isError(written)) {
997  ERR("ZSTD_endStream failed: %s\n", ZSTD_getErrorName(written));
999  ExFreePool(comp_data);
1000  return STATUS_INTERNAL_ERROR;
1001  }
1002 
1004 
1005  out_left = output.size - output.pos;
1006 
1007  if (out_left < fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent
1008  ExFreePool(comp_data);
1009 
1010  comp_length = (uint32_t)(end_data - start_data);
1011  comp_data = data;
1013 
1014  *compressed = false;
1015  } else {
1016  uint32_t cl;
1017 
1019  cl = (uint32_t)(end_data - start_data - out_left);
1020  comp_length = (uint32_t)sector_align(cl, fcb->Vcb->superblock.sector_size);
1021 
1022  RtlZeroMemory(comp_data + cl, comp_length - cl);
1023 
1024  *compressed = true;
1025  }
1026 
1027  ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true);
1028 
1029  le = fcb->Vcb->chunks.Flink;
1030  while (le != &fcb->Vcb->chunks) {
1032 
1033  if (!c->readonly && !c->reloc) {
1035 
1036  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
1037  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
1038  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
1039 
1041  ExFreePool(comp_data);
1042 
1043  return STATUS_SUCCESS;
1044  }
1045  }
1046 
1048  }
1049 
1050  le = le->Flink;
1051  }
1052 
1053  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
1054 
1055  ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true);
1056 
1057  Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false);
1058 
1059  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
1060 
1061  if (!NT_SUCCESS(Status)) {
1062  ERR("alloc_chunk returned %08x\n", Status);
1063 
1065  ExFreePool(comp_data);
1066 
1067  return Status;
1068  }
1069 
1070  if (c) {
1072 
1073  if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) {
1074  if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) {
1076  ExFreePool(comp_data);
1077 
1078  return STATUS_SUCCESS;
1079  }
1080  }
1081 
1083  }
1084 
1085  WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length);
1086 
1088  ExFreePool(comp_data);
1089 
1090  return STATUS_DISK_FULL;
1091 }
ZSTDLIB_API const char * ZSTD_getErrorName(size_t code)
Definition: zstd_common.c:39
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:61
_In_ PIRP Irp
Definition: csq.h:116
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
release_chunk_lock(c, Vcb)
#define BTRFS_COMPRESSION_ZSTD
Definition: btrfs.h:64
ZSTD_customMem zstd_mem
Definition: compress.c:98
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1314
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define ALLOC_TAG
Definition: btrfs_drv.h:91
GLenum const GLfloat * params
Definition: glext.h:5645
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream *zcs)
static DWORD comp_length(DWORD len, DWORD flags, WCHAR *comp)
Definition: url.c:345
#define Vcb
Definition: cdprocs.h:1425
const GLubyte * c
Definition: glext.h:8905
size_t ZSTD_initCStream_advanced(ZSTD_CStream *zcs, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ZSTD_BTRFS_MAX_WINDOWLOG
Definition: compress.c:92
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:2368
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1314
Definition: typedefs.h:117
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
#define ZSTD_isError
GLenum GLenum GLenum input
Definition: glext.h:9031
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1104
Definition: list.h:27
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1314
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define c
Definition: ke_i.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ZSTD_CStream * ZSTD_createCStream_advanced(ZSTD_customMem customMem)
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size)
Definition: write.c:361
#define uint32_t
Definition: nsiface.idl:61
return STATUS_SUCCESS
Definition: btrfs.c:2938
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)

Referenced by write_compressed_bit().

Variable Documentation

◆ zstd_mem

ZSTD_customMem zstd_mem = { .customAlloc = zstd_malloc, .customFree = zstd_free, .opaque = NULL }

Definition at line 98 of file compress.c.

Referenced by zstd_decompress(), and zstd_write_compressed_bit().