diff options
Diffstat (limited to 'fs/cramfs')
-rw-r--r-- | fs/cramfs/inode.c | 36 | ||||
-rw-r--r-- | fs/cramfs/uncompress.c | 2 |
2 files changed, 27 insertions, 11 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a07338d2d140..46e52980b98a 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -459,11 +459,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
459 | static int cramfs_readpage(struct file *file, struct page * page) | 459 | static int cramfs_readpage(struct file *file, struct page * page) |
460 | { | 460 | { |
461 | struct inode *inode = page->mapping->host; | 461 | struct inode *inode = page->mapping->host; |
462 | u32 maxblock, bytes_filled; | 462 | u32 maxblock; |
463 | int bytes_filled; | ||
463 | void *pgdata; | 464 | void *pgdata; |
464 | 465 | ||
465 | maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 466 | maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
466 | bytes_filled = 0; | 467 | bytes_filled = 0; |
468 | pgdata = kmap(page); | ||
469 | |||
467 | if (page->index < maxblock) { | 470 | if (page->index < maxblock) { |
468 | struct super_block *sb = inode->i_sb; | 471 | struct super_block *sb = inode->i_sb; |
469 | u32 blkptr_offset = OFFSET(inode) + page->index*4; | 472 | u32 blkptr_offset = OFFSET(inode) + page->index*4; |
@@ -472,30 +475,43 @@ static int cramfs_readpage(struct file *file, struct page * page) | |||
472 | start_offset = OFFSET(inode) + maxblock*4; | 475 | start_offset = OFFSET(inode) + maxblock*4; |
473 | mutex_lock(&read_mutex); | 476 | mutex_lock(&read_mutex); |
474 | if (page->index) | 477 | if (page->index) |
475 | start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); | 478 | start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, |
476 | compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset); | 479 | 4); |
480 | compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - | ||
481 | start_offset); | ||
477 | mutex_unlock(&read_mutex); | 482 | mutex_unlock(&read_mutex); |
478 | pgdata = kmap(page); | 483 | |
479 | if (compr_len == 0) | 484 | if (compr_len == 0) |
480 | ; /* hole */ | 485 | ; /* hole */ |
481 | else if (compr_len > (PAGE_CACHE_SIZE << 1)) | 486 | else if (unlikely(compr_len > (PAGE_CACHE_SIZE << 1))) { |
482 | printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); | 487 | pr_err("cramfs: bad compressed blocksize %u\n", |
483 | else { | 488 | compr_len); |
489 | goto err; | ||
490 | } else { | ||
484 | mutex_lock(&read_mutex); | 491 | mutex_lock(&read_mutex); |
485 | bytes_filled = cramfs_uncompress_block(pgdata, | 492 | bytes_filled = cramfs_uncompress_block(pgdata, |
486 | PAGE_CACHE_SIZE, | 493 | PAGE_CACHE_SIZE, |
487 | cramfs_read(sb, start_offset, compr_len), | 494 | cramfs_read(sb, start_offset, compr_len), |
488 | compr_len); | 495 | compr_len); |
489 | mutex_unlock(&read_mutex); | 496 | mutex_unlock(&read_mutex); |
497 | if (unlikely(bytes_filled < 0)) | ||
498 | goto err; | ||
490 | } | 499 | } |
491 | } else | 500 | } |
492 | pgdata = kmap(page); | 501 | |
493 | memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); | 502 | memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); |
494 | kunmap(page); | ||
495 | flush_dcache_page(page); | 503 | flush_dcache_page(page); |
504 | kunmap(page); | ||
496 | SetPageUptodate(page); | 505 | SetPageUptodate(page); |
497 | unlock_page(page); | 506 | unlock_page(page); |
498 | return 0; | 507 | return 0; |
508 | |||
509 | err: | ||
510 | kunmap(page); | ||
511 | ClearPageUptodate(page); | ||
512 | SetPageError(page); | ||
513 | unlock_page(page); | ||
514 | return 0; | ||
499 | } | 515 | } |
500 | 516 | ||
501 | static const struct address_space_operations cramfs_aops = { | 517 | static const struct address_space_operations cramfs_aops = { |
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index fc3ccb74626f..023329800d2e 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c | |||
@@ -50,7 +50,7 @@ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen) | |||
50 | err: | 50 | err: |
51 | printk("Error %d while decompressing!\n", err); | 51 | printk("Error %d while decompressing!\n", err); |
52 | printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); | 52 | printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); |
53 | return 0; | 53 | return -EIO; |
54 | } | 54 | } |
55 | 55 | ||
56 | int cramfs_uncompress_init(void) | 56 | int cramfs_uncompress_init(void) |