diff options
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r-- | fs/btrfs/compression.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index f745287fbf2e..4d2110eafe29 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -562,7 +562,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
562 | u64 em_len; | 562 | u64 em_len; |
563 | u64 em_start; | 563 | u64 em_start; |
564 | struct extent_map *em; | 564 | struct extent_map *em; |
565 | int ret; | 565 | int ret = -ENOMEM; |
566 | u32 *sums; | 566 | u32 *sums; |
567 | 567 | ||
568 | tree = &BTRFS_I(inode)->io_tree; | 568 | tree = &BTRFS_I(inode)->io_tree; |
@@ -577,6 +577,9 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
577 | 577 | ||
578 | compressed_len = em->block_len; | 578 | compressed_len = em->block_len; |
579 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); | 579 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); |
580 | if (!cb) | ||
581 | goto out; | ||
582 | |||
580 | atomic_set(&cb->pending_bios, 0); | 583 | atomic_set(&cb->pending_bios, 0); |
581 | cb->errors = 0; | 584 | cb->errors = 0; |
582 | cb->inode = inode; | 585 | cb->inode = inode; |
@@ -597,13 +600,18 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
597 | 600 | ||
598 | nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / | 601 | nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / |
599 | PAGE_CACHE_SIZE; | 602 | PAGE_CACHE_SIZE; |
600 | cb->compressed_pages = kmalloc(sizeof(struct page *) * nr_pages, | 603 | cb->compressed_pages = kzalloc(sizeof(struct page *) * nr_pages, |
601 | GFP_NOFS); | 604 | GFP_NOFS); |
605 | if (!cb->compressed_pages) | ||
606 | goto fail1; | ||
607 | |||
602 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 608 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; |
603 | 609 | ||
604 | for (page_index = 0; page_index < nr_pages; page_index++) { | 610 | for (page_index = 0; page_index < nr_pages; page_index++) { |
605 | cb->compressed_pages[page_index] = alloc_page(GFP_NOFS | | 611 | cb->compressed_pages[page_index] = alloc_page(GFP_NOFS | |
606 | __GFP_HIGHMEM); | 612 | __GFP_HIGHMEM); |
613 | if (!cb->compressed_pages[page_index]) | ||
614 | goto fail2; | ||
607 | } | 615 | } |
608 | cb->nr_pages = nr_pages; | 616 | cb->nr_pages = nr_pages; |
609 | 617 | ||
@@ -614,6 +622,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
614 | cb->len = uncompressed_len; | 622 | cb->len = uncompressed_len; |
615 | 623 | ||
616 | comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); | 624 | comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); |
625 | if (!comp_bio) | ||
626 | goto fail2; | ||
617 | comp_bio->bi_private = cb; | 627 | comp_bio->bi_private = cb; |
618 | comp_bio->bi_end_io = end_compressed_bio_read; | 628 | comp_bio->bi_end_io = end_compressed_bio_read; |
619 | atomic_inc(&cb->pending_bios); | 629 | atomic_inc(&cb->pending_bios); |
@@ -681,6 +691,17 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
681 | 691 | ||
682 | bio_put(comp_bio); | 692 | bio_put(comp_bio); |
683 | return 0; | 693 | return 0; |
694 | |||
695 | fail2: | ||
696 | for (page_index = 0; page_index < nr_pages; page_index++) | ||
697 | free_page((unsigned long)cb->compressed_pages[page_index]); | ||
698 | |||
699 | kfree(cb->compressed_pages); | ||
700 | fail1: | ||
701 | kfree(cb); | ||
702 | out: | ||
703 | free_extent_map(em); | ||
704 | return ret; | ||
684 | } | 705 | } |
685 | 706 | ||
686 | static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; | 707 | static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; |
@@ -900,7 +921,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, | |||
900 | return ret; | 921 | return ret; |
901 | } | 922 | } |
902 | 923 | ||
903 | void __exit btrfs_exit_compress(void) | 924 | void btrfs_exit_compress(void) |
904 | { | 925 | { |
905 | free_workspaces(); | 926 | free_workspaces(); |
906 | } | 927 | } |