• Home
  • Raw
  • Download

Lines Matching +full:sub +full:- +full:block

2  * compress.c - NTFS kernel compressed attributes handling.
3 * Part of the Linux-NTFS project.
5 * Copyright (c) 2001-2004 Anton Altaparmakov
19 * along with this program (in the main directory of the Linux-NTFS
21 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 * ntfs_compression_constants - enum of constants used in the compression code
44 /* Compression sub-block constants. */
50 * The maximum compression block size is by definition 16 * the cluster
59 * ntfs_compression_buffer - one buffer for the decompression engine
64 * ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
69 * allocate_compression_buffers - allocate the decompression buffers
73 * Return 0 on success or -ENOMEM if the allocations failed.
81 return -ENOMEM; in allocate_compression_buffers()
86 * free_compression_buffers - free the decompression buffers
98 * zero_partial_compressed_page - zero out of bounds compressed page region
107 if (((s64)page->index << PAGE_SHIFT) >= initialized_size) { in zero_partial_compressed_page()
112 memset(kp + kp_ofs, 0, PAGE_SIZE - kp_ofs); in zero_partial_compressed_page()
117 * handle_bounds_compressed_page - test for&handle out of bounds compressed page
122 if ((page->index >= (initialized_size >> PAGE_SHIFT)) && in handle_bounds_compressed_page()
129 * ntfs_decompress - decompress a compression block into an array of pages
136 * @xpage: the target page (-1 if none) (IN)
138 * @cb_start: compression block to decompress (IN)
139 * @cb_size: size of compression block @cb_start in bytes (IN)
146 * This decompresses the compression block @cb_start into the array of
151 * If xpage is -1 or @xpage has not been completed, @xpage_done is not modified.
153 * @cb_start is a pointer to the compression block which needs decompressing
154 * and @cb_size is the size of @cb_start in bytes (8-64kiB).
156 * Return 0 if success or -EOVERFLOW on error in the compressed stream.
158 * completed during the decompression of the compression block (@cb_start).
164 * the compression block @cb_start as it is a per-CPU buffer.
173 * Pointers into the compressed data, i.e. the compression block (cb), in ntfs_decompress()
174 * and the therein contained sub-blocks (sb). in ntfs_decompress()
184 u8 *dp_sb_start; /* Start of current sub-block in dp. */ in ntfs_decompress()
187 u16 do_sb_start; /* @dest_ofs when starting this sub-block. */ in ntfs_decompress()
197 int err = -EOVERFLOW; in ntfs_decompress()
201 ntfs_debug("Beginning sub-block at offset = 0x%zx in the cb.", in ntfs_decompress()
202 cb - cb_start); in ntfs_decompress()
204 * Have we reached the end of the compression block or the end of the in ntfs_decompress()
206 * position in the compression block is one byte before its end so the in ntfs_decompress()
245 /* Setup offsets for the current sub-block destination. */ in ntfs_decompress()
257 /* Setup the current sub-block source pointers and validate range. */ in ntfs_decompress()
267 /* No page present. Skip decompression of this sub-block. */ in ntfs_decompress()
270 /* Advance destination position to next sub-block. */ in ntfs_decompress()
280 /* Now, we are ready to process the current sub-block (sb). */ in ntfs_decompress()
282 ntfs_debug("Found uncompressed sub-block."); in ntfs_decompress()
289 if (cb_sb_end - cb != NTFS_SB_SIZE) in ntfs_decompress()
292 /* Copy the block and advance the source position. */ in ntfs_decompress()
296 /* Advance destination position to next sub-block. */ in ntfs_decompress()
310 ntfs_debug("Found compressed sub-block."); in ntfs_decompress()
317 /* Forward to the first tag in the sub-block. */ in ntfs_decompress()
321 /* Check if the decompressed sub-block was not full-length. */ in ntfs_decompress()
323 int nr_bytes = do_sb_end - *dest_ofs; in ntfs_decompress()
325 ntfs_debug("Filling incomplete sub-block with " in ntfs_decompress()
331 /* We have finished the current sub-block. */ in ntfs_decompress()
379 * O(n). We just need an arch-optimized log2() function now. in ntfs_decompress()
382 for (i = *dest_ofs - do_sb_start - 1; i >= 0x10; i >>= 1) in ntfs_decompress()
390 * the destination using the fact that p = (pt >> (12 - lg)) + 1 in ntfs_decompress()
393 dp_back_addr = dp_addr - (pt >> (12 - lg)) - 1; in ntfs_decompress()
405 /* The number of non-overlapping bytes. */ in ntfs_decompress()
406 max_non_overlap = dp_addr - dp_back_addr; in ntfs_decompress()
416 * The byte sequence does overlap, copy non-overlapping in ntfs_decompress()
424 length -= max_non_overlap; in ntfs_decompress()
425 while (length--) in ntfs_decompress()
437 ntfs_error(NULL, "Failed. Returning -EOVERFLOW."); in ntfs_decompress()
442 * ntfs_read_compressed_block - read a compressed block into the page cache
443 * @page: locked page in the compression block(s) we need to read
446 * attribute is known to be non-resident, not encrypted, but compressed.
448 * 1. Determine which compression block(s) @page is in.
449 * 2. Get hold of all pages corresponding to this/these compression block(s).
450 * 3. Read the (first) compression block.
453 * block or return success if no more compression blocks left.
457 * them with the out-of-date uncompressed data.
462 * moment we would just return -EIO on such a page. This bug will only become
480 struct address_space *mapping = page->mapping; in ntfs_read_compressed_block()
481 ntfs_inode *ni = NTFS_I(mapping->host); in ntfs_read_compressed_block()
482 ntfs_volume *vol = ni->vol; in ntfs_read_compressed_block()
483 struct super_block *sb = vol->sb; in ntfs_read_compressed_block()
485 unsigned long flags, block_size = sb->s_blocksize; in ntfs_read_compressed_block()
486 unsigned char block_size_bits = sb->s_blocksize_bits; in ntfs_read_compressed_block()
489 unsigned long offset, index = page->index; in ntfs_read_compressed_block()
490 u32 cb_size = ni->itype.compressed.block_size; in ntfs_read_compressed_block()
491 u64 cb_size_mask = cb_size - 1UL; in ntfs_read_compressed_block()
496 vol->cluster_size_bits; in ntfs_read_compressed_block()
501 VCN end_vcn = ((((s64)(index + 1UL) << PAGE_SHIFT) + cb_size - 1) in ntfs_read_compressed_block()
502 & ~cb_size_mask) >> vol->cluster_size_bits; in ntfs_read_compressed_block()
504 unsigned int nr_cbs = (end_vcn - start_vcn) << vol->cluster_size_bits in ntfs_read_compressed_block()
505 >> ni->itype.compressed.block_size_bits; in ntfs_read_compressed_block()
511 unsigned int nr_pages = (end_vcn - start_vcn) << in ntfs_read_compressed_block()
512 vol->cluster_size_bits >> PAGE_SHIFT; in ntfs_read_compressed_block()
515 int block, max_block, cb_max_page, bhs_size, nr_bhs, err = 0; in ntfs_read_compressed_block() local
520 ntfs_debug("Entering, page->index = 0x%lx, cb_size = 0x%x, nr_pages = " in ntfs_read_compressed_block()
526 BUG_ON(ni->type != AT_DATA); in ntfs_read_compressed_block()
527 BUG_ON(ni->name_len); in ntfs_read_compressed_block()
541 ntfs_error(vol->sb, "Failed to allocate internal buffers."); in ntfs_read_compressed_block()
542 return -ENOMEM; in ntfs_read_compressed_block()
549 offset = start_vcn << vol->cluster_size_bits >> PAGE_SHIFT; in ntfs_read_compressed_block()
550 xpage = index - offset; in ntfs_read_compressed_block()
554 * cache, alignment guarantees keep all the below much simpler. (-8 in ntfs_read_compressed_block()
556 read_lock_irqsave(&ni->size_lock, flags); in ntfs_read_compressed_block()
558 initialized_size = ni->initialized_size; in ntfs_read_compressed_block()
559 read_unlock_irqrestore(&ni->size_lock, flags); in ntfs_read_compressed_block()
560 max_page = ((i_size + PAGE_SIZE - 1) >> PAGE_SHIFT) - in ntfs_read_compressed_block()
568 ntfs_debug("Compressed read outside i_size - truncated?"); in ntfs_read_compressed_block()
599 * Now read the first compression block. in ntfs_read_compressed_block()
603 cb_clusters = ni->itype.compressed.block_clusters; in ntfs_read_compressed_block()
605 nr_cbs--; in ntfs_read_compressed_block()
616 down_read(&ni->runlist.lock); in ntfs_read_compressed_block()
617 rl = ni->runlist.rl; in ntfs_read_compressed_block()
621 while (rl->length && rl[1].vcn <= vcn) in ntfs_read_compressed_block()
643 up_read(&ni->runlist.lock); in ntfs_read_compressed_block()
648 block = lcn << vol->cluster_size_bits >> block_size_bits; in ntfs_read_compressed_block()
650 max_block = block + (vol->cluster_size >> block_size_bits); in ntfs_read_compressed_block()
652 ntfs_debug("block = 0x%x.", block); in ntfs_read_compressed_block()
653 if (unlikely(!(bhs[nr_bhs] = sb_getblk(sb, block)))) in ntfs_read_compressed_block()
656 } while (++block < max_block); in ntfs_read_compressed_block()
661 up_read(&ni->runlist.lock); in ntfs_read_compressed_block()
674 tbh->b_end_io = end_buffer_read_sync; in ntfs_read_compressed_block()
695 ntfs_warning(vol->sb, "Buffer is unlocked but not " in ntfs_read_compressed_block()
703 ntfs_warning(vol->sb, "Buffer is now uptodate. Good."); in ntfs_read_compressed_block()
721 memcpy(cb_pos, bhs[i]->b_data, block_size); in ntfs_read_compressed_block()
733 ntfs_debug("Successfully read the compression block."); in ntfs_read_compressed_block()
740 /* Catch end of file inside a compression block. */ in ntfs_read_compressed_block()
744 if (vcn == start_vcn - cb_clusters) { in ntfs_read_compressed_block()
746 ntfs_debug("Found sparse compression block."); in ntfs_read_compressed_block()
750 cb_max_page--; in ntfs_read_compressed_block()
758 PAGE_SIZE - in ntfs_read_compressed_block()
770 cb_pos += PAGE_SIZE - cur_ofs; in ntfs_read_compressed_block()
780 cb_max_ofs - cur_ofs); in ntfs_read_compressed_block()
783 * cb_pos += cb_max_ofs - cur_ofs; in ntfs_read_compressed_block()
793 ntfs_debug("Found uncompressed compression block."); in ntfs_read_compressed_block()
801 * Or if we choose not to do the read-ahead/-behind stuff, we in ntfs_read_compressed_block()
806 cb_max_page--; in ntfs_read_compressed_block()
812 PAGE_SIZE - cur_ofs); in ntfs_read_compressed_block()
813 cb_pos += PAGE_SIZE - cur_ofs; in ntfs_read_compressed_block()
823 cb_max_ofs - cur_ofs); in ntfs_read_compressed_block()
824 cb_pos += cb_max_ofs - cur_ofs; in ntfs_read_compressed_block()
849 cb_pos2 += PAGE_SIZE - cur_ofs2; in ntfs_read_compressed_block()
858 ntfs_debug("Found compressed compression block."); in ntfs_read_compressed_block()
861 &xpage_done, cb_pos, cb_size - (cb_pos - cb), in ntfs_read_compressed_block()
868 ntfs_error(vol->sb, "ntfs_decompress() failed in inode " in ntfs_read_compressed_block()
870 "this compression block.", in ntfs_read_compressed_block()
871 ni->mft_no, -err); in ntfs_read_compressed_block()
902 ntfs_error(vol->sb, "Still have pages left! " in ntfs_read_compressed_block()
905 "0x%lx.", ni->mft_no, page->index); in ntfs_read_compressed_block()
923 ntfs_debug("Failed. Returning error code %s.", err == -EOVERFLOW ? in ntfs_read_compressed_block()
925 return err < 0 ? err : -EIO; in ntfs_read_compressed_block()
928 ntfs_error(vol->sb, "IO error while reading compressed data."); in ntfs_read_compressed_block()
935 ntfs_error(vol->sb, "ntfs_map_runlist() failed. Cannot read " in ntfs_read_compressed_block()
936 "compression block."); in ntfs_read_compressed_block()
940 up_read(&ni->runlist.lock); in ntfs_read_compressed_block()
941 ntfs_error(vol->sb, "ntfs_rl_vcn_to_lcn() failed. Cannot read " in ntfs_read_compressed_block()
942 "compression block."); in ntfs_read_compressed_block()
946 up_read(&ni->runlist.lock); in ntfs_read_compressed_block()
947 ntfs_error(vol->sb, "getblk() failed. Cannot read compression block."); in ntfs_read_compressed_block()
963 return -EIO; in ntfs_read_compressed_block()