aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/scrub.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r--fs/btrfs/scrub.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 6cf23f4f7bb7..460e30bb1884 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -116,6 +116,9 @@ struct scrub_ctx {
116 u32 sectorsize; 116 u32 sectorsize;
117 u32 nodesize; 117 u32 nodesize;
118 u32 leafsize; 118 u32 leafsize;
119
120 int is_dev_replace;
121
119 /* 122 /*
120 * statistics 123 * statistics
121 */ 124 */
@@ -284,7 +287,7 @@ static noinline_for_stack void scrub_free_ctx(struct scrub_ctx *sctx)
284} 287}
285 288
286static noinline_for_stack 289static noinline_for_stack
287struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev) 290struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace)
288{ 291{
289 struct scrub_ctx *sctx; 292 struct scrub_ctx *sctx;
290 int i; 293 int i;
@@ -296,6 +299,7 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev)
296 sctx = kzalloc(sizeof(*sctx), GFP_NOFS); 299 sctx = kzalloc(sizeof(*sctx), GFP_NOFS);
297 if (!sctx) 300 if (!sctx)
298 goto nomem; 301 goto nomem;
302 sctx->is_dev_replace = is_dev_replace;
299 sctx->pages_per_bio = pages_per_bio; 303 sctx->pages_per_bio = pages_per_bio;
300 sctx->curr = -1; 304 sctx->curr = -1;
301 sctx->dev_root = dev->dev_root; 305 sctx->dev_root = dev->dev_root;
@@ -2293,7 +2297,7 @@ static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info)
2293 2297
2294int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, 2298int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2295 u64 end, struct btrfs_scrub_progress *progress, 2299 u64 end, struct btrfs_scrub_progress *progress,
2296 int readonly) 2300 int readonly, int is_dev_replace)
2297{ 2301{
2298 struct scrub_ctx *sctx; 2302 struct scrub_ctx *sctx;
2299 int ret; 2303 int ret;
@@ -2356,14 +2360,14 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2356 2360
2357 mutex_lock(&fs_info->fs_devices->device_list_mutex); 2361 mutex_lock(&fs_info->fs_devices->device_list_mutex);
2358 dev = btrfs_find_device(fs_info, devid, NULL, NULL); 2362 dev = btrfs_find_device(fs_info, devid, NULL, NULL);
2359 if (!dev || dev->missing) { 2363 if (!dev || (dev->missing && !is_dev_replace)) {
2360 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2364 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2361 scrub_workers_put(fs_info); 2365 scrub_workers_put(fs_info);
2362 return -ENODEV; 2366 return -ENODEV;
2363 } 2367 }
2364 mutex_lock(&fs_info->scrub_lock); 2368 mutex_lock(&fs_info->scrub_lock);
2365 2369
2366 if (!dev->in_fs_metadata) { 2370 if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) {
2367 mutex_unlock(&fs_info->scrub_lock); 2371 mutex_unlock(&fs_info->scrub_lock);
2368 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2372 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2369 scrub_workers_put(fs_info); 2373 scrub_workers_put(fs_info);
@@ -2376,7 +2380,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2376 scrub_workers_put(fs_info); 2380 scrub_workers_put(fs_info);
2377 return -EINPROGRESS; 2381 return -EINPROGRESS;
2378 } 2382 }
2379 sctx = scrub_setup_ctx(dev); 2383 sctx = scrub_setup_ctx(dev, is_dev_replace);
2380 if (IS_ERR(sctx)) { 2384 if (IS_ERR(sctx)) {
2381 mutex_unlock(&fs_info->scrub_lock); 2385 mutex_unlock(&fs_info->scrub_lock);
2382 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2386 mutex_unlock(&fs_info->fs_devices->device_list_mutex);