zisofs: fix readpage() outside i_size
[sfrench/cifs-2.6.git] / fs / isofs / compress.c
index 6bbbdb53581d1bb42b1db87f88a4de9799b82808..defb932eee9a9f45836ac2f62ee9dcf5f3838152 100644 (file)
@@ -33,7 +33,7 @@ static char zisofs_sink_page[PAGE_CACHE_SIZE];
  * allocation; this avoids failures at block-decompression time.
  */
 static void *zisofs_zlib_workspace;
-static struct semaphore zisofs_zlib_semaphore;
+static DEFINE_MUTEX(zisofs_zlib_lock);
 
 /*
  * When decompressing, we typically obtain more than one page
@@ -72,6 +72,17 @@ static int zisofs_readpage(struct file *file, struct page *page)
        offset = index & ~zisofs_block_page_mask;
        blockindex = offset >> zisofs_block_page_shift;
        maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
+       /*
+        * If this page is wholly outside i_size we just return zero;
+        * do_generic_file_read() will handle this for us
+        */
+       if (page->index >= maxpage) {
+               SetPageUptodate(page);
+               unlock_page(page);
+               return 0;
+       }
+
        maxpage = min(zisofs_block_pages, maxpage-offset);
 
        for ( i = 0 ; i < maxpage ; i++, offset++ ) {
@@ -180,9 +191,9 @@ static int zisofs_readpage(struct file *file, struct page *page)
 
                /* First block is special since it may be fractional.
                   We also wait for it before grabbing the zlib
-                  semaphore; odds are that the subsequent blocks are
+                  mutex; odds are that the subsequent blocks are
                   going to come in in short order so we don't hold
-                  the zlib semaphore longer than necessary. */
+                  the zlib mutex longer than necessary. */
 
                if ( !bh || (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
                        printk(KERN_DEBUG "zisofs: Hit null buffer, fpage = %d, xpage = %d, csize = %ld\n",
@@ -194,7 +205,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
                csize -= stream.avail_in;
 
                stream.workspace = zisofs_zlib_workspace;
-               down(&zisofs_zlib_semaphore);
+               mutex_lock(&zisofs_zlib_lock);
                
                zerr = zlib_inflateInit(&stream);
                if ( zerr != Z_OK ) {
@@ -281,7 +292,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
                zlib_inflateEnd(&stream);
 
        z_eio:
-               up(&zisofs_zlib_semaphore);
+               mutex_unlock(&zisofs_zlib_lock);
 
        b_eio:
                for ( i = 0 ; i < haveblocks ; i++ ) {
@@ -317,31 +328,16 @@ const struct address_space_operations zisofs_aops = {
        /* No bmap operation supported */
 };
 
-static int initialized;
-
 int __init zisofs_init(void)
 {
-       if ( initialized ) {
-               printk("zisofs_init: called more than once\n");
-               return 0;
-       }
-
        zisofs_zlib_workspace = vmalloc(zlib_inflate_workspacesize());
        if ( !zisofs_zlib_workspace )
                return -ENOMEM;
-       init_MUTEX(&zisofs_zlib_semaphore);
 
-       initialized = 1;
        return 0;
 }
 
 void zisofs_cleanup(void)
 {
-       if ( !initialized ) {
-               printk("zisofs_cleanup: called without initialization\n");
-               return;
-       }
-
        vfree(zisofs_zlib_workspace);
-       initialized = 0;
 }