Commit 5a2c6075 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: make set_btree_ioerr accept extent buffer and be subpage compatible



Current set_btree_ioerr() only accepts @page parameter and grabs extent
buffer from page::private.  This works fine for sector size == PAGE_SIZE
case, but not for subpage case.

Add an extra parameter, @eb, for callers to pass extent buffer to this
function, so that subpage code can reuse this function.

And also add subpage special handling to update
btrfs_subpage::error_bitmap.

Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 0d27797e
Loading
Loading
Loading
Loading
+8 −10
Original line number Original line Diff line number Diff line
@@ -4012,12 +4012,11 @@ static noinline_for_stack int lock_extent_buffer_for_io(struct extent_buffer *eb
	return ret;
	return ret;
}
}


static void set_btree_ioerr(struct page *page)
static void set_btree_ioerr(struct page *page, struct extent_buffer *eb)
{
{
	struct extent_buffer *eb = (struct extent_buffer *)page->private;
	struct btrfs_fs_info *fs_info = eb->fs_info;
	struct btrfs_fs_info *fs_info;


	SetPageError(page);
	btrfs_page_set_error(fs_info, page, eb->start, eb->len);
	if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags))
	if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags))
		return;
		return;


@@ -4025,7 +4024,6 @@ static void set_btree_ioerr(struct page *page)
	 * If we error out, we should add back the dirty_metadata_bytes
	 * If we error out, we should add back the dirty_metadata_bytes
	 * to make it consistent.
	 * to make it consistent.
	 */
	 */
	fs_info = eb->fs_info;
	percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
	percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
				 eb->len, fs_info->dirty_metadata_batch);
				 eb->len, fs_info->dirty_metadata_batch);


@@ -4069,13 +4067,13 @@ static void set_btree_ioerr(struct page *page)
	 */
	 */
	switch (eb->log_index) {
	switch (eb->log_index) {
	case -1:
	case -1:
		set_bit(BTRFS_FS_BTREE_ERR, &eb->fs_info->flags);
		set_bit(BTRFS_FS_BTREE_ERR, &fs_info->flags);
		break;
		break;
	case 0:
	case 0:
		set_bit(BTRFS_FS_LOG1_ERR, &eb->fs_info->flags);
		set_bit(BTRFS_FS_LOG1_ERR, &fs_info->flags);
		break;
		break;
	case 1:
	case 1:
		set_bit(BTRFS_FS_LOG2_ERR, &eb->fs_info->flags);
		set_bit(BTRFS_FS_LOG2_ERR, &fs_info->flags);
		break;
		break;
	default:
	default:
		BUG(); /* unexpected, logic error */
		BUG(); /* unexpected, logic error */
@@ -4100,7 +4098,7 @@ static void end_bio_extent_buffer_writepage(struct bio *bio)
		if (bio->bi_status ||
		if (bio->bi_status ||
		    test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) {
		    test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) {
			ClearPageUptodate(page);
			ClearPageUptodate(page);
			set_btree_ioerr(page);
			set_btree_ioerr(page, eb);
		}
		}


		end_page_writeback(page);
		end_page_writeback(page);
@@ -4156,7 +4154,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
					 end_bio_extent_buffer_writepage,
					 end_bio_extent_buffer_writepage,
					 0, 0, 0, false);
					 0, 0, 0, false);
		if (ret) {
		if (ret) {
			set_btree_ioerr(p);
			set_btree_ioerr(p, eb);
			if (PageWriteback(p))
			if (PageWriteback(p))
				end_page_writeback(p);
				end_page_writeback(p);
			if (atomic_sub_and_test(num_pages - i, &eb->io_pages))
			if (atomic_sub_and_test(num_pages - i, &eb->io_pages))