raid5-cache.c (016c76ac76e4c678b01a75a602dc6be0282f5b29) | raid5-cache.c (1ad45a9bc4e0cd5a6e6fb0e6c5d35d6c87f14c76) |
---|---|
1/* 2 * Copyright (C) 2015 Shaohua Li <shli@fb.com> 3 * Copyright (C) 2016 Song Liu <songliubraving@fb.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * --- 1988 unchanged lines hidden (view full) --- 1997 page = alloc_page(GFP_KERNEL); 1998 if (!page) 1999 return -ENOMEM; 2000 2001 while (mb_offset < le32_to_cpu(mb->meta_size)) { 2002 payload = (void *)mb + mb_offset; 2003 payload_flush = (void *)mb + mb_offset; 2004 | 1/* 2 * Copyright (C) 2015 Shaohua Li <shli@fb.com> 3 * Copyright (C) 2016 Song Liu <songliubraving@fb.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * --- 1988 unchanged lines hidden (view full) --- 1997 page = alloc_page(GFP_KERNEL); 1998 if (!page) 1999 return -ENOMEM; 2000 2001 while (mb_offset < le32_to_cpu(mb->meta_size)) { 2002 payload = (void *)mb + mb_offset; 2003 payload_flush = (void *)mb + mb_offset; 2004 |
2005 if (payload->header.type == R5LOG_PAYLOAD_DATA) { | 2005 if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_DATA) { |
2006 if (r5l_recovery_verify_data_checksum( 2007 log, ctx, page, log_offset, 2008 payload->checksum[0]) < 0) 2009 goto mismatch; | 2006 if (r5l_recovery_verify_data_checksum( 2007 log, ctx, page, log_offset, 2008 payload->checksum[0]) < 0) 2009 goto mismatch; |
2010 } else if (payload->header.type == R5LOG_PAYLOAD_PARITY) { | 2010 } else if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_PARITY) { |
2011 if (r5l_recovery_verify_data_checksum( 2012 log, ctx, page, log_offset, 2013 payload->checksum[0]) < 0) 2014 goto mismatch; 2015 if (conf->max_degraded == 2 && /* q for RAID 6 */ 2016 r5l_recovery_verify_data_checksum( 2017 log, ctx, page, 2018 r5l_ring_add(log, log_offset, 2019 BLOCK_SECTORS), 2020 payload->checksum[1]) < 0) 2021 goto mismatch; | 2011 if (r5l_recovery_verify_data_checksum( 2012 log, ctx, page, log_offset, 2013 payload->checksum[0]) < 0) 2014 goto mismatch; 2015 if (conf->max_degraded == 2 && /* q for RAID 6 */ 2016 r5l_recovery_verify_data_checksum( 2017 log, ctx, page, 2018 r5l_ring_add(log, log_offset, 2019 BLOCK_SECTORS), 2020 payload->checksum[1]) < 0) 2021 goto mismatch; |
2022 } else if (payload->header.type == R5LOG_PAYLOAD_FLUSH) { | 2022 } else if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_FLUSH) { |
2023 /* nothing to do for R5LOG_PAYLOAD_FLUSH here */ 2024 } else /* not R5LOG_PAYLOAD_DATA/PARITY/FLUSH */ 2025 goto mismatch; 2026 | 2023 /* nothing to do for R5LOG_PAYLOAD_FLUSH here */ 2024 } else /* not R5LOG_PAYLOAD_DATA/PARITY/FLUSH */ 2025 goto mismatch; 2026 |
2027 if (payload->header.type == R5LOG_PAYLOAD_FLUSH) { | 2027 if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_FLUSH) { |
2028 mb_offset += sizeof(struct r5l_payload_flush) + 2029 le32_to_cpu(payload_flush->size); 2030 } else { 2031 /* DATA or PARITY payload */ 2032 log_offset = r5l_ring_add(log, log_offset, 2033 le32_to_cpu(payload->size)); 2034 mb_offset += sizeof(struct r5l_payload_data_parity) + 2035 sizeof(__le32) * --- 50 unchanged lines hidden (view full) --- 2086 log_offset = r5l_ring_add(log, ctx->pos, BLOCK_SECTORS); 2087 2088 while (mb_offset < le32_to_cpu(mb->meta_size)) { 2089 int dd; 2090 2091 payload = (void *)mb + mb_offset; 2092 payload_flush = (void *)mb + mb_offset; 2093 | 2028 mb_offset += sizeof(struct r5l_payload_flush) + 2029 le32_to_cpu(payload_flush->size); 2030 } else { 2031 /* DATA or PARITY payload */ 2032 log_offset = r5l_ring_add(log, log_offset, 2033 le32_to_cpu(payload->size)); 2034 mb_offset += sizeof(struct r5l_payload_data_parity) + 2035 sizeof(__le32) * --- 50 unchanged lines hidden (view full) --- 2086 log_offset = r5l_ring_add(log, ctx->pos, BLOCK_SECTORS); 2087 2088 while (mb_offset < le32_to_cpu(mb->meta_size)) { 2089 int dd; 2090 2091 payload = (void *)mb + mb_offset; 2092 payload_flush = (void *)mb + mb_offset; 2093 |
2094 if (payload->header.type == R5LOG_PAYLOAD_FLUSH) { | 2094 if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_FLUSH) { |
2095 int i, count; 2096 2097 count = le32_to_cpu(payload_flush->size) / sizeof(__le64); 2098 for (i = 0; i < count; ++i) { 2099 stripe_sect = le64_to_cpu(payload_flush->flush_stripes[i]); 2100 sh = r5c_recovery_lookup_stripe(cached_stripe_list, 2101 stripe_sect); 2102 if (sh) { --- 5 unchanged lines hidden (view full) --- 2108 } 2109 2110 mb_offset += sizeof(struct r5l_payload_flush) + 2111 le32_to_cpu(payload_flush->size); 2112 continue; 2113 } 2114 2115 /* DATA or PARITY payload */ | 2095 int i, count; 2096 2097 count = le32_to_cpu(payload_flush->size) / sizeof(__le64); 2098 for (i = 0; i < count; ++i) { 2099 stripe_sect = le64_to_cpu(payload_flush->flush_stripes[i]); 2100 sh = r5c_recovery_lookup_stripe(cached_stripe_list, 2101 stripe_sect); 2102 if (sh) { --- 5 unchanged lines hidden (view full) --- 2108 } 2109 2110 mb_offset += sizeof(struct r5l_payload_flush) + 2111 le32_to_cpu(payload_flush->size); 2112 continue; 2113 } 2114 2115 /* DATA or PARITY payload */ |
2116 stripe_sect = (payload->header.type == R5LOG_PAYLOAD_DATA) ? | 2116 stripe_sect = (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_DATA) ? |
2117 raid5_compute_sector( 2118 conf, le64_to_cpu(payload->location), 0, &dd, 2119 NULL) 2120 : le64_to_cpu(payload->location); 2121 2122 sh = r5c_recovery_lookup_stripe(cached_stripe_list, 2123 stripe_sect); 2124 --- 21 unchanged lines hidden (view full) --- 2146 if (!sh) { 2147 pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n", 2148 mdname(mddev)); 2149 return -ENOMEM; 2150 } 2151 list_add_tail(&sh->lru, cached_stripe_list); 2152 } 2153 | 2117 raid5_compute_sector( 2118 conf, le64_to_cpu(payload->location), 0, &dd, 2119 NULL) 2120 : le64_to_cpu(payload->location); 2121 2122 sh = r5c_recovery_lookup_stripe(cached_stripe_list, 2123 stripe_sect); 2124 --- 21 unchanged lines hidden (view full) --- 2146 if (!sh) { 2147 pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n", 2148 mdname(mddev)); 2149 return -ENOMEM; 2150 } 2151 list_add_tail(&sh->lru, cached_stripe_list); 2152 } 2153 |
2154 if (payload->header.type == R5LOG_PAYLOAD_DATA) { | 2154 if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_DATA) { |
2155 if (!test_bit(STRIPE_R5C_CACHING, &sh->state) && 2156 test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) { 2157 r5l_recovery_replay_one_stripe(conf, sh, ctx); 2158 list_move_tail(&sh->lru, cached_stripe_list); 2159 } 2160 r5l_recovery_load_data(log, sh, ctx, payload, 2161 log_offset); | 2155 if (!test_bit(STRIPE_R5C_CACHING, &sh->state) && 2156 test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) { 2157 r5l_recovery_replay_one_stripe(conf, sh, ctx); 2158 list_move_tail(&sh->lru, cached_stripe_list); 2159 } 2160 r5l_recovery_load_data(log, sh, ctx, payload, 2161 log_offset); |
2162 } else if (payload->header.type == R5LOG_PAYLOAD_PARITY) | 2162 } else if (le16_to_cpu(payload->header.type) == R5LOG_PAYLOAD_PARITY) |
2163 r5l_recovery_load_parity(log, sh, ctx, payload, 2164 log_offset); 2165 else 2166 return -EINVAL; 2167 2168 log_offset = r5l_ring_add(log, log_offset, 2169 le32_to_cpu(payload->size)); 2170 --- 185 unchanged lines hidden (view full) --- 2356 struct r5dev *dev = &sh->dev[i]; 2357 struct r5l_payload_data_parity *payload; 2358 void *addr; 2359 2360 if (test_bit(R5_InJournal, &dev->flags)) { 2361 payload = (void *)mb + offset; 2362 payload->header.type = cpu_to_le16( 2363 R5LOG_PAYLOAD_DATA); | 2163 r5l_recovery_load_parity(log, sh, ctx, payload, 2164 log_offset); 2165 else 2166 return -EINVAL; 2167 2168 log_offset = r5l_ring_add(log, log_offset, 2169 le32_to_cpu(payload->size)); 2170 --- 185 unchanged lines hidden (view full) --- 2356 struct r5dev *dev = &sh->dev[i]; 2357 struct r5l_payload_data_parity *payload; 2358 void *addr; 2359 2360 if (test_bit(R5_InJournal, &dev->flags)) { 2361 payload = (void *)mb + offset; 2362 payload->header.type = cpu_to_le16( 2363 R5LOG_PAYLOAD_DATA); |
2364 payload->size = BLOCK_SECTORS; | 2364 payload->size = cpu_to_le32(BLOCK_SECTORS); |
2365 payload->location = cpu_to_le64( 2366 raid5_compute_blocknr(sh, i, 0)); 2367 addr = kmap_atomic(dev->page); 2368 payload->checksum[0] = cpu_to_le32( 2369 crc32c_le(log->uuid_checksum, addr, 2370 PAGE_SIZE)); 2371 kunmap_atomic(addr); 2372 sync_page_io(log->rdev, write_pos, PAGE_SIZE, --- 735 unchanged lines hidden --- | 2365 payload->location = cpu_to_le64( 2366 raid5_compute_blocknr(sh, i, 0)); 2367 addr = kmap_atomic(dev->page); 2368 payload->checksum[0] = cpu_to_le32( 2369 crc32c_le(log->uuid_checksum, addr, 2370 PAGE_SIZE)); 2371 kunmap_atomic(addr); 2372 sync_page_io(log->rdev, write_pos, PAGE_SIZE, --- 735 unchanged lines hidden --- |