Skip to content

Commit 0678b61

Browse files
Mark Fashehkdave
authored andcommitted
btrfs: Don't BUG_ON kzalloc error in btrfs_lookup_csums_range()
Unfortunately it isn't enough to just exit here - the kzalloc() happens in a loop and the allocated items are added to a linked list whose head is passed in from the caller. To fix the BUG_ON() and also provide the semantic that the list passed in is only modified on success, I create function-local temporary list that we add items too. If no error is met, that list is spliced to the callers at the end of the function. Otherwise the list will be walked and all items freed before the error value is returned. I did a simple test on this patch by forcing an error at the kzalloc() point and verifying that when this hits (git clone seemed to exercise this), the function throws the proper error. Unfortunately but predictably, we later hit a BUG_ON(ret) type line that still hasn't been fixed up ;) Signed-off-by: Mark Fasheh <[email protected]>
1 parent be1a556 commit 0678b61

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

fs/btrfs/file-item.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
284284
struct btrfs_ordered_sum *sums;
285285
struct btrfs_sector_sum *sector_sum;
286286
struct btrfs_csum_item *item;
287+
LIST_HEAD(tmplist);
287288
unsigned long offset;
288289
int ret;
289290
size_t size;
@@ -358,7 +359,10 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
358359
MAX_ORDERED_SUM_BYTES(root));
359360
sums = kzalloc(btrfs_ordered_sum_size(root, size),
360361
GFP_NOFS);
361-
BUG_ON(!sums);
362+
if (!sums) {
363+
ret = -ENOMEM;
364+
goto fail;
365+
}
362366

363367
sector_sum = sums->sums;
364368
sums->bytenr = start;
@@ -380,12 +384,19 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
380384
offset += csum_size;
381385
sector_sum++;
382386
}
383-
list_add_tail(&sums->list, list);
387+
list_add_tail(&sums->list, &tmplist);
384388
}
385389
path->slots[0]++;
386390
}
387391
ret = 0;
388392
fail:
393+
while (ret < 0 && !list_empty(&tmplist)) {
394+
sums = list_entry(&tmplist, struct btrfs_ordered_sum, list);
395+
list_del(&sums->list);
396+
kfree(sums);
397+
}
398+
list_splice_tail(&tmplist, list);
399+
389400
btrfs_free_path(path);
390401
return ret;
391402
}

0 commit comments

Comments
 (0)