diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r-- | fs/btrfs/dev-replace.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 1a3d24592859..5aebedf12b5f 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -302,8 +302,8 @@ void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info) | |||
302 | dev_replace->cursor_left_last_write_of_item; | 302 | dev_replace->cursor_left_last_write_of_item; |
303 | } | 303 | } |
304 | 304 | ||
305 | int btrfs_dev_replace_start(struct btrfs_root *root, | 305 | int btrfs_dev_replace_start(struct btrfs_root *root, char *tgtdev_name, |
306 | struct btrfs_ioctl_dev_replace_args *args) | 306 | u64 srcdevid, char *srcdev_name, int read_src) |
307 | { | 307 | { |
308 | struct btrfs_trans_handle *trans; | 308 | struct btrfs_trans_handle *trans; |
309 | struct btrfs_fs_info *fs_info = root->fs_info; | 309 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -312,25 +312,16 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
312 | struct btrfs_device *tgt_device = NULL; | 312 | struct btrfs_device *tgt_device = NULL; |
313 | struct btrfs_device *src_device = NULL; | 313 | struct btrfs_device *src_device = NULL; |
314 | 314 | ||
315 | switch (args->start.cont_reading_from_srcdev_mode) { | ||
316 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS: | ||
317 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID: | ||
318 | break; | ||
319 | default: | ||
320 | return -EINVAL; | ||
321 | } | ||
322 | |||
323 | /* the disk copy procedure reuses the scrub code */ | 315 | /* the disk copy procedure reuses the scrub code */ |
324 | mutex_lock(&fs_info->volume_mutex); | 316 | mutex_lock(&fs_info->volume_mutex); |
325 | ret = btrfs_find_device_by_devspec(root, args->start.srcdevid, | 317 | ret = btrfs_find_device_by_devspec(root, srcdevid, |
326 | args->start.srcdev_name, | 318 | srcdev_name, &src_device); |
327 | &src_device); | ||
328 | if (ret) { | 319 | if (ret) { |
329 | mutex_unlock(&fs_info->volume_mutex); | 320 | mutex_unlock(&fs_info->volume_mutex); |
330 | return ret; | 321 | return ret; |
331 | } | 322 | } |
332 | 323 | ||
333 | ret = btrfs_init_dev_replace_tgtdev(root, args->start.tgtdev_name, | 324 | ret = btrfs_init_dev_replace_tgtdev(root, tgtdev_name, |
334 | src_device, &tgt_device); | 325 | src_device, &tgt_device); |
335 | mutex_unlock(&fs_info->volume_mutex); | 326 | mutex_unlock(&fs_info->volume_mutex); |
336 | if (ret) | 327 | if (ret) |
@@ -357,12 +348,11 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
357 | break; | 348 | break; |
358 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: | 349 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: |
359 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: | 350 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: |
360 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED; | 351 | ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED; |
361 | goto leave; | 352 | goto leave; |
362 | } | 353 | } |
363 | 354 | ||
364 | dev_replace->cont_reading_from_srcdev_mode = | 355 | dev_replace->cont_reading_from_srcdev_mode = read_src; |
365 | args->start.cont_reading_from_srcdev_mode; | ||
366 | WARN_ON(!src_device); | 356 | WARN_ON(!src_device); |
367 | dev_replace->srcdev = src_device; | 357 | dev_replace->srcdev = src_device; |
368 | WARN_ON(!tgt_device); | 358 | WARN_ON(!tgt_device); |
@@ -389,7 +379,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
389 | dev_replace->item_needs_writeback = 1; | 379 | dev_replace->item_needs_writeback = 1; |
390 | atomic64_set(&dev_replace->num_write_errors, 0); | 380 | atomic64_set(&dev_replace->num_write_errors, 0); |
391 | atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); | 381 | atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); |
392 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; | ||
393 | btrfs_dev_replace_unlock(dev_replace, 1); | 382 | btrfs_dev_replace_unlock(dev_replace, 1); |
394 | 383 | ||
395 | ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); | 384 | ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); |
@@ -415,10 +404,8 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
415 | &dev_replace->scrub_progress, 0, 1); | 404 | &dev_replace->scrub_progress, 0, 1); |
416 | 405 | ||
417 | ret = btrfs_dev_replace_finishing(fs_info, ret); | 406 | ret = btrfs_dev_replace_finishing(fs_info, ret); |
418 | /* don't warn if EINPROGRESS, someone else might be running scrub */ | ||
419 | if (ret == -EINPROGRESS) { | 407 | if (ret == -EINPROGRESS) { |
420 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS; | 408 | ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS; |
421 | ret = 0; | ||
422 | } else { | 409 | } else { |
423 | WARN_ON(ret); | 410 | WARN_ON(ret); |
424 | } | 411 | } |
@@ -433,6 +420,35 @@ leave: | |||
433 | return ret; | 420 | return ret; |
434 | } | 421 | } |
435 | 422 | ||
423 | int btrfs_dev_replace_by_ioctl(struct btrfs_root *root, | ||
424 | struct btrfs_ioctl_dev_replace_args *args) | ||
425 | { | ||
426 | int ret; | ||
427 | |||
428 | switch (args->start.cont_reading_from_srcdev_mode) { | ||
429 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS: | ||
430 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID: | ||
431 | break; | ||
432 | default: | ||
433 | return -EINVAL; | ||
434 | } | ||
435 | |||
436 | if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') || | ||
437 | args->start.tgtdev_name[0] == '\0') | ||
438 | return -EINVAL; | ||
439 | |||
440 | ret = btrfs_dev_replace_start(root, args->start.tgtdev_name, | ||
441 | args->start.srcdevid, | ||
442 | args->start.srcdev_name, | ||
443 | args->start.cont_reading_from_srcdev_mode); | ||
444 | args->result = ret; | ||
445 | /* don't warn if EINPROGRESS, someone else might be running scrub */ | ||
446 | if (ret == BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS) | ||
447 | ret = 0; | ||
448 | |||
449 | return ret; | ||
450 | } | ||
451 | |||
436 | /* | 452 | /* |
437 | * blocked until all flighting bios are finished. | 453 | * blocked until all flighting bios are finished. |
438 | */ | 454 | */ |