* [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c @ 2016-09-30 5:04 Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo ` (3 more replies) 0 siblings, 4 replies; 7+ messages in thread From: Qu Wenruo @ 2016-09-30 5:04 UTC (permalink / raw) To: linux-btrfs; +Cc: dsterba This allows us to put raid5 codes into that file other than creating a new raid5.c. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- v2: Split patch --- Makefile.in | 2 +- disk-io.h | 2 +- raid6.c => raid56.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename raid6.c => raid56.c (100%) diff --git a/Makefile.in b/Makefile.in index 20b740a..0ae2cd5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ CHECKER_FLAGS := -include $(check_defs) -D__CHECKER__ \ objects = ctree.o disk-io.o kernel-lib/radix-tree.o extent-tree.o print-tree.o \ root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \ extent-cache.o extent_io.o volumes.o utils.o repair.o \ - qgroup.o raid6.o free-space-cache.o kernel-lib/list_sort.o props.o \ + qgroup.o raid56.o free-space-cache.o kernel-lib/list_sort.o props.o \ ulist.o qgroup-verify.o backref.o string-table.o task-utils.o \ inode.o file.o find-root.o free-space-tree.o help.o cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ diff --git a/disk-io.h b/disk-io.h index 1080fc1..440baa9 100644 --- a/disk-io.h +++ b/disk-io.h @@ -190,7 +190,7 @@ int write_tree_block(struct btrfs_trans_handle *trans, int write_and_map_eb(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *eb); -/* raid6.c */ +/* raid56.c */ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs); #endif diff --git a/raid6.c b/raid56.c similarity index 100% rename from raid6.c rename to raid56.c -- 2.10.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine 2016-09-30 5:04 [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c Qu Wenruo @ 2016-09-30 5:04 ` Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 3/4] btrfs-progs: raid56: Introduce new function to calculate raid5 parity or data stripe Qu Wenruo ` (2 subsequent siblings) 3 siblings, 0 replies; 7+ messages in thread From: Qu Wenruo @ 2016-09-30 5:04 UTC (permalink / raw) To: linux-btrfs; +Cc: dsterba Remove various BUG_ON in raid56 write routine, including: 1) Memory allocation error 2) Write error 3) Validation check Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- v2: Split patch Remove all BUG_ON() in raid56 write routine. --- volumes.c | 84 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/volumes.c b/volumes.c index da79751..93ce934 100644 --- a/volumes.c +++ b/volumes.c @@ -2061,8 +2061,8 @@ static int rmw_eb(struct btrfs_fs_info *info, return 0; } -static void split_eb_for_raid56(struct btrfs_fs_info *info, - struct extent_buffer *orig_eb, +static int split_eb_for_raid56(struct btrfs_fs_info *info, + struct extent_buffer *orig_eb, struct extent_buffer **ebs, u64 stripe_len, u64 *raid_map, int num_stripes) @@ -2071,34 +2071,38 @@ static void split_eb_for_raid56(struct btrfs_fs_info *info, u64 start = orig_eb->start; u64 this_eb_start; int i; - int ret; + int ret = 0; + eb = calloc(num_stripes, sizeof(*eb) + stripe_len); + if (!eb) + return -ENOMEM; for (i = 0; i < num_stripes; i++) { if (raid_map[i] >= BTRFS_RAID5_P_STRIPE) break; - eb = calloc(1, sizeof(struct extent_buffer) + stripe_len); - if (!eb) - BUG(); - - eb->start = raid_map[i]; - eb->len = stripe_len; - eb->refs = 1; - eb->flags = 0; - eb->fd = -1; - eb->dev_bytenr = (u64)-1; + eb[i].start = raid_map[i]; + eb[i].len = stripe_len; + eb[i].refs = 1; + eb[i].flags = 0; + eb[i].fd = -1; + eb[i].dev_bytenr = (u64)-1; this_eb_start = raid_map[i]; if (start > this_eb_start || start + orig_eb->len < this_eb_start + stripe_len) { ret = rmw_eb(info, eb, orig_eb); - BUG_ON(ret); + if (ret) + break; } else { - memcpy(eb->data, orig_eb->data + eb->start - start, stripe_len); + memcpy(eb->data, orig_eb->data + eb->start - start, + stripe_len); } - ebs[i] = eb; + ebs[i] = &eb[i]; } + if (ret) + free(eb); + return ret; } int write_raid56_with_parity(struct btrfs_fs_info *info, @@ -2111,15 +2115,20 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, int j; int ret; int alloc_size = eb->len; + void **pointers; - ebs = kmalloc(sizeof(*ebs) * multi->num_stripes, GFP_NOFS); - BUG_ON(!ebs); + ebs = malloc(sizeof(*ebs) * multi->num_stripes); + pointers = malloc(sizeof(*pointers) * multi->num_stripes); + if (!ebs || !pointers) + return -ENOMEM; if (stripe_len > alloc_size) alloc_size = stripe_len; - split_eb_for_raid56(info, eb, ebs, stripe_len, raid_map, - multi->num_stripes); + ret = split_eb_for_raid56(info, eb, ebs, stripe_len, raid_map, + multi->num_stripes); + if (ret) + goto out; for (i = 0; i < multi->num_stripes; i++) { struct extent_buffer *new_eb; @@ -2127,11 +2136,17 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, ebs[i]->dev_bytenr = multi->stripes[i].physical; ebs[i]->fd = multi->stripes[i].dev->fd; multi->stripes[i].dev->total_ios++; - BUG_ON(ebs[i]->start != raid_map[i]); + if (ebs[i]->start != raid_map[i]) { + ret = -EINVAL; + goto out_free_split; + } continue; } - new_eb = kmalloc(sizeof(*eb) + alloc_size, GFP_NOFS); - BUG_ON(!new_eb); + new_eb = malloc(sizeof(*eb) + alloc_size); + if (!new_eb) { + ret = -ENOMEM; + goto out_free_split; + } new_eb->dev_bytenr = multi->stripes[i].physical; new_eb->fd = multi->stripes[i].dev->fd; multi->stripes[i].dev->total_ios++; @@ -2143,12 +2158,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, q_eb = new_eb; } if (q_eb) { - void **pointers; - - pointers = kmalloc(sizeof(*pointers) * multi->num_stripes, - GFP_NOFS); - BUG_ON(!pointers); - ebs[multi->num_stripes - 2] = p_eb; ebs[multi->num_stripes - 1] = q_eb; @@ -2156,7 +2165,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, pointers[i] = ebs[i]->data; raid6_gen_syndrome(multi->num_stripes, stripe_len, pointers); - kfree(pointers); } else { ebs[multi->num_stripes - 1] = p_eb; memcpy(p_eb->data, ebs[0]->data, stripe_len); @@ -2175,12 +2183,18 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, for (i = 0; i < multi->num_stripes; i++) { ret = write_extent_to_disk(ebs[i]); - BUG_ON(ret); - if (ebs[i] != eb) - kfree(ebs[i]); + if (ret < 0) + goto out_free_split; } - kfree(ebs); +out_free_split: + for (i = 0; i < multi->num_stripes; i++) { + if (ebs[i] != eb) + free(ebs[i]); + } +out: + free(ebs); + free(pointers); - return 0; + return ret; } -- 2.10.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/4] btrfs-progs: raid56: Introduce new function to calculate raid5 parity or data stripe 2016-09-30 5:04 [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo @ 2016-09-30 5:04 ` Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 4/4] btrfs-progs: volumes: Use new raid5_gen_result to calculate raid5 parity Qu Wenruo 2016-10-13 15:56 ` [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c David Sterba 3 siblings, 0 replies; 7+ messages in thread From: Qu Wenruo @ 2016-09-30 5:04 UTC (permalink / raw) To: linux-btrfs; +Cc: dsterba Introduce new function raid5_gen_result() to calculate parity or data stripe. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- v2: Patch split Change parameter type from void* to char* for xor_range() Change parameter order for xxor_range() Handle unaligned memory address for xor_range() --- disk-io.h | 1 + raid56.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/disk-io.h b/disk-io.h index 440baa9..9fc7e92 100644 --- a/disk-io.h +++ b/disk-io.h @@ -192,5 +192,6 @@ int write_and_map_eb(struct btrfs_trans_handle *trans, struct btrfs_root *root, /* raid56.c */ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs); +int raid5_gen_result(int nr_devs, size_t stripe_len, int dest, void **data); #endif diff --git a/raid56.c b/raid56.c index 833df5f..8c79c45 100644 --- a/raid56.c +++ b/raid56.c @@ -26,6 +26,8 @@ #include "kerncompat.h" #include "ctree.h" #include "disk-io.h" +#include "volumes.h" +#include "utils.h" /* * This is the C data type to use @@ -107,3 +109,64 @@ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs) } } +static void xor_range(char *dst, const char*src, size_t size) +{ + /* Move to DWORD aligned */ + while (size && ((unsigned long)dst & sizeof(unsigned long))) { + *dst++ ^= *src++; + size--; + } + + /* DWORD aligned part */ + while (size >= sizeof(unsigned long)) { + *(unsigned long *)dst ^= *(unsigned long *)src; + src += sizeof(unsigned long); + dst += sizeof(unsigned long); + size -= sizeof(unsigned long); + } + /* Remaining */ + while (size) { + *dst++ ^= *src++; + size--; + } +} + +/* + * Generate desired data/parity stripe for RAID5 + * + * @nr_devs: Total number of devices, including parity + * @stripe_len: Stripe length + * @data: Data, with special layout: + * data[0]: Data stripe 0 + * data[nr_devs-2]: Last data stripe + * data[nr_devs-1]: RAID5 parity + * @dest: To generate which data. should follow above data layout + */ +int raid5_gen_result(int nr_devs, size_t stripe_len, int dest, void **data) +{ + int i; + char *buf = data[dest]; + + /* Validation check */ + if (stripe_len <= 0 || stripe_len != BTRFS_STRIPE_LEN) { + error("invalid parameter for %s", __func__); + return -EINVAL; + } + + if (dest >= nr_devs || nr_devs < 2) { + error("invalid parameter for %s", __func__); + return -EINVAL; + } + /* Shortcut for 2 devs RAID5, which is just RAID1 */ + if (nr_devs == 2) { + memcpy(data[dest], data[1 - dest], stripe_len); + return 0; + } + memset(buf, 0, stripe_len); + for (i = 0; i < nr_devs; i++) { + if (i == dest) + continue; + xor_range(buf, data[i], stripe_len); + } + return 0; +} -- 2.10.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/4] btrfs-progs: volumes: Use new raid5_gen_result to calculate raid5 parity 2016-09-30 5:04 [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 3/4] btrfs-progs: raid56: Introduce new function to calculate raid5 parity or data stripe Qu Wenruo @ 2016-09-30 5:04 ` Qu Wenruo 2016-10-13 15:56 ` [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c David Sterba 3 siblings, 0 replies; 7+ messages in thread From: Qu Wenruo @ 2016-09-30 5:04 UTC (permalink / raw) To: linux-btrfs; +Cc: dsterba Use thew raid5_gen_result() function to calculate raid5 parity. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- v2: Patch split --- volumes.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/volumes.c b/volumes.c index 93ce934..e78d157 100644 --- a/volumes.c +++ b/volumes.c @@ -2112,7 +2112,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, { struct extent_buffer **ebs, *p_eb = NULL, *q_eb = NULL; int i; - int j; int ret; int alloc_size = eb->len; void **pointers; @@ -2167,18 +2166,12 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, raid6_gen_syndrome(multi->num_stripes, stripe_len, pointers); } else { ebs[multi->num_stripes - 1] = p_eb; - memcpy(p_eb->data, ebs[0]->data, stripe_len); - for (j = 1; j < multi->num_stripes - 1; j++) { - for (i = 0; i < stripe_len; i += sizeof(u64)) { - u64 p_eb_data; - u64 ebs_data; - - p_eb_data = get_unaligned_64(p_eb->data + i); - ebs_data = get_unaligned_64(ebs[j]->data + i); - p_eb_data ^= ebs_data; - put_unaligned_64(p_eb_data, p_eb->data + i); - } - } + for (i = 0; i < multi->num_stripes; i++) + pointers[i] = ebs[i]->data; + ret = raid5_gen_result(multi->num_stripes, stripe_len, + multi->num_stripes - 1, pointers); + if (ret < 0) + goto out_free_split; } for (i = 0; i < multi->num_stripes; i++) { -- 2.10.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c 2016-09-30 5:04 [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c Qu Wenruo ` (2 preceding siblings ...) 2016-09-30 5:04 ` [PATCH v2 4/4] btrfs-progs: volumes: Use new raid5_gen_result to calculate raid5 parity Qu Wenruo @ 2016-10-13 15:56 ` David Sterba 3 siblings, 0 replies; 7+ messages in thread From: David Sterba @ 2016-10-13 15:56 UTC (permalink / raw) To: Qu Wenruo; +Cc: linux-btrfs, dsterba Hi, 1-4 applied, thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c @ 2016-10-25 2:11 Qu Wenruo 2016-10-25 2:11 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo 0 siblings, 1 reply; 7+ messages in thread From: Qu Wenruo @ 2016-10-25 2:11 UTC (permalink / raw) To: linux-btrfs, dsterba; +Cc: David Sterba This allows us to put raid5 codes into that file other than creating a new raid5.c. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com> --- Changelog v2: None --- Makefile.in | 2 +- disk-io.h | 2 +- raid6.c => raid56.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename raid6.c => raid56.c (100%) diff --git a/Makefile.in b/Makefile.in index 5187a93..b53cf2c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -91,7 +91,7 @@ CHECKER_FLAGS := -include $(check_defs) -D__CHECKER__ \ objects = ctree.o disk-io.o kernel-lib/radix-tree.o extent-tree.o print-tree.o \ root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \ extent-cache.o extent_io.o volumes.o utils.o repair.o \ - qgroup.o raid6.o free-space-cache.o kernel-lib/list_sort.o props.o \ + qgroup.o raid56.o free-space-cache.o kernel-lib/list_sort.o props.o \ ulist.o qgroup-verify.o backref.o string-table.o task-utils.o \ inode.o file.o find-root.o free-space-tree.o help.o cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ diff --git a/disk-io.h b/disk-io.h index 1fc0bb7..8ab36aa 100644 --- a/disk-io.h +++ b/disk-io.h @@ -190,7 +190,7 @@ int write_tree_block(struct btrfs_trans_handle *trans, int write_and_map_eb(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *eb); -/* raid6.c */ +/* raid56.c */ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs); #endif diff --git a/raid6.c b/raid56.c similarity index 100% rename from raid6.c rename to raid56.c -- 2.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine 2016-10-25 2:11 Qu Wenruo @ 2016-10-25 2:11 ` Qu Wenruo 2016-10-25 12:29 ` David Sterba 0 siblings, 1 reply; 7+ messages in thread From: Qu Wenruo @ 2016-10-25 2:11 UTC (permalink / raw) To: linux-btrfs, dsterba; +Cc: David Sterba Remove various BUG_ON in raid56 write routine, including: 1) Memory allocation error Old codes allocates memory when code needs new memory in a loop, and catch the error using BUG_ON(). New codes allocates memory in a allocation loop first, if any failure is caught, freeing already allocated memories then throw -ENOMEM. 2) Write error Change BUG_ON() to correct return value. 3) Validation check Same as write error. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com> --- changelog: v2: Fix error in calloc usage which leads to double free() on data stripes. Thanks David for pointing it out. --- volumes.c | 89 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/volumes.c b/volumes.c index b9ca550..70d8940 100644 --- a/volumes.c +++ b/volumes.c @@ -2063,25 +2063,39 @@ static int rmw_eb(struct btrfs_fs_info *info, return 0; } -static void split_eb_for_raid56(struct btrfs_fs_info *info, - struct extent_buffer *orig_eb, +static int split_eb_for_raid56(struct btrfs_fs_info *info, + struct extent_buffer *orig_eb, struct extent_buffer **ebs, u64 stripe_len, u64 *raid_map, int num_stripes) { - struct extent_buffer *eb; + struct extent_buffer **tmp_ebs; u64 start = orig_eb->start; u64 this_eb_start; int i; - int ret; + int ret = 0; + + tmp_ebs = calloc(num_stripes, sizeof(*tmp_ebs)); + if (!tmp_ebs) + return -ENOMEM; + /* Alloc memory in a row for data stripes */ for (i = 0; i < num_stripes; i++) { if (raid_map[i] >= BTRFS_RAID5_P_STRIPE) break; - eb = calloc(1, sizeof(struct extent_buffer) + stripe_len); - if (!eb) - BUG(); + tmp_ebs[i] = calloc(1, sizeof(**tmp_ebs) + stripe_len); + if (!tmp_ebs[i]) { + ret = -ENOMEM; + goto clean_up; + } + } + + for (i = 0; i < num_stripes; i++) { + struct extent_buffer *eb = tmp_ebs[i]; + + if (raid_map[i] >= BTRFS_RAID5_P_STRIPE) + break; eb->start = raid_map[i]; eb->len = stripe_len; @@ -2095,12 +2109,21 @@ static void split_eb_for_raid56(struct btrfs_fs_info *info, if (start > this_eb_start || start + orig_eb->len < this_eb_start + stripe_len) { ret = rmw_eb(info, eb, orig_eb); - BUG_ON(ret); + if (ret) + goto clean_up; } else { - memcpy(eb->data, orig_eb->data + eb->start - start, stripe_len); + memcpy(eb->data, orig_eb->data + eb->start - start, + stripe_len); } ebs[i] = eb; } + free(tmp_ebs); + return ret; +clean_up: + for (i = 0; i < num_stripes; i++) + free(tmp_ebs[i]); + free(tmp_ebs); + return ret; } int write_raid56_with_parity(struct btrfs_fs_info *info, @@ -2113,15 +2136,20 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, int j; int ret; int alloc_size = eb->len; + void **pointers; - ebs = kmalloc(sizeof(*ebs) * multi->num_stripes, GFP_NOFS); - BUG_ON(!ebs); + ebs = malloc(sizeof(*ebs) * multi->num_stripes); + pointers = malloc(sizeof(*pointers) * multi->num_stripes); + if (!ebs || !pointers) + return -ENOMEM; if (stripe_len > alloc_size) alloc_size = stripe_len; - split_eb_for_raid56(info, eb, ebs, stripe_len, raid_map, - multi->num_stripes); + ret = split_eb_for_raid56(info, eb, ebs, stripe_len, raid_map, + multi->num_stripes); + if (ret) + goto out; for (i = 0; i < multi->num_stripes; i++) { struct extent_buffer *new_eb; @@ -2129,11 +2157,17 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, ebs[i]->dev_bytenr = multi->stripes[i].physical; ebs[i]->fd = multi->stripes[i].dev->fd; multi->stripes[i].dev->total_ios++; - BUG_ON(ebs[i]->start != raid_map[i]); + if (ebs[i]->start != raid_map[i]) { + ret = -EINVAL; + goto out_free_split; + } continue; } - new_eb = kmalloc(sizeof(*eb) + alloc_size, GFP_NOFS); - BUG_ON(!new_eb); + new_eb = malloc(sizeof(*eb) + alloc_size); + if (!new_eb) { + ret = -ENOMEM; + goto out_free_split; + } new_eb->dev_bytenr = multi->stripes[i].physical; new_eb->fd = multi->stripes[i].dev->fd; multi->stripes[i].dev->total_ios++; @@ -2145,12 +2179,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, q_eb = new_eb; } if (q_eb) { - void **pointers; - - pointers = kmalloc(sizeof(*pointers) * multi->num_stripes, - GFP_NOFS); - BUG_ON(!pointers); - ebs[multi->num_stripes - 2] = p_eb; ebs[multi->num_stripes - 1] = q_eb; @@ -2158,7 +2186,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, pointers[i] = ebs[i]->data; raid6_gen_syndrome(multi->num_stripes, stripe_len, pointers); - kfree(pointers); } else { ebs[multi->num_stripes - 1] = p_eb; memcpy(p_eb->data, ebs[0]->data, stripe_len); @@ -2177,12 +2204,18 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, for (i = 0; i < multi->num_stripes; i++) { ret = write_extent_to_disk(ebs[i]); - BUG_ON(ret); - if (ebs[i] != eb) - kfree(ebs[i]); + if (ret < 0) + goto out_free_split; } - kfree(ebs); +out_free_split: + for (i = 0; i < multi->num_stripes; i++) { + if (ebs[i] != eb) + free(ebs[i]); + } +out: + free(ebs); + free(pointers); - return 0; + return ret; } -- 2.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine 2016-10-25 2:11 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo @ 2016-10-25 12:29 ` David Sterba 0 siblings, 0 replies; 7+ messages in thread From: David Sterba @ 2016-10-25 12:29 UTC (permalink / raw) To: Qu Wenruo; +Cc: linux-btrfs, dsterba, David Sterba On Tue, Oct 25, 2016 at 10:11:04AM +0800, Qu Wenruo wrote: > Remove various BUG_ON in raid56 write routine, including: > 1) Memory allocation error > Old codes allocates memory when code needs new memory in a loop, and > catch the error using BUG_ON(). > New codes allocates memory in a allocation loop first, if any failure > is caught, freeing already allocated memories then throw -ENOMEM. > > 2) Write error > Change BUG_ON() to correct return value. > > 3) Validation check > Same as write error. > > Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> > Signed-off-by: David Sterba <dsterba@suse.com> > --- > changelog: > v2: > Fix error in calloc usage which leads to double free() on data > stripes. Patch replaced in relevant branches, thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-10-25 12:29 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-09-30 5:04 [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 3/4] btrfs-progs: raid56: Introduce new function to calculate raid5 parity or data stripe Qu Wenruo 2016-09-30 5:04 ` [PATCH v2 4/4] btrfs-progs: volumes: Use new raid5_gen_result to calculate raid5 parity Qu Wenruo 2016-10-13 15:56 ` [PATCH v2 1/4] btrfs-progs: rename raid6.c to raid56.c David Sterba 2016-10-25 2:11 Qu Wenruo 2016-10-25 2:11 ` [PATCH v2 2/4] btrfs-progs: volumes: Remove BUG_ON in raid56 write routine Qu Wenruo 2016-10-25 12:29 ` David Sterba
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.