Commit 2d83ed6c authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: return any hit error from extent_writepage_io()



Since the support of bs < ps support, extent_writepage_io() will submit
multiple blocks inside the folio.

But if we hit error submitting one sector, but the next sector can still
be submitted successfully, the function extent_writepage_io() will still
return 0.

This will make btrfs to silently ignore the error without setting error
flag for the filemap.

Fix it by recording the first error hit, and always return that value.

Fixes: 8bf334be ("btrfs: fix double accounting race when extent_writepage_io() failed")
Reviewed-by: default avatarDaniel Vacek <neelx@suse.com>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 5afe85b7
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1679,7 +1679,7 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	unsigned long range_bitmap = 0;
	bool submitted_io = false;
	bool error = false;
	int found_error = 0;
	const u64 folio_start = folio_pos(folio);
	const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
	u64 cur;
@@ -1743,7 +1743,8 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
			 */
			btrfs_mark_ordered_io_finished(inode, folio, cur,
						       fs_info->sectorsize, false);
			error = true;
			if (!found_error)
				found_error = ret;
			continue;
		}
		submitted_io = true;
@@ -1760,11 +1761,11 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
	 * If we hit any error, the corresponding sector will have its dirty
	 * flag cleared and writeback finished, thus no need to handle the error case.
	 */
	if (!submitted_io && !error) {
	if (!submitted_io && !found_error) {
		btrfs_folio_set_writeback(fs_info, folio, start, len);
		btrfs_folio_clear_writeback(fs_info, folio, start, len);
	}
	return ret;
	return found_error;
}

/*