diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/check-integrity.c | 15 | ||||
-rw-r--r-- | fs/btrfs/compression.c | 6 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 44 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 4 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 27 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 2 |
6 files changed, 65 insertions, 33 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 8f9abedae2c3..badc6f141b6f 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -1585,6 +1585,18 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, | |||
1585 | ret = btrfs_map_block(state->root->fs_info, READ, | 1585 | ret = btrfs_map_block(state->root->fs_info, READ, |
1586 | bytenr, &length, &multi, mirror_num); | 1586 | bytenr, &length, &multi, mirror_num); |
1587 | 1587 | ||
1588 | if (ret) { | ||
1589 | block_ctx_out->start = 0; | ||
1590 | block_ctx_out->dev_bytenr = 0; | ||
1591 | block_ctx_out->len = 0; | ||
1592 | block_ctx_out->dev = NULL; | ||
1593 | block_ctx_out->datav = NULL; | ||
1594 | block_ctx_out->pagev = NULL; | ||
1595 | block_ctx_out->mem_to_free = NULL; | ||
1596 | |||
1597 | return ret; | ||
1598 | } | ||
1599 | |||
1588 | device = multi->stripes[0].dev; | 1600 | device = multi->stripes[0].dev; |
1589 | block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev); | 1601 | block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev); |
1590 | block_ctx_out->dev_bytenr = multi->stripes[0].physical; | 1602 | block_ctx_out->dev_bytenr = multi->stripes[0].physical; |
@@ -1594,8 +1606,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, | |||
1594 | block_ctx_out->pagev = NULL; | 1606 | block_ctx_out->pagev = NULL; |
1595 | block_ctx_out->mem_to_free = NULL; | 1607 | block_ctx_out->mem_to_free = NULL; |
1596 | 1608 | ||
1597 | if (0 == ret) | 1609 | kfree(multi); |
1598 | kfree(multi); | ||
1599 | if (NULL == block_ctx_out->dev) { | 1610 | if (NULL == block_ctx_out->dev) { |
1600 | ret = -ENXIO; | 1611 | ret = -ENXIO; |
1601 | printk(KERN_INFO "btrfsic: error, cannot lookup dev (#1)!\n"); | 1612 | printk(KERN_INFO "btrfsic: error, cannot lookup dev (#1)!\n"); |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index c6467aa88bee..94ab2f80e7e3 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -687,7 +687,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
687 | 687 | ||
688 | ret = btrfs_map_bio(root, READ, comp_bio, | 688 | ret = btrfs_map_bio(root, READ, comp_bio, |
689 | mirror_num, 0); | 689 | mirror_num, 0); |
690 | BUG_ON(ret); /* -ENOMEM */ | 690 | if (ret) |
691 | bio_endio(comp_bio, ret); | ||
691 | 692 | ||
692 | bio_put(comp_bio); | 693 | bio_put(comp_bio); |
693 | 694 | ||
@@ -712,7 +713,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
712 | } | 713 | } |
713 | 714 | ||
714 | ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); | 715 | ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); |
715 | BUG_ON(ret); /* -ENOMEM */ | 716 | if (ret) |
717 | bio_endio(comp_bio, ret); | ||
716 | 718 | ||
717 | bio_put(comp_bio); | 719 | bio_put(comp_bio); |
718 | return 0; | 720 | return 0; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 9d1b71060813..0e410478ad27 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -852,11 +852,16 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | |||
852 | int mirror_num, unsigned long bio_flags, | 852 | int mirror_num, unsigned long bio_flags, |
853 | u64 bio_offset) | 853 | u64 bio_offset) |
854 | { | 854 | { |
855 | int ret; | ||
856 | |||
855 | /* | 857 | /* |
856 | * when we're called for a write, we're already in the async | 858 | * when we're called for a write, we're already in the async |
857 | * submission context. Just jump into btrfs_map_bio | 859 | * submission context. Just jump into btrfs_map_bio |
858 | */ | 860 | */ |
859 | return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1); | 861 | ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1); |
862 | if (ret) | ||
863 | bio_endio(bio, ret); | ||
864 | return ret; | ||
860 | } | 865 | } |
861 | 866 | ||
862 | static int check_async_write(struct inode *inode, unsigned long bio_flags) | 867 | static int check_async_write(struct inode *inode, unsigned long bio_flags) |
@@ -878,7 +883,6 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
878 | int ret; | 883 | int ret; |
879 | 884 | ||
880 | if (!(rw & REQ_WRITE)) { | 885 | if (!(rw & REQ_WRITE)) { |
881 | |||
882 | /* | 886 | /* |
883 | * called for a read, do the setup so that checksum validation | 887 | * called for a read, do the setup so that checksum validation |
884 | * can happen in the async kernel threads | 888 | * can happen in the async kernel threads |
@@ -886,26 +890,32 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
886 | ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info, | 890 | ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info, |
887 | bio, 1); | 891 | bio, 1); |
888 | if (ret) | 892 | if (ret) |
889 | return ret; | 893 | goto out_w_error; |
890 | return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, | 894 | ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, |
891 | mirror_num, 0); | 895 | mirror_num, 0); |
892 | } else if (!async) { | 896 | } else if (!async) { |
893 | ret = btree_csum_one_bio(bio); | 897 | ret = btree_csum_one_bio(bio); |
894 | if (ret) | 898 | if (ret) |
895 | return ret; | 899 | goto out_w_error; |
896 | return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, | 900 | ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, |
897 | mirror_num, 0); | 901 | mirror_num, 0); |
902 | } else { | ||
903 | /* | ||
904 | * kthread helpers are used to submit writes so that | ||
905 | * checksumming can happen in parallel across all CPUs | ||
906 | */ | ||
907 | ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | ||
908 | inode, rw, bio, mirror_num, 0, | ||
909 | bio_offset, | ||
910 | __btree_submit_bio_start, | ||
911 | __btree_submit_bio_done); | ||
898 | } | 912 | } |
899 | 913 | ||
900 | /* | 914 | if (ret) { |
901 | * kthread helpers are used to submit writes so that checksumming | 915 | out_w_error: |
902 | * can happen in parallel across all CPUs | 916 | bio_endio(bio, ret); |
903 | */ | 917 | } |
904 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | 918 | return ret; |
905 | inode, rw, bio, mirror_num, 0, | ||
906 | bio_offset, | ||
907 | __btree_submit_bio_start, | ||
908 | __btree_submit_bio_done); | ||
909 | } | 919 | } |
910 | 920 | ||
911 | #ifdef CONFIG_MIGRATION | 921 | #ifdef CONFIG_MIGRATION |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 62ec6e45f705..1b319df29eee 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2462,10 +2462,6 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | |||
2462 | return bio; | 2462 | return bio; |
2463 | } | 2463 | } |
2464 | 2464 | ||
2465 | /* | ||
2466 | * Since writes are async, they will only return -ENOMEM. | ||
2467 | * Reads can return the full range of I/O error conditions. | ||
2468 | */ | ||
2469 | static int __must_check submit_one_bio(int rw, struct bio *bio, | 2465 | static int __must_check submit_one_bio(int rw, struct bio *bio, |
2470 | int mirror_num, unsigned long bio_flags) | 2466 | int mirror_num, unsigned long bio_flags) |
2471 | { | 2467 | { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5d1675a8c9e2..d7bf2e7ee8a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1602,7 +1602,12 @@ static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | |||
1602 | u64 bio_offset) | 1602 | u64 bio_offset) |
1603 | { | 1603 | { |
1604 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1604 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1605 | return btrfs_map_bio(root, rw, bio, mirror_num, 1); | 1605 | int ret; |
1606 | |||
1607 | ret = btrfs_map_bio(root, rw, bio, mirror_num, 1); | ||
1608 | if (ret) | ||
1609 | bio_endio(bio, ret); | ||
1610 | return ret; | ||
1606 | } | 1611 | } |
1607 | 1612 | ||
1608 | /* | 1613 | /* |
@@ -1626,15 +1631,17 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
1626 | if (!(rw & REQ_WRITE)) { | 1631 | if (!(rw & REQ_WRITE)) { |
1627 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, metadata); | 1632 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, metadata); |
1628 | if (ret) | 1633 | if (ret) |
1629 | return ret; | 1634 | goto out; |
1630 | 1635 | ||
1631 | if (bio_flags & EXTENT_BIO_COMPRESSED) { | 1636 | if (bio_flags & EXTENT_BIO_COMPRESSED) { |
1632 | return btrfs_submit_compressed_read(inode, bio, | 1637 | ret = btrfs_submit_compressed_read(inode, bio, |
1633 | mirror_num, bio_flags); | 1638 | mirror_num, |
1639 | bio_flags); | ||
1640 | goto out; | ||
1634 | } else if (!skip_sum) { | 1641 | } else if (!skip_sum) { |
1635 | ret = btrfs_lookup_bio_sums(root, inode, bio, NULL); | 1642 | ret = btrfs_lookup_bio_sums(root, inode, bio, NULL); |
1636 | if (ret) | 1643 | if (ret) |
1637 | return ret; | 1644 | goto out; |
1638 | } | 1645 | } |
1639 | goto mapit; | 1646 | goto mapit; |
1640 | } else if (!skip_sum) { | 1647 | } else if (!skip_sum) { |
@@ -1642,15 +1649,21 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
1642 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) | 1649 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) |
1643 | goto mapit; | 1650 | goto mapit; |
1644 | /* we're doing a write, do the async checksumming */ | 1651 | /* we're doing a write, do the async checksumming */ |
1645 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | 1652 | ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, |
1646 | inode, rw, bio, mirror_num, | 1653 | inode, rw, bio, mirror_num, |
1647 | bio_flags, bio_offset, | 1654 | bio_flags, bio_offset, |
1648 | __btrfs_submit_bio_start, | 1655 | __btrfs_submit_bio_start, |
1649 | __btrfs_submit_bio_done); | 1656 | __btrfs_submit_bio_done); |
1657 | goto out; | ||
1650 | } | 1658 | } |
1651 | 1659 | ||
1652 | mapit: | 1660 | mapit: |
1653 | return btrfs_map_bio(root, rw, bio, mirror_num, 0); | 1661 | ret = btrfs_map_bio(root, rw, bio, mirror_num, 0); |
1662 | |||
1663 | out: | ||
1664 | if (ret < 0) | ||
1665 | bio_endio(bio, ret); | ||
1666 | return ret; | ||
1654 | } | 1667 | } |
1655 | 1668 | ||
1656 | /* | 1669 | /* |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 31f7af878d96..415862885b67 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -4435,7 +4435,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
4435 | 4435 | ||
4436 | ret = btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, | 4436 | ret = btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, |
4437 | mirror_num); | 4437 | mirror_num); |
4438 | if (ret) /* -ENOMEM */ | 4438 | if (ret) |
4439 | return ret; | 4439 | return ret; |
4440 | 4440 | ||
4441 | total_devs = bbio->num_stripes; | 4441 | total_devs = bbio->num_stripes; |