This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / fs / ntfs / compress.c
index fba39c9..2959ef1 100644 (file)
@@ -197,9 +197,15 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
 do_next_sb:
        ntfs_debug("Beginning sub-block at offset = 0x%x 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((u16*)cb) ||
+                       (*dest_index == dest_max_index &&
+                       *dest_ofs == dest_max_ofs)) {
                int i;
 
                ntfs_debug("Completed. Returning success (0).");
@@ -501,7 +507,7 @@ int ntfs_read_compressed_block(struct page *page)
         */
        unsigned int nr_pages = (end_vcn - start_vcn) <<
                        vol->cluster_size_bits >> PAGE_CACHE_SHIFT;
-       unsigned int xpage, max_page, cur_page, cur_ofs, i;
+       unsigned int xpage, max_page, max_ofs, cur_page, cur_ofs, i;
        unsigned int cb_clusters, cb_max_ofs;
        int block, max_block, cb_max_page, bhs_size, nr_bhs, err = 0;
        struct page **pages;
@@ -544,8 +550,11 @@ int ntfs_read_compressed_block(struct page *page)
         */
        max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >>
                        PAGE_CACHE_SHIFT) - offset;
-       if (nr_pages < max_page)
+       max_ofs = (VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) & ~PAGE_CACHE_MASK;
+       if (nr_pages < max_page) {
                max_page = nr_pages;
+               max_ofs = 0;
+       }
        for (i = 0; i < max_page; i++, offset++) {
                if (i != xpage)
                        pages[i] = grab_cache_page_nowait(mapping, offset);
@@ -713,8 +722,14 @@ lock_retry_remap:
        cb_max_page >>= PAGE_CACHE_SHIFT;
 
        /* Catch end of file inside a compression block. */
-       if (cb_max_page > max_page)
-               cb_max_page = max_page;
+       if (cb_max_page >= max_page) {
+               if (cb_max_page > max_page) {
+                       cb_max_page = max_page;
+                       cb_max_ofs = max_ofs;
+               } else if (cb_max_ofs > max_ofs) {
+                       cb_max_ofs = max_ofs;
+               }
+       }
 
        if (vcn == start_vcn - cb_clusters) {
                /* Sparse cb, zero out page range overlapping the cb. */