bi_size += bvec->bv_len;
 
        if (bio->bi_status)
-               cb->errors = 1;
+               cb->status = bio->bi_status;
 
        ASSERT(bi_size && bi_size <= cb->compressed_len);
        last_io = refcount_sub_and_test(bi_size >> fs_info->sectorsize_bits,
        }
 
        /* Do io completion on the original bio */
-       if (cb->errors) {
-               bio_io_error(cb->orig_bio);
+       if (cb->status != BLK_STS_OK) {
+               cb->orig_bio->bi_status = cb->status;
+               bio_endio(cb->orig_bio);
        } else {
                struct bio_vec *bvec;
                struct bvec_iter_all iter_all;
         * Some IO in this cb have failed, just skip checksum as there
         * is no way it could be correct.
         */
-       if (cb->errors == 1)
+       if (cb->status != BLK_STS_OK)
                goto csum_failed;
 
        inode = cb->inode;
 
 csum_failed:
        if (ret)
-               cb->errors = 1;
+               cb->status = errno_to_blk_status(ret);
        finish_compressed_bio_read(cb);
 out:
        bio_put(bio);
        unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT;
        struct page *pages[16];
        unsigned long nr_pages = end_index - index + 1;
+       const int errno = blk_status_to_errno(cb->status);
        int i;
        int ret;
 
-       if (cb->errors)
-               mapping_set_error(inode->i_mapping, -EIO);
+       if (errno)
+               mapping_set_error(inode->i_mapping, errno);
 
        while (nr_pages > 0) {
                ret = find_get_pages_contig(inode->i_mapping, index,
                        continue;
                }
                for (i = 0; i < ret; i++) {
-                       if (cb->errors)
+                       if (errno)
                                SetPageError(pages[i]);
                        btrfs_page_clamp_clear_writeback(fs_info, pages[i],
                                                         cb->start, cb->len);
         */
        btrfs_writepage_endio_finish_ordered(BTRFS_I(inode), NULL,
                        cb->start, cb->start + cb->len - 1,
-                       !cb->errors);
+                       cb->status == BLK_STS_OK);
 
        if (cb->writeback)
                end_compressed_writeback(inode, cb);
        if (!cb)
                return BLK_STS_RESOURCE;
        refcount_set(&cb->pending_sectors, compressed_len >> fs_info->sectorsize_bits);
-       cb->errors = 0;
+       cb->status = BLK_STS_OK;
        cb->inode = &inode->vfs_inode;
        cb->start = start;
        cb->len = len;
                goto out;
 
        refcount_set(&cb->pending_sectors, compressed_len >> fs_info->sectorsize_bits);
-       cb->errors = 0;
+       cb->status = BLK_STS_OK;
        cb->inode = inode;
        cb->mirror_num = mirror_num;
        sums = cb->sums;