Commit 6b82ce8d824bd46053e46a895876cde39d9026e4

Authored by liubo
Committed by Chris Mason
1 parent eab49bec41

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