Commit 78e62c02 authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba
Browse files

btrfs: Remove extent_io_ops::readpage_io_failed_hook



For data inodes this hook does nothing but to return -EAGAIN which is
used to signal to the endio routines that this bio belongs to a data
inode. If this is the case the actual retrying is handled by
bio_readpage_error. Alternatively, if this bio belongs to the btree
inode then btree_io_failed_hook just does some cleanup and doesn't retry
anything.

This patch simplifies the code flow by eliminating
readpage_io_failed_hook and instead open-coding btree_io_failed_hook in
end_bio_extent_readpage. Also eliminate some needless checks since IO is
always performed on either data inode or btree inode, both of which are
guaranteed to have their extent_io_tree::ops set.

Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 7b41ba71
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -673,19 +673,6 @@ out:
	return ret;
}

static int btree_io_failed_hook(struct page *page, int failed_mirror)
{
	struct extent_buffer *eb;

	eb = (struct extent_buffer *)page->private;
	set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
	eb->read_mirror = failed_mirror;
	atomic_dec(&eb->io_pages);
	if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))
		btree_readahead_hook(eb, -EIO);
	return -EIO;	/* we fixed nothing */
}

static void end_workqueue_bio(struct bio *bio)
{
	struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
@@ -4560,7 +4547,4 @@ static const struct extent_io_ops btree_extent_io_ops = {
	/* mandatory callbacks */
	.submit_bio_hook = btree_submit_bio_hook,
	.readpage_end_io_hook = btree_readpage_end_io_hook,
	.readpage_io_failed_hook = btree_io_failed_hook,

	/* optional callbacks */
};
+35 −36
Original line number Diff line number Diff line
@@ -2333,13 +2333,11 @@ struct bio *btrfs_create_repair_bio(struct inode *inode, struct bio *failed_bio,
}

/*
 * this is a generic handler for readpage errors (default
 * readpage_io_failed_hook). if other copies exist, read those and write back
 * good data to the failed position. does not investigate in remapping the
 * failed extent elsewhere, hoping the device will be smart enough to do this as
 * needed
 * This is a generic handler for readpage errors. If other copies exist, read
 * those and write back good data to the failed position. Does not investigate
 * in remapping the failed extent elsewhere, hoping the device will be smart
 * enough to do this as needed
 */

static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
			      struct page *page, u64 start, u64 end,
			      int failed_mirror)
@@ -2501,6 +2499,8 @@ static void end_bio_extent_readpage(struct bio *bio)
		struct page *page = bvec->bv_page;
		struct inode *inode = page->mapping->host;
		struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
		bool data_inode = btrfs_ino(BTRFS_I(inode))
			!= BTRFS_BTREE_INODE_OBJECTID;

		btrfs_debug(fs_info,
			"end_bio_extent_readpage: bi_sector=%llu, err=%d, mirror=%u",
@@ -2530,7 +2530,7 @@ static void end_bio_extent_readpage(struct bio *bio)
		len = bvec->bv_len;

		mirror = io_bio->mirror_num;
		if (likely(uptodate && tree->ops)) {
		if (likely(uptodate)) {
			ret = tree->ops->readpage_end_io_hook(io_bio, offset,
							      page, start, end,
							      mirror);
@@ -2546,38 +2546,37 @@ static void end_bio_extent_readpage(struct bio *bio)
		if (likely(uptodate))
			goto readpage_ok;

		if (tree->ops) {
			ret = tree->ops->readpage_io_failed_hook(page, mirror);
			if (ret == -EAGAIN) {
		if (data_inode) {

			/*
				 * Data inode's readpage_io_failed_hook() always
				 * returns -EAGAIN.
				 *
				 * The generic bio_readpage_error handles errors
				 * the following way: If possible, new read
				 * requests are created and submitted and will
				 * end up in end_bio_extent_readpage as well (if
				 * we're lucky, not in the !uptodate case). In
				 * that case it returns 0 and we just go on with
				 * the next page in our bio. If it can't handle
				 * the error it will return -EIO and we remain
				 * responsible for that page.
				 */
				ret = bio_readpage_error(bio, offset, page,
							 start, end, mirror);
			 * The generic bio_readpage_error handles errors the
			 * following way: If possible, new read requests are
			 * created and submitted and will end up in
			 * end_bio_extent_readpage as well (if we're lucky,
			 * not in the !uptodate case). In that case it returns
			 * 0 and we just go on with the next page in our bio.
			 * If it can't handle the error it will return -EIO and
			 * we remain responsible for that page.
			 */
			ret = bio_readpage_error(bio, offset, page, start, end,
						 mirror);
			if (ret == 0) {
				uptodate = !bio->bi_status;
				offset += len;
				continue;
			}
			}
		} else {
			struct extent_buffer *eb;

			/*
			 * metadata's readpage_io_failed_hook() always returns
			 * -EIO and fixes nothing.  -EIO is also returned if
			 * data inode error could not be fixed.
			 */
			ASSERT(ret == -EIO);
			eb = (struct extent_buffer *)page->private;
			set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
			eb->read_mirror = mirror;
			atomic_dec(&eb->io_pages);
			if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD,
					       &eb->bflags))
				btree_readahead_hook(eb, -EIO);

			ret = -EIO;
		}
readpage_ok:
		if (likely(uptodate)) {
+0 −1
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ struct extent_io_ops {
	int (*readpage_end_io_hook)(struct btrfs_io_bio *io_bio, u64 phy_offset,
				    struct page *page, u64 start, u64 end,
				    int mirror);
	int (*readpage_io_failed_hook)(struct page *page, int failed_mirror);
};

struct extent_io_tree {
+0 −7
Original line number Diff line number Diff line
@@ -10409,12 +10409,6 @@ out:
	return ret;
}

__attribute__((const))
static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror)
{
	return -EAGAIN;
}

void btrfs_set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
{
	struct inode *inode = tree->private_data;
@@ -10810,7 +10804,6 @@ static const struct extent_io_ops btrfs_extent_io_ops = {
	/* mandatory callbacks */
	.submit_bio_hook = btrfs_submit_bio_hook,
	.readpage_end_io_hook = btrfs_readpage_end_io_hook,
	.readpage_io_failed_hook = btrfs_readpage_io_failed_hook,
};

/*