aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/check-integrity.c15
-rw-r--r--fs/btrfs/compression.c6
-rw-r--r--fs/btrfs/disk-io.c44
-rw-r--r--fs/btrfs/extent_io.c4
-rw-r--r--fs/btrfs/inode.c27
-rw-r--r--fs/btrfs/volumes.c2
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
862static int check_async_write(struct inode *inode, unsigned long bio_flags) 867static 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 915out_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 */
2469static int __must_check submit_one_bio(int rw, struct bio *bio, 2465static 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
1652mapit: 1660mapit:
1653 return btrfs_map_bio(root, rw, bio, mirror_num, 0); 1661 ret = btrfs_map_bio(root, rw, bio, mirror_num, 0);
1662
1663out:
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;