diff options
author | Song Liu <songliubraving@fb.com> | 2016-12-07 12:42:05 -0500 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2016-12-08 13:34:03 -0500 |
commit | 5c88f403a5d2bd75911c6faaacc9bea97ac7d121 (patch) | |
tree | 63a30076fc9664afc1c991dbb72caa3ad73be565 | |
parent | d30dfeb9be25c67c9cfdfd932db57a571fd347b4 (diff) |
md/raid5-cache: fix crc in rewrite_data_only_stripes()
r5l_recovery_create_empty_meta_block() creates crc for the empty
metablock. After the metablock is updated, we need clear the
checksum before recalculate it.
Shaohua: moved checksum calculation out of
r5l_recovery_create_empty_meta_block. We should calculate it after all fields
are updated.
Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Shaohua Li <shli@fb.com>
-rw-r--r-- | drivers/md/raid5-cache.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 7c732c5f87c9..aa990bde1fe2 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c | |||
@@ -1522,7 +1522,6 @@ r5l_recovery_create_empty_meta_block(struct r5l_log *log, | |||
1522 | sector_t pos, u64 seq) | 1522 | sector_t pos, u64 seq) |
1523 | { | 1523 | { |
1524 | struct r5l_meta_block *mb; | 1524 | struct r5l_meta_block *mb; |
1525 | u32 crc; | ||
1526 | 1525 | ||
1527 | mb = page_address(page); | 1526 | mb = page_address(page); |
1528 | clear_page(mb); | 1527 | clear_page(mb); |
@@ -1531,19 +1530,21 @@ r5l_recovery_create_empty_meta_block(struct r5l_log *log, | |||
1531 | mb->meta_size = cpu_to_le32(sizeof(struct r5l_meta_block)); | 1530 | mb->meta_size = cpu_to_le32(sizeof(struct r5l_meta_block)); |
1532 | mb->seq = cpu_to_le64(seq); | 1531 | mb->seq = cpu_to_le64(seq); |
1533 | mb->position = cpu_to_le64(pos); | 1532 | mb->position = cpu_to_le64(pos); |
1534 | crc = crc32c_le(log->uuid_checksum, mb, PAGE_SIZE); | ||
1535 | mb->checksum = cpu_to_le32(crc); | ||
1536 | } | 1533 | } |
1537 | 1534 | ||
1538 | static int r5l_log_write_empty_meta_block(struct r5l_log *log, sector_t pos, | 1535 | static int r5l_log_write_empty_meta_block(struct r5l_log *log, sector_t pos, |
1539 | u64 seq) | 1536 | u64 seq) |
1540 | { | 1537 | { |
1541 | struct page *page; | 1538 | struct page *page; |
1539 | struct r5l_meta_block *mb; | ||
1542 | 1540 | ||
1543 | page = alloc_page(GFP_KERNEL); | 1541 | page = alloc_page(GFP_KERNEL); |
1544 | if (!page) | 1542 | if (!page) |
1545 | return -ENOMEM; | 1543 | return -ENOMEM; |
1546 | r5l_recovery_create_empty_meta_block(log, page, pos, seq); | 1544 | r5l_recovery_create_empty_meta_block(log, page, pos, seq); |
1545 | mb = page_address(page); | ||
1546 | mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum, | ||
1547 | mb, PAGE_SIZE)); | ||
1547 | if (!sync_page_io(log->rdev, pos, PAGE_SIZE, page, REQ_OP_WRITE, | 1548 | if (!sync_page_io(log->rdev, pos, PAGE_SIZE, page, REQ_OP_WRITE, |
1548 | WRITE_FUA, false)) { | 1549 | WRITE_FUA, false)) { |
1549 | __free_page(page); | 1550 | __free_page(page); |
@@ -2117,7 +2118,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log, | |||
2117 | } | 2118 | } |
2118 | } | 2119 | } |
2119 | mb->meta_size = cpu_to_le32(offset); | 2120 | mb->meta_size = cpu_to_le32(offset); |
2120 | mb->checksum = crc32c_le(log->uuid_checksum, mb, PAGE_SIZE); | 2121 | mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum, |
2122 | mb, PAGE_SIZE)); | ||
2121 | sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page, | 2123 | sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page, |
2122 | REQ_OP_WRITE, WRITE_FUA, false); | 2124 | REQ_OP_WRITE, WRITE_FUA, false); |
2123 | sh->log_start = ctx->pos; | 2125 | sh->log_start = ctx->pos; |