On 10/30/20 9:51 AM, Naohiro Aota wrote:
This is 2/4 patch to implement device-replace for ZONED mode.
On zoned mode, a block group must be either copied (from the source device
to the destination device) or cloned (to the both device).
This commit implements the cloning part. If a block group targeted by an IO
is marked to copy, we should not clone the IO to the destination device,
because the block group is eventually copied by the replace process.
This commit also handles cloning of device reset.
Signed-off-by: Naohiro Aota <naohiro.aota@xxxxxxx>
---
fs/btrfs/dev-replace.c | 4 ++--
fs/btrfs/extent-tree.c | 20 ++++++++++++++++++--
fs/btrfs/scrub.c | 2 +-
fs/btrfs/volumes.c | 33 +++++++++++++++++++++++++++++++--
fs/btrfs/zoned.c | 11 +++++++++++
5 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index e86aff38aea4..848f8063dc1c 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -454,7 +454,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
u64 chunk_offset, length;
/* Do not use "to_copy" on non-ZONED for now */
- if (!btrfs_fs_incompat(fs_info, ZONED))
+ if (!btrfs_is_zoned(fs_info))
return 0;
mutex_lock(&fs_info->chunk_mutex);
@@ -565,7 +565,7 @@ bool btrfs_finish_block_group_to_copy(struct btrfs_device *srcdev,
int i;
/* Do not use "to_copy" on non-ZONED for now */
- if (!btrfs_fs_incompat(fs_info, ZONED))
+ if (!btrfs_is_zoned(fs_info))
return true;
Heh these
spin_lock(&cache->lock);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 57454ef4c91e..1bb95d5aaed2 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -35,6 +35,7 @@
#include "discard.h"
#include "rcu-string.h"
#include "zoned.h"
+#include "dev-replace.h"
#undef SCRAMBLE_DELAYED_REFS
@@ -1336,6 +1337,8 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
u64 length = stripe->length;
u64 bytes;
struct request_queue *req_q;
+ struct btrfs_dev_replace *dev_replace =
+ &fs_info->dev_replace;
if (!stripe->dev->bdev) {
ASSERT(btrfs_test_opt(fs_info, DEGRADED));
@@ -1344,15 +1347,28 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
req_q = bdev_get_queue(stripe->dev->bdev);
/* zone reset in ZONED mode */
- if (btrfs_can_zone_reset(dev, physical, length))
+ if (btrfs_can_zone_reset(dev, physical, length)) {
ret = btrfs_reset_device_zone(dev, physical,
length, &bytes);
- else if (blk_queue_discard(req_q))
+ if (ret)
+ goto next;
+ if (!btrfs_dev_replace_is_ongoing(
+ dev_replace) ||
+ dev != dev_replace->srcdev)
+ goto next;
+
+ discarded_bytes += bytes;
+ /* send to replace target as well */
+ ret = btrfs_reset_device_zone(
+ dev_replace->tgtdev,
+ physical, length, &bytes);
+ } else if (blk_queue_discard(req_q))
And this needs to go into a helper, because lord it's not pretty. Thanks,
Josef