Skip to content

Commit 4afb912

Browse files
josefbacikkdave
authored andcommitted
btrfs: fix abort logic in btrfs_replace_file_extents
Error injection testing uncovered a case where we'd end up with a corrupt file system with a missing extent in the middle of a file. This occurs because the if statement to decide if we should abort is wrong. The only way we would abort in this case is if we got a ret != -EOPNOTSUPP and we called from the file clone code. However the prealloc code uses this path too. Instead we need to abort if there is an error, and the only error we _don't_ abort on is -EOPNOTSUPP and only if we came from the clone file code. CC: [email protected] # 5.10+ Reviewed-by: Nikolay Borisov <[email protected]> Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent cfd3126 commit 4afb912

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

fs/btrfs/file.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,14 +2703,16 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
27032703
drop_args.bytes_found);
27042704
if (ret != -ENOSPC) {
27052705
/*
2706-
* When cloning we want to avoid transaction aborts when
2707-
* nothing was done and we are attempting to clone parts
2708-
* of inline extents, in such cases -EOPNOTSUPP is
2709-
* returned by __btrfs_drop_extents() without having
2710-
* changed anything in the file.
2706+
* The only time we don't want to abort is if we are
2707+
* attempting to clone a partial inline extent, in which
2708+
* case we'll get EOPNOTSUPP. However if we aren't
2709+
* clone we need to abort no matter what, because if we
2710+
* got EOPNOTSUPP via prealloc then we messed up and
2711+
* need to abort.
27112712
*/
2712-
if (extent_info && !extent_info->is_new_extent &&
2713-
ret && ret != -EOPNOTSUPP)
2713+
if (ret &&
2714+
(ret != -EOPNOTSUPP ||
2715+
(extent_info && extent_info->is_new_extent)))
27142716
btrfs_abort_transaction(trans, ret);
27152717
break;
27162718
}

0 commit comments

Comments
 (0)