Commit 98310e581e098514867573031b2bfa4ba89c0d93

Authored by David VomLehn
Committed by Linus Torvalds
1 parent 6e873ec71d

cramfs: propagate uncompression errors

Decompression errors can arise due to corruption of compressed blocks on
flash or in memory.  This patch propagates errors detected during
decompression back to the block layer.

Signed-off-by: David VomLehn <dvomlehn@cisco.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 27 additions and 11 deletions Side-by-side Diff

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