提交 98310e58 编写于 作者: D David VomLehn 提交者: Linus Torvalds

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: NDavid VomLehn <dvomlehn@cisco.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 6e873ec7
......@@ -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;
......@@ -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 = {
......
......@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册