From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.burntcomma.com (mail2.burntcomma.com [217.169.27.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F11162D3727 for ; Mon, 24 Nov 2025 18:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.169.27.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764010420; cv=none; b=ODyeGmIYcb211RI/9fnAC59hFkn7ljxuzUAnhksO62gADf9gPU+//CswnKNPI6wWr7BfGE9WkyI2w23Q5pVL91M6aGkNIxjXXfCeobjt4ojG//VfdqYBuJuKfsR7oNxtkMgmhjhjODt71RES0Qh88ZagwOc8q9miZlLJkyxkTgc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764010420; c=relaxed/simple; bh=aQEiJxa3zWaZE+GFbcmkLcOl4q01bLtQbcJDH54V+3s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Mime-Version; b=VqmxzwcSQawdK2qaqLZiY4oLaHzNr+VH793VgFim3VN1hRbBRcZNl4V2wNS5d3VfYXMT5nq1OeKMohgdLiZc55m7sg9bFidDtQ2WXlUPviZiFSjln5cc1UrwPd+2L7vj5vHtCWAnw/1kjtOPv6l1mvXCeDL8XaFRIEYJNwItEoE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=harmstone.com; spf=pass smtp.mailfrom=harmstone.com; dkim=pass (1024-bit key) header.d=harmstone.com header.i=@harmstone.com header.b=Tcj32lB5; arc=none smtp.client-ip=217.169.27.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=harmstone.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=harmstone.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=harmstone.com header.i=@harmstone.com header.b="Tcj32lB5" Received: from beren (beren.burntcomma.com [IPv6:2a02:8012:8cf0:0:ce28:aaff:fe0d:6db2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) by mail.burntcomma.com (Postfix) with ESMTPSA id 322F82DEC60; Mon, 24 Nov 2025 18:53:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1764010411; bh=1Etf0A9vG47K3rMRWjNVt519Z4UalX8z9zQBR6iR56o=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Tcj32lB5+f52B2U0L3K7iJ+t14tIwbZRRTpt0+fu8Mgw3lkGJeiHiG6g0PIBudJyD waIDKgclLS9zTg+IcDKtJucvYsxbx7vyLT7dRVCVsz4huILnfRCx3ThN/KIkfJX0lu hi+3KGh3XHRhyixizVWLLZ8fTpHOlcjvvRjBkfpQ= From: Mark Harmstone To: linux-btrfs@vger.kernel.org Cc: Mark Harmstone , Boris Burkov Subject: [PATCH v7 08/16] btrfs: redirect I/O for remapped block groups Date: Mon, 24 Nov 2025 18:53:00 +0000 Message-ID: <20251124185335.16556-9-mark@harmstone.com> In-Reply-To: <20251124185335.16556-1-mark@harmstone.com> References: <20251124185335.16556-1-mark@harmstone.com> Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Change btrfs_map_block() so that if the block group has the REMAPPED flag set, we call btrfs_translate_remap() to obtain a new address. btrfs_translate_remap() searches the remap tree for a range corresponding to the logical address passed to btrfs_map_block(). If it is within an identity remap, this part of the block group hasn't yet been relocated, and so we use the existing address. If it is within an actual remap, we subtract the start of the remap range and add the address of its destination, contained in the item's payload. Signed-off-by: Mark Harmstone Reviewed-by: Boris Burkov --- fs/btrfs/relocation.c | 54 +++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/relocation.h | 2 ++ fs/btrfs/volumes.c | 19 +++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 5bfefc3e9c06..2d3aa3424c71 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3860,6 +3860,60 @@ static const char *stage_to_string(enum reloc_stage stage) return "unknown"; } +int btrfs_translate_remap(struct btrfs_fs_info *fs_info, u64 *logical, + u64 *length) +{ + int ret; + struct btrfs_key key, found_key; + struct extent_buffer *leaf; + struct btrfs_remap *remap; + BTRFS_PATH_AUTO_FREE(path); + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = *logical; + key.type = (u8)-1; + key.offset = (u64)-1; + + ret = btrfs_search_slot(NULL, fs_info->remap_root, &key, path, + 0, 0); + if (ret < 0) + return ret; + + leaf = path->nodes[0]; + + if (path->slots[0] == 0) + return -ENOENT; + + path->slots[0]--; + + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); + + if (found_key.type != BTRFS_REMAP_KEY && + found_key.type != BTRFS_IDENTITY_REMAP_KEY) { + return -ENOENT; + } + + if (found_key.objectid > *logical || + found_key.objectid + found_key.offset <= *logical) { + return -ENOENT; + } + + if (*logical + *length > found_key.objectid + found_key.offset) + *length = found_key.objectid + found_key.offset - *logical; + + if (found_key.type == BTRFS_IDENTITY_REMAP_KEY) + return 0; + + remap = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap); + + *logical += btrfs_remap_address(leaf, remap) - found_key.objectid; + + return 0; +} + /* * function to relocate all extents in a block group. */ diff --git a/fs/btrfs/relocation.h b/fs/btrfs/relocation.h index 5c36b3f84b57..b2ba83966650 100644 --- a/fs/btrfs/relocation.h +++ b/fs/btrfs/relocation.h @@ -31,5 +31,7 @@ int btrfs_should_cancel_balance(const struct btrfs_fs_info *fs_info); struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr); bool btrfs_should_ignore_reloc_root(const struct btrfs_root *root); u64 btrfs_get_reloc_bg_bytenr(const struct btrfs_fs_info *fs_info); +int btrfs_translate_remap(struct btrfs_fs_info *fs_info, u64 *logical, + u64 *length); #endif diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a9fbced3ad5c..d25a97c2eb4d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6585,6 +6585,25 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op, if (IS_ERR(map)) return PTR_ERR(map); + if (map->type & BTRFS_BLOCK_GROUP_REMAPPED) { + u64 new_logical = logical; + + ret = btrfs_translate_remap(fs_info, &new_logical, length); + if (ret) + return ret; + + if (new_logical != logical) { + btrfs_free_chunk_map(map); + + map = btrfs_get_chunk_map(fs_info, new_logical, + *length); + if (IS_ERR(map)) + return PTR_ERR(map); + + logical = new_logical; + } + } + num_copies = btrfs_chunk_map_num_copies(map); if (io_geom.mirror_num > num_copies) return -EINVAL; -- 2.51.0