@@ -1959,13 +1959,15 @@ r5l_recovery_verify_data_checksum_for_mb(struct r5l_log *log,
19591959 sector_t log_offset = r5l_ring_add (log , ctx -> pos , BLOCK_SECTORS );
19601960 struct page * page ;
19611961 struct r5l_payload_data_parity * payload ;
1962+ struct r5l_payload_flush * payload_flush ;
19621963
19631964 page = alloc_page (GFP_KERNEL );
19641965 if (!page )
19651966 return - ENOMEM ;
19661967
19671968 while (mb_offset < le32_to_cpu (mb -> meta_size )) {
19681969 payload = (void * )mb + mb_offset ;
1970+ payload_flush = (void * )mb + mb_offset ;
19691971
19701972 if (payload -> header .type == R5LOG_PAYLOAD_DATA ) {
19711973 if (r5l_recovery_verify_data_checksum (
@@ -1984,15 +1986,23 @@ r5l_recovery_verify_data_checksum_for_mb(struct r5l_log *log,
19841986 BLOCK_SECTORS ),
19851987 payload -> checksum [1 ]) < 0 )
19861988 goto mismatch ;
1987- } else /* not R5LOG_PAYLOAD_DATA or R5LOG_PAYLOAD_PARITY */
1989+ } else if (payload -> header .type == R5LOG_PAYLOAD_FLUSH ) {
1990+ /* nothing to do for R5LOG_PAYLOAD_FLUSH here */
1991+ } else /* not R5LOG_PAYLOAD_DATA/PARITY/FLUSH */
19881992 goto mismatch ;
19891993
1990- log_offset = r5l_ring_add (log , log_offset ,
1991- le32_to_cpu (payload -> size ));
1994+ if (payload -> header .type == R5LOG_PAYLOAD_FLUSH ) {
1995+ mb_offset += sizeof (struct r5l_payload_flush ) +
1996+ le32_to_cpu (payload_flush -> size );
1997+ } else {
1998+ /* DATA or PARITY payload */
1999+ log_offset = r5l_ring_add (log , log_offset ,
2000+ le32_to_cpu (payload -> size ));
2001+ mb_offset += sizeof (struct r5l_payload_data_parity ) +
2002+ sizeof (__le32 ) *
2003+ (le32_to_cpu (payload -> size ) >> (PAGE_SHIFT - 9 ));
2004+ }
19922005
1993- mb_offset += sizeof (struct r5l_payload_data_parity ) +
1994- sizeof (__le32 ) *
1995- (le32_to_cpu (payload -> size ) >> (PAGE_SHIFT - 9 ));
19962006 }
19972007
19982008 put_page (page );
@@ -2020,6 +2030,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
20202030 struct r5conf * conf = mddev -> private ;
20212031 struct r5l_meta_block * mb ;
20222032 struct r5l_payload_data_parity * payload ;
2033+ struct r5l_payload_flush * payload_flush ;
20232034 int mb_offset ;
20242035 sector_t log_offset ;
20252036 sector_t stripe_sect ;
@@ -2045,6 +2056,30 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
20452056 int dd ;
20462057
20472058 payload = (void * )mb + mb_offset ;
2059+ payload_flush = (void * )mb + mb_offset ;
2060+
2061+ if (payload -> header .type == R5LOG_PAYLOAD_FLUSH ) {
2062+ int i , count ;
2063+
2064+ count = le32_to_cpu (payload_flush -> size ) / sizeof (__le64 );
2065+ for (i = 0 ; i < count ; ++ i ) {
2066+ stripe_sect = le64_to_cpu (payload_flush -> flush_stripes [i ]);
2067+ sh = r5c_recovery_lookup_stripe (cached_stripe_list ,
2068+ stripe_sect );
2069+ if (sh ) {
2070+ WARN_ON (test_bit (STRIPE_R5C_CACHING , & sh -> state ));
2071+ r5l_recovery_reset_stripe (sh );
2072+ list_del_init (& sh -> lru );
2073+ raid5_release_stripe (sh );
2074+ }
2075+ }
2076+
2077+ mb_offset += sizeof (struct r5l_payload_flush ) +
2078+ le32_to_cpu (payload_flush -> size );
2079+ continue ;
2080+ }
2081+
2082+ /* DATA or PARITY payload */
20482083 stripe_sect = (payload -> header .type == R5LOG_PAYLOAD_DATA ) ?
20492084 raid5_compute_sector (
20502085 conf , le64_to_cpu (payload -> location ), 0 , & dd ,
0 commit comments