diff options
Diffstat (limited to 'fs/cramfs/inode.c')
-rw-r--r-- | fs/cramfs/inode.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a07338d2d140..dd3634e4c967 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -318,6 +318,7 @@ out: | |||
318 | static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 318 | static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
319 | { | 319 | { |
320 | struct super_block *sb = dentry->d_sb; | 320 | struct super_block *sb = dentry->d_sb; |
321 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | ||
321 | 322 | ||
322 | buf->f_type = CRAMFS_MAGIC; | 323 | buf->f_type = CRAMFS_MAGIC; |
323 | buf->f_bsize = PAGE_CACHE_SIZE; | 324 | buf->f_bsize = PAGE_CACHE_SIZE; |
@@ -326,6 +327,8 @@ static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
326 | buf->f_bavail = 0; | 327 | buf->f_bavail = 0; |
327 | buf->f_files = CRAMFS_SB(sb)->files; | 328 | buf->f_files = CRAMFS_SB(sb)->files; |
328 | buf->f_ffree = 0; | 329 | buf->f_ffree = 0; |
330 | buf->f_fsid.val[0] = (u32)id; | ||
331 | buf->f_fsid.val[1] = (u32)(id >> 32); | ||
329 | buf->f_namelen = CRAMFS_MAXPATHLEN; | 332 | buf->f_namelen = CRAMFS_MAXPATHLEN; |
330 | return 0; | 333 | return 0; |
331 | } | 334 | } |
@@ -459,11 +462,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
459 | static int cramfs_readpage(struct file *file, struct page * page) | 462 | static int cramfs_readpage(struct file *file, struct page * page) |
460 | { | 463 | { |
461 | struct inode *inode = page->mapping->host; | 464 | struct inode *inode = page->mapping->host; |
462 | u32 maxblock, bytes_filled; | 465 | u32 maxblock; |
466 | int bytes_filled; | ||
463 | void *pgdata; | 467 | void *pgdata; |
464 | 468 | ||
465 | maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 469 | maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
466 | bytes_filled = 0; | 470 | bytes_filled = 0; |
471 | pgdata = kmap(page); | ||
472 | |||
467 | if (page->index < maxblock) { | 473 | if (page->index < maxblock) { |
468 | struct super_block *sb = inode->i_sb; | 474 | struct super_block *sb = inode->i_sb; |
469 | u32 blkptr_offset = OFFSET(inode) + page->index*4; | 475 | u32 blkptr_offset = OFFSET(inode) + page->index*4; |
@@ -472,30 +478,43 @@ static int cramfs_readpage(struct file *file, struct page * page) | |||
472 | start_offset = OFFSET(inode) + maxblock*4; | 478 | start_offset = OFFSET(inode) + maxblock*4; |
473 | mutex_lock(&read_mutex); | 479 | mutex_lock(&read_mutex); |
474 | if (page->index) | 480 | if (page->index) |
475 | start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); | 481 | start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, |
476 | compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset); | 482 | 4); |
483 | compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - | ||
484 | start_offset); | ||
477 | mutex_unlock(&read_mutex); | 485 | mutex_unlock(&read_mutex); |
478 | pgdata = kmap(page); | 486 | |
479 | if (compr_len == 0) | 487 | if (compr_len == 0) |
480 | ; /* hole */ | 488 | ; /* hole */ |
481 | else if (compr_len > (PAGE_CACHE_SIZE << 1)) | 489 | else if (unlikely(compr_len > (PAGE_CACHE_SIZE << 1))) { |
482 | printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); | 490 | pr_err("cramfs: bad compressed blocksize %u\n", |
483 | else { | 491 | compr_len); |
492 | goto err; | ||
493 | } else { | ||
484 | mutex_lock(&read_mutex); | 494 | mutex_lock(&read_mutex); |
485 | bytes_filled = cramfs_uncompress_block(pgdata, | 495 | bytes_filled = cramfs_uncompress_block(pgdata, |
486 | PAGE_CACHE_SIZE, | 496 | PAGE_CACHE_SIZE, |
487 | cramfs_read(sb, start_offset, compr_len), | 497 | cramfs_read(sb, start_offset, compr_len), |
488 | compr_len); | 498 | compr_len); |
489 | mutex_unlock(&read_mutex); | 499 | mutex_unlock(&read_mutex); |
500 | if (unlikely(bytes_filled < 0)) | ||
501 | goto err; | ||
490 | } | 502 | } |
491 | } else | 503 | } |
492 | pgdata = kmap(page); | 504 | |
493 | memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); | 505 | memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); |
494 | kunmap(page); | ||
495 | flush_dcache_page(page); | 506 | flush_dcache_page(page); |
507 | kunmap(page); | ||
496 | SetPageUptodate(page); | 508 | SetPageUptodate(page); |
497 | unlock_page(page); | 509 | unlock_page(page); |
498 | return 0; | 510 | return 0; |
511 | |||
512 | err: | ||
513 | kunmap(page); | ||
514 | ClearPageUptodate(page); | ||
515 | SetPageError(page); | ||
516 | unlock_page(page); | ||
517 | return 0; | ||
499 | } | 518 | } |
500 | 519 | ||
501 | static const struct address_space_operations cramfs_aops = { | 520 | static const struct address_space_operations cramfs_aops = { |