mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	btrfs: scrub: remove scrub_bio structure
Since scrub path has been fully moved to scrub_stripe based facilities, no more scrub_bio would be submitted. Thus we can remove it completely, this involves: - SCRUB_SECTORS_PER_BIO macro - SCRUB_BIOS_PER_SCTX macro - SCRUB_MAX_PAGES macro - BTRFS_MAX_MIRRORS macro - scrub_bio structure - scrub_ctx::bios member - scrub_ctx::curr member - scrub_ctx::bios_in_flight member - scrub_ctx::workers_pending member - scrub_ctx::list_lock member - scrub_ctx::list_wait member - function scrub_bio_end_io_worker() - function scrub_pending_bio_inc() - function scrub_pending_bio_dec() - function scrub_throttle() - function scrub_submit() - function scrub_find_csum() - function drop_csum_range() - Some unnecessary flush and scrub pauses Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									001e3fc263
								
							
						
					
					
						commit
						13a62fd997
					
				
					 2 changed files with 6 additions and 244 deletions
				
			
		
							
								
								
									
										245
									
								
								fs/btrfs/scrub.c
									
									
									
									
									
								
							
							
						
						
									
										245
									
								
								fs/btrfs/scrub.c
									
									
									
									
									
								
							|  | @ -41,14 +41,10 @@ | ||||||
| struct scrub_ctx; | struct scrub_ctx; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * The following three values only influence the performance. |  * The following value only influences the performance. | ||||||
|  * |  * | ||||||
|  * The last one configures the number of parallel and outstanding I/O |  * This determines the batch size for stripe submitted in one go. | ||||||
|  * operations. The first one configures an upper limit for the number |  | ||||||
|  * of (dynamically allocated) pages that are added to a bio. |  | ||||||
|  */ |  */ | ||||||
| #define SCRUB_SECTORS_PER_BIO	32	/* 128KiB per bio for 4KiB pages */ |  | ||||||
| #define SCRUB_BIOS_PER_SCTX	64	/* 8MiB per device in flight for 4KiB pages */ |  | ||||||
| #define SCRUB_STRIPES_PER_SCTX	8	/* That would be 8 64K stripe per-device. */ | #define SCRUB_STRIPES_PER_SCTX	8	/* That would be 8 64K stripe per-device. */ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -57,19 +53,6 @@ struct scrub_ctx; | ||||||
|  */ |  */ | ||||||
| #define SCRUB_MAX_SECTORS_PER_BLOCK	(BTRFS_MAX_METADATA_BLOCKSIZE / SZ_4K) | #define SCRUB_MAX_SECTORS_PER_BLOCK	(BTRFS_MAX_METADATA_BLOCKSIZE / SZ_4K) | ||||||
| 
 | 
 | ||||||
| #define SCRUB_MAX_PAGES			(DIV_ROUND_UP(BTRFS_MAX_METADATA_BLOCKSIZE, PAGE_SIZE)) |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Maximum number of mirrors that can be available for all profiles counting |  | ||||||
|  * the target device of dev-replace as one. During an active device replace |  | ||||||
|  * procedure, the target device of the copy operation is a mirror for the |  | ||||||
|  * filesystem data as well that can be used to read data in order to repair |  | ||||||
|  * read errors on other disks. |  | ||||||
|  * |  | ||||||
|  * Current value is derived from RAID1C4 with 4 copies. |  | ||||||
|  */ |  | ||||||
| #define BTRFS_MAX_MIRRORS (4 + 1) |  | ||||||
| 
 |  | ||||||
| /* Represent one sector and its needed info to verify the content. */ | /* Represent one sector and its needed info to verify the content. */ | ||||||
| struct scrub_sector_verification { | struct scrub_sector_verification { | ||||||
| 	bool is_metadata; | 	bool is_metadata; | ||||||
|  | @ -182,31 +165,12 @@ struct scrub_stripe { | ||||||
| 	struct work_struct work; | 	struct work_struct work; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct scrub_bio { |  | ||||||
| 	int			index; |  | ||||||
| 	struct scrub_ctx	*sctx; |  | ||||||
| 	struct btrfs_device	*dev; |  | ||||||
| 	struct bio		*bio; |  | ||||||
| 	blk_status_t		status; |  | ||||||
| 	u64			logical; |  | ||||||
| 	u64			physical; |  | ||||||
| 	int			sector_count; |  | ||||||
| 	int			next_free; |  | ||||||
| 	struct work_struct	work; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct scrub_ctx { | struct scrub_ctx { | ||||||
| 	struct scrub_bio	*bios[SCRUB_BIOS_PER_SCTX]; |  | ||||||
| 	struct scrub_stripe	stripes[SCRUB_STRIPES_PER_SCTX]; | 	struct scrub_stripe	stripes[SCRUB_STRIPES_PER_SCTX]; | ||||||
| 	struct scrub_stripe	*raid56_data_stripes; | 	struct scrub_stripe	*raid56_data_stripes; | ||||||
| 	struct btrfs_fs_info	*fs_info; | 	struct btrfs_fs_info	*fs_info; | ||||||
| 	int			first_free; | 	int			first_free; | ||||||
| 	int			curr; |  | ||||||
| 	int			cur_stripe; | 	int			cur_stripe; | ||||||
| 	atomic_t		bios_in_flight; |  | ||||||
| 	atomic_t		workers_pending; |  | ||||||
| 	spinlock_t		list_lock; |  | ||||||
| 	wait_queue_head_t	list_wait; |  | ||||||
| 	struct list_head	csum_list; | 	struct list_head	csum_list; | ||||||
| 	atomic_t		cancel_req; | 	atomic_t		cancel_req; | ||||||
| 	int			readonly; | 	int			readonly; | ||||||
|  | @ -305,22 +269,8 @@ static void wait_scrub_stripe_io(struct scrub_stripe *stripe) | ||||||
| 	wait_event(stripe->io_wait, atomic_read(&stripe->pending_io) == 0); | 	wait_event(stripe->io_wait, atomic_read(&stripe->pending_io) == 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void scrub_bio_end_io_worker(struct work_struct *work); |  | ||||||
| static void scrub_put_ctx(struct scrub_ctx *sctx); | static void scrub_put_ctx(struct scrub_ctx *sctx); | ||||||
| 
 | 
 | ||||||
| static void scrub_pending_bio_inc(struct scrub_ctx *sctx) |  | ||||||
| { |  | ||||||
| 	refcount_inc(&sctx->refs); |  | ||||||
| 	atomic_inc(&sctx->bios_in_flight); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void scrub_pending_bio_dec(struct scrub_ctx *sctx) |  | ||||||
| { |  | ||||||
| 	atomic_dec(&sctx->bios_in_flight); |  | ||||||
| 	wake_up(&sctx->list_wait); |  | ||||||
| 	scrub_put_ctx(sctx); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void __scrub_blocked_if_needed(struct btrfs_fs_info *fs_info) | static void __scrub_blocked_if_needed(struct btrfs_fs_info *fs_info) | ||||||
| { | { | ||||||
| 	while (atomic_read(&fs_info->scrub_pause_req)) { | 	while (atomic_read(&fs_info->scrub_pause_req)) { | ||||||
|  | @ -371,21 +321,6 @@ static noinline_for_stack void scrub_free_ctx(struct scrub_ctx *sctx) | ||||||
| 	if (!sctx) | 	if (!sctx) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	/* this can happen when scrub is cancelled */ |  | ||||||
| 	if (sctx->curr != -1) { |  | ||||||
| 		struct scrub_bio *sbio = sctx->bios[sctx->curr]; |  | ||||||
| 
 |  | ||||||
| 		bio_put(sbio->bio); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < SCRUB_BIOS_PER_SCTX; ++i) { |  | ||||||
| 		struct scrub_bio *sbio = sctx->bios[i]; |  | ||||||
| 
 |  | ||||||
| 		if (!sbio) |  | ||||||
| 			break; |  | ||||||
| 		kfree(sbio); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < SCRUB_STRIPES_PER_SCTX; i++) | 	for (i = 0; i < SCRUB_STRIPES_PER_SCTX; i++) | ||||||
| 		release_scrub_stripe(&sctx->stripes[i]); | 		release_scrub_stripe(&sctx->stripes[i]); | ||||||
| 
 | 
 | ||||||
|  | @ -410,28 +345,8 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx( | ||||||
| 		goto nomem; | 		goto nomem; | ||||||
| 	refcount_set(&sctx->refs, 1); | 	refcount_set(&sctx->refs, 1); | ||||||
| 	sctx->is_dev_replace = is_dev_replace; | 	sctx->is_dev_replace = is_dev_replace; | ||||||
| 	sctx->sectors_per_bio = SCRUB_SECTORS_PER_BIO; |  | ||||||
| 	sctx->curr = -1; |  | ||||||
| 	sctx->fs_info = fs_info; | 	sctx->fs_info = fs_info; | ||||||
| 	INIT_LIST_HEAD(&sctx->csum_list); | 	INIT_LIST_HEAD(&sctx->csum_list); | ||||||
| 	for (i = 0; i < SCRUB_BIOS_PER_SCTX; ++i) { |  | ||||||
| 		struct scrub_bio *sbio; |  | ||||||
| 
 |  | ||||||
| 		sbio = kzalloc(sizeof(*sbio), GFP_KERNEL); |  | ||||||
| 		if (!sbio) |  | ||||||
| 			goto nomem; |  | ||||||
| 		sctx->bios[i] = sbio; |  | ||||||
| 
 |  | ||||||
| 		sbio->index = i; |  | ||||||
| 		sbio->sctx = sctx; |  | ||||||
| 		sbio->sector_count = 0; |  | ||||||
| 		INIT_WORK(&sbio->work, scrub_bio_end_io_worker); |  | ||||||
| 
 |  | ||||||
| 		if (i != SCRUB_BIOS_PER_SCTX - 1) |  | ||||||
| 			sctx->bios[i]->next_free = i + 1; |  | ||||||
| 		else |  | ||||||
| 			sctx->bios[i]->next_free = -1; |  | ||||||
| 	} |  | ||||||
| 	for (i = 0; i < SCRUB_STRIPES_PER_SCTX; i++) { | 	for (i = 0; i < SCRUB_STRIPES_PER_SCTX; i++) { | ||||||
| 		int ret; | 		int ret; | ||||||
| 
 | 
 | ||||||
|  | @ -441,13 +356,9 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx( | ||||||
| 		sctx->stripes[i].sctx = sctx; | 		sctx->stripes[i].sctx = sctx; | ||||||
| 	} | 	} | ||||||
| 	sctx->first_free = 0; | 	sctx->first_free = 0; | ||||||
| 	atomic_set(&sctx->bios_in_flight, 0); |  | ||||||
| 	atomic_set(&sctx->workers_pending, 0); |  | ||||||
| 	atomic_set(&sctx->cancel_req, 0); | 	atomic_set(&sctx->cancel_req, 0); | ||||||
| 
 | 
 | ||||||
| 	spin_lock_init(&sctx->list_lock); |  | ||||||
| 	spin_lock_init(&sctx->stat_lock); | 	spin_lock_init(&sctx->stat_lock); | ||||||
| 	init_waitqueue_head(&sctx->list_wait); |  | ||||||
| 	sctx->throttle_deadline = 0; | 	sctx->throttle_deadline = 0; | ||||||
| 
 | 
 | ||||||
| 	mutex_init(&sctx->wr_lock); | 	mutex_init(&sctx->wr_lock); | ||||||
|  | @ -1286,6 +1197,10 @@ static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *str | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Throttling of IO submission, bandwidth-limit based, the timeslice is 1 | ||||||
|  |  * second.  Limit can be set via /sys/fs/UUID/devinfo/devid/scrub_speed_max. | ||||||
|  |  */ | ||||||
| static void scrub_throttle_dev_io(struct scrub_ctx *sctx, struct btrfs_device *device, | static void scrub_throttle_dev_io(struct scrub_ctx *sctx, struct btrfs_device *device, | ||||||
| 				  unsigned int bio_size) | 				  unsigned int bio_size) | ||||||
| { | { | ||||||
|  | @ -1338,112 +1253,6 @@ static void scrub_throttle_dev_io(struct scrub_ctx *sctx, struct btrfs_device *d | ||||||
| 	sctx->throttle_deadline = 0; | 	sctx->throttle_deadline = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Throttling of IO submission, bandwidth-limit based, the timeslice is 1 |  | ||||||
|  * second.  Limit can be set via /sys/fs/UUID/devinfo/devid/scrub_speed_max. |  | ||||||
|  */ |  | ||||||
| static void scrub_throttle(struct scrub_ctx *sctx) |  | ||||||
| { |  | ||||||
| 	struct scrub_bio *sbio = sctx->bios[sctx->curr]; |  | ||||||
| 
 |  | ||||||
| 	scrub_throttle_dev_io(sctx, sbio->dev, sbio->bio->bi_iter.bi_size); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void scrub_submit(struct scrub_ctx *sctx) |  | ||||||
| { |  | ||||||
| 	struct scrub_bio *sbio; |  | ||||||
| 
 |  | ||||||
| 	if (sctx->curr == -1) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	scrub_throttle(sctx); |  | ||||||
| 
 |  | ||||||
| 	sbio = sctx->bios[sctx->curr]; |  | ||||||
| 	sctx->curr = -1; |  | ||||||
| 	scrub_pending_bio_inc(sctx); |  | ||||||
| 	btrfsic_check_bio(sbio->bio); |  | ||||||
| 	submit_bio(sbio->bio); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void scrub_bio_end_io_worker(struct work_struct *work) |  | ||||||
| { |  | ||||||
| 	struct scrub_bio *sbio = container_of(work, struct scrub_bio, work); |  | ||||||
| 	struct scrub_ctx *sctx = sbio->sctx; |  | ||||||
| 
 |  | ||||||
| 	ASSERT(sbio->sector_count <= SCRUB_SECTORS_PER_BIO); |  | ||||||
| 
 |  | ||||||
| 	bio_put(sbio->bio); |  | ||||||
| 	sbio->bio = NULL; |  | ||||||
| 	spin_lock(&sctx->list_lock); |  | ||||||
| 	sbio->next_free = sctx->first_free; |  | ||||||
| 	sctx->first_free = sbio->index; |  | ||||||
| 	spin_unlock(&sctx->list_lock); |  | ||||||
| 
 |  | ||||||
| 	scrub_pending_bio_dec(sctx); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void drop_csum_range(struct scrub_ctx *sctx, struct btrfs_ordered_sum *sum) |  | ||||||
| { |  | ||||||
| 	sctx->stat.csum_discards += sum->len >> sctx->fs_info->sectorsize_bits; |  | ||||||
| 	list_del(&sum->list); |  | ||||||
| 	kfree(sum); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Find the desired csum for range [logical, logical + sectorsize), and store |  | ||||||
|  * the csum into @csum. |  | ||||||
|  * |  | ||||||
|  * The search source is sctx->csum_list, which is a pre-populated list |  | ||||||
|  * storing bytenr ordered csum ranges.  We're responsible to cleanup any range |  | ||||||
|  * that is before @logical. |  | ||||||
|  * |  | ||||||
|  * Return 0 if there is no csum for the range. |  | ||||||
|  * Return 1 if there is csum for the range and copied to @csum. |  | ||||||
|  */ |  | ||||||
| int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum) |  | ||||||
| { |  | ||||||
| 	bool found = false; |  | ||||||
| 
 |  | ||||||
| 	while (!list_empty(&sctx->csum_list)) { |  | ||||||
| 		struct btrfs_ordered_sum *sum = NULL; |  | ||||||
| 		unsigned long index; |  | ||||||
| 		unsigned long num_sectors; |  | ||||||
| 
 |  | ||||||
| 		sum = list_first_entry(&sctx->csum_list, |  | ||||||
| 				       struct btrfs_ordered_sum, list); |  | ||||||
| 		/* The current csum range is beyond our range, no csum found */ |  | ||||||
| 		if (sum->bytenr > logical) |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		/*
 |  | ||||||
| 		 * The current sum is before our bytenr, since scrub is always |  | ||||||
| 		 * done in bytenr order, the csum will never be used anymore, |  | ||||||
| 		 * clean it up so that later calls won't bother with the range, |  | ||||||
| 		 * and continue search the next range. |  | ||||||
| 		 */ |  | ||||||
| 		if (sum->bytenr + sum->len <= logical) { |  | ||||||
| 			drop_csum_range(sctx, sum); |  | ||||||
| 			continue; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		/* Now the csum range covers our bytenr, copy the csum */ |  | ||||||
| 		found = true; |  | ||||||
| 		index = (logical - sum->bytenr) >> sctx->fs_info->sectorsize_bits; |  | ||||||
| 		num_sectors = sum->len >> sctx->fs_info->sectorsize_bits; |  | ||||||
| 
 |  | ||||||
| 		memcpy(csum, sum->sums + index * sctx->fs_info->csum_size, |  | ||||||
| 		       sctx->fs_info->csum_size); |  | ||||||
| 
 |  | ||||||
| 		/* Cleanup the range if we're at the end of the csum range */ |  | ||||||
| 		if (index == num_sectors - 1) |  | ||||||
| 			drop_csum_range(sctx, sum); |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 	if (!found) |  | ||||||
| 		return 0; |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Given a physical address, this will calculate it's |  * Given a physical address, this will calculate it's | ||||||
|  * logical offset. if this is a parity stripe, it will return |  * logical offset. if this is a parity stripe, it will return | ||||||
|  | @ -1624,8 +1433,6 @@ static int sync_write_pointer_for_zoned(struct scrub_ctx *sctx, u64 logical, | ||||||
| 	if (!btrfs_is_zoned(fs_info)) | 	if (!btrfs_is_zoned(fs_info)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); |  | ||||||
| 
 |  | ||||||
| 	mutex_lock(&sctx->wr_lock); | 	mutex_lock(&sctx->wr_lock); | ||||||
| 	if (sctx->write_pointer < physical_end) { | 	if (sctx->write_pointer < physical_end) { | ||||||
| 		ret = btrfs_sync_zone_write_pointer(sctx->wr_tgtdev, logical, | 		ret = btrfs_sync_zone_write_pointer(sctx->wr_tgtdev, logical, | ||||||
|  | @ -2153,11 +1960,6 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx, | ||||||
| 		/* Paused? */ | 		/* Paused? */ | ||||||
| 		if (atomic_read(&fs_info->scrub_pause_req)) { | 		if (atomic_read(&fs_info->scrub_pause_req)) { | ||||||
| 			/* Push queued extents */ | 			/* Push queued extents */ | ||||||
| 			scrub_submit(sctx); |  | ||||||
| 			mutex_lock(&sctx->wr_lock); |  | ||||||
| 			mutex_unlock(&sctx->wr_lock); |  | ||||||
| 			wait_event(sctx->list_wait, |  | ||||||
| 				   atomic_read(&sctx->bios_in_flight) == 0); |  | ||||||
| 			scrub_blocked_if_needed(fs_info); | 			scrub_blocked_if_needed(fs_info); | ||||||
| 		} | 		} | ||||||
| 		/* Block group removed? */ | 		/* Block group removed? */ | ||||||
|  | @ -2285,8 +2087,6 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | ||||||
| 	u64 stripe_logical; | 	u64 stripe_logical; | ||||||
| 	int stop_loop = 0; | 	int stop_loop = 0; | ||||||
| 
 | 
 | ||||||
| 	wait_event(sctx->list_wait, |  | ||||||
| 		   atomic_read(&sctx->bios_in_flight) == 0); |  | ||||||
| 	scrub_blocked_if_needed(fs_info); | 	scrub_blocked_if_needed(fs_info); | ||||||
| 
 | 
 | ||||||
| 	if (sctx->is_dev_replace && | 	if (sctx->is_dev_replace && | ||||||
|  | @ -2402,8 +2202,6 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | ||||||
| 			break; | 			break; | ||||||
| 	} | 	} | ||||||
| out: | out: | ||||||
| 	/* push queued extents */ |  | ||||||
| 	scrub_submit(sctx); |  | ||||||
| 	flush_scrub_stripes(sctx); | 	flush_scrub_stripes(sctx); | ||||||
| 	if (sctx->raid56_data_stripes) { | 	if (sctx->raid56_data_stripes) { | ||||||
| 		for (int i = 0; i < nr_data_stripes(map); i++) | 		for (int i = 0; i < nr_data_stripes(map); i++) | ||||||
|  | @ -2728,34 +2526,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | ||||||
| 
 | 
 | ||||||
| 		ret = scrub_chunk(sctx, cache, scrub_dev, found_key.offset, | 		ret = scrub_chunk(sctx, cache, scrub_dev, found_key.offset, | ||||||
| 				  dev_extent_len); | 				  dev_extent_len); | ||||||
| 
 |  | ||||||
| 		/*
 |  | ||||||
| 		 * flush, submit all pending read and write bios, afterwards |  | ||||||
| 		 * wait for them. |  | ||||||
| 		 * Note that in the dev replace case, a read request causes |  | ||||||
| 		 * write requests that are submitted in the read completion |  | ||||||
| 		 * worker. Therefore in the current situation, it is required |  | ||||||
| 		 * that all write requests are flushed, so that all read and |  | ||||||
| 		 * write requests are really completed when bios_in_flight |  | ||||||
| 		 * changes to 0. |  | ||||||
| 		 */ |  | ||||||
| 		scrub_submit(sctx); |  | ||||||
| 
 |  | ||||||
| 		wait_event(sctx->list_wait, |  | ||||||
| 			   atomic_read(&sctx->bios_in_flight) == 0); |  | ||||||
| 
 |  | ||||||
| 		scrub_pause_on(fs_info); |  | ||||||
| 
 |  | ||||||
| 		/*
 |  | ||||||
| 		 * must be called before we decrease @scrub_paused. |  | ||||||
| 		 * make sure we don't block transaction commit while |  | ||||||
| 		 * we are waiting pending workers finished. |  | ||||||
| 		 */ |  | ||||||
| 		wait_event(sctx->list_wait, |  | ||||||
| 			   atomic_read(&sctx->workers_pending) == 0); |  | ||||||
| 
 |  | ||||||
| 		scrub_pause_off(fs_info); |  | ||||||
| 
 |  | ||||||
| 		if (sctx->is_dev_replace && | 		if (sctx->is_dev_replace && | ||||||
| 		    !btrfs_finish_block_group_to_copy(dev_replace->srcdev, | 		    !btrfs_finish_block_group_to_copy(dev_replace->srcdev, | ||||||
| 						      cache, found_key.offset)) | 						      cache, found_key.offset)) | ||||||
|  | @ -3086,12 +2856,9 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | ||||||
| 		ret = scrub_enumerate_chunks(sctx, dev, start, end); | 		ret = scrub_enumerate_chunks(sctx, dev, start, end); | ||||||
| 	memalloc_nofs_restore(nofs_flag); | 	memalloc_nofs_restore(nofs_flag); | ||||||
| 
 | 
 | ||||||
| 	wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); |  | ||||||
| 	atomic_dec(&fs_info->scrubs_running); | 	atomic_dec(&fs_info->scrubs_running); | ||||||
| 	wake_up(&fs_info->scrub_pause_wait); | 	wake_up(&fs_info->scrub_pause_wait); | ||||||
| 
 | 
 | ||||||
| 	wait_event(sctx->list_wait, atomic_read(&sctx->workers_pending) == 0); |  | ||||||
| 
 |  | ||||||
| 	if (progress) | 	if (progress) | ||||||
| 		memcpy(progress, &sctx->stat, sizeof(*progress)); | 		memcpy(progress, &sctx->stat, sizeof(*progress)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,9 +13,4 @@ int btrfs_scrub_cancel_dev(struct btrfs_device *dev); | ||||||
| int btrfs_scrub_progress(struct btrfs_fs_info *fs_info, u64 devid, | int btrfs_scrub_progress(struct btrfs_fs_info *fs_info, u64 devid, | ||||||
| 			 struct btrfs_scrub_progress *progress); | 			 struct btrfs_scrub_progress *progress); | ||||||
| 
 | 
 | ||||||
| /* Temporary declaration, would be deleted later. */ |  | ||||||
| struct scrub_ctx; |  | ||||||
| struct scrub_block; |  | ||||||
| int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum); |  | ||||||
| 
 |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Qu Wenruo
						Qu Wenruo