diff options
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r-- | fs/btrfs/scrub.c | 14 |
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 | ||
286 | static noinline_for_stack | 289 | static noinline_for_stack |
287 | struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev) | 290 | struct 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 | ||
2294 | int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | 2298 | int 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); |