@@ -2175,7 +2175,7 @@ static unsigned int scrub_stripe_get_page_offset(struct scrub_stripe *stripe,
21752175 return offset_in_page (sector_nr << fs_info -> sectorsize_bits );
21762176}
21772177
2178- void scrub_verify_one_metadata (struct scrub_stripe * stripe , int sector_nr )
2178+ static void scrub_verify_one_metadata (struct scrub_stripe * stripe , int sector_nr )
21792179{
21802180 struct btrfs_fs_info * fs_info = stripe -> bg -> fs_info ;
21812181 const u32 sectors_per_tree = fs_info -> nodesize >> fs_info -> sectorsize_bits ;
@@ -2265,6 +2265,81 @@ void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr)
22652265 bitmap_clear (& stripe -> meta_error_bitmap , sector_nr , sectors_per_tree );
22662266}
22672267
2268+ static void scrub_verify_one_sector (struct scrub_stripe * stripe , int sector_nr )
2269+ {
2270+ struct btrfs_fs_info * fs_info = stripe -> bg -> fs_info ;
2271+ struct scrub_sector_verification * sector = & stripe -> sectors [sector_nr ];
2272+ const u32 sectors_per_tree = fs_info -> nodesize >> fs_info -> sectorsize_bits ;
2273+ struct page * page = scrub_stripe_get_page (stripe , sector_nr );
2274+ unsigned int pgoff = scrub_stripe_get_page_offset (stripe , sector_nr );
2275+ u8 csum_buf [BTRFS_CSUM_SIZE ];
2276+ int ret ;
2277+
2278+ ASSERT (sector_nr >= 0 && sector_nr < stripe -> nr_sectors );
2279+
2280+ /* Sector not utilized, skip it. */
2281+ if (!test_bit (sector_nr , & stripe -> extent_sector_bitmap ))
2282+ return ;
2283+
2284+ /* IO error, no need to check. */
2285+ if (test_bit (sector_nr , & stripe -> io_error_bitmap ))
2286+ return ;
2287+
2288+ /* Metadata, verify the full tree block. */
2289+ if (sector -> is_metadata ) {
2290+ /*
2291+ * Check if the tree block crosses the stripe boudary. If
2292+ * crossed the boundary, we cannot verify it but only give a
2293+ * warning.
2294+ *
2295+ * This can only happen on a very old filesystem where chunks
2296+ * are not ensured to be stripe aligned.
2297+ */
2298+ if (unlikely (sector_nr + sectors_per_tree > stripe -> nr_sectors )) {
2299+ btrfs_warn_rl (fs_info ,
2300+ "tree block at %llu crosses stripe boundary %llu" ,
2301+ stripe -> logical +
2302+ (sector_nr << fs_info -> sectorsize_bits ),
2303+ stripe -> logical );
2304+ return ;
2305+ }
2306+ scrub_verify_one_metadata (stripe , sector_nr );
2307+ return ;
2308+ }
2309+
2310+ /*
2311+ * Data is easier, we just verify the data csum (if we have it). For
2312+ * cases without csum, we have no other choice but to trust it.
2313+ */
2314+ if (!sector -> csum ) {
2315+ clear_bit (sector_nr , & stripe -> error_bitmap );
2316+ return ;
2317+ }
2318+
2319+ ret = btrfs_check_sector_csum (fs_info , page , pgoff , csum_buf , sector -> csum );
2320+ if (ret < 0 ) {
2321+ set_bit (sector_nr , & stripe -> csum_error_bitmap );
2322+ set_bit (sector_nr , & stripe -> error_bitmap );
2323+ } else {
2324+ clear_bit (sector_nr , & stripe -> csum_error_bitmap );
2325+ clear_bit (sector_nr , & stripe -> error_bitmap );
2326+ }
2327+ }
2328+
2329+ /* Verify specified sectors of a stripe. */
2330+ void scrub_verify_one_stripe (struct scrub_stripe * stripe , unsigned long bitmap )
2331+ {
2332+ struct btrfs_fs_info * fs_info = stripe -> bg -> fs_info ;
2333+ const u32 sectors_per_tree = fs_info -> nodesize >> fs_info -> sectorsize_bits ;
2334+ int sector_nr ;
2335+
2336+ for_each_set_bit (sector_nr , & bitmap , stripe -> nr_sectors ) {
2337+ scrub_verify_one_sector (stripe , sector_nr );
2338+ if (stripe -> sectors [sector_nr ].is_metadata )
2339+ sector_nr += sectors_per_tree - 1 ;
2340+ }
2341+ }
2342+
22682343static int scrub_checksum_tree_block (struct scrub_block * sblock )
22692344{
22702345 struct scrub_ctx * sctx = sblock -> sctx ;
0 commit comments