X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fntfs%2Fcompress.c;h=cc3aac147ba30b888348e138a64663b0a07d3e34;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=fba39c9b738f543d0d4121696d12712e37a7f4cd;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index fba39c9b7..cc3aac147 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -195,11 +195,17 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index, ntfs_debug("Entering, cb_size = 0x%x.", cb_size); do_next_sb: - ntfs_debug("Beginning sub-block at offset = 0x%x in the cb.", + ntfs_debug("Beginning sub-block at offset = 0x%zx in the cb.", cb - cb_start); - - /* Have we reached the end of the compression block? */ - if (cb == cb_end || !le16_to_cpup((u16*)cb)) { + /* + * Have we reached the end of the compression block or the end of the + * decompressed data? The latter can happen for example if the current + * position in the compression block is one byte before its end so the + * first two checks do not detect it. + */ + if (cb == cb_end || !le16_to_cpup((le16*)cb) || + (*dest_index == dest_max_index && + *dest_ofs == dest_max_ofs)) { int i; ntfs_debug("Completed. Returning success (0)."); @@ -249,7 +255,7 @@ return_error: /* Setup the current sub-block source pointers and validate range. */ cb_sb_start = cb; - cb_sb_end = cb_sb_start + (le16_to_cpup((u16*)cb) & NTFS_SB_SIZE_MASK) + cb_sb_end = cb_sb_start + (le16_to_cpup((le16*)cb) & NTFS_SB_SIZE_MASK) + 3; if (cb_sb_end > cb_end) goto return_overflow; @@ -271,7 +277,7 @@ return_error: dp_addr = (u8*)page_address(dp) + do_sb_start; /* Now, we are ready to process the current sub-block (sb). */ - if (!(le16_to_cpup((u16*)cb) & NTFS_SB_IS_COMPRESSED)) { + if (!(le16_to_cpup((le16*)cb) & NTFS_SB_IS_COMPRESSED)) { ntfs_debug("Found uncompressed sub-block."); /* This sb is not compressed, just copy it into destination. */ @@ -376,7 +382,7 @@ do_next_tag: lg++; /* Get the phrase token into i. */ - pt = le16_to_cpup((u16*)cb); + pt = le16_to_cpup((le16*)cb); /* * Calculate starting position of the byte sequence in @@ -427,7 +433,7 @@ do_next_tag: goto do_next_tag; return_overflow: - ntfs_error(NULL, "Failed. Returning -EOVERFLOW.\n"); + ntfs_error(NULL, "Failed. Returning -EOVERFLOW."); goto return_error; } @@ -472,7 +478,7 @@ int ntfs_read_compressed_block(struct page *page) ntfs_inode *ni = NTFS_I(mapping->host); ntfs_volume *vol = ni->vol; struct super_block *sb = vol->sb; - run_list_element *rl; + runlist_element *rl; unsigned long block_size = sb->s_blocksize; unsigned char block_size_bits = sb->s_blocksize_bits; u8 *cb, *cb_pos, *cb_end; @@ -569,7 +575,7 @@ int ntfs_read_compressed_block(struct page *page) } /* - * We have the run list, and all the destination pages we need to fill. + * We have the runlist, and all the destination pages we need to fill. * Now read the first compression block. */ cur_page = 0; @@ -587,14 +593,14 @@ do_next_cb: if (!rl) { lock_retry_remap: - down_read(&ni->run_list.lock); - rl = ni->run_list.rl; + down_read(&ni->runlist.lock); + rl = ni->runlist.rl; } if (likely(rl != NULL)) { /* Seek to element containing target vcn. */ while (rl->length && rl[1].vcn <= vcn) rl++; - lcn = vcn_to_lcn(rl, vcn); + lcn = ntfs_vcn_to_lcn(rl, vcn); } else lcn = (LCN)LCN_RL_NOT_MAPPED; ntfs_debug("Reading vcn = 0x%llx, lcn = 0x%llx.", @@ -611,11 +617,11 @@ lock_retry_remap: goto rl_err; is_retry = TRUE; /* - * Attempt to map run list, dropping lock for the + * Attempt to map runlist, dropping lock for the * duration. */ - up_read(&ni->run_list.lock); - if (!map_run_list(ni, vcn)) + up_read(&ni->runlist.lock); + if (!ntfs_map_runlist(ni, vcn)) goto lock_retry_remap; goto map_rl_err; } @@ -632,7 +638,7 @@ lock_retry_remap: /* Release the lock if we took it. */ if (rl) - up_read(&ni->run_list.lock); + up_read(&ni->runlist.lock); /* Setup and initiate io on all buffer heads. */ for (i = 0; i < nr_bhs; i++) { @@ -845,7 +851,7 @@ lock_retry_remap: if (err) { ntfs_error(vol->sb, "ntfs_decompress() failed in inode " "0x%lx with error code %i. Skipping " - "this compression block.\n", + "this compression block.", ni->mft_no, -err); /* Release the unfinished pages. */ for (; prev_cur_page < cur_page; prev_cur_page++) { @@ -882,7 +888,8 @@ lock_retry_remap: if (page) { ntfs_error(vol->sb, "Still have pages left! " "Terminating them with extreme " - "prejudice."); + "prejudice. Inode 0x%lx, page index " + "0x%lx.", ni->mft_no, page->index); if (cur_page == xpage && !xpage_done) SetPageError(page); flush_dcache_page(page); @@ -913,18 +920,18 @@ read_err: goto err_out; map_rl_err: - ntfs_error(vol->sb, "map_run_list() failed. Cannot read compression " - "block."); + ntfs_error(vol->sb, "ntfs_map_runlist() failed. Cannot read " + "compression block."); goto err_out; rl_err: - up_read(&ni->run_list.lock); - ntfs_error(vol->sb, "vcn_to_lcn() failed. Cannot read compression " - "block."); + up_read(&ni->runlist.lock); + ntfs_error(vol->sb, "ntfs_vcn_to_lcn() failed. Cannot read " + "compression block."); goto err_out; getblk_err: - up_read(&ni->run_list.lock); + up_read(&ni->runlist.lock); ntfs_error(vol->sb, "getblk() failed. Cannot read compression block."); err_out: