summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 99eab7b3e5e1..aeef6cd8aaeb 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3144,12 +3144,13 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
* locking. We use an array for the page pointers. Size of the array is
* bounded by len, which is in turn bounded by BTRFS_MAX_DEDUPE_LEN.
*/
- cmp.src_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
- cmp.dst_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+ cmp.src_pages = kvmalloc_array(num_pages, sizeof(struct page *),
+ GFP_KERNEL | __GFP_ZERO);
+ cmp.dst_pages = kvmalloc_array(num_pages, sizeof(struct page *),
+ GFP_KERNEL | __GFP_ZERO);
if (!cmp.src_pages || !cmp.dst_pages) {
- kfree(cmp.src_pages);
- kfree(cmp.dst_pages);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_free;
}
for (i = 0; i < chunk_count; i++) {
@@ -3172,8 +3173,9 @@ out_unlock:
else
btrfs_double_inode_unlock(src, dst);
- kfree(cmp.src_pages);
- kfree(cmp.dst_pages);
+out_free:
+ kvfree(cmp.src_pages);
+ kvfree(cmp.dst_pages);
return ret;
}