78ce9fc269
This is the 1/4 patch to support device-replace on zoned filesystems. We have two types of IOs during the device replace process. One is an IO to "copy" (by the scrub functions) all the device extents from the source device to the destination device. The other one is an IO to "clone" (by handle_ops_on_dev_replace()) new incoming write IOs from users to the source device into the target device. Cloning incoming IOs can break the sequential write rule in on target device. When a write is mapped in the middle of a block group, the IO is directed to the middle of a target device zone, which breaks the sequential write requirement. However, the cloning function cannot be disabled since incoming IOs targeting already copied device extents must be cloned so that the IO is executed on the target device. We cannot use dev_replace->cursor_{left,right} to determine whether a bio is going to a not yet copied region. Since we have a time gap between finishing btrfs_scrub_dev() and rewriting the mapping tree in btrfs_dev_replace_finishing(), we can have a newly allocated device extent which is never cloned nor copied. So the point is to copy only already existing device extents. This patch introduces mark_block_group_to_copy() to mark existing block groups as a target of copying. Then, handle_ops_on_dev_replace() and dev-replace can check the flag to do their job. Also, btrfs_finish_block_group_to_copy() will check if the copied stripe is the last stripe in the block group. With the last stripe copied, the to_copy flag is finally disabled. Afterwards we can safely clone incoming IOs on this block group. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
26 lines
970 B
C
26 lines
970 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) STRATO AG 2012. All rights reserved.
|
|
*/
|
|
|
|
#ifndef BTRFS_DEV_REPLACE_H
|
|
#define BTRFS_DEV_REPLACE_H
|
|
|
|
struct btrfs_ioctl_dev_replace_args;
|
|
|
|
int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info);
|
|
int btrfs_run_dev_replace(struct btrfs_trans_handle *trans);
|
|
int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,
|
|
struct btrfs_ioctl_dev_replace_args *args);
|
|
void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
|
|
struct btrfs_ioctl_dev_replace_args *args);
|
|
int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info);
|
|
void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info);
|
|
int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info);
|
|
int __pure btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace);
|
|
bool btrfs_finish_block_group_to_copy(struct btrfs_device *srcdev,
|
|
struct btrfs_block_group *cache,
|
|
u64 physical);
|
|
|
|
#endif
|