Skip to content

Commit aa5ccf2

Browse files
josefbacikkdave
authored andcommitted
btrfs: handle errors in btrfs_reloc_clone_csums properly
In the cow path we will clone the reloc csums for relocated data extents, and if there's an error we already have an ordered extent and rely on the ordered extent finishing to clean everything up. There's a problem however, we don't mark the ordered extent with an error, we pretend like everything was just fine. If we were at the end of our range we won't actually bubble up this error anywhere, and we could end up inserting an extent that doesn't have csums where it should have them. Fix this by adding a helper to mark the ordered extent with an error, and then use this when we fail to lookup the csums in btrfs_reloc_clone_csums. Use this helper in the other place where we use the same pattern while we're here. This will prevent us from erroneously inserting the extent that doesn't have the required checksums. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent e98bf64 commit aa5ccf2

4 files changed

Lines changed: 12 additions & 4 deletions

File tree

fs/btrfs/inode.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3183,9 +3183,8 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
31833183
* set the mapping error, so we need to set it if we're the ones
31843184
* marking this ordered extent as failed.
31853185
*/
3186-
if (ret && !test_and_set_bit(BTRFS_ORDERED_IOERR,
3187-
&ordered_extent->flags))
3188-
mapping_set_error(ordered_extent->inode->i_mapping, -EIO);
3186+
if (ret)
3187+
btrfs_mark_ordered_extent_error(ordered_extent);
31893188

31903189
if (truncated)
31913190
unwritten_start += logical_len;

fs/btrfs/ordered-data.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,12 @@ void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry,
294294
spin_unlock_irq(&inode->ordered_tree_lock);
295295
}
296296

297+
void btrfs_mark_ordered_extent_error(struct btrfs_ordered_extent *ordered)
298+
{
299+
if (!test_and_set_bit(BTRFS_ORDERED_IOERR, &ordered->flags))
300+
mapping_set_error(ordered->inode->i_mapping, -EIO);
301+
}
302+
297303
static void finish_ordered_fn(struct btrfs_work *work)
298304
{
299305
struct btrfs_ordered_extent *ordered_extent;

fs/btrfs/ordered-data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ bool btrfs_try_lock_ordered_range(struct btrfs_inode *inode, u64 start, u64 end,
203203
struct extent_state **cached_state);
204204
struct btrfs_ordered_extent *btrfs_split_ordered_extent(
205205
struct btrfs_ordered_extent *ordered, u64 len);
206+
void btrfs_mark_ordered_extent_error(struct btrfs_ordered_extent *ordered);
206207
int __init ordered_data_init(void);
207208
void __cold ordered_data_exit(void);
208209

fs/btrfs/relocation.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4403,8 +4403,10 @@ int btrfs_reloc_clone_csums(struct btrfs_ordered_extent *ordered)
44034403
ret = btrfs_lookup_csums_list(csum_root, disk_bytenr,
44044404
disk_bytenr + ordered->num_bytes - 1,
44054405
&list, false);
4406-
if (ret < 0)
4406+
if (ret < 0) {
4407+
btrfs_mark_ordered_extent_error(ordered);
44074408
return ret;
4409+
}
44084410

44094411
while (!list_empty(&list)) {
44104412
struct btrfs_ordered_sum *sums =

0 commit comments

Comments
 (0)