Commit 1c10702e authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: raid56: avoid double for loop inside raid56_parity_scrub_stripe()



Originally it's iterating all the sectors which has dbitmap sector for
the vertical stripe.

It can be easily converted to sector bytenr iteration with an test_bit()
call.

Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 550cdeb3
Loading
Loading
Loading
Loading
+31 −31
Original line number Original line Diff line number Diff line
@@ -2661,8 +2661,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
	int bios_to_read = 0;
	int bios_to_read = 0;
	struct bio_list bio_list;
	struct bio_list bio_list;
	int ret;
	int ret;
	int sectornr;
	int total_sector_nr;
	int stripe;
	struct bio *bio;
	struct bio *bio;


	bio_list_init(&bio_list);
	bio_list_init(&bio_list);
@@ -2672,18 +2671,21 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
		goto cleanup;
		goto cleanup;


	atomic_set(&rbio->error, 0);
	atomic_set(&rbio->error, 0);
	/*
	/* Build a list of bios to read all the missing parts. */
	 * build a list of bios to read all the missing parts of this
	for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
	 * stripe
	     total_sector_nr++) {
	 */
		int sectornr = total_sector_nr % rbio->stripe_nsectors;
	for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
		int stripe = total_sector_nr / rbio->stripe_nsectors;
		for_each_set_bit(sectornr, &rbio->dbitmap, rbio->stripe_nsectors) {
		struct sector_ptr *sector;
		struct sector_ptr *sector;

		/* No data in the vertical stripe, no need to read. */
		if (!test_bit(sectornr, &rbio->dbitmap))
			continue;

		/*
		/*
			 * We want to find all the sectors missing from the
		 * We want to find all the sectors missing from the rbio and
			 * rbio and read them from the disk.  If * sector_in_rbio()
		 * read them from the disk. If sector_in_rbio() finds a sector
			 * finds a sector in the bio list we don't need to read
		 * in the bio list we don't need to read it off the stripe.
			 * it off the stripe.
		 */
		 */
		sector = sector_in_rbio(rbio, stripe, sectornr, 1);
		sector = sector_in_rbio(rbio, stripe, sectornr, 1);
		if (sector)
		if (sector)
@@ -2691,19 +2693,17 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)


		sector = rbio_stripe_sector(rbio, stripe, sectornr);
		sector = rbio_stripe_sector(rbio, stripe, sectornr);
		/*
		/*
			 * The bio cache may have handed us an uptodate sector.
		 * The bio cache may have handed us an uptodate sector.  If so,
			 * If so, be happy and use it.
		 * use it.
		 */
		 */
		if (sector->uptodate)
		if (sector->uptodate)
			continue;
			continue;


			ret = rbio_add_io_sector(rbio, &bio_list, sector,
		ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
						 stripe, sectornr, rbio->stripe_len,
					 sectornr, rbio->stripe_len, REQ_OP_READ);
						 REQ_OP_READ);
		if (ret)
		if (ret)
			goto cleanup;
			goto cleanup;
	}
	}
	}


	bios_to_read = bio_list_size(&bio_list);
	bios_to_read = bio_list_size(&bio_list);
	if (!bios_to_read) {
	if (!bios_to_read) {