aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2017-06-14 10:24:56 -0400
committerDavid Sterba <dsterba@suse.com>2017-08-16 10:12:03 -0400
commit74b595fe672a4c4a40fe87c727304e2df3485f13 (patch)
treefeaa2157743c43edbb9537e8b201162736bb6eac /fs/btrfs/dev-replace.c
parent0a52d108089f337ce20d74bf53f2e574c8ee43f2 (diff)
btrfs: factor reading progress out of btrfs_dev_replace_status
We'll want to read the percentage value from dev_replace elsewhere, move the logic to a separate helper. Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r--fs/btrfs/dev-replace.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index bee3edeea7a3..31d01eefecd0 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -639,11 +639,39 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
639 write_unlock(&em_tree->lock); 639 write_unlock(&em_tree->lock);
640} 640}
641 641
642/*
643 * Read progress of device replace status according to the state and last
644 * stored position. The value format is the same as for
645 * btrfs_dev_replace::progress_1000
646 */
647static u64 btrfs_dev_replace_progress(struct btrfs_fs_info *fs_info)
648{
649 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
650 u64 ret = 0;
651
652 switch (dev_replace->replace_state) {
653 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
654 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
655 ret = 0;
656 break;
657 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
658 ret = 1000;
659 break;
660 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
661 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
662 ret = div64_u64(dev_replace->cursor_left,
663 div_u64(btrfs_device_get_total_bytes(
664 dev_replace->srcdev), 1000));
665 break;
666 }
667
668 return ret;
669}
670
642void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, 671void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
643 struct btrfs_ioctl_dev_replace_args *args) 672 struct btrfs_ioctl_dev_replace_args *args)
644{ 673{
645 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 674 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
646 struct btrfs_device *srcdev;
647 675
648 btrfs_dev_replace_lock(dev_replace, 0); 676 btrfs_dev_replace_lock(dev_replace, 0);
649 /* even if !dev_replace_is_valid, the values are good enough for 677 /* even if !dev_replace_is_valid, the values are good enough for
@@ -656,21 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
656 atomic64_read(&dev_replace->num_write_errors); 684 atomic64_read(&dev_replace->num_write_errors);
657 args->status.num_uncorrectable_read_errors = 685 args->status.num_uncorrectable_read_errors =
658 atomic64_read(&dev_replace->num_uncorrectable_read_errors); 686 atomic64_read(&dev_replace->num_uncorrectable_read_errors);
659 switch (dev_replace->replace_state) { 687 args->status.progress_1000 = btrfs_dev_replace_progress(fs_info);
660 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
661 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
662 args->status.progress_1000 = 0;
663 break;
664 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
665 args->status.progress_1000 = 1000;
666 break;
667 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
668 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
669 srcdev = dev_replace->srcdev;
670 args->status.progress_1000 = div64_u64(dev_replace->cursor_left,
671 div_u64(btrfs_device_get_total_bytes(srcdev), 1000));
672 break;
673 }
674 btrfs_dev_replace_unlock(dev_replace, 0); 688 btrfs_dev_replace_unlock(dev_replace, 0);
675} 689}
676 690