summaryrefslogtreecommitdiffstats
path: root/raid6check.c
diff options
context:
space:
mode:
authorPiergiorgio Sartor <piergiorgio.sartor@nexgo.de>2014-03-15 17:56:22 +0100
committerNeilBrown <neilb@suse.de>2014-03-31 07:06:34 +0200
commitc22ac3b1074fdfe3b128deee7a8b1959138dfc7e (patch)
treedb35054b0e0eecf70bd77a0b1d5370895ef9e1a4 /raid6check.c
parentraid6check.c: lock the stripe until necessary (diff)
downloadmdadm-c22ac3b1074fdfe3b128deee7a8b1959138dfc7e.tar.xz
mdadm-c22ac3b1074fdfe3b128deee7a8b1959138dfc7e.zip
raid6check.c: move autorepair code to separate function
This patch cleans up a bit the code by moving the autorepair part into a separate function. Signed off: piergiorgio.sartor@nexgo.de Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to '')
-rw-r--r--raid6check.c114
1 files changed, 65 insertions, 49 deletions
diff --git a/raid6check.c b/raid6check.c
index 08765e12..9551c664 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -156,6 +156,64 @@ int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) {
return rv * 256;
}
+/* Autorepair */
+int autorepair(int *disk, int diskP, int diskQ, unsigned long long start, int chunk_size,
+ char *name[], int raid_disks, int data_disks, char **blocks_page,
+ char **blocks, uint8_t *p, char **stripes, int *block_index_for_slot,
+ int *source, unsigned long long *offsets)
+{
+ int i, j;
+ int pages_to_write_count = 0;
+ int page_to_write[chunk_size >> CHECK_PAGE_BITS];
+ for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) {
+ if (disk[j] >= 0) {
+ printf("Auto-repairing slot %d (%s)\n", disk[j], name[disk[j]]);
+ pages_to_write_count++;
+ page_to_write[j] = 1;
+ for(i = 0; i < raid_disks; i++) {
+ blocks_page[i] = blocks[i] + j * CHECK_PAGE_SIZE;
+ }
+ if (disk[j] == diskQ) {
+ qsyndrome(p, (uint8_t*)stripes[diskQ] + j * CHECK_PAGE_SIZE, (uint8_t**)blocks_page, data_disks, CHECK_PAGE_SIZE);
+ }
+ else {
+ char *all_but_failed_blocks[data_disks];
+ int failed_block_index = block_index_for_slot[disk[j]];
+ for(i = 0; i < data_disks; i++) {
+ if (failed_block_index == i) {
+ all_but_failed_blocks[i] = stripes[diskP] + j * CHECK_PAGE_SIZE;
+ }
+ else {
+ all_but_failed_blocks[i] = blocks_page[i];
+ }
+ }
+ xor_blocks(stripes[disk[j]] + j * CHECK_PAGE_SIZE,
+ all_but_failed_blocks, data_disks, CHECK_PAGE_SIZE);
+ }
+ }
+ else {
+ page_to_write[j] = 0;
+ }
+ }
+
+ if(pages_to_write_count > 0) {
+ int write_res = 0;
+ for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) {
+ if(page_to_write[j] == 1) {
+ lseek64(source[disk[j]], offsets[disk[j]] + start * chunk_size + j * CHECK_PAGE_SIZE, SEEK_SET);
+ write_res += write(source[disk[j]], stripes[disk[j]] + j * CHECK_PAGE_SIZE, CHECK_PAGE_SIZE);
+ }
+ }
+
+ if (write_res != (CHECK_PAGE_SIZE * pages_to_write_count)) {
+ fprintf(stderr, "Failed to write a full chunk.\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
int raid_disks, int chunk_size, int level, int layout,
unsigned long long start, unsigned long long length, char *name[],
@@ -243,55 +301,13 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
}
if(repair == AUTO_REPAIR) {
- int pages_to_write_count = 0;
- int page_to_write[chunk_size >> CHECK_PAGE_BITS];
- for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) {
- if (disk[j] >= 0) {
- printf("Auto-repairing slot %d (%s)\n", disk[j], name[disk[j]]);
- pages_to_write_count++;
- page_to_write[j] = 1;
- for(i = 0; i < raid_disks; i++) {
- blocks_page[i] = blocks[i] + j * CHECK_PAGE_SIZE;
- }
- if (disk[j] == diskQ) {
- qsyndrome(p, (uint8_t*)stripes[diskQ] + j * CHECK_PAGE_SIZE, (uint8_t**)blocks_page, data_disks, CHECK_PAGE_SIZE);
- }
- else {
- char *all_but_failed_blocks[data_disks];
- int failed_block_index = block_index_for_slot[disk[j]];
- for (i = 0; i < data_disks; i++) {
- if (failed_block_index == i) {
- all_but_failed_blocks[i] = stripes[diskP] + j * CHECK_PAGE_SIZE;
- }
- else {
- all_but_failed_blocks[i] = blocks_page[i];
- }
- }
- xor_blocks(stripes[disk[j]] + j * CHECK_PAGE_SIZE,
- all_but_failed_blocks, data_disks, CHECK_PAGE_SIZE);
- }
- }
- else {
- page_to_write[j] = 0;
- }
- }
-
- if(pages_to_write_count > 0) {
-
- int write_res = 0;
- for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) {
- if(page_to_write[j] == 1) {
- lseek64(source[disk[j]], offsets[disk[j]] + start * chunk_size + j * CHECK_PAGE_SIZE, SEEK_SET);
- write_res += write(source[disk[j]], stripes[disk[j]] + j * CHECK_PAGE_SIZE, CHECK_PAGE_SIZE);
- }
- }
-
- if (write_res != (CHECK_PAGE_SIZE * pages_to_write_count)) {
- fprintf(stderr, "Failed to write a full chunk.\n");
- unlock_all_stripes(info, sig);
- err = -1;
- goto exitCheck;
- }
+ err = autorepair(disk, diskP, diskQ, start, chunk_size,
+ name, raid_disks, data_disks, blocks_page,
+ blocks, p, stripes, block_index_for_slot,
+ source, offsets);
+ if(err != 0) {
+ unlock_all_stripes(info, sig);
+ goto exitCheck;
}
}