Commit a8d58a7c authored by robbieko's avatar robbieko Committed by David Sterba
Browse files

btrfs: check return value of btrfs_partially_delete_raid_extent()



btrfs_partially_delete_raid_extent() returns an error code (e.g.
-ENOMEM from kzalloc(), or errors from btrfs_del_item/btrfs_insert_item()),
but all three call sites in btrfs_delete_raid_extent() discard the
return value, silently losing errors and potentially leaving the stripe
tree in an inconsistent state.

Fix by capturing the return value into ret at all three call sites and
breaking out of the loop on error where appropriate.

Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarrobbieko <robbieko@synology.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent fe0cdfd7
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -223,7 +223,8 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
			/* The "left" item. */
			path->slots[0]--;
			btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
			btrfs_partially_delete_raid_extent(trans, path, &key,
			ret = btrfs_partially_delete_raid_extent(trans, path,
								 &key,
								 diff_start, 0);
			break;
		}
@@ -240,8 +241,11 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
		if (found_start < start) {
			u64 diff_start = start - found_start;

			btrfs_partially_delete_raid_extent(trans, path, &key,
			ret = btrfs_partially_delete_raid_extent(trans, path,
								 &key,
								 diff_start, 0);
			if (ret)
				break;

			start += (key.offset - diff_start);
			length -= (key.offset - diff_start);
@@ -264,7 +268,8 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
		if (found_end > end) {
			u64 diff_end = found_end - end;

			btrfs_partially_delete_raid_extent(trans, path, &key,
			ret = btrfs_partially_delete_raid_extent(trans, path,
								 &key,
								 key.offset - length,
								 length);
			ASSERT(key.offset - diff_end == length);