2 * compress.c - Compressed attribute handling code. Originated from the Linux-NTFS
5 * Copyright (c) 2004-2005 Anton Altaparmakov
6 * Copyright (c) 2004-2006 Szabolcs Szakacsits
7 * Copyright (c) 2005 Yura Pakhuchiy
8 * Copyright (c) 2009-2011 Jean-Pierre Andre
10 * This program/include file is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program/include file is distributed in the hope that it will be
16 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program (in the main directory of the NTFS-3G
22 * distribution in the file COPYING); if not, write to the Free Software
23 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * A part of the compression algorithm is based on lzhuf.c whose header
26 * describes the roles of the original authors (with no apparent copyright
27 * notice, and according to http://home.earthlink.net/~neilbawd/pall.html
28 * this was put into public domain in 1988 by Haruhiko OKUMURA).
30 * LZHUF.C English version 1.0
31 * Based on Japanese version 29-NOV-1988
32 * LZSS coded by Haruhiko OKUMURA
33 * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
34 * Edited and translated to English by Kenji RIKITAKE
66 /* the standard le16_to_cpup() crashes for unaligned data on some processors */
67 #define le16_to_cpup(p) (*(u8*)(p) + (((u8*)(p))[1] << 8))
70 * enum ntfs_compression_constants - constants used in the compression code
73 /* Token types and access mask. */
74 NTFS_SYMBOL_TOKEN
= 0,
75 NTFS_PHRASE_TOKEN
= 1,
78 /* Compression sub-block constants. */
79 NTFS_SB_SIZE_MASK
= 0x0fff,
80 NTFS_SB_SIZE
= 0x1000,
81 NTFS_SB_IS_COMPRESSED
= 0x8000,
82 } ntfs_compression_constants
;
84 struct COMPRESS_CONTEXT
{
85 const unsigned char *inbuf
;
91 s16 lson
[NTFS_SB_SIZE
];
92 s16 rson
[NTFS_SB_SIZE
];
96 * Search for the longest sequence matching current position
98 * A binary tree is maintained to locate all previously met sequences,
99 * and this function has to be called for all of them.
101 * This function is heavily used, it has to be optimized carefully
103 * Returns the size of the longest match,
104 * zero if no match is found.
107 static int ntfs_best_match(struct COMPRESS_CONTEXT
*pctx
, int i
)
117 register const unsigned char *p1
,*p2
;
120 node
= pctx
->head
[p1
[i
] & 255];
122 /* search the best match at current position */
124 bufsize
= pctx
->bufsize
;
125 /* restrict matches to the longest allowed sequence */
127 if ((i
+ pctx
->mxsz
) < maxpos
)
128 maxpos
= i
+ pctx
->mxsz
;
129 startj
= i
+ 1 - maxpos
;
131 /* make indexes relative to end of allowed position */
135 /* indexes are negative */
137 /* no need to compare the first byte */
139 /* the second byte cannot lead to useful compression */
140 if (p1
[j
] == p2
[j
]) {
144 } while ((p1
[j
] == p2
[j
])
147 /* remember the match, if better */
153 /* walk in the tree in the right direction */
154 if ((j
< 0) && (p1
[j
] < p2
[j
]))
155 prev
= &pctx
->lson
[node
];
157 prev
= &pctx
->rson
[node
];
159 /* stop if reaching a leaf or maximum length */
160 } while ((node
>= 0) && (j
< 0));
161 /* put the node into the tree if we reached a leaf */
165 /* done, return the best match */
166 pctx
->size
= bestj
+ maxpos
- i
;
167 pctx
->rel
= bestnode
- i
;
169 pctx
->head
[p1
[i
] & 255] = i
;
177 * Compress a 4096-byte block
179 * Returns a header of two bytes followed by the compressed data.
180 * If compression is not effective, the header and an uncompressed
183 * Note : two bytes may be output before output buffer overflow
184 * is detected, so a 4100-bytes output buffer must be reserved.
186 * Returns the size of the compressed block, including the
187 * header (minimal size is 2, maximum size is 4098)
188 * 0 if an error has been met.
191 static unsigned int ntfs_compress_block(const char *inbuf
, int bufsize
,
194 struct COMPRESS_CONTEXT
*pctx
;
195 int i
; /* current position */
196 int j
; /* end of best match from current position */
197 int k
; /* end of best match from next position */
198 int offs
; /* offset to best match */
200 int bp
; /* bits to store offset */
201 int mxoff
; /* max match offset : 1 << bp */
204 unsigned int q
; /* aggregated offset and size */
206 char *ptag
; /* location reserved for a tag */
207 int tag
; /* current value of tag */
208 int ntag
; /* count of bits still undefined in tag */
210 pctx
= (struct COMPRESS_CONTEXT
*)ntfs_malloc(sizeof(struct COMPRESS_CONTEXT
));
212 for (n
=0; n
<NTFS_SB_SIZE
; n
++)
213 pctx
->lson
[n
] = pctx
->rson
[n
] = -1;
214 for (n
=0; n
<256; n
++)
216 pctx
->inbuf
= (const unsigned char*)inbuf
;
217 pctx
->bufsize
= bufsize
;
223 pctx
->mxsz
= (1 << (16 - bp
)) + 2;
227 ptag
= &outbuf
[xout
++];
228 while ((i
< bufsize
) && (xout
< (NTFS_SB_SIZE
+ 2))) {
229 /* adjust the longest match we can output */
233 pctx
->mxsz
= (pctx
->mxsz
+ 2) >> 1;
235 /* search the best match at current position */
238 ntfs_best_match(pctx
,++done
);
241 if ((j
- i
) > pctx
->mxsz
)
246 /* check whether there is a better run at i+1 */
247 ntfs_best_match(pctx
,i
+1);
249 k
= i
+ 1 + pctx
->size
;
252 mxsz2
= (pctx
->mxsz
+ 2) >> 1;
256 /* issue a single byte */
257 outbuf
[xout
++] = inbuf
[i
];
260 q
= (~offs
<< (16 - bp
))
262 outbuf
[xout
++] = q
& 255;
263 outbuf
[xout
++] = (q
>> 8) & 255;
264 tag
|= (1 << (8 - ntag
));
268 outbuf
[xout
++] = inbuf
[i
];
271 /* store the tag if fully used */
275 ptag
= &outbuf
[xout
++];
279 /* store the last tag, if partially used */
284 /* uncompressed must be full size, accept if better */
285 if ((i
>= bufsize
) && (xout
< (NTFS_SB_SIZE
+ 2))) {
286 outbuf
[0] = (xout
- 3) & 255;
287 outbuf
[1] = 0xb0 + (((xout
- 3) >> 8) & 15);
289 memcpy(&outbuf
[2],inbuf
,bufsize
);
290 if (bufsize
< NTFS_SB_SIZE
)
291 memset(&outbuf
[bufsize
+2], 0,
292 NTFS_SB_SIZE
- bufsize
);
295 xout
= NTFS_SB_SIZE
+ 2;
306 * ntfs_decompress - decompress a compression block into an array of pages
307 * @dest: buffer to which to write the decompressed data
308 * @dest_size: size of buffer @dest in bytes
309 * @cb_start: compression block to decompress
310 * @cb_size: size of compression block @cb_start in bytes
312 * This decompresses the compression block @cb_start into the destination
315 * @cb_start is a pointer to the compression block which needs decompressing
316 * and @cb_size is the size of @cb_start in bytes (8-64kiB).
318 * Return 0 if success or -EOVERFLOW on error in the compressed stream.
320 static int ntfs_decompress(u8
*dest
, const u32 dest_size
,
321 u8
*const cb_start
, const u32 cb_size
)
324 * Pointers into the compressed data, i.e. the compression block (cb),
325 * and the therein contained sub-blocks (sb).
327 u8
*cb_end
= cb_start
+ cb_size
; /* End of cb. */
328 u8
*cb
= cb_start
; /* Current position in cb. */
329 u8
*cb_sb_start
= cb
; /* Beginning of the current sb in the cb. */
330 u8
*cb_sb_end
; /* End of current sb / beginning of next sb. */
331 /* Variables for uncompressed data / destination. */
332 u8
*dest_end
= dest
+ dest_size
; /* End of dest buffer. */
333 u8
*dest_sb_start
; /* Start of current sub-block in dest. */
334 u8
*dest_sb_end
; /* End of current sb in dest. */
335 /* Variables for tag and token parsing. */
336 u8 tag
; /* Current tag. */
337 int token
; /* Loop counter for the eight tokens in tag. */
339 ntfs_log_trace("Entering, cb_size = 0x%x.\n", (unsigned)cb_size
);
341 ntfs_log_debug("Beginning sub-block at offset = %d in the cb.\n",
342 (int)(cb
- cb_start
));
344 * Have we reached the end of the compression block or the end of the
345 * decompressed data? The latter can happen for example if the current
346 * position in the compression block is one byte before its end so the
347 * first two checks do not detect it.
349 if (cb
== cb_end
|| !le16_to_cpup((le16
*)cb
) || dest
== dest_end
) {
350 ntfs_log_debug("Completed. Returning success (0).\n");
353 /* Setup offset for the current sub-block destination. */
354 dest_sb_start
= dest
;
355 dest_sb_end
= dest
+ NTFS_SB_SIZE
;
356 /* Check that we are still within allowed boundaries. */
357 if (dest_sb_end
> dest_end
)
358 goto return_overflow
;
359 /* Does the minimum size of a compressed sb overflow valid range? */
361 goto return_overflow
;
362 /* Setup the current sub-block source pointers and validate range. */
364 cb_sb_end
= cb_sb_start
+ (le16_to_cpup((le16
*)cb
) & NTFS_SB_SIZE_MASK
)
366 if (cb_sb_end
> cb_end
)
367 goto return_overflow
;
368 /* Now, we are ready to process the current sub-block (sb). */
369 if (!(le16_to_cpup((le16
*)cb
) & NTFS_SB_IS_COMPRESSED
)) {
370 ntfs_log_debug("Found uncompressed sub-block.\n");
371 /* This sb is not compressed, just copy it into destination. */
372 /* Advance source position to first data byte. */
374 /* An uncompressed sb must be full size. */
375 if (cb_sb_end
- cb
!= NTFS_SB_SIZE
)
376 goto return_overflow
;
377 /* Copy the block and advance the source position. */
378 memcpy(dest
, cb
, NTFS_SB_SIZE
);
380 /* Advance destination position to next sub-block. */
381 dest
+= NTFS_SB_SIZE
;
384 ntfs_log_debug("Found compressed sub-block.\n");
385 /* This sb is compressed, decompress it into destination. */
386 /* Forward to the first tag in the sub-block. */
389 if (cb
== cb_sb_end
) {
390 /* Check if the decompressed sub-block was not full-length. */
391 if (dest
< dest_sb_end
) {
392 int nr_bytes
= dest_sb_end
- dest
;
394 ntfs_log_debug("Filling incomplete sub-block with zeroes.\n");
395 /* Zero remainder and update destination position. */
396 memset(dest
, 0, nr_bytes
);
399 /* We have finished the current sub-block. */
402 /* Check we are still in range. */
403 if (cb
> cb_sb_end
|| dest
> dest_sb_end
)
404 goto return_overflow
;
405 /* Get the next tag and advance to first token. */
407 /* Parse the eight tokens described by the tag. */
408 for (token
= 0; token
< 8; token
++, tag
>>= 1) {
409 u16 lg
, pt
, length
, max_non_overlap
;
413 /* Check if we are done / still in range. */
414 if (cb
>= cb_sb_end
|| dest
> dest_sb_end
)
416 /* Determine token type and parse appropriately.*/
417 if ((tag
& NTFS_TOKEN_MASK
) == NTFS_SYMBOL_TOKEN
) {
419 * We have a symbol token, copy the symbol across, and
420 * advance the source and destination positions.
423 /* Continue with the next token. */
427 * We have a phrase token. Make sure it is not the first tag in
428 * the sb as this is illegal and would confuse the code below.
430 if (dest
== dest_sb_start
)
431 goto return_overflow
;
433 * Determine the number of bytes to go back (p) and the number
434 * of bytes to copy (l). We use an optimized algorithm in which
435 * we first calculate log2(current destination position in sb),
436 * which allows determination of l and p in O(1) rather than
437 * O(n). We just need an arch-optimized log2() function now.
440 for (i
= dest
- dest_sb_start
- 1; i
>= 0x10; i
>>= 1)
442 /* Get the phrase token into i. */
443 pt
= le16_to_cpup((le16
*)cb
);
445 * Calculate starting position of the byte sequence in
446 * the destination using the fact that p = (pt >> (12 - lg)) + 1
447 * and make sure we don't go too far back.
449 dest_back_addr
= dest
- (pt
>> (12 - lg
)) - 1;
450 if (dest_back_addr
< dest_sb_start
)
451 goto return_overflow
;
452 /* Now calculate the length of the byte sequence. */
453 length
= (pt
& (0xfff >> lg
)) + 3;
454 /* Verify destination is in range. */
455 if (dest
+ length
> dest_sb_end
)
456 goto return_overflow
;
457 /* The number of non-overlapping bytes. */
458 max_non_overlap
= dest
- dest_back_addr
;
459 if (length
<= max_non_overlap
) {
460 /* The byte sequence doesn't overlap, just copy it. */
461 memcpy(dest
, dest_back_addr
, length
);
462 /* Advance destination pointer. */
466 * The byte sequence does overlap, copy non-overlapping
467 * part and then do a slow byte by byte copy for the
468 * overlapping part. Also, advance the destination
471 memcpy(dest
, dest_back_addr
, max_non_overlap
);
472 dest
+= max_non_overlap
;
473 dest_back_addr
+= max_non_overlap
;
474 length
-= max_non_overlap
;
476 *dest
++ = *dest_back_addr
++;
478 /* Advance source position and continue with the next token. */
481 /* No tokens left in the current tag. Continue with the next tag. */
485 ntfs_log_perror("Failed to decompress file");
490 * ntfs_is_cb_compressed - internal function, do not use
492 * This is a very specialised function determining if a cb is compressed or
493 * uncompressed. It is assumed that checking for a sparse cb has already been
494 * performed and that the cb is not sparse. It makes all sorts of other
495 * assumptions as well and hence it is not useful anywhere other than where it
496 * is used at the moment. Please, do not make this function available for use
497 * outside of compress.c as it is bound to confuse people and not do what they
500 * Return TRUE on errors so that the error will be detected later on in the
501 * code. Might be a bit confusing to debug but there really should never be
502 * errors coming from here.
504 static BOOL
ntfs_is_cb_compressed(ntfs_attr
*na
, runlist_element
*rl
,
505 VCN cb_start_vcn
, int cb_clusters
)
508 * The simplest case: the run starting at @cb_start_vcn contains
509 * @cb_clusters clusters which are all not sparse, thus the cb is not
513 cb_clusters
-= rl
->length
- (cb_start_vcn
- rl
->vcn
);
514 while (cb_clusters
> 0) {
515 /* Go to the next run. */
517 /* Map the next runlist fragment if it is not mapped. */
518 if (rl
->lcn
< LCN_HOLE
|| !rl
->length
) {
519 cb_start_vcn
= rl
->vcn
;
520 rl
= ntfs_attr_find_vcn(na
, rl
->vcn
);
521 if (!rl
|| rl
->lcn
< LCN_HOLE
|| !rl
->length
)
524 * If the runs were merged need to deal with the
525 * resulting partial run so simply restart.
527 if (rl
->vcn
< cb_start_vcn
)
530 /* If the current run is sparse, the cb is compressed. */
531 if (rl
->lcn
== LCN_HOLE
)
533 /* If the whole cb is not sparse, it is not compressed. */
534 if (rl
->length
>= cb_clusters
)
536 cb_clusters
-= rl
->length
;
538 /* All cb_clusters were not sparse thus the cb is not compressed. */
543 * ntfs_compressed_attr_pread - read from a compressed attribute
544 * @na: ntfs attribute to read from
545 * @pos: byte position in the attribute to begin reading from
546 * @count: number of bytes to read
547 * @b: output data buffer
549 * NOTE: You probably want to be using attrib.c::ntfs_attr_pread() instead.
551 * This function will read @count bytes starting at offset @pos from the
552 * compressed ntfs attribute @na into the data buffer @b.
554 * On success, return the number of successfully read bytes. If this number
555 * is lower than @count this means that the read reached end of file or that
556 * an error was encountered during the read so that the read is partial.
557 * 0 means end of file or nothing was read (also return 0 when @count is 0).
559 * On error and nothing has been read, return -1 with errno set appropriately
560 * to the return code of ntfs_pread(), or to EINVAL in case of invalid
563 s64
ntfs_compressed_attr_pread(ntfs_attr
*na
, s64 pos
, s64 count
, void *b
)
565 s64 br
, to_read
, ofs
, total
, total2
;
567 VCN start_vcn
, vcn
, end_vcn
;
570 u8
*dest
, *cb
, *cb_pos
, *cb_end
;
573 ATTR_FLAGS data_flags
;
574 FILE_ATTR_FLAGS compression
;
575 unsigned int nr_cbs
, cb_clusters
;
577 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, count 0x%llx.\n",
578 (unsigned long long)na
->ni
->mft_no
, na
->type
,
579 (long long)pos
, (long long)count
);
580 data_flags
= na
->data_flags
;
581 compression
= na
->ni
->flags
& FILE_ATTR_COMPRESSED
;
582 if (!na
|| !na
->ni
|| !na
->ni
->vol
|| !b
583 || ((data_flags
& ATTR_COMPRESSION_MASK
)
584 != ATTR_IS_COMPRESSED
)
585 || pos
< 0 || count
< 0) {
590 * Encrypted attributes are not supported. We return access denied,
591 * which is what Windows NT4 does, too.
593 if (NAttrEncrypted(na
)) {
599 /* Truncate reads beyond end of attribute. */
600 if (pos
+ count
> na
->data_size
) {
601 if (pos
>= na
->data_size
) {
604 count
= na
->data_size
- pos
;
606 /* If it is a resident attribute, simply use ntfs_attr_pread(). */
607 if (!NAttrNonResident(na
))
608 return ntfs_attr_pread(na
, pos
, count
, b
);
610 /* Zero out reads beyond initialized size. */
611 if (pos
+ count
> na
->initialized_size
) {
612 if (pos
>= na
->initialized_size
) {
616 total2
= pos
+ count
- na
->initialized_size
;
618 memset((u8
*)b
+ count
, 0, total2
);
621 cb_size
= na
->compression_block_size
;
622 cb_size_mask
= cb_size
- 1UL;
623 cb_clusters
= na
->compression_block_clusters
;
625 /* Need a temporary buffer for each loaded compression block. */
626 cb
= (u8
*)ntfs_malloc(cb_size
);
630 /* Need a temporary buffer for each uncompressed block. */
631 dest
= (u8
*)ntfs_malloc(cb_size
);
637 * The first vcn in the first compression block (cb) which we need to
640 start_vcn
= (pos
& ~cb_size_mask
) >> vol
->cluster_size_bits
;
641 /* Offset in the uncompressed cb at which to start reading data. */
642 ofs
= pos
& cb_size_mask
;
644 * The first vcn in the cb after the last cb which we need to
647 end_vcn
= ((pos
+ count
+ cb_size
- 1) & ~cb_size_mask
) >>
648 vol
->cluster_size_bits
;
649 /* Number of compression blocks (cbs) in the wanted vcn range. */
650 nr_cbs
= (end_vcn
- start_vcn
) << vol
->cluster_size_bits
>>
651 na
->compression_block_size_bits
;
652 cb_end
= cb
+ cb_size
;
657 start_vcn
+= cb_clusters
;
659 /* Check whether the compression block is sparse. */
660 rl
= ntfs_attr_find_vcn(na
, vcn
);
661 if (!rl
|| rl
->lcn
< LCN_HOLE
) {
666 /* FIXME: Do we want EIO or the error code? (AIA) */
670 if (rl
->lcn
== LCN_HOLE
) {
671 /* Sparse cb, zero out destination range overlapping the cb. */
672 ntfs_log_debug("Found sparse compression block.\n");
673 to_read
= min(count
, cb_size
- ofs
);
674 memset(b
, 0, to_read
);
678 b
= (u8
*)b
+ to_read
;
679 } else if (!ntfs_is_cb_compressed(na
, rl
, vcn
, cb_clusters
)) {
680 s64 tdata_size
, tinitialized_size
;
682 * Uncompressed cb, read it straight into the destination range
683 * overlapping the cb.
685 ntfs_log_debug("Found uncompressed compression block.\n");
687 * Read the uncompressed data into the destination buffer.
688 * NOTE: We cheat a little bit here by marking the attribute as
689 * not compressed in the ntfs_attr structure so that we can
690 * read the data by simply using ntfs_attr_pread(). (-8
691 * NOTE: we have to modify data_size and initialized_size
692 * temporarily as well...
694 to_read
= min(count
, cb_size
- ofs
);
695 ofs
+= vcn
<< vol
->cluster_size_bits
;
696 NAttrClearCompressed(na
);
697 na
->data_flags
&= ~ATTR_COMPRESSION_MASK
;
698 tdata_size
= na
->data_size
;
699 tinitialized_size
= na
->initialized_size
;
700 na
->data_size
= na
->initialized_size
= na
->allocated_size
;
702 br
= ntfs_attr_pread(na
, ofs
, to_read
, b
);
705 ntfs_log_error("Failed to read an"
706 " uncompressed cluster,"
707 " inode %lld offs 0x%llx\n",
708 (long long)na
->ni
->mft_no
,
713 na
->data_size
= tdata_size
;
714 na
->initialized_size
= tinitialized_size
;
715 na
->ni
->flags
|= compression
;
716 na
->data_flags
= data_flags
;
729 } while (to_read
> 0);
730 na
->data_size
= tdata_size
;
731 na
->initialized_size
= tinitialized_size
;
732 na
->ni
->flags
|= compression
;
733 na
->data_flags
= data_flags
;
736 s64 tdata_size
, tinitialized_size
;
739 * Compressed cb, decompress it into the temporary buffer, then
740 * copy the data to the destination range overlapping the cb.
742 ntfs_log_debug("Found compressed compression block.\n");
744 * Read the compressed data into the temporary buffer.
745 * NOTE: We cheat a little bit here by marking the attribute as
746 * not compressed in the ntfs_attr structure so that we can
747 * read the raw, compressed data by simply using
748 * ntfs_attr_pread(). (-8
749 * NOTE: We have to modify data_size and initialized_size
750 * temporarily as well...
753 NAttrClearCompressed(na
);
754 na
->data_flags
&= ~ATTR_COMPRESSION_MASK
;
755 tdata_size
= na
->data_size
;
756 tinitialized_size
= na
->initialized_size
;
757 na
->data_size
= na
->initialized_size
= na
->allocated_size
;
759 br
= ntfs_attr_pread(na
,
760 (vcn
<< vol
->cluster_size_bits
) +
761 (cb_pos
- cb
), to_read
, cb_pos
);
764 ntfs_log_error("Failed to read a"
765 " compressed cluster, "
766 " inode %lld offs 0x%llx\n",
767 (long long)na
->ni
->mft_no
,
768 (long long)(vcn
<< vol
->cluster_size_bits
));
772 na
->data_size
= tdata_size
;
773 na
->initialized_size
= tinitialized_size
;
774 na
->ni
->flags
|= compression
;
775 na
->data_flags
= data_flags
;
785 } while (to_read
> 0);
786 na
->data_size
= tdata_size
;
787 na
->initialized_size
= tinitialized_size
;
788 na
->ni
->flags
|= compression
;
789 na
->data_flags
= data_flags
;
790 /* Just a precaution. */
791 if (cb_pos
+ 2 <= cb_end
)
793 ntfs_log_debug("Successfully read the compression block.\n");
794 if (ntfs_decompress(dest
, cb_size
, cb
, cb_size
) < 0) {
803 to_read
= min(count
, cb_size
- ofs
);
804 memcpy(b
, dest
+ ofs
, to_read
);
807 b
= (u8
*)b
+ to_read
;
810 /* Do we have more work to do? */
813 /* We no longer need the buffers. */
816 /* Return number of bytes read. */
817 return total
+ total2
;
821 * Read data from a set of clusters
823 * Returns the amount of data read
826 static u32
read_clusters(ntfs_volume
*vol
, const runlist_element
*rl
,
827 s64 offs
, u32 to_read
, char *inbuf
)
835 const runlist_element
*xrl
;
842 count
= xrl
->length
<< vol
->cluster_size_bits
;
843 xpos
= xrl
->lcn
<< vol
->cluster_size_bits
;
848 if ((to_read
- got
) < count
)
849 count
= to_read
- got
;
850 xgot
= ntfs_pread(vol
->dev
, xpos
, count
, xinbuf
);
851 if (xgot
== (int)count
) {
858 } while ((xgot
== (int)count
) && (got
< to_read
));
863 * Write data to a set of clusters
865 * Returns the amount of data written
868 static s32
write_clusters(ntfs_volume
*vol
, const runlist_element
*rl
,
869 s64 offs
, s32 to_write
, const char *outbuf
)
876 const runlist_element
*xrl
;
883 count
= xrl
->length
<< vol
->cluster_size_bits
;
884 xpos
= xrl
->lcn
<< vol
->cluster_size_bits
;
889 if ((to_write
- put
) < count
)
890 count
= to_write
- put
;
891 xput
= ntfs_pwrite(vol
->dev
, xpos
, count
, xoutbuf
);
899 } while ((xput
== count
) && (put
< to_write
));
905 * Compress and write a set of blocks
907 * returns the size actually written (rounded to a full cluster)
908 * or 0 if all zeroes (nothing is written)
909 * or -1 if could not compress (nothing is written)
910 * or -2 if there were an irrecoverable error (errno set)
913 static s32
ntfs_comp_set(ntfs_attr
*na
, runlist_element
*rl
,
914 s64 offs
, u32 insz
, const char *inbuf
)
928 /* a single compressed zero */
929 static char onezero
[] = { 0x01, 0xb0, 0x00, 0x00 } ;
930 /* a couple of compressed zeroes */
931 static char twozeroes
[] = { 0x02, 0xb0, 0x00, 0x00, 0x00 } ;
932 /* more compressed zeroes, to be followed by some count */
933 static char morezeroes
[] = { 0x03, 0xb0, 0x02, 0x00 } ;
936 written
= -1; /* default return */
937 clsz
= 1 << vol
->cluster_size_bits
;
938 /* may need 2 extra bytes per block and 2 more bytes */
939 outbuf
= (char*)ntfs_malloc(na
->compression_block_size
940 + 2*(na
->compression_block_size
/NTFS_SB_SIZE
)
946 for (p
=0; (p
<insz
) && !fail
; p
+=NTFS_SB_SIZE
) {
947 if ((p
+ NTFS_SB_SIZE
) < insz
)
951 pbuf
= &outbuf
[compsz
];
952 sz
= ntfs_compress_block(&inbuf
[p
],bsz
,pbuf
);
953 /* fail if all the clusters (or more) are needed */
954 if (!sz
|| ((compsz
+ sz
+ clsz
+ 2)
955 > na
->compression_block_size
))
959 /* check whether this is all zeroes */
981 if (!fail
&& !allzeroes
) {
982 /* add a couple of null bytes, space has been checked */
983 outbuf
[compsz
++] = 0;
984 outbuf
[compsz
++] = 0;
985 /* write a full cluster, to avoid partial reading */
986 rounded
= ((compsz
- 1) | (clsz
- 1)) + 1;
987 written
= write_clusters(vol
, rl
, offs
, rounded
, outbuf
);
988 if (written
!= rounded
) {
990 * TODO : previously written text has been
991 * spoilt, should return a specific error
993 ntfs_log_error("error writing compressed data\n");
1006 * Check the validity of a compressed runlist
1007 * The check starts at the beginning of current run and ends
1008 * at the end of runlist
1009 * errno is set if the runlist is not valid
1012 static BOOL
valid_compressed_run(ntfs_attr
*na
, runlist_element
*rl
,
1013 BOOL fullcheck
, const char *text
)
1015 runlist_element
*xrl
;
1020 while (xrl
->vcn
& (na
->compression_block_clusters
- 1))
1022 err
= (const char*)NULL
;
1023 while (xrl
->length
) {
1024 if ((xrl
->vcn
+ xrl
->length
) != xrl
[1].vcn
)
1025 err
= "Runs not adjacent";
1026 if (xrl
->lcn
== LCN_HOLE
) {
1027 if ((xrl
->vcn
+ xrl
->length
)
1028 & (na
->compression_block_clusters
- 1)) {
1029 err
= "Invalid hole";
1031 if (fullcheck
&& (xrl
[1].lcn
== LCN_HOLE
)) {
1032 err
= "Adjacent holes";
1036 ntfs_log_error("%s at %s index %ld inode %lld\n",
1037 err
, text
, (long)(xrl
- na
->rl
),
1038 (long long)na
->ni
->mft_no
);
1041 err
= (const char*)NULL
;
1049 * Free unneeded clusters after overwriting compressed data
1051 * This generally requires one or two empty slots at the end of runlist,
1052 * but we do not want to reallocate the runlist here because
1053 * there are many pointers to it.
1054 * So the empty slots have to be reserved beforehand
1056 * Returns zero unless some error occurred (described by errno)
1058 * +======= start of block =====+
1059 * 0 |A chunk may overflow | <-- rl usedcnt : A + B
1060 * |A on previous block | then B
1062 * +-- end of allocated chunk --+ freelength : C
1063 * |B | (incl overflow)
1064 * +== end of compressed data ==+
1065 * |C | <-- freerl freecnt : C + D
1066 * |C chunk may overflow |
1067 * |C on next block |
1068 * +-- end of allocated chunk --+
1070 * |D chunk may overflow |
1071 * 15 |D on next block |
1072 * +======== end of block ======+
1076 static int ntfs_compress_overwr_free(ntfs_attr
*na
, runlist_element
*rl
,
1077 s32 usedcnt
, s32 freecnt
, VCN
*update_from
)
1085 runlist_element
*freerl
;
1092 freelcn
= rl
->lcn
+ usedcnt
;
1093 freevcn
= rl
->vcn
+ usedcnt
;
1094 freelength
= rl
->length
- usedcnt
;
1095 beginhole
= !usedcnt
&& !rl
->vcn
;
1096 /* can merge with hole before ? */
1097 mergeholes
= !usedcnt
1099 && (rl
[-1].lcn
== LCN_HOLE
);
1100 /* truncate current run, carry to subsequent hole */
1102 oldlength
= rl
->length
;
1104 /* merging with a hole before */
1107 rl
->length
-= freelength
; /* warning : can be zero */
1110 if (!mergeholes
&& (usedcnt
|| beginhole
)) {
1112 runlist_element
*frl
;
1113 runlist_element
*erl
;
1117 /* free the unneeded clusters from initial run, then freerl */
1118 threeparts
= (freelength
> freecnt
);
1122 res
= ntfs_cluster_free_basic(vol
,freelcn
,
1123 (threeparts
? freecnt
: freelength
));
1125 freed
+= (threeparts
? freecnt
: freelength
);
1129 freerl
->length
+= (threeparts
1130 ? freecnt
: freelength
);
1131 if (freerl
->vcn
< *update_from
)
1132 *update_from
= freerl
->vcn
;
1135 while (!res
&& frl
->length
&& (freed
< freecnt
)) {
1136 if (frl
->length
<= (freecnt
- freed
)) {
1137 res
= ntfs_cluster_free_basic(vol
, frl
->lcn
,
1140 freed
+= frl
->length
;
1141 frl
->lcn
= LCN_HOLE
;
1142 frl
->length
+= carry
;
1147 res
= ntfs_cluster_free_basic(vol
, frl
->lcn
,
1150 frl
->lcn
+= freecnt
- freed
;
1151 frl
->vcn
+= freecnt
- freed
;
1152 frl
->length
-= freecnt
- freed
;
1158 na
->compressed_size
-= freed
<< vol
->cluster_size_bits
;
1161 /* there are no hole, must insert one */
1162 /* space for hole has been prereserved */
1163 if (freerl
->lcn
== LCN_HOLE
) {
1170 } while (erl
-- != freerl
);
1172 freerl
[1].length
= freelength
- freecnt
;
1173 freerl
->length
= freecnt
;
1174 freerl
[1].lcn
= freelcn
+ freecnt
;
1175 freerl
[1].vcn
= freevcn
+ freecnt
;
1176 freerl
[2].lcn
= LCN_HOLE
;
1177 freerl
[2].vcn
= freerl
[1].vcn
1179 freerl
->vcn
= freevcn
;
1181 freerl
->vcn
= freevcn
;
1182 freerl
->length
+= freelength
;
1191 } while (erl
-- != freerl
);
1192 freerl
[1].lcn
= freelcn
+ freecnt
;
1193 freerl
[1].vcn
= freevcn
+ freecnt
;
1194 freerl
[1].length
= oldlength
- usedcnt
- freecnt
;
1198 } while (erl
-- != freerl
);
1200 freerl
->lcn
= LCN_HOLE
;
1201 freerl
->vcn
= freevcn
;
1202 freerl
->length
= freecnt
;
1206 /* there is a single hole, may have to merge */
1207 freerl
->vcn
= freevcn
;
1208 freerl
->length
= freecnt
;
1209 if (freerl
[1].lcn
== LCN_HOLE
) {
1210 freerl
->length
+= freerl
[1].length
;
1215 } while (erl
->length
);
1219 /* there were several holes, must merge them */
1220 freerl
->lcn
= LCN_HOLE
;
1221 freerl
->vcn
= freevcn
;
1222 freerl
->length
= freecnt
;
1223 if (freerl
[holes
].lcn
== LCN_HOLE
) {
1224 freerl
->length
+= freerl
[holes
].length
;
1230 *erl
= erl
[holes
- 1];
1231 } while (erl
->length
);
1236 runlist_element
*frl
;
1237 runlist_element
*xrl
;
1241 if (freerl
->vcn
< *update_from
)
1242 *update_from
= freerl
->vcn
;
1243 while (!res
&& frl
->length
&& (freed
< freecnt
)) {
1244 if (frl
->length
<= (freecnt
- freed
)) {
1245 freerl
->length
+= frl
->length
;
1246 freed
+= frl
->length
;
1247 res
= ntfs_cluster_free_basic(vol
, frl
->lcn
,
1251 freerl
->length
+= freecnt
- freed
;
1252 res
= ntfs_cluster_free_basic(vol
, frl
->lcn
,
1254 frl
->lcn
+= freecnt
- freed
;
1255 frl
->vcn
+= freecnt
- freed
;
1256 frl
->length
-= freecnt
- freed
;
1260 /* remove unneded runlist entries */
1262 /* group with next run if also a hole */
1263 if (frl
->length
&& (frl
->lcn
== LCN_HOLE
)) {
1264 xrl
->length
+= frl
->length
;
1267 while (frl
->length
) {
1270 *++xrl
= *frl
; /* terminator */
1271 na
->compressed_size
-= freed
<< vol
->cluster_size_bits
;
1278 * Free unneeded clusters after compression
1280 * This generally requires one or two empty slots at the end of runlist,
1281 * but we do not want to reallocate the runlist here because
1282 * there are many pointers to it.
1283 * So the empty slots have to be reserved beforehand
1285 * Returns zero unless some error occurred (described by errno)
1288 static int ntfs_compress_free(ntfs_attr
*na
, runlist_element
*rl
,
1289 s64 used
, s64 reserved
, BOOL appending
,
1301 runlist_element
*freerl
;
1303 res
= -1; /* default return */
1305 freecnt
= (reserved
- used
) >> vol
->cluster_size_bits
;
1306 usedcnt
= (reserved
>> vol
->cluster_size_bits
) - freecnt
;
1307 if (rl
->vcn
< *update_from
)
1308 *update_from
= rl
->vcn
;
1309 /* skip entries fully used, if any */
1310 while (rl
->length
&& (rl
->length
< usedcnt
)) {
1311 usedcnt
-= rl
->length
; /* must be > 0 */
1316 * Splitting the current allocation block requires
1317 * an extra runlist element to create the hole.
1318 * The required entry has been prereserved when
1319 * mapping the runlist.
1321 /* get the free part in initial run */
1322 freelcn
= rl
->lcn
+ usedcnt
;
1323 freevcn
= rl
->vcn
+ usedcnt
;
1324 /* new count of allocated clusters */
1325 if (!((freevcn
+ freecnt
)
1326 & (na
->compression_block_clusters
- 1))) {
1328 res
= ntfs_compress_overwr_free(na
,rl
,
1329 usedcnt
,freecnt
,update_from
);
1331 freelength
= rl
->length
- usedcnt
;
1332 beginhole
= !usedcnt
&& !rl
->vcn
;
1333 mergeholes
= !usedcnt
1335 && (rl
[-1].lcn
== LCN_HOLE
);
1339 /* shorten the runs which have free space */
1342 while (freerl
->length
< carry
) {
1343 carry
-= freerl
->length
;
1346 freerl
->length
= carry
;
1349 rl
->length
= usedcnt
; /* can be zero ? */
1352 if ((freelength
> 0)
1354 && (usedcnt
|| beginhole
)) {
1356 * move the unused part to the end. Doing so,
1357 * the vcn will be out of order. This does
1358 * not harm, the vcn are meaningless now, and
1359 * only the lcn are meaningful for freeing.
1361 /* locate current end */
1364 /* new terminator relocated */
1365 rl
[1].vcn
= rl
->vcn
;
1366 rl
[1].lcn
= LCN_ENOENT
;
1368 /* hole, currently allocated */
1371 rl
->length
= freelength
;
1373 /* why is this different from the begin hole case ? */
1374 if ((freelength
> 0)
1378 freerl
->length
= freelength
;
1379 if (freerl
->vcn
< *update_from
)
1385 res
= ntfs_cluster_free_from_rl(vol
,freerl
);
1387 na
->compressed_size
-= freecnt
1388 << vol
->cluster_size_bits
;
1390 /* merge with adjacent hole */
1392 freerl
->length
+= freecnt
;
1396 /* mark hole as free */
1397 freerl
->lcn
= LCN_HOLE
;
1398 freerl
->vcn
= freevcn
;
1399 freerl
->length
= freecnt
;
1401 if (freerl
->vcn
< *update_from
)
1402 *update_from
= freerl
->vcn
;
1403 /* and set up the new end */
1404 freerl
[1].lcn
= LCN_ENOENT
;
1405 freerl
[1].vcn
= freevcn
+ freecnt
;
1406 freerl
[1].length
= 0;
1410 ntfs_log_error("Bad end of a compression block set\n");
1414 ntfs_log_error("No cluster to free after compression\n");
1421 * Read existing data, decompress and append buffer
1422 * Do nothing if something fails
1425 static int ntfs_read_append(ntfs_attr
*na
, const runlist_element
*rl
,
1426 s64 offs
, u32 compsz
, s32 pos
, BOOL appending
,
1427 char *outbuf
, s64 to_write
, const void *b
)
1434 if (compsz
== na
->compression_block_size
) {
1435 /* if the full block was requested, it was a hole */
1436 memset(outbuf
,0,compsz
);
1437 memcpy(&outbuf
[pos
],b
,to_write
);
1440 compbuf
= (char*)ntfs_malloc(compsz
);
1442 /* must align to full block for decompression */
1444 decompsz
= ((pos
- 1) | (NTFS_SB_SIZE
- 1)) + 1;
1446 decompsz
= na
->compression_block_size
;
1447 got
= read_clusters(na
->ni
->vol
, rl
, offs
,
1450 && !ntfs_decompress((u8
*)outbuf
,decompsz
,
1451 (u8
*)compbuf
,compsz
)) {
1452 memcpy(&outbuf
[pos
],b
,to_write
);
1462 * Flush a full compression block
1464 * returns the size actually written (rounded to a full cluster)
1465 * or 0 if could not compress (and written uncompressed)
1466 * or -1 if there were an irrecoverable error (errno set)
1469 static s32
ntfs_flush(ntfs_attr
*na
, runlist_element
*rl
, s64 offs
,
1470 const char *outbuf
, s32 count
, BOOL compress
,
1471 BOOL appending
, VCN
*update_from
)
1478 written
= ntfs_comp_set(na
, rl
, offs
, count
, outbuf
);
1482 && ntfs_compress_free(na
,rl
,offs
+ written
,
1483 offs
+ na
->compression_block_size
, appending
,
1489 clsz
= 1 << na
->ni
->vol
->cluster_size_bits
;
1490 rounded
= ((count
- 1) | (clsz
- 1)) + 1;
1491 written
= write_clusters(na
->ni
->vol
, rl
,
1492 offs
, rounded
, outbuf
);
1493 if (written
!= rounded
)
1500 * Write some data to be compressed.
1501 * Compression only occurs when a few clusters (usually 16) are
1502 * full. When this occurs an extra runlist slot may be needed, so
1503 * it has to be reserved beforehand.
1505 * Returns the size of uncompressed data written,
1506 * or negative if an error occurred.
1507 * When the returned size is less than requested, new clusters have
1508 * to be allocated before the function is called again.
1511 s64
ntfs_compressed_pwrite(ntfs_attr
*na
, runlist_element
*wrl
, s64 wpos
,
1512 s64 offs
, s64 to_write
, s64 rounded
,
1513 const void *b
, int compressed_part
,
1517 runlist_element
*brl
; /* entry containing the beginning of block */
1518 int compression_length
;
1535 if (!valid_compressed_run(na
,wrl
,FALSE
,"begin compressed write")) {
1538 if ((*update_from
< 0)
1539 || (compressed_part
< 0)
1540 || (compressed_part
> (int)na
->compression_block_clusters
)) {
1541 ntfs_log_error("Bad update vcn or compressed_part %d for compressed write\n",
1546 /* make sure there are two unused entries in runlist */
1547 if (na
->unused_runs
< 2) {
1548 ntfs_log_error("No unused runs for compressed write\n");
1552 if (wrl
->vcn
< *update_from
)
1553 *update_from
= wrl
->vcn
;
1554 written
= -1; /* default return */
1556 compression_length
= na
->compression_block_clusters
;
1560 * Cannot accept writing beyond the current compression set
1561 * because when compression occurs, clusters are freed
1562 * and have to be reallocated.
1563 * (cannot happen with standard fuse 4K buffers)
1564 * Caller has to avoid this situation, or face consequences.
1566 nextblock
= ((offs
+ (wrl
->vcn
<< vol
->cluster_size_bits
))
1567 | (na
->compression_block_size
- 1)) + 1;
1568 /* determine whether we are appending to file */
1569 endwrite
= offs
+ to_write
+ (wrl
->vcn
<< vol
->cluster_size_bits
);
1570 appending
= endwrite
>= na
->initialized_size
;
1571 if (endwrite
>= nextblock
) {
1572 /* it is time to compress */
1574 /* only process what we can */
1575 to_write
= rounded
= nextblock
1576 - (offs
+ (wrl
->vcn
<< vol
->cluster_size_bits
));
1583 * If we are about to compress or we need to decompress
1584 * existing data, we have to process a full set of blocks.
1585 * So relocate the parameters to the beginning of allocation
1586 * containing the first byte of the set of blocks.
1588 if (compress
|| compressed_part
) {
1589 /* find the beginning of block */
1590 start_vcn
= (wrl
->vcn
+ (offs
>> vol
->cluster_size_bits
))
1591 & -compression_length
;
1592 if (start_vcn
< *update_from
)
1593 *update_from
= start_vcn
;
1594 while (brl
->vcn
&& (brl
->vcn
> start_vcn
)) {
1595 /* jumping back a hole means big trouble */
1596 if (brl
->lcn
== (LCN
)LCN_HOLE
) {
1597 ntfs_log_error("jump back over a hole when appending\n");
1602 offs
+= brl
->length
<< vol
->cluster_size_bits
;
1604 roffs
= (start_vcn
- brl
->vcn
) << vol
->cluster_size_bits
;
1606 if (compressed_part
&& !fail
) {
1608 * The set of compression blocks contains compressed data
1609 * (we are reopening an existing file to append to it)
1610 * Decompress the data and append
1612 compsz
= (s32
)compressed_part
<< vol
->cluster_size_bits
;
1613 outbuf
= (char*)ntfs_malloc(na
->compression_block_size
);
1616 to_read
= offs
- roffs
;
1617 to_flush
= to_read
+ to_write
;
1619 to_read
= na
->data_size
1620 - (brl
->vcn
<< vol
->cluster_size_bits
);
1621 if (to_read
> na
->compression_block_size
)
1622 to_read
= na
->compression_block_size
;
1625 if (!ntfs_read_append(na
, brl
, roffs
, compsz
,
1626 (s32
)(offs
- roffs
), appending
,
1627 outbuf
, to_write
, b
)) {
1628 written
= ntfs_flush(na
, brl
, roffs
,
1629 outbuf
, to_flush
, compress
, appending
,
1639 if (compress
&& !fail
) {
1641 * we are filling up a block, read the full set
1642 * of blocks and compress it
1644 inbuf
= (char*)ntfs_malloc(na
->compression_block_size
);
1646 to_read
= offs
- roffs
;
1648 got
= read_clusters(vol
, brl
, roffs
,
1652 if (got
== to_read
) {
1653 memcpy(&inbuf
[to_read
],b
,to_write
);
1654 written
= ntfs_comp_set(na
, brl
, roffs
,
1655 to_read
+ to_write
, inbuf
);
1657 * if compression was not successful,
1658 * only write the part which was requested
1661 /* free the unused clusters */
1662 && !ntfs_compress_free(na
,brl
,
1664 na
->compression_block_size
1666 appending
, update_from
)) {
1676 * if the compression block is not full, or
1677 * if compression failed for whatever reason,
1678 * write uncompressed
1680 /* check we are not overflowing current allocation */
1681 if ((wpos
+ rounded
)
1682 > ((wrl
->lcn
+ wrl
->length
)
1683 << vol
->cluster_size_bits
)) {
1684 ntfs_log_error("writing on unallocated clusters\n");
1687 written
= ntfs_pwrite(vol
->dev
, wpos
,
1689 if (written
== rounded
)
1695 && !valid_compressed_run(na
,wrl
,TRUE
,"end compressed write"))
1701 * Close a file written compressed.
1702 * This compresses the last partial compression block of the file.
1703 * Two empty runlist slots have to be reserved beforehand.
1705 * Returns zero if closing is successful.
1708 int ntfs_compressed_close(ntfs_attr
*na
, runlist_element
*wrl
, s64 offs
,
1712 runlist_element
*brl
; /* entry containing the beginning of block */
1713 int compression_length
;
1723 if (na
->unused_runs
< 2) {
1724 ntfs_log_error("No unused runs for compressed close\n");
1728 if (*update_from
< 0) {
1729 ntfs_log_error("Bad update vcn for compressed close\n");
1733 if (wrl
->vcn
< *update_from
)
1734 *update_from
= wrl
->vcn
;
1736 compression_length
= na
->compression_block_clusters
;
1739 * There generally is an uncompressed block at end of file,
1740 * read the full block and compress it
1742 inbuf
= (char*)ntfs_malloc(na
->compression_block_size
);
1744 start_vcn
= (wrl
->vcn
+ (offs
>> vol
->cluster_size_bits
))
1745 & -compression_length
;
1746 if (start_vcn
< *update_from
)
1747 *update_from
= start_vcn
;
1748 to_read
= offs
+ ((wrl
->vcn
- start_vcn
)
1749 << vol
->cluster_size_bits
);
1752 while (brl
->vcn
&& (brl
->vcn
> start_vcn
)) {
1753 if (brl
->lcn
== (LCN
)LCN_HOLE
) {
1754 ntfs_log_error("jump back over a hole when closing\n");
1761 /* roffs can be an offset from another uncomp block */
1762 roffs
= (start_vcn
- brl
->vcn
)
1763 << vol
->cluster_size_bits
;
1765 got
= read_clusters(vol
, brl
, roffs
, to_read
,
1767 if (got
== to_read
) {
1768 written
= ntfs_comp_set(na
, brl
, roffs
,
1771 /* free the unused clusters */
1772 && !ntfs_compress_free(na
,brl
,
1774 na
->compression_block_size
+ roffs
,
1775 TRUE
, update_from
)) {
1778 /* if compression failed, leave uncompressed */
1787 if (done
&& !valid_compressed_run(na
,wrl
,TRUE
,"end compressed close"))