Skip to content

Commit

Permalink
cramfs: propagate uncompression errors
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
David VomLehn authored and torvalds committed Apr 3, 2009
1 parent 6e873ec commit 98310e5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
36 changes: 26 additions & 10 deletions fs/cramfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s
static int cramfs_readpage(struct file *file, struct page * page)
{
struct inode *inode = page->mapping->host;
u32 maxblock, bytes_filled;
u32 maxblock;
int bytes_filled;
void *pgdata;

maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
bytes_filled = 0;
pgdata = kmap(page);

if (page->index < maxblock) {
struct super_block *sb = inode->i_sb;
u32 blkptr_offset = OFFSET(inode) + page->index*4;
Expand All @@ -472,30 +475,43 @@ static int cramfs_readpage(struct file *file, struct page * page)
start_offset = OFFSET(inode) + maxblock*4;
mutex_lock(&read_mutex);
if (page->index)
start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4);
compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset);
start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4,
4);
compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) -
start_offset);
mutex_unlock(&read_mutex);
pgdata = kmap(page);

if (compr_len == 0)
; /* hole */
else if (compr_len > (PAGE_CACHE_SIZE << 1))
printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len);
else {
else if (unlikely(compr_len > (PAGE_CACHE_SIZE << 1))) {
pr_err("cramfs: bad compressed blocksize %u\n",
compr_len);
goto err;
} else {
mutex_lock(&read_mutex);
bytes_filled = cramfs_uncompress_block(pgdata,
PAGE_CACHE_SIZE,
cramfs_read(sb, start_offset, compr_len),
compr_len);
mutex_unlock(&read_mutex);
if (unlikely(bytes_filled < 0))
goto err;
}
} else
pgdata = kmap(page);
}

memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled);
kunmap(page);
flush_dcache_page(page);
kunmap(page);
SetPageUptodate(page);
unlock_page(page);
return 0;

err:
kunmap(page);
ClearPageUptodate(page);
SetPageError(page);
unlock_page(page);
return 0;
}

static const struct address_space_operations cramfs_aops = {
Expand Down
2 changes: 1 addition & 1 deletion fs/cramfs/uncompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
err:
printk("Error %d while decompressing!\n", err);
printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
return 0;
return -EIO;
}

int cramfs_uncompress_init(void)
Expand Down

0 comments on commit 98310e5

Please sign in to comment.