Commit 6b82ce8d824bd46053e46a895876cde39d9026e4
Committed by
Chris Mason
1 parent
eab49bec41
Exists in
master
and in
7 other branches
btrfs: fix uncheck memory allocation in btrfs_submit_compressed_read
btrfs_submit_compressed_read() is lack of memory allocation checks and corresponding error route. After this fix, if it comes to "no memory" case, errno will be returned to userland step by step, and tell users this operation cannot go on. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Showing 2 changed files with 25 additions and 4 deletions Side-by-side Diff
fs/btrfs/compression.c
... | ... | @@ -562,7 +562,7 @@ |
562 | 562 | u64 em_len; |
563 | 563 | u64 em_start; |
564 | 564 | struct extent_map *em; |
565 | - int ret; | |
565 | + int ret = -ENOMEM; | |
566 | 566 | u32 *sums; |
567 | 567 | |
568 | 568 | tree = &BTRFS_I(inode)->io_tree; |
... | ... | @@ -577,6 +577,9 @@ |
577 | 577 | |
578 | 578 | compressed_len = em->block_len; |
579 | 579 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); |
580 | + if (!cb) | |
581 | + goto out; | |
582 | + | |
580 | 583 | atomic_set(&cb->pending_bios, 0); |
581 | 584 | cb->errors = 0; |
582 | 585 | cb->inode = inode; |
583 | 586 | |
584 | 587 | |
... | ... | @@ -597,13 +600,18 @@ |
597 | 600 | |
598 | 601 | nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / |
599 | 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 | 604 | GFP_NOFS); |
605 | + if (!cb->compressed_pages) | |
606 | + goto fail1; | |
607 | + | |
602 | 608 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; |
603 | 609 | |
604 | 610 | for (page_index = 0; page_index < nr_pages; page_index++) { |
605 | 611 | cb->compressed_pages[page_index] = alloc_page(GFP_NOFS | |
606 | 612 | __GFP_HIGHMEM); |
613 | + if (!cb->compressed_pages[page_index]) | |
614 | + goto fail2; | |
607 | 615 | } |
608 | 616 | cb->nr_pages = nr_pages; |
609 | 617 | |
... | ... | @@ -614,6 +622,8 @@ |
614 | 622 | cb->len = uncompressed_len; |
615 | 623 | |
616 | 624 | comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); |
625 | + if (!comp_bio) | |
626 | + goto fail2; | |
617 | 627 | comp_bio->bi_private = cb; |
618 | 628 | comp_bio->bi_end_io = end_compressed_bio_read; |
619 | 629 | atomic_inc(&cb->pending_bios); |
... | ... | @@ -681,6 +691,17 @@ |
681 | 691 | |
682 | 692 | bio_put(comp_bio); |
683 | 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 | 707 | static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; |
fs/btrfs/extent_io.c
... | ... | @@ -1865,7 +1865,7 @@ |
1865 | 1865 | bio_get(bio); |
1866 | 1866 | |
1867 | 1867 | if (tree->ops && tree->ops->submit_bio_hook) |
1868 | - tree->ops->submit_bio_hook(page->mapping->host, rw, bio, | |
1868 | + ret = tree->ops->submit_bio_hook(page->mapping->host, rw, bio, | |
1869 | 1869 | mirror_num, bio_flags, start); |
1870 | 1870 | else |
1871 | 1871 | submit_bio(rw, bio); |
... | ... | @@ -2126,7 +2126,7 @@ |
2126 | 2126 | ret = __extent_read_full_page(tree, page, get_extent, &bio, 0, |
2127 | 2127 | &bio_flags); |
2128 | 2128 | if (bio) |
2129 | - submit_one_bio(READ, bio, 0, bio_flags); | |
2129 | + ret = submit_one_bio(READ, bio, 0, bio_flags); | |
2130 | 2130 | return ret; |
2131 | 2131 | } |
2132 | 2132 |