From nobody Mon Feb 9 15:10:18 2026 Received: from box.fidei.email (box.fidei.email [71.19.144.250]) (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 C8E296FE38; Wed, 3 Apr 2024 07:33:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=71.19.144.250 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712129598; cv=none; b=tlGglh3BPfrkKLIjosbSb68gdjqiGojVdcSDCCnNL8V4lParZQ6mXMT+86R5zUZ2a40lG0xTy1jcH/nrCCVq68TaBuTAXJzsb/Yj9ByxKa2UJmFxk8uwarVHzG0Apxj+C+lwMs9hPE7/xawb5lEVgmWOYB1Z4+73IbdoXfdMs/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712129598; c=relaxed/simple; bh=k2cIvdzLg3sljiZ/6znD/m3Ichqz9W7DWE80AeNEY2E=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OxKKHiAhFUuQRGq4iUaRbR/jNjeFnfIvH20j2wbRcodTpaMcCehzQsT9n8dypztZVXY6xDiNKIDH6D2g43OlZp7Pl19i/x8RuvgLb7E/x/tvSRE/NSSFWbZYvtH328sbSlsdKcotw2q7Ubqgh+wag9u8yG2L3WKYC0invTthwwE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=dorminy.me; spf=pass smtp.mailfrom=dorminy.me; dkim=pass (2048-bit key) header.d=dorminy.me header.i=@dorminy.me header.b=QewS3YWB; arc=none smtp.client-ip=71.19.144.250 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=dorminy.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=dorminy.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=dorminy.me header.i=@dorminy.me header.b="QewS3YWB" Received: from authenticated-user (box.fidei.email [71.19.144.250]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.fidei.email (Postfix) with ESMTPSA id 85BD2807F9; Wed, 3 Apr 2024 03:33:15 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dorminy.me; s=mail; t=1712129596; bh=k2cIvdzLg3sljiZ/6znD/m3Ichqz9W7DWE80AeNEY2E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=QewS3YWB1Udfrmc/U+d3uuM7Whmk18AUwovF8JVhddL2HNuIMXaUpIm41h3L4CYTs 5KScePZY2mnNQLA2JWbk7uAmVjO/Q0ocd2pjHbwWhNJ9WeQQ6ErauUPhc3TSpxHsZz IzCe9DHOenanCyWyEZ7PBdaPAQOwz0o5/dwXJq9jHPTyz64Cm4WLLoL8mXGR5VAvFt ieU26UGsxvoUwgp6smA3DzC2kFa+OUkmSZV2Dtt5LZ15W88v7JyshorRDs/anyn52b qaT/UPkoL8UVb6bDkx5xa2Eliks4n2naoWdnSMU7ngNNU+5h23bqxiIVqnuLPee3y9 ighpvtsu8WGLA== From: Sweet Tea Dorminy To: Jonathan Corbet , Kent Overstreet , Brian Foster , Chris Mason , Josef Bacik , David Sterba , Jaegeuk Kim , Chao Yu , Alexander Viro , Christian Brauner , Jan Kara , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , Sweet Tea Dorminy , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bcachefs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, kernel-team@meta.com Subject: [PATCH v3 05/13] btrfs: fiemap: return extent physical size Date: Wed, 3 Apr 2024 03:22:46 -0400 Message-ID: <62391207f8d60060fddc18404af600c4b4f9b170.1712126039.git.sweettea-kernel@dorminy.me> In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that fiemap allows returning extent physical size, make btrfs return the appropriate extent's actual disk size. Signed-off-by: Sweet Tea Dorminy --- fs/btrfs/extent_io.c | 70 ++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index e9df670ef7d2..b631f387cc3c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2506,7 +2506,8 @@ int try_release_extent_mapping(struct page *page, gfp= _t mask) struct btrfs_fiemap_entry { u64 offset; u64 phys; - u64 len; + u64 log_len; + u64 phys_len; u32 flags; }; =20 @@ -2564,7 +2565,8 @@ struct fiemap_cache { /* Fields for the cached extent (unsubmitted, not ready, extent). */ u64 offset; u64 phys; - u64 len; + u64 log_len; + u64 phys_len; u32 flags; bool cached; }; @@ -2577,8 +2579,8 @@ static int flush_fiemap_cache(struct fiemap_extent_in= fo *fieinfo, int ret; =20 ret =3D fiemap_fill_next_extent(fieinfo, entry->offset, - entry->phys, entry->len, 0, - entry->flags); + entry->phys, entry->log_len, + entry->phys_len, entry->flags); /* * Ignore 1 (reached max entries) because we keep track of that * ourselves in emit_fiemap_extent(). @@ -2603,7 +2605,8 @@ static int flush_fiemap_cache(struct fiemap_extent_in= fo *fieinfo, */ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo, struct fiemap_cache *cache, - u64 offset, u64 phys, u64 len, u32 flags) + u64 offset, u64 phys, u64 log_len, + u64 phys_len, u32 flags) { struct btrfs_fiemap_entry *entry; u64 cache_end; @@ -2611,6 +2614,9 @@ static int emit_fiemap_extent(struct fiemap_extent_in= fo *fieinfo, /* Set at the end of extent_fiemap(). */ ASSERT((flags & FIEMAP_EXTENT_LAST) =3D=3D 0); =20 + /* We always set the correct physical length. */ + flags |=3D FIEMAP_EXTENT_HAS_PHYS_LEN; + if (!cache->cached) goto assign; =20 @@ -2646,7 +2652,7 @@ static int emit_fiemap_extent(struct fiemap_extent_in= fo *fieinfo, * or equals to what we have in cache->offset. We deal with this as * described below. */ - cache_end =3D cache->offset + cache->len; + cache_end =3D cache->offset + cache->log_len; if (cache_end > offset) { if (offset =3D=3D cache->offset) { /* @@ -2670,10 +2676,10 @@ static int emit_fiemap_extent(struct fiemap_extent_= info *fieinfo, * where a previously found file extent item was split * due to an ordered extent completing. */ - cache->len =3D offset - cache->offset; + cache->log_len =3D offset - cache->offset; goto emit; } else { - const u64 range_end =3D offset + len; + const u64 range_end =3D offset + log_len; =20 /* * The offset of the file extent item we have just found @@ -2706,11 +2712,13 @@ static int emit_fiemap_extent(struct fiemap_extent_= info *fieinfo, if (range_end <=3D cache_end) return 0; =20 - if (!(flags & (FIEMAP_EXTENT_DATA_COMPRESSED | FIEMAP_EXTENT_DELALLOC))) + if (!(flags & (FIEMAP_EXTENT_DATA_COMPRESSED | FIEMAP_EXTENT_DELALLOC))= ) { phys +=3D cache_end - offset; + phys_len -=3D cache_end - offset; + } =20 offset =3D cache_end; - len =3D range_end - cache_end; + log_len =3D range_end - cache_end; goto emit; } } @@ -2720,15 +2728,17 @@ static int emit_fiemap_extent(struct fiemap_extent_= info *fieinfo, * 1) Their logical addresses are continuous * * 2) Their physical addresses are continuous - * So truly compressed (physical size smaller than logical size) - * extents won't get merged with each other * * 3) Share same flags + * + * 4) Not compressed */ - if (cache->offset + cache->len =3D=3D offset && - cache->phys + cache->len =3D=3D phys && - cache->flags =3D=3D flags) { - cache->len +=3D len; + if (cache->offset + cache->log_len =3D=3D offset && + cache->phys + cache->log_len =3D=3D phys && + cache->flags =3D=3D flags && + !(flags & FIEMAP_EXTENT_DATA_COMPRESSED)) { + cache->log_len +=3D log_len; + cache->phys_len +=3D phys_len; return 0; } =20 @@ -2745,7 +2755,7 @@ static int emit_fiemap_extent(struct fiemap_extent_in= fo *fieinfo, * to miss it. */ entry =3D &cache->entries[cache->entries_size - 1]; - cache->next_search_offset =3D entry->offset + entry->len; + cache->next_search_offset =3D entry->offset + entry->log_len; cache->cached =3D false; =20 return BTRFS_FIEMAP_FLUSH_CACHE; @@ -2754,7 +2764,8 @@ static int emit_fiemap_extent(struct fiemap_extent_in= fo *fieinfo, entry =3D &cache->entries[cache->entries_pos]; entry->offset =3D cache->offset; entry->phys =3D cache->phys; - entry->len =3D cache->len; + entry->log_len =3D cache->log_len; + entry->phys_len =3D cache->phys_len; entry->flags =3D cache->flags; cache->entries_pos++; cache->extents_mapped++; @@ -2767,7 +2778,8 @@ static int emit_fiemap_extent(struct fiemap_extent_in= fo *fieinfo, cache->cached =3D true; cache->offset =3D offset; cache->phys =3D phys; - cache->len =3D len; + cache->log_len =3D log_len; + cache->phys_len =3D phys_len; cache->flags =3D flags; =20 return 0; @@ -2793,7 +2805,8 @@ static int emit_last_fiemap_cache(struct fiemap_exten= t_info *fieinfo, return 0; =20 ret =3D fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys, - cache->len, 0, cache->flags); + cache->log_len, cache->phys_len, + cache->flags); cache->cached =3D false; if (ret > 0) ret =3D 0; @@ -2987,13 +3000,15 @@ static int fiemap_process_hole(struct btrfs_inode *= inode, } ret =3D emit_fiemap_extent(fieinfo, cache, prealloc_start, disk_bytenr + extent_offset, - prealloc_len, prealloc_flags); + prealloc_len, prealloc_len, + prealloc_flags); if (ret) return ret; extent_offset +=3D prealloc_len; } =20 ret =3D emit_fiemap_extent(fieinfo, cache, delalloc_start, 0, + delalloc_end + 1 - delalloc_start, delalloc_end + 1 - delalloc_start, FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN); @@ -3034,7 +3049,8 @@ static int fiemap_process_hole(struct btrfs_inode *in= ode, } ret =3D emit_fiemap_extent(fieinfo, cache, prealloc_start, disk_bytenr + extent_offset, - prealloc_len, prealloc_flags); + prealloc_len, prealloc_len, + prealloc_flags); if (ret) return ret; } @@ -3180,6 +3196,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct f= iemap_extent_info *fieinfo, u64 extent_offset =3D 0; u64 extent_gen; u64 disk_bytenr =3D 0; + u64 disk_size =3D 0; u64 flags =3D 0; int extent_type; u8 compression; @@ -3242,7 +3259,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct f= iemap_extent_info *fieinfo, flags |=3D FIEMAP_EXTENT_DATA_INLINE; flags |=3D FIEMAP_EXTENT_NOT_ALIGNED; ret =3D emit_fiemap_extent(fieinfo, &cache, key.offset, 0, - extent_len, flags); + extent_len, extent_len, flags); } else if (extent_type =3D=3D BTRFS_FILE_EXTENT_PREALLOC) { ret =3D fiemap_process_hole(inode, fieinfo, &cache, &delalloc_cached_state, @@ -3257,6 +3274,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct f= iemap_extent_info *fieinfo, backref_ctx, 0, 0, 0, key.offset, extent_end - 1); } else { + disk_size =3D btrfs_file_extent_disk_num_bytes(leaf, ei); /* We have a regular extent. */ if (fieinfo->fi_extents_max) { ret =3D btrfs_is_data_extent_shared(inode, @@ -3271,7 +3289,9 @@ int extent_fiemap(struct btrfs_inode *inode, struct f= iemap_extent_info *fieinfo, =20 ret =3D emit_fiemap_extent(fieinfo, &cache, key.offset, disk_bytenr + extent_offset, - extent_len, flags); + extent_len, + disk_size - extent_offset, + flags); } =20 if (ret < 0) { @@ -3309,7 +3329,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct f= iemap_extent_info *fieinfo, prev_extent_end =3D range_end; } =20 - if (cache.cached && cache.offset + cache.len >=3D last_extent_end) { + if (cache.cached && cache.offset + cache.log_len >=3D last_extent_end) { const u64 i_size =3D i_size_read(&inode->vfs_inode); =20 if (prev_extent_end < i_size) { --=20 2.43.0