ReactOS 0.4.16-dev-329-g9223134
compress.c
Go to the documentation of this file.
1/* Copyright (c) Mark Harmstone 2016-17
2 * Copyright (c) Reimar Doeffinger 2006
3 * Copyright (c) Markus Oberhumer 1996
4 *
5 * This file is part of WinBtrfs.
6 *
7 * WinBtrfs is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public Licence as published by
9 * the Free Software Foundation, either version 3 of the Licence, or
10 * (at your option) any later version.
11 *
12 * WinBtrfs is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public Licence for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public Licence
18 * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
19
20// Portions of the LZO decompression code here were cribbed from code in
21// libavcodec, also under the LGPL. Thank you, Reimar Doeffinger.
22
23// The LZO compression code comes from v0.22 of lzo, written way back in
24// 1996, and available here:
25// https://www.ibiblio.org/pub/historic-linux/ftp-archives/sunsite.unc.edu/Sep-29-1996/libs/lzo-0.22.tar.gz
26// Modern versions of lzo are licensed under the GPL, but the very oldest
27// versions are under the LGPL and hence okay to use here.
28
29#include "btrfs_drv.h"
30
31#define Z_SOLO
32#define ZLIB_INTERNAL
33
34#ifndef __REACTOS__
35#include "zlib/zlib.h"
36#include "zlib/inftrees.h"
37#include "zlib/inflate.h"
38#else
39#include <zlib.h>
40#endif // __REACTOS__
41
42#define ZSTD_STATIC_LINKING_ONLY
43
44#include "zstd/zstd.h"
45
46#define LZO_PAGE_SIZE 4096
47
48typedef struct {
55 bool error;
56 void* wrkmem;
58
59#define LZO1X_MEM_COMPRESS ((uint32_t) (16384L * sizeof(uint8_t*)))
60
61#define M1_MAX_OFFSET 0x0400
62#define M2_MAX_OFFSET 0x0800
63#define M3_MAX_OFFSET 0x4000
64#define M4_MAX_OFFSET 0xbfff
65
66#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
67
68#define M1_MARKER 0
69#define M2_MARKER 64
70#define M3_MARKER 32
71#define M4_MARKER 16
72
73#define _DV2(p, shift1, shift2) (((( (uint32_t)(p[2]) << shift1) ^ p[1]) << shift2) ^ p[0])
74#define DVAL_NEXT(dv, p) dv ^= p[-1]; dv = (((dv) >> 5) ^ ((uint32_t)(p[2]) << (2*5)))
75#define _DV(p, shift) _DV2(p, shift, shift)
76#define DVAL_FIRST(dv, p) dv = _DV((p), 5)
77#define _DINDEX(dv, p) ((40799u * (dv)) >> 5)
78#define DINDEX(dv, p) (((_DINDEX(dv, p)) & 0x3fff) << 0)
79#define UPDATE_D(dict, cycle, dv, p) dict[DINDEX(dv, p)] = (p)
80#define UPDATE_I(dict, cycle, index, p) dict[index] = (p)
81
82#define LZO_CHECK_MPOS_NON_DET(m_pos, m_off, in, ip, max_offset) \
83 ((void*) m_pos < (void*) in || \
84 (m_off = (uint8_t*) ip - (uint8_t*) m_pos) <= 0 || \
85 m_off > max_offset)
86
87#define LZO_BYTE(x) ((unsigned char) (x))
88
89#define ZSTD_ALLOC_TAG 0x6474737a // "zstd"
90
91// needs to be the same as Linux (fs/btrfs/zstd.c)
92#define ZSTD_BTRFS_MAX_WINDOWLOG 17
93
94static void* zstd_malloc(void* opaque, size_t size);
95static void zstd_free(void* opaque, void* address);
96
97#ifndef __REACTOS__
98ZSTD_customMem zstd_mem = { .customAlloc = zstd_malloc, .customFree = zstd_free, .opaque = NULL };
99#else
100ZSTD_customMem zstd_mem = { zstd_malloc, zstd_free, NULL };
101#endif
102
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}
116
117static int lzo_len(lzo_stream* stream, int byte, int mask) {
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}
132
133static void lzo_copy(lzo_stream* stream, int len) {
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}
151
152static void lzo_copyback(lzo_stream* stream, uint32_t back, int len) {
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}
169
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)
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}
277
278NTSTATUS lzo_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t inpageoff) {
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 > %x\n", partlen, inoff, inlen);
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 %08lx\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}
323
324static void* zlib_alloc(void* opaque, unsigned int items, unsigned int size) {
325 UNUSED(opaque);
326
328}
329
330static void zlib_free(void* opaque, void* ptr) {
331 UNUSED(opaque);
332
334}
335
336NTSTATUS zlib_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int level, unsigned int* space_left) {
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 = deflateInit(&c_stream, level);
345
346 if (ret != Z_OK) {
347 ERR("deflateInit returned %i\n", ret);
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 = deflate(&c_stream, Z_FINISH);
359
360 if (ret != Z_OK && ret != Z_STREAM_END) {
361 ERR("deflate returned %i\n", ret);
362 deflateEnd(&c_stream);
364 }
365
366 if (c_stream.avail_in == 0 || c_stream.avail_out == 0)
367 break;
368 } while (ret != Z_STREAM_END);
369
370 deflateEnd(&c_stream);
371
372 *space_left = c_stream.avail_in > 0 ? 0 : c_stream.avail_out;
373
374 return STATUS_SUCCESS;
375}
376
378 z_stream c_stream;
379 int ret;
380
381 c_stream.zalloc = zlib_alloc;
382 c_stream.zfree = zlib_free;
383 c_stream.opaque = (voidpf)0;
384
385 ret = inflateInit(&c_stream);
386
387 if (ret != Z_OK) {
388 ERR("inflateInit returned %i\n", ret);
390 }
391
392 c_stream.next_in = inbuf;
393 c_stream.avail_in = inlen;
394
395 c_stream.next_out = outbuf;
396 c_stream.avail_out = outlen;
397
398 do {
399 ret = inflate(&c_stream, Z_NO_FLUSH);
400
401 if (ret != Z_OK && ret != Z_STREAM_END) {
402 ERR("inflate returned %i\n", ret);
403 inflateEnd(&c_stream);
405 }
406
407 if (c_stream.avail_out == 0)
408 break;
409 } while (ret != Z_STREAM_END);
410
411 ret = inflateEnd(&c_stream);
412
413 if (ret != Z_OK) {
414 ERR("inflateEnd returned %i\n", ret);
416 }
417
418 // FIXME - if we're short, should we zero the end of outbuf so we don't leak information into userspace?
419
420 return STATUS_SUCCESS;
421}
422
423static NTSTATUS lzo_do_compress(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t* out_len, void* wrkmem) {
424 const uint8_t* ip;
425 uint32_t dv;
426 uint8_t* op;
427 const uint8_t* in_end = in + in_len;
428 const uint8_t* ip_end = in + in_len - 9 - 4;
429 const uint8_t* ii;
430 const uint8_t** dict = (const uint8_t**)wrkmem;
431
432 op = out;
433 ip = in;
434 ii = ip;
435
436 DVAL_FIRST(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
437 DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
438 DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
439 DVAL_NEXT(dv, ip); UPDATE_D(dict, cycle, dv, ip); ip++;
440
441 while (1) {
442 const uint8_t* m_pos;
443 uint32_t m_len;
444 ptrdiff_t m_off;
445 uint32_t lit, dindex;
446
447 dindex = DINDEX(dv, ip);
448 m_pos = dict[dindex];
449 UPDATE_I(dict, cycle, dindex, ip);
450
451 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]) {
452 lit = (uint32_t)(ip - ii);
453 m_pos += 3;
454 if (m_off <= M2_MAX_OFFSET)
455 goto match;
456
457 if (lit == 3) { /* better compression, but slower */
458 if (op - 2 <= out)
460
461 op[-2] |= LZO_BYTE(3);
462 *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
463 goto code_match;
464 }
465
466 if (*m_pos == ip[3])
467 goto match;
468 }
469
470 /* a literal */
471 ++ip;
472 if (ip >= ip_end)
473 break;
474 DVAL_NEXT(dv, ip);
475 continue;
476
477 /* a match */
478match:
479 /* store current literal run */
480 if (lit > 0) {
481 uint32_t t = lit;
482
483 if (t <= 3) {
484 if (op - 2 <= out)
486
487 op[-2] |= LZO_BYTE(t);
488 } else if (t <= 18)
489 *op++ = LZO_BYTE(t - 3);
490 else {
491 uint32_t tt = t - 18;
492
493 *op++ = 0;
494 while (tt > 255) {
495 tt -= 255;
496 *op++ = 0;
497 }
498
499 if (tt <= 0)
501
502 *op++ = LZO_BYTE(tt);
503 }
504
505 do {
506 *op++ = *ii++;
507 } while (--t > 0);
508 }
509
510
511 /* code the match */
512code_match:
513 if (ii != ip)
515
516 ip += 3;
517 if (*m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++ ||
518 *m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++) {
519 --ip;
520 m_len = (uint32_t)(ip - ii);
521
522 if (m_len < 3 || m_len > 8)
524
525 if (m_off <= M2_MAX_OFFSET) {
526 m_off -= 1;
527 *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
528 *op++ = LZO_BYTE(m_off >> 3);
529 } else if (m_off <= M3_MAX_OFFSET) {
530 m_off -= 1;
531 *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
532 goto m3_m4_offset;
533 } else {
534 m_off -= 0x4000;
535
536 if (m_off <= 0 || m_off > 0x7fff)
538
539 *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
540 goto m3_m4_offset;
541 }
542 } else {
543 const uint8_t* end;
544 end = in_end;
545 while (ip < end && *m_pos == *ip)
546 m_pos++, ip++;
547 m_len = (uint32_t)(ip - ii);
548
549 if (m_len < 3)
551
552 if (m_off <= M3_MAX_OFFSET) {
553 m_off -= 1;
554 if (m_len <= 33)
555 *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
556 else {
557 m_len -= 33;
558 *op++ = M3_MARKER | 0;
559 goto m3_m4_len;
560 }
561 } else {
562 m_off -= 0x4000;
563
564 if (m_off <= 0 || m_off > 0x7fff)
566
567 if (m_len <= 9)
568 *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
569 else {
570 m_len -= 9;
571 *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
572m3_m4_len:
573 while (m_len > 255) {
574 m_len -= 255;
575 *op++ = 0;
576 }
577
578 if (m_len <= 0)
580
581 *op++ = LZO_BYTE(m_len);
582 }
583 }
584
585m3_m4_offset:
586 *op++ = LZO_BYTE((m_off & 63) << 2);
587 *op++ = LZO_BYTE(m_off >> 6);
588 }
589
590 ii = ip;
591 if (ip >= ip_end)
592 break;
593 DVAL_FIRST(dv, ip);
594 }
595
596 /* store final literal run */
597 if (in_end - ii > 0) {
598 uint32_t t = (uint32_t)(in_end - ii);
599
600 if (op == out && t <= 238)
601 *op++ = LZO_BYTE(17 + t);
602 else if (t <= 3)
603 op[-2] |= LZO_BYTE(t);
604 else if (t <= 18)
605 *op++ = LZO_BYTE(t - 3);
606 else {
607 uint32_t tt = t - 18;
608
609 *op++ = 0;
610 while (tt > 255) {
611 tt -= 255;
612 *op++ = 0;
613 }
614
615 if (tt <= 0)
617
618 *op++ = LZO_BYTE(tt);
619 }
620
621 do {
622 *op++ = *ii++;
623 } while (--t > 0);
624 }
625
626 *out_len = (uint32_t)(op - out);
627
628 return STATUS_SUCCESS;
629}
630
632 uint8_t *op = stream->out;
634
635 if (stream->inlen <= 0)
636 stream->outlen = 0;
637 else if (stream->inlen <= 9 + 4) {
638 *op++ = LZO_BYTE(17 + stream->inlen);
639
640 stream->inpos = 0;
641 do {
642 *op++ = stream->in[stream->inpos];
643 stream->inpos++;
644 } while (stream->inlen < stream->inpos);
645 stream->outlen = (uint32_t)(op - stream->out);
646 } else
647 Status = lzo_do_compress(stream->in, stream->inlen, stream->out, &stream->outlen, stream->wrkmem);
648
649 if (Status == STATUS_SUCCESS) {
650 op = stream->out + stream->outlen;
651 *op++ = M4_MARKER | 1;
652 *op++ = 0;
653 *op++ = 0;
654 stream->outlen += 3;
655 }
656
657 return Status;
658}
659
660static __inline uint32_t lzo_max_outlen(uint32_t inlen) {
661 return inlen + (inlen / 16) + 64 + 3; // formula comes from LZO.FAQ
662}
663
664static void* zstd_malloc(void* opaque, size_t size) {
665 UNUSED(opaque);
666
668}
669
670static void zstd_free(void* opaque, void* address) {
671 UNUSED(opaque);
672
674}
675
679 size_t init_res, read;
681 ZSTD_outBuffer output;
682
684
685 if (!stream) {
686 ERR("ZSTD_createDStream failed.\n");
688 }
689
690 init_res = ZSTD_initDStream(stream);
691
692 if (ZSTD_isError(init_res)) {
693 ERR("ZSTD_initDStream failed: %s\n", ZSTD_getErrorName(init_res));
695 goto end;
696 }
697
698 input.src = inbuf;
699 input.size = inlen;
700 input.pos = 0;
701
702 output.dst = outbuf;
703 output.size = outlen;
704 output.pos = 0;
705
706 do {
708
709 if (ZSTD_isError(read)) {
710 ERR("ZSTD_decompressStream failed: %s\n", ZSTD_getErrorName(read));
712 goto end;
713 }
714
715 if (output.pos == output.size)
716 break;
717 } while (read != 0);
718
720
721end:
723
724 return Status;
725}
726
727NTSTATUS lzo_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int* space_left) {
729 unsigned int num_pages;
730 unsigned int comp_data_len;
731 uint8_t* comp_data;
734
735 num_pages = (unsigned int)sector_align(inlen, LZO_PAGE_SIZE) / LZO_PAGE_SIZE;
736
737 // Four-byte overall header
738 // Another four-byte header page
739 // Each page has a maximum size of lzo_max_outlen(LZO_PAGE_SIZE)
740 // Plus another four bytes for possible padding
741 comp_data_len = sizeof(uint32_t) + ((lzo_max_outlen(LZO_PAGE_SIZE) + (2 * sizeof(uint32_t))) * num_pages);
742
743 // FIXME - can we write this so comp_data isn't necessary?
744
745 comp_data = ExAllocatePoolWithTag(PagedPool, comp_data_len, ALLOC_TAG);
746 if (!comp_data) {
747 ERR("out of memory\n");
749 }
750
752 if (!stream.wrkmem) {
753 ERR("out of memory\n");
754 ExFreePool(comp_data);
756 }
757
758 out_size = (uint32_t*)comp_data;
759 *out_size = sizeof(uint32_t);
760
761 stream.in = inbuf;
762 stream.out = comp_data + (2 * sizeof(uint32_t));
763
764 for (unsigned int i = 0; i < num_pages; i++) {
765 uint32_t* pagelen = (uint32_t*)(stream.out - sizeof(uint32_t));
766
767 stream.inlen = (uint32_t)min(LZO_PAGE_SIZE, outlen - (i * LZO_PAGE_SIZE));
768
770 if (!NT_SUCCESS(Status)) {
771 ERR("lzo1x_1_compress returned %08lx\n", Status);
772 ExFreePool(comp_data);
773 return Status;
774 }
775
776 *pagelen = stream.outlen;
777 *out_size += stream.outlen + sizeof(uint32_t);
778
779 stream.in += LZO_PAGE_SIZE;
780 stream.out += stream.outlen + sizeof(uint32_t);
781
782 // new page needs to start at a 32-bit boundary
783 if (LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE) < sizeof(uint32_t)) {
787 }
788 }
789
790 ExFreePool(stream.wrkmem);
791
792 if (*out_size >= outlen)
793 *space_left = 0;
794 else {
795 *space_left = outlen - *out_size;
796
797 RtlCopyMemory(outbuf, comp_data, *out_size);
798 }
799
800 ExFreePool(comp_data);
801
802 return STATUS_SUCCESS;
803}
804
805NTSTATUS zstd_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t level, unsigned int* space_left) {
807 size_t init_res, written;
809 ZSTD_outBuffer output;
810 ZSTD_parameters params;
811
813
814 if (!stream) {
815 ERR("ZSTD_createCStream failed.\n");
817 }
818
819 params = ZSTD_getParams(level, inlen, 0);
820
821 if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
822 params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
823
824 init_res = ZSTD_initCStream_advanced(stream, NULL, 0, params, inlen);
825
826 if (ZSTD_isError(init_res)) {
827 ERR("ZSTD_initCStream_advanced failed: %s\n", ZSTD_getErrorName(init_res));
830 }
831
832 input.src = inbuf;
833 input.size = inlen;
834 input.pos = 0;
835
836 output.dst = outbuf;
837 output.size = outlen;
838 output.pos = 0;
839
840 while (input.pos < input.size && output.pos < output.size) {
841 written = ZSTD_compressStream(stream, &output, &input);
842
843 if (ZSTD_isError(written)) {
844 ERR("ZSTD_compressStream failed: %s\n", ZSTD_getErrorName(written));
847 }
848 }
849
850 written = ZSTD_endStream(stream, &output);
851 if (ZSTD_isError(written)) {
852 ERR("ZSTD_endStream failed: %s\n", ZSTD_getErrorName(written));
855 }
856
858
859 if (input.pos < input.size) // output would be larger than input
860 *space_left = 0;
861 else
862 *space_left = output.size - output.pos;
863
864 return STATUS_SUCCESS;
865}
866
867typedef struct {
870 unsigned int inlen;
871 unsigned int outlen;
873} comp_part;
874
877 uint64_t i;
878 unsigned int num_parts = (unsigned int)sector_align(end_data - start_data, COMPRESSED_EXTENT_SIZE) / COMPRESSED_EXTENT_SIZE;
881 unsigned int buflen = 0;
882 uint8_t* buf;
883 chunk* c = NULL;
884 LIST_ENTRY* le;
885 uint64_t address, extaddr;
886 void* csum = NULL;
887
888 if (fcb->Vcb->options.compress_type != 0 && fcb->prop_compression == PropCompression_None)
889 type = fcb->Vcb->options.compress_type;
890 else {
891 if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD) && fcb->prop_compression == PropCompression_ZSTD)
895 else if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO) && fcb->prop_compression == PropCompression_LZO)
897 else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO && fcb->prop_compression != PropCompression_Zlib)
899 else
901 }
902
904 if (!NT_SUCCESS(Status)) {
905 ERR("excise_extents returned %08lx\n", Status);
906 return Status;
907 }
908
910 if (!parts) {
911 ERR("out of memory\n");
913 }
914
915 for (i = 0; i < num_parts; i++) {
916 if (i == num_parts - 1)
917 parts[i].inlen = ((unsigned int)(end_data - start_data) - ((num_parts - 1) * COMPRESSED_EXTENT_SIZE));
918 else
920
922 parts[i].buf, parts[i].inlen, &parts[i].cj);
923 if (!NT_SUCCESS(Status)) {
924 ERR("add_calc_job_comp returned %08lx\n", Status);
925
926 for (unsigned int j = 0; j < i; j++) {
929 }
930
932 return Status;
933 }
934 }
935
937
938 for (int i = num_parts - 1; i >= 0; i--) {
940
942
943 if (!NT_SUCCESS(parts[i].cj->Status))
944 Status = parts[i].cj->Status;
945 }
946
947 if (!NT_SUCCESS(Status)) {
948 ERR("calc job returned %08lx\n", Status);
949
950 for (unsigned int i = 0; i < num_parts; i++) {
952 }
953
955 return Status;
956 }
957
958 for (unsigned int i = 0; i < num_parts; i++) {
959 if (parts[i].cj->space_left >= fcb->Vcb->superblock.sector_size) {
960 parts[i].compression_type = type;
961 parts[i].outlen = parts[i].inlen - parts[i].cj->space_left;
962
964 fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO;
965 else if (type == BTRFS_COMPRESSION_ZSTD)
966 fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD;
967
968 if ((parts[i].outlen & (fcb->Vcb->superblock.sector_size - 1)) != 0) {
969 unsigned int newlen = (unsigned int)sector_align(parts[i].outlen, fcb->Vcb->superblock.sector_size);
970
971 RtlZeroMemory(parts[i].buf + parts[i].outlen, newlen - parts[i].outlen);
972
973 parts[i].outlen = newlen;
974 }
975 } else {
976 parts[i].compression_type = BTRFS_COMPRESSION_NONE;
977 parts[i].outlen = (unsigned int)sector_align(parts[i].inlen, fcb->Vcb->superblock.sector_size);
978 }
979
980 buflen += parts[i].outlen;
982 }
983
984 // check if first 128 KB of file is incompressible
985
986 if (start_data == 0 && parts[0].compression_type == BTRFS_COMPRESSION_NONE && !fcb->Vcb->options.compress_force) {
987 TRACE("adding nocompress flag to subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode);
988
990 fcb->inode_item_changed = true;
992 }
993
994 // join together into continuous buffer
995
997 if (!buf) {
998 ERR("out of memory\n");
1001 }
1002
1003 {
1004 uint8_t* buf2 = buf;
1005
1006 for (i = 0; i < num_parts; i++) {
1007 if (parts[i].compression_type == BTRFS_COMPRESSION_NONE)
1008 RtlCopyMemory(buf2, (uint8_t*)data + (i * COMPRESSED_EXTENT_SIZE), parts[i].outlen);
1009 else
1010 RtlCopyMemory(buf2, parts[i].buf, parts[i].outlen);
1011
1012 buf2 += parts[i].outlen;
1013 }
1014 }
1015
1016 // find an address
1017
1018 ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true);
1019
1020 le = fcb->Vcb->chunks.Flink;
1021 while (le != &fcb->Vcb->chunks) {
1023
1024 if (!c2->readonly && !c2->reloc) {
1026
1027 if (c2->chunk_item->type == fcb->Vcb->data_flags && (c2->chunk_item->size - c2->used) >= buflen) {
1028 if (find_data_address_in_chunk(fcb->Vcb, c2, buflen, &address)) {
1029 c = c2;
1030 c->used += buflen;
1033 break;
1034 }
1035 }
1036
1038 }
1039
1040 le = le->Flink;
1041 }
1042
1043 ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
1044
1045 if (!c) {
1046 chunk* c2;
1047
1048 ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true);
1049
1050 Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c2, false);
1051
1052 ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
1053
1054 if (!NT_SUCCESS(Status)) {
1055 ERR("alloc_chunk returned %08lx\n", Status);
1056 ExFreePool(buf);
1058 return Status;
1059 }
1060
1062
1063 if (find_data_address_in_chunk(fcb->Vcb, c2, buflen, &address)) {
1064 c = c2;
1065 c->used += buflen;
1067 }
1068
1070 }
1071
1072 if (!c) {
1073 WARN("couldn't find any data chunks with %x bytes free\n", buflen);
1074 ExFreePool(buf);
1076 return STATUS_DISK_FULL;
1077 }
1078
1079 // write to disk
1080
1081 TRACE("writing %x bytes to %I64x\n", buflen, address);
1082
1083 Status = write_data_complete(fcb->Vcb, address, buf, buflen, Irp, NULL, false, 0,
1085 if (!NT_SUCCESS(Status)) {
1086 ERR("write_data_complete returned %08lx\n", Status);
1087 ExFreePool(buf);
1089 return Status;
1090 }
1091
1092 // FIXME - do rest of the function while we're waiting for I/O to finish?
1093
1094 // calculate csums if necessary
1095
1097 unsigned int sl = buflen >> fcb->Vcb->sector_shift;
1098
1099 csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG);
1100 if (!csum) {
1101 ERR("out of memory\n");
1102 ExFreePool(buf);
1105 }
1106
1107 do_calc_job(fcb->Vcb, buf, sl, csum);
1108 }
1109
1110 ExFreePool(buf);
1111
1112 // add extents to fcb
1113
1114 extaddr = address;
1115
1116 for (i = 0; i < num_parts; i++) {
1117 EXTENT_DATA* ed;
1118 EXTENT_DATA2* ed2;
1119 void* csum2;
1120
1122 if (!ed) {
1123 ERR("out of memory\n");
1125
1126 if (csum)
1128
1130 }
1131
1132 ed->generation = fcb->Vcb->superblock.generation;
1133 ed->decoded_size = parts[i].inlen;
1134 ed->compression = parts[i].compression_type;
1138
1139 ed2 = (EXTENT_DATA2*)ed->data;
1140 ed2->address = extaddr;
1141 ed2->size = parts[i].outlen;
1142 ed2->offset = 0;
1143 ed2->num_bytes = parts[i].inlen;
1144
1145 if (csum) {
1146 csum2 = ExAllocatePoolWithTag(PagedPool, (parts[i].outlen * fcb->Vcb->csum_size) >> fcb->Vcb->sector_shift, ALLOC_TAG);
1147 if (!csum2) {
1148 ERR("out of memory\n");
1149 ExFreePool(ed);
1153 }
1154
1155 RtlCopyMemory(csum2, (uint8_t*)csum + (((extaddr - address) * fcb->Vcb->csum_size) >> fcb->Vcb->sector_shift),
1156 (parts[i].outlen * fcb->Vcb->csum_size) >> fcb->Vcb->sector_shift);
1157 } else
1158 csum2 = NULL;
1159
1161 true, csum2, rollback);
1162 if (!NT_SUCCESS(Status)) {
1163 ERR("add_extent_to_fcb returned %08lx\n", Status);
1164 ExFreePool(ed);
1166
1167 if (csum)
1169
1170 return Status;
1171 }
1172
1173 ExFreePool(ed);
1174
1175 fcb->inode_item.st_blocks += parts[i].inlen;
1176
1177 extaddr += parts[i].outlen;
1178 }
1179
1180 if (csum)
1182
1183 // update extent refcounts
1184
1185 ExAcquireResourceExclusiveLite(&c->changed_extents_lock, true);
1186
1187 extaddr = address;
1188
1189 for (i = 0; i < num_parts; i++) {
1190 add_changed_extent_ref(c, extaddr, parts[i].outlen, fcb->subvol->id, fcb->inode,
1192
1193 extaddr += parts[i].outlen;
1194 }
1195
1196 ExReleaseResourceLite(&c->changed_extents_lock);
1197
1198 fcb->extents_changed = true;
1199 fcb->inode_item_changed = true;
1201
1203
1204 return STATUS_SUCCESS;
1205}
std::map< E_STRING, PART_TEST > parts
Definition: LocaleTests.cpp:67
#define read
Definition: acwin.h:96
static int inbuf
Definition: adnsresfilter.c:73
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1139
_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:1365
void do_calc_job(device_extension *Vcb, uint8_t *data, uint32_t sectors, void *csum)
Definition: calcthread.c:141
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size) __attribute__((nonnull(1
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
NTSTATUS bool find_data_address_in_chunk(device_extension *Vcb, chunk *c, uint64_t length, uint64_t *address) __attribute__((nonnull(1
NTSTATUS add_calc_job_comp(device_extension *Vcb, uint8_t compression, void *in, unsigned int inlen, void *out, unsigned int outlen, calc_job **pcj)
Definition: calcthread.c:237
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1364
#define COMPRESSED_EXTENT_SIZE
Definition: btrfs_drv.h:112
void add_changed_extent_ref(chunk *c, uint64_t address, uint64_t size, uint64_t root, uint64_t objid, uint64_t offset, uint32_t count, bool no_csum)
Definition: extent-tree.c:2076
#define UNUSED(x)
Definition: btrfs_drv.h:82
NTSTATUS bool void NTSTATUS add_extent_to_fcb(_In_ fcb *fcb, _In_ uint64_t offset, _In_reads_bytes_(edsize) EXTENT_DATA *ed, _In_ uint16_t edsize, _In_ bool unique, _In_opt_ _When_(return >=0, __drv_aliasesMem) void *csum, _In_ LIST_ENTRY *rollback) __attribute__((nonnull(1
NTSTATUS NTSTATUS NTSTATUS write_data_complete(device_extension *Vcb, uint64_t address, void *data, uint32_t length, PIRP Irp, chunk *c, bool file_write, uint64_t irp_offset, ULONG priority) __attribute__((nonnull(1
void calc_thread_main(device_extension *Vcb, calc_job *cj)
Definition: calcthread.c:22
@ PropCompression_None
Definition: btrfs_drv.h:268
@ PropCompression_LZO
Definition: btrfs_drv.h:270
@ PropCompression_Zlib
Definition: btrfs_drv.h:269
@ PropCompression_ZSTD
Definition: btrfs_drv.h:271
#define release_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1140
void space_list_subtract(chunk *c, uint64_t address, uint64_t length, LIST_ENTRY *rollback)
Definition: free-space.c:2234
#define ALLOC_TAG_ZLIB
Definition: btrfs_drv.h:88
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
UINT op
Definition: effect.c:236
int inflate(z_streamp strm, int flush)
Definition: inflate.c:1257
int inflateEnd(z_streamp strm)
Definition: inflate.c:1910
void FAR * voidpf
Definition: zlib.h:42
#define Z_STREAM_END
Definition: zlib.h:115
#define Z_FINISH
Definition: zlib.h:109
#define Z_OK
Definition: zlib.h:114
int deflate(z_streamp strm, int flush) DECLSPEC_HIDDEN
Definition: deflate.c:815
#define Z_NO_FLUSH
Definition: zlib.h:105
int deflateEnd(z_streamp strm) DECLSPEC_HIDDEN
Definition: deflate.c:1130
#define byte(x, n)
Definition: tomcrypt.h:118
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1695
#define BTRFS_COMPRESSION_LZO
Definition: btrfs.h:67
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD
Definition: btrfs.h:119
#define BTRFS_COMPRESSION_ZLIB
Definition: btrfs.h:66
#define BTRFS_COMPRESSION_ZSTD
Definition: btrfs.h:68
#define BTRFS_ENCODING_NONE
Definition: btrfs.h:72
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:75
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
#define BTRFS_ENCRYPTION_NONE
Definition: btrfs.h:70
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO
Definition: btrfs.h:118
#define DINDEX(dv, p)
Definition: compress.c:78
static int lzo_len(lzo_stream *stream, int byte, int mask)
Definition: compress.c:117
NTSTATUS zlib_compress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, unsigned int level, unsigned int *space_left)
Definition: compress.c:336
#define M2_MAX_OFFSET
Definition: compress.c:62
static __inline uint32_t lzo_max_outlen(uint32_t inlen)
Definition: compress.c:660
static void zstd_free(void *opaque, void *address)
Definition: compress.c:670
NTSTATUS zlib_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
Definition: compress.c:377
#define LZO_BYTE(x)
Definition: compress.c:87
static void lzo_copyback(lzo_stream *stream, uint32_t back, int len)
Definition: compress.c:152
#define UPDATE_I(dict, cycle, index, p)
Definition: compress.c:80
NTSTATUS zstd_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
Definition: compress.c:676
#define LZO1X_MEM_COMPRESS
Definition: compress.c:59
#define DVAL_FIRST(dv, p)
Definition: compress.c:76
#define ZSTD_BTRFS_MAX_WINDOWLOG
Definition: compress.c:92
static void zlib_free(void *opaque, void *ptr)
Definition: compress.c:330
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:423
static void lzo_copy(lzo_stream *stream, int len)
Definition: compress.c:133
NTSTATUS lzo_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, uint32_t inpageoff)
Definition: compress.c:278
#define LZO_CHECK_MPOS_NON_DET(m_pos, m_off, in, ip, max_offset)
Definition: compress.c:82
static uint8_t lzo_nextbyte(lzo_stream *stream)
Definition: compress.c:103
#define M3_MARKER
Definition: compress.c:70
#define DVAL_NEXT(dv, p)
Definition: compress.c:74
#define LZO_PAGE_SIZE
Definition: compress.c:46
static void * zlib_alloc(void *opaque, unsigned int items, unsigned int size)
Definition: compress.c:324
NTSTATUS write_compressed(fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, PIRP Irp, LIST_ENTRY *rollback)
Definition: compress.c:875
#define M4_MARKER
Definition: compress.c:71
ZSTD_customMem zstd_mem
Definition: compress.c:98
static NTSTATUS do_lzo_decompress(lzo_stream *stream)
Definition: compress.c:170
#define UPDATE_D(dict, cycle, dv, p)
Definition: compress.c:79
NTSTATUS lzo_compress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, unsigned int *space_left)
Definition: compress.c:727
#define ZSTD_ALLOC_TAG
Definition: compress.c:89
#define M4_MAX_OFFSET
Definition: compress.c:64
#define M3_MAX_OFFSET
Definition: compress.c:63
static void * zstd_malloc(void *opaque, size_t size)
Definition: compress.c:664
static NTSTATUS lzo1x_1_compress(lzo_stream *stream)
Definition: compress.c:631
NTSTATUS zstd_compress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, uint32_t level, unsigned int *space_left)
Definition: compress.c:805
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
#define FSRTL_FLAG2_IS_PAGING_FILE
Definition: fsrtltypes.h:57
Status
Definition: gdiplustypes.h:25
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLuint address
Definition: glext.h:9393
const GLubyte * c
Definition: glext.h:8905
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
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
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 GLint GLint j
Definition: glfuncs.h:250
#define c
Definition: ke_i.h:80
if(dx< 0)
Definition: linetemp.h:194
@ NormalPagePriority
Definition: imports.h:54
@ HighPagePriority
Definition: imports.h:55
static PVOID ptr
Definition: dispmode.c:27
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
#define min(a, b)
Definition: monoChain.cc:55
BYTE uint8_t
Definition: msvideo1.c:66
#define KernelMode
Definition: asm.h:34
#define uint32_t
Definition: nsiface.idl:61
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
static TCHAR * items[]
Definition: page1.c:45
#define BTRFS_INODE_NOCOMPRESS
Definition: propsheet.h:79
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
static FILE * out
Definition: regtests2xml.c:44
#define offsetof(TYPE, MEMBER)
#define inflateInit(strm)
Definition: zlib.h:1812
#define deflateInit(strm, level)
Definition: zlib.h:1810
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t size
Definition: btrfs.h:340
uint64_t type
Definition: btrfs.h:343
uint64_t num_bytes
Definition: btrfs.h:371
uint64_t address
Definition: btrfs.h:368
uint64_t size
Definition: btrfs.h:369
uint64_t offset
Definition: btrfs.h:370
uint8_t data[1]
Definition: btrfs.h:364
uint64_t generation
Definition: btrfs.h:358
uint8_t type
Definition: btrfs.h:363
uint16_t encoding
Definition: btrfs.h:362
uint8_t encryption
Definition: btrfs.h:361
uint8_t compression
Definition: btrfs.h:360
uint64_t decoded_size
Definition: btrfs.h:359
uint32_t flags
Definition: btrfs.h:297
uint64_t st_blocks
Definition: btrfs.h:290
size_t size
Definition: zstd.h:574
size_t pos
Definition: zstd.h:575
void * dst
Definition: zstd.h:573
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
uint64_t inode
Definition: btrfs_drv.h:289
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
struct _root * subvol
Definition: btrfs_drv.h:288
bool extents_changed
Definition: btrfs_drv.h:323
enum prop_compression_type prop_compression
Definition: btrfs_drv.h:307
bool inode_item_changed
Definition: btrfs_drv.h:306
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
bool readonly
Definition: btrfs_drv.h:580
bool reloc
Definition: btrfs_drv.h:581
uint64_t used
Definition: btrfs_drv.h:565
CHUNK_ITEM * chunk_item
Definition: btrfs_drv.h:562
unsigned int outlen
Definition: compress.c:871
uint8_t compression_type
Definition: compress.c:869
calc_job * cj
Definition: compress.c:872
unsigned int inlen
Definition: compress.c:870
Definition: ffs.h:52
Definition: dhcpd.h:62
Definition: list.h:27
uint32_t outpos
Definition: compress.c:54
uint8_t * in
Definition: compress.c:49
bool error
Definition: compress.c:55
uint8_t * out
Definition: compress.c:52
uint32_t inlen
Definition: compress.c:50
void * wrkmem
Definition: compress.c:56
uint32_t outlen
Definition: compress.c:53
uint32_t inpos
Definition: compress.c:51
Definition: match.c:28
Definition: parse.h:23
uInt avail_in
Definition: zlib.h:60
z_const Bytef * next_in
Definition: zlib.h:59
alloc_func zalloc
Definition: zlib.h:70
uInt avail_out
Definition: zlib.h:64
Bytef * next_out
Definition: zlib.h:63
free_func zfree
Definition: zlib.h:71
voidpf opaque
Definition: zlib.h:72
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
int ret
_In_ ULONG cj
Definition: winddi.h:3540
@ Executive
Definition: ketypes.h:415
ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream *zds)
ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream *zcs)
ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
ZSTDLIB_API const char * ZSTD_getErrorName(size_t code)
Definition: zstd_common.c:41
ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)
ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream *zds)
ZSTD_CStream * ZSTD_createCStream_advanced(ZSTD_customMem customMem)
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
size_t ZSTD_initCStream_advanced(ZSTD_CStream *zcs, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pss)
ZSTD_DStream * ZSTD_createDStream_advanced(ZSTD_customMem customMem)
#define ZSTD_isError
Definition: zstd_internal.h:46