From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
To: Jonathan Corbet <corbet@lwn.net>, Chris Mason <clm@fb.com>,
Josef Bacik <josef@toxicpanda.com>,
David Sterba <dsterba@suse.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
Sweet Tea Dorminy <sweettea-kernel@dorminy.me>,
linux-doc@vger.kernel.org, linux-btrfs@vger.kernel.org,
linux-fsdevel@vger.kernel.org, kernel-team@meta.com
Subject: [PATCH v2 5/5] btrfs: fiemap: return extent physical size
Date: Wed, 27 Mar 2024 21:22:23 -0400 [thread overview]
Message-ID: <93686d5c4467befe12f76e4921bfc20a13a74e2d.1711588701.git.sweettea-kernel@dorminy.me> (raw)
In-Reply-To: <cover.1711588701.git.sweettea-kernel@dorminy.me>
Now that fiemap allows returning extent physical size, make btrfs return
the appropriate extent's actual disk size.
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
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 30fcbb9393fe..9921dc1567d6 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2456,7 +2456,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;
};
@@ -2514,7 +2515,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;
};
@@ -2527,8 +2529,8 @@ static int flush_fiemap_cache(struct fiemap_extent_info *fieinfo,
int ret;
ret = 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().
@@ -2553,7 +2555,8 @@ static int flush_fiemap_cache(struct fiemap_extent_info *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;
@@ -2561,6 +2564,9 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
/* Set at the end of extent_fiemap(). */
ASSERT((flags & FIEMAP_EXTENT_LAST) == 0);
+ /* We always set the correct physical length. */
+ flags |= FIEMAP_EXTENT_HAS_PHYS_LEN;
+
if (!cache->cached)
goto assign;
@@ -2596,7 +2602,7 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* or equals to what we have in cache->offset. We deal with this as
* described below.
*/
- cache_end = cache->offset + cache->len;
+ cache_end = cache->offset + cache->log_len;
if (cache_end > offset) {
if (offset == cache->offset) {
/*
@@ -2620,10 +2626,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 = offset - cache->offset;
+ cache->log_len = offset - cache->offset;
goto emit;
} else {
- const u64 range_end = offset + len;
+ const u64 range_end = offset + log_len;
/*
* The offset of the file extent item we have just found
@@ -2656,11 +2662,13 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
if (range_end <= cache_end)
return 0;
- if (!(flags & (FIEMAP_EXTENT_DATA_COMPRESSED | FIEMAP_EXTENT_DELALLOC)))
+ if (!(flags & (FIEMAP_EXTENT_DATA_COMPRESSED | FIEMAP_EXTENT_DELALLOC))) {
phys += cache_end - offset;
+ phys_len -= cache_end - offset;
+ }
offset = cache_end;
- len = range_end - cache_end;
+ log_len = range_end - cache_end;
goto emit;
}
}
@@ -2670,15 +2678,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 == offset &&
- cache->phys + cache->len == phys &&
- cache->flags == flags) {
- cache->len += len;
+ if (cache->offset + cache->log_len == offset &&
+ cache->phys + cache->log_len == phys &&
+ cache->flags == flags &&
+ !(flags & FIEMAP_EXTENT_DATA_COMPRESSED)) {
+ cache->log_len += log_len;
+ cache->phys_len += phys_len;
return 0;
}
@@ -2695,7 +2705,7 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* to miss it.
*/
entry = &cache->entries[cache->entries_size - 1];
- cache->next_search_offset = entry->offset + entry->len;
+ cache->next_search_offset = entry->offset + entry->log_len;
cache->cached = false;
return BTRFS_FIEMAP_FLUSH_CACHE;
@@ -2704,7 +2714,8 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
entry = &cache->entries[cache->entries_pos];
entry->offset = cache->offset;
entry->phys = cache->phys;
- entry->len = cache->len;
+ entry->log_len = cache->log_len;
+ entry->phys_len = cache->phys_len;
entry->flags = cache->flags;
cache->entries_pos++;
cache->extents_mapped++;
@@ -2717,7 +2728,8 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
cache->cached = true;
cache->offset = offset;
cache->phys = phys;
- cache->len = len;
+ cache->log_len = log_len;
+ cache->phys_len = phys_len;
cache->flags = flags;
return 0;
@@ -2743,7 +2755,8 @@ static int emit_last_fiemap_cache(struct fiemap_extent_info *fieinfo,
return 0;
ret = fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys,
- cache->len, 0, cache->flags);
+ cache->log_len, cache->phys_len,
+ cache->flags);
cache->cached = false;
if (ret > 0)
ret = 0;
@@ -2937,13 +2950,15 @@ static int fiemap_process_hole(struct btrfs_inode *inode,
}
ret = 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 += prealloc_len;
}
ret = emit_fiemap_extent(fieinfo, cache, delalloc_start, 0,
+ delalloc_end + 1 - delalloc_start,
delalloc_end + 1 - delalloc_start,
FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_UNKNOWN);
@@ -2984,7 +2999,8 @@ static int fiemap_process_hole(struct btrfs_inode *inode,
}
ret = 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;
}
@@ -3130,6 +3146,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
u64 extent_offset = 0;
u64 extent_gen;
u64 disk_bytenr = 0;
+ u64 disk_size = 0;
u64 flags = 0;
int extent_type;
u8 compression;
@@ -3192,7 +3209,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
flags |= FIEMAP_EXTENT_DATA_INLINE;
flags |= FIEMAP_EXTENT_NOT_ALIGNED;
ret = emit_fiemap_extent(fieinfo, &cache, key.offset, 0,
- extent_len, flags);
+ extent_len, extent_len, flags);
} else if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
ret = fiemap_process_hole(inode, fieinfo, &cache,
&delalloc_cached_state,
@@ -3207,6 +3224,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
backref_ctx, 0, 0, 0,
key.offset, extent_end - 1);
} else {
+ disk_size = btrfs_file_extent_disk_num_bytes(leaf, ei);
/* We have a regular extent. */
if (fieinfo->fi_extents_max) {
ret = btrfs_is_data_extent_shared(inode,
@@ -3221,7 +3239,9 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
ret = emit_fiemap_extent(fieinfo, &cache, key.offset,
disk_bytenr + extent_offset,
- extent_len, flags);
+ extent_len,
+ disk_size - extent_offset,
+ flags);
}
if (ret < 0) {
@@ -3259,7 +3279,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
prev_extent_end = range_end;
}
- if (cache.cached && cache.offset + cache.len >= last_extent_end) {
+ if (cache.cached && cache.offset + cache.log_len >= last_extent_end) {
const u64 i_size = i_size_read(&inode->vfs_inode);
if (prev_extent_end < i_size) {
--
2.43.0
next prev parent reply other threads:[~2024-03-28 1:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-28 1:22 [PATCH v2 0/5] fiemap extension for more physical information Sweet Tea Dorminy
2024-03-28 1:22 ` [PATCH v2 1/5] fs: fiemap: add physical_length field to extents Sweet Tea Dorminy
2024-03-28 1:22 ` [PATCH v2 2/5] fs: fiemap: update fiemap_fill_next_extent() signature Sweet Tea Dorminy
2024-03-28 1:22 ` [PATCH v2 3/5] fs: fiemap: add new COMPRESSED extent state Sweet Tea Dorminy
2024-03-28 1:22 ` [PATCH v2 4/5] btrfs: fiemap: emit new COMPRESSED fiemap state Sweet Tea Dorminy
2024-03-28 1:22 ` Sweet Tea Dorminy [this message]
2024-03-31 9:03 ` [PATCH v2 5/5] btrfs: fiemap: return extent physical size Qu Wenruo
2024-04-03 5:32 ` Sweet Tea Dorminy
2024-04-03 5:52 ` Qu Wenruo
2024-04-03 7:18 ` Sweet Tea Dorminy
2024-04-03 6:02 ` Sweet Tea Dorminy
2024-04-03 7:19 ` Qu Wenruo
2024-04-09 18:52 ` David Sterba
2024-04-09 19:31 ` Andreas Dilger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=93686d5c4467befe12f76e4921bfc20a13a74e2d.1711588701.git.sweettea-kernel@dorminy.me \
--to=sweettea-kernel@dorminy.me \
--cc=brauner@kernel.org \
--cc=clm@fb.com \
--cc=corbet@lwn.net \
--cc=dsterba@suse.com \
--cc=jack@suse.cz \
--cc=josef@toxicpanda.com \
--cc=kernel-team@meta.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).