* [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent
@ 2024-05-23 5:03 Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 01/11] btrfs: rename extent_map::orig_block_len to disk_num_bytes Qu Wenruo
` (12 more replies)
0 siblings, 13 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs
[CHANGELOG]
v3:
- Rebased to the latest for-next
There is a small conflicts with the extent map tree members changes,
no big deal.
- Fix an error where original code is checking
btrfs_file_extent_disk_bytenr()
The newer code is checking disk_num_bytes, which is wrong.
- Various commit messages/comments update
Mostly some grammar fixes and removal of rants on the btrfs_file_extent
member mismatches for btrfs_alloc_ordered_extent().
However a comment is still left inside btrfs_alloc_ordered_extent()
for NOCOW/PREALLOC as a reminder for further cleanup.
v2:
- Rebased to the latest for-next
There is a conflicts with extent locking, and maybe some other
hidden conflicts for NOCOW/PREALLOC?
As previously the patchset passes fstests auto group, but after
the merging with other patches, it always crashes as btrfs/060.
- Fix an error in the final cleanup patch
It's the NOCOW/PREALLOC shenanigans again, in the buffered NOCOW path,
that we have to use the old inaccurate numbers for NOCOW/PREALLOC OEs.
- Split the final cleanup into 4 patches
Most cleanups are very straightforward, but the cleanup for
btrfs_alloc_ordered_extent() needs extra special handling for
NOCOW/PREALLOC.
v1:
- Rebased to the latest for-next
To resolve the conflicts with the recently introduced extent map
shrinker
- A new cleanup patch to remove the recursive header inclusion
- Use a new structure to pass the file extent item related members
around
- Add a new comment on why we're intentionally passing incorrect
numbers for NOCOW/PREALLOC ordered extents inside
btrfs_create_dio_extent()
[REPO]
https://github.com/adam900710/linux/tree/em_cleanup
This series introduce two new members (disk_bytenr/offset) to
extent_map, and removes three old members
(block_start/block_len/offset), finally rename one member
(orig_block_len -> disk_num_bytes).
This should save us one u64 for extent_map, although with the recent
extent map shrinker, the saving is not that useful.
But to make things safe to migrate, I introduce extra sanity checks for
extent_map, and do cross check for both old and new members.
The extra sanity checks already exposed one bug (thankfully harmless)
causing em::block_start to be incorrect.
But so far, the patchset is fine for default fstests run.
Furthermore, since we're already having too long parameter lists for
extent_map/ordered_extent/can_nocow_extent, here is a new structure,
btrfs_file_extent, a memory-access-friendly structure to represent a
btrfs_file_extent_item.
With the help of that structure, we can use that to represent a file
extent item without a super long parameter list.
The patchset would rename orig_block_len to disk_num_bytes first.
Then introduce the new member, the extra sanity checks, and introduce the
new btrfs_file_extent structure and use that to remove the older 3 members
from extent_map.
After all above works done, use btrfs_file_extent to further cleanup
can_nocow_file_extent_args()/btrfs_alloc_ordered_extent()/create_io_em()/
btrfs_create_dio_extent().
The cleanup is in fact pretty tricky, the current code base never
expects correct numbers for NOCOW/PREALLOC OEs, thus we have to keep the
old but incorrect numbers just for NOCOW/PREALLOC.
I will address the NOCOW/PREALLOC shenanigans the future, but
after the huge cleanup across multiple core structures.
Qu Wenruo (11):
btrfs: rename extent_map::orig_block_len to disk_num_bytes
btrfs: export the expected file extent through can_nocow_extent()
btrfs: introduce new members for extent_map
btrfs: introduce extra sanity checks for extent maps
btrfs: remove extent_map::orig_start member
btrfs: remove extent_map::block_len member
btrfs: remove extent_map::block_start member
btrfs: cleanup duplicated parameters related to
can_nocow_file_extent_args
btrfs: cleanup duplicated parameters related to
btrfs_alloc_ordered_extent
btrfs: cleanup duplicated parameters related to create_io_em()
btrfs: cleanup duplicated parameters related to
btrfs_create_dio_extent()
fs/btrfs/btrfs_inode.h | 4 +-
fs/btrfs/compression.c | 7 +-
fs/btrfs/defrag.c | 14 +-
fs/btrfs/extent_io.c | 10 +-
fs/btrfs/extent_map.c | 192 +++++++++++++------
fs/btrfs/extent_map.h | 51 +++--
fs/btrfs/file-item.c | 23 +--
fs/btrfs/file.c | 18 +-
fs/btrfs/inode.c | 308 +++++++++++++-----------------
fs/btrfs/ordered-data.c | 34 +++-
fs/btrfs/ordered-data.h | 19 +-
fs/btrfs/relocation.c | 5 +-
fs/btrfs/tests/extent-map-tests.c | 114 ++++++-----
fs/btrfs/tests/inode-tests.c | 177 ++++++++---------
fs/btrfs/tree-log.c | 23 ++-
fs/btrfs/zoned.c | 4 +-
include/trace/events/btrfs.h | 18 +-
17 files changed, 541 insertions(+), 480 deletions(-)
--
2.45.1
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 01/11] btrfs: rename extent_map::orig_block_len to disk_num_bytes
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 02/11] btrfs: export the expected file extent through can_nocow_extent() Qu Wenruo
` (11 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
This would make it very obvious that the member just matches
btrfs_file_extent_item::disk_num_bytes.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/extent_map.c | 16 ++++++++--------
fs/btrfs/extent_map.h | 2 +-
fs/btrfs/file-item.c | 4 ++--
fs/btrfs/file.c | 2 +-
fs/btrfs/inode.c | 12 ++++++------
fs/btrfs/tree-log.c | 4 ++--
6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 35e163152dbc..a9d60d1eade9 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -785,14 +785,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->block_len = em->block_len;
else
split->block_len = split->len;
- split->orig_block_len = max(split->block_len,
- em->orig_block_len);
+ split->disk_num_bytes = max(split->block_len,
+ em->disk_num_bytes);
split->ram_bytes = em->ram_bytes;
} else {
split->orig_start = split->start;
split->block_len = 0;
split->block_start = em->block_start;
- split->orig_block_len = 0;
+ split->disk_num_bytes = 0;
split->ram_bytes = split->len;
}
@@ -817,8 +817,8 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->generation = gen;
if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- split->orig_block_len = max(em->block_len,
- em->orig_block_len);
+ split->disk_num_bytes = max(em->block_len,
+ em->disk_num_bytes);
split->ram_bytes = em->ram_bytes;
if (compressed) {
@@ -835,7 +835,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->ram_bytes = split->len;
split->orig_start = split->start;
split->block_len = 0;
- split->orig_block_len = 0;
+ split->disk_num_bytes = 0;
}
if (extent_map_in_tree(em)) {
@@ -992,7 +992,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_pre->orig_start = split_pre->start;
split_pre->block_start = new_logical;
split_pre->block_len = split_pre->len;
- split_pre->orig_block_len = split_pre->block_len;
+ split_pre->disk_num_bytes = split_pre->block_len;
split_pre->ram_bytes = split_pre->len;
split_pre->flags = flags;
split_pre->generation = em->generation;
@@ -1010,7 +1010,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_mid->orig_start = split_mid->start;
split_mid->block_start = em->block_start + pre;
split_mid->block_len = split_mid->len;
- split_mid->orig_block_len = split_mid->block_len;
+ split_mid->disk_num_bytes = split_mid->block_len;
split_mid->ram_bytes = split_mid->len;
split_mid->flags = flags;
split_mid->generation = em->generation;
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 9144721b88a5..2b7bbffd594b 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -74,7 +74,7 @@ struct extent_map {
* The full on-disk extent length, matching
* btrfs_file_extent_item::disk_num_bytes.
*/
- u64 orig_block_len;
+ u64 disk_num_bytes;
/*
* The decompressed size of the whole on-disk extent, matching
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index f3ed78e21fa4..430dce44ebd2 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -1295,7 +1295,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->len = btrfs_file_extent_end(path) - extent_start;
em->orig_start = extent_start -
btrfs_file_extent_offset(leaf, fi);
- em->orig_block_len = btrfs_file_extent_disk_num_bytes(leaf, fi);
+ em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
if (bytenr == 0) {
em->block_start = EXTENT_MAP_HOLE;
@@ -1304,7 +1304,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
if (compress_type != BTRFS_COMPRESS_NONE) {
extent_map_set_compression(em, compress_type);
em->block_start = bytenr;
- em->block_len = em->orig_block_len;
+ em->block_len = em->disk_num_bytes;
} else {
bytenr += btrfs_file_extent_offset(leaf, fi);
em->block_start = bytenr;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index af58a1b33498..a216a0fdf58d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2351,7 +2351,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->block_len = 0;
- hole_em->orig_block_len = 0;
+ hole_em->disk_num_bytes = 0;
hole_em->generation = trans->transid;
ret = btrfs_replace_extent_map_range(inode, hole_em, true);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b4410b463c6a..7148da50e435 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -139,7 +139,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 orig_start, u64 block_start,
- u64 block_len, u64 orig_block_len,
+ u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
int type);
@@ -5001,7 +5001,7 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->block_len = 0;
- hole_em->orig_block_len = 0;
+ hole_em->disk_num_bytes = 0;
hole_em->ram_bytes = hole_size;
hole_em->generation = btrfs_get_fs_generation(fs_info);
@@ -7330,7 +7330,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 orig_start, u64 block_start,
- u64 block_len, u64 orig_block_len,
+ u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
int type)
{
@@ -7362,7 +7362,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
ASSERT(block_len == len);
/* COW results a new extent matching our file extent size. */
- ASSERT(orig_block_len == len);
+ ASSERT(disk_num_bytes == len);
ASSERT(ram_bytes == len);
/* Since it's a new extent, we should not have any offset. */
@@ -7389,7 +7389,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
em->len = len;
em->block_len = block_len;
em->block_start = block_start;
- em->orig_block_len = orig_block_len;
+ em->disk_num_bytes = disk_num_bytes;
em->ram_bytes = ram_bytes;
em->generation = -1;
em->flags |= EXTENT_FLAG_PINNED;
@@ -9614,7 +9614,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->len = ins.offset;
em->block_start = ins.objectid;
em->block_len = ins.offset;
- em->orig_block_len = ins.offset;
+ em->disk_num_bytes = ins.offset;
em->ram_bytes = ins.offset;
em->flags |= EXTENT_FLAG_PREALLOC;
em->generation = trans->transid;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 51a167559ae8..f237b5ed80ec 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4651,7 +4651,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
/* If we're compressed we have to save the entire range of csums. */
if (extent_map_is_compressed(em)) {
csum_offset = 0;
- csum_len = max(em->block_len, em->orig_block_len);
+ csum_len = max(em->block_len, em->disk_num_bytes);
} else {
csum_offset = mod_start - em->start;
csum_len = mod_len;
@@ -4701,7 +4701,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
else
btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_REG);
- block_len = max(em->block_len, em->orig_block_len);
+ block_len = max(em->block_len, em->disk_num_bytes);
compress_type = extent_map_compression(em);
if (compress_type != BTRFS_COMPRESS_NONE) {
btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start);
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 02/11] btrfs: export the expected file extent through can_nocow_extent()
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 01/11] btrfs: rename extent_map::orig_block_len to disk_num_bytes Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 03/11] btrfs: introduce new members for extent_map Qu Wenruo
` (10 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Currently function can_nocow_extent() only returns members needed for
extent_map.
However since we will soon change the extent_map structure to be more
like btrfs_file_extent_item, we want to expose the expected file extent
caused by the NOCOW write for future usage.
This introduces a new structure, btrfs_file_extent, to be a more
memory-access-friendly representation of btrfs_file_extent_item.
And use that structure to expose the expected file extent caused by the
NOCOW write.
For now there is no user of the new structure yet.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/btrfs_inode.h | 17 ++++++++++++++++-
fs/btrfs/file.c | 2 +-
fs/btrfs/inode.c | 22 +++++++++++++++++++---
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 60fd81eaedb8..9ada4185ff93 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -514,9 +514,24 @@ int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page,
u32 pgoff, u8 *csum, const u8 * const csum_expected);
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
u32 bio_offset, struct bio_vec *bv);
+
+/*
+ * This represents details about the target file extent item of a write
+ * operation.
+ */
+struct btrfs_file_extent {
+ u64 disk_bytenr;
+ u64 disk_num_bytes;
+ u64 num_bytes;
+ u64 ram_bytes;
+ u64 offset;
+ u8 compression;
+};
+
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
u64 *orig_start, u64 *orig_block_len,
- u64 *ram_bytes, bool nowait, bool strict);
+ u64 *ram_bytes, struct btrfs_file_extent *file_extent,
+ bool nowait, bool strict);
void btrfs_del_delalloc_inode(struct btrfs_inode *inode);
struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a216a0fdf58d..7c42565da70c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1104,7 +1104,7 @@ int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
&cached_state);
}
ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
- NULL, NULL, NULL, nowait, false);
+ NULL, NULL, NULL, NULL, nowait, false);
if (ret <= 0)
btrfs_drew_write_unlock(&root->snapshot_lock);
else
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7148da50e435..8ac489fb5e39 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1855,6 +1855,9 @@ struct can_nocow_file_extent_args {
u64 extent_offset;
/* Number of bytes that can be written to in NOCOW mode. */
u64 num_bytes;
+
+ /* The expected file extent for the NOCOW write. */
+ struct btrfs_file_extent file_extent;
};
/*
@@ -1919,6 +1922,12 @@ static int can_nocow_file_extent(struct btrfs_path *path,
extent_end = btrfs_file_extent_end(path);
+ args->file_extent.disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
+ args->file_extent.disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
+ args->file_extent.ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
+ args->file_extent.offset = btrfs_file_extent_offset(leaf, fi);
+ args->file_extent.compression = btrfs_file_extent_compression(leaf, fi);
+
/*
* The following checks can be expensive, as they need to take other
* locks and do btree or rbtree searches, so release the path to avoid
@@ -1953,6 +1962,9 @@ static int can_nocow_file_extent(struct btrfs_path *path,
args->disk_bytenr += args->start - key->offset;
args->num_bytes = min(args->end + 1, extent_end) - args->start;
+ args->file_extent.num_bytes = args->num_bytes;
+ args->file_extent.offset += args->start - key->offset;
+
/*
* Force COW if csums exist in the range. This ensures that csums for a
* given extent are either valid or do not exist.
@@ -7137,7 +7149,8 @@ static bool btrfs_extent_readonly(struct btrfs_fs_info *fs_info, u64 bytenr)
*/
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
u64 *orig_start, u64 *orig_block_len,
- u64 *ram_bytes, bool nowait, bool strict)
+ u64 *ram_bytes, struct btrfs_file_extent *file_extent,
+ bool nowait, bool strict)
{
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
struct can_nocow_file_extent_args nocow_args = { 0 };
@@ -7226,6 +7239,9 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
*orig_start = key.offset - nocow_args.extent_offset;
if (orig_block_len)
*orig_block_len = nocow_args.disk_num_bytes;
+ if (file_extent)
+ memcpy(file_extent, &nocow_args.file_extent,
+ sizeof(*file_extent));
*len = nocow_args.num_bytes;
ret = 1;
@@ -7445,7 +7461,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
block_start = em->block_start + (start - em->start);
if (can_nocow_extent(inode, start, &len, &orig_start,
- &orig_block_len, &ram_bytes, false, false) == 1) {
+ &orig_block_len, &ram_bytes, NULL, false, false) == 1) {
bg = btrfs_inc_nocow_writers(fs_info, block_start);
if (bg)
can_nocow = true;
@@ -10687,7 +10703,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
free_extent_map(em);
em = NULL;
- ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, false, true);
+ ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, NULL, false, true);
if (ret < 0) {
goto out;
} else if (ret) {
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 03/11] btrfs: introduce new members for extent_map
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 01/11] btrfs: rename extent_map::orig_block_len to disk_num_bytes Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 02/11] btrfs: export the expected file extent through can_nocow_extent() Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 16:53 ` Filipe Manana
2024-05-23 18:21 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps Qu Wenruo
` (9 subsequent siblings)
12 siblings, 2 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Introduce two new members for extent_map:
- disk_bytenr
- offset
Both are matching the members with the same name inside
btrfs_file_extent_items.
For now this patch only touches those members when:
- Reading btrfs_file_extent_items from disk
- Inserting new holes
- Merging two extent maps
With the new disk_bytenr and disk_num_bytes, doing merging would be a
little more complex, as we have 3 different cases:
* Both extent maps are referring to the same data extents
|<----- data extent A ----->|
|<- em 1 ->|<- em 2 ->|
* Both extent maps are referring to different data extents
|<-- data extent A -->|<-- data extent B -->|
|<- em 1 ->|<- em 2 ->|
* One of the extent maps is referring to a merged and larger data
extent that covers both extent maps
This is not really valid case other than some selftests.
So this test case would be removed.
A new helper merge_ondisk_extents() would be introduced to handle
above valid cases.
To properly assign values for those new members, a new btrfs_file_extent
parameter is introduced to all the involved call sites.
- For NOCOW writes the btrfs_file_extent would be exposed from
can_nocow_file_extent().
- For other writes, the members can be easily calculated
As most of them have 0 offset and utilizing the whole on-disk data
extent.
The exception is encoded write, but thankfully that interface provided
offset directly and all other needed info.
For now, both the old members (block_start/block_len/orig_start) are
co-existing with the new members (disk_bytenr/offset), meanwhile all the
critical code is still using the old members only.
The cleanup would happen later after all the older and newer members are
properly validated.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/defrag.c | 4 +++
fs/btrfs/extent_map.c | 78 ++++++++++++++++++++++++++++++++++++++++---
fs/btrfs/extent_map.h | 17 ++++++++++
fs/btrfs/file-item.c | 9 ++++-
fs/btrfs/file.c | 1 +
fs/btrfs/inode.c | 57 +++++++++++++++++++++++++++----
6 files changed, 155 insertions(+), 11 deletions(-)
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index 407ccec3e57e..242c5469f4ba 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -709,6 +709,10 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
em->start = start;
em->orig_start = start;
em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
+ em->disk_num_bytes = 0;
+ em->ram_bytes = 0;
+ em->offset = 0;
em->len = key.offset - start;
break;
}
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index a9d60d1eade9..c7d2393692e6 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -229,6 +229,60 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
return next->block_start == prev->block_start;
}
+/*
+ * Handle the ondisk data extents merge for @prev and @next.
+ *
+ * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
+ * For now only uncompressed regular extent can be merged.
+ *
+ * @prev and @next will be both updated to point to the new merged range.
+ * Thus one of them should be removed by the caller.
+ */
+static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
+{
+ u64 new_disk_bytenr;
+ u64 new_disk_num_bytes;
+ u64 new_offset;
+
+ /* @prev and @next should not be compressed. */
+ ASSERT(!extent_map_is_compressed(prev));
+ ASSERT(!extent_map_is_compressed(next));
+
+ /*
+ * There are two different cases where @prev and @next can be merged.
+ *
+ * 1) They are referring to the same data extent
+ * |<----- data extent A ----->|
+ * |<- prev ->|<- next ->|
+ *
+ * 2) They are referring to different data extents but still adjacent
+ *
+ * |<-- data extent A -->|<-- data extent B -->|
+ * |<- prev ->|<- next ->|
+ *
+ * The calculation here always merge the data extents first, then update
+ * @offset using the new data extents.
+ *
+ * For case 1), the merged data extent would be the same.
+ * For case 2), we just merge the two data extents into one.
+ */
+ new_disk_bytenr = min(prev->disk_bytenr, next->disk_bytenr);
+ new_disk_num_bytes = max(prev->disk_bytenr + prev->disk_num_bytes,
+ next->disk_bytenr + next->disk_num_bytes) -
+ new_disk_bytenr;
+ new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
+
+ prev->disk_bytenr = new_disk_bytenr;
+ prev->disk_num_bytes = new_disk_num_bytes;
+ prev->ram_bytes = new_disk_num_bytes;
+ prev->offset = new_offset;
+
+ next->disk_bytenr = new_disk_bytenr;
+ next->disk_num_bytes = new_disk_num_bytes;
+ next->ram_bytes = new_disk_num_bytes;
+ next->offset = new_offset;
+}
+
static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
{
struct extent_map_tree *tree = &inode->extent_tree;
@@ -260,6 +314,9 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
em->block_len += merge->block_len;
em->block_start = merge->block_start;
em->generation = max(em->generation, merge->generation);
+
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
+ merge_ondisk_extents(merge, em);
em->flags |= EXTENT_FLAG_MERGED;
rb_erase(&merge->rb_node, &tree->root);
@@ -275,6 +332,8 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
em->len += merge->len;
em->block_len += merge->block_len;
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
+ merge_ondisk_extents(em, merge);
rb_erase(&merge->rb_node, &tree->root);
RB_CLEAR_NODE(&merge->rb_node);
em->generation = max(em->generation, merge->generation);
@@ -562,6 +621,7 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
!extent_map_is_compressed(em)) {
em->block_start += start_diff;
em->block_len = em->len;
+ em->offset += start_diff;
}
return add_extent_mapping(inode, em, 0);
}
@@ -785,14 +845,18 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->block_len = em->block_len;
else
split->block_len = split->len;
+ split->disk_bytenr = em->disk_bytenr;
split->disk_num_bytes = max(split->block_len,
em->disk_num_bytes);
+ split->offset = em->offset;
split->ram_bytes = em->ram_bytes;
} else {
split->orig_start = split->start;
split->block_len = 0;
split->block_start = em->block_start;
+ split->disk_bytenr = em->disk_bytenr;
split->disk_num_bytes = 0;
+ split->offset = 0;
split->ram_bytes = split->len;
}
@@ -813,13 +877,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->start = end;
split->len = em_end - end;
split->block_start = em->block_start;
+ split->disk_bytenr = em->disk_bytenr;
split->flags = flags;
split->generation = gen;
if (em->block_start < EXTENT_MAP_LAST_BYTE) {
split->disk_num_bytes = max(em->block_len,
em->disk_num_bytes);
-
+ split->offset = em->offset + end - em->start;
split->ram_bytes = em->ram_bytes;
if (compressed) {
split->block_len = em->block_len;
@@ -832,10 +897,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->orig_start = em->orig_start;
}
} else {
+ split->disk_num_bytes = 0;
+ split->offset = 0;
split->ram_bytes = split->len;
split->orig_start = split->start;
split->block_len = 0;
- split->disk_num_bytes = 0;
}
if (extent_map_in_tree(em)) {
@@ -989,10 +1055,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
/* First, replace the em with a new extent_map starting from * em->start */
split_pre->start = em->start;
split_pre->len = pre;
+ split_pre->disk_bytenr = new_logical;
+ split_pre->disk_num_bytes = split_pre->len;
+ split_pre->offset = 0;
split_pre->orig_start = split_pre->start;
split_pre->block_start = new_logical;
split_pre->block_len = split_pre->len;
- split_pre->disk_num_bytes = split_pre->block_len;
split_pre->ram_bytes = split_pre->len;
split_pre->flags = flags;
split_pre->generation = em->generation;
@@ -1007,10 +1075,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
/* Insert the middle extent_map. */
split_mid->start = em->start + pre;
split_mid->len = em->len - pre;
+ split_mid->disk_bytenr = em->block_start + pre;
+ split_mid->disk_num_bytes = split_mid->len;
+ split_mid->offset = 0;
split_mid->orig_start = split_mid->start;
split_mid->block_start = em->block_start + pre;
split_mid->block_len = split_mid->len;
- split_mid->disk_num_bytes = split_mid->block_len;
split_mid->ram_bytes = split_mid->len;
split_mid->flags = flags;
split_mid->generation = em->generation;
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 2b7bbffd594b..0b1a8e409377 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -70,12 +70,29 @@ struct extent_map {
*/
u64 orig_start;
+ /*
+ * The bytenr of the full on-disk extent.
+ *
+ * For regular extents it's btrfs_file_extent_item::disk_bytenr.
+ * For holes it's EXTENT_MAP_HOLE and for inline extents it's
+ * EXTENT_MAP_INLINE.
+ */
+ u64 disk_bytenr;
+
/*
* The full on-disk extent length, matching
* btrfs_file_extent_item::disk_num_bytes.
*/
u64 disk_num_bytes;
+ /*
+ * Offset inside the decompressed extent.
+ *
+ * For regular extents it's btrfs_file_extent_item::offset.
+ * For holes and inline extents it's 0.
+ */
+ u64 offset;
+
/*
* The decompressed size of the whole on-disk extent, matching
* btrfs_file_extent_item::ram_bytes.
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 430dce44ebd2..1298afea9503 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -1295,12 +1295,17 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->len = btrfs_file_extent_end(path) - extent_start;
em->orig_start = extent_start -
btrfs_file_extent_offset(leaf, fi);
- em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
if (bytenr == 0) {
em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
+ em->disk_num_bytes = 0;
+ em->offset = 0;
return;
}
+ em->disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
+ em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
+ em->offset = btrfs_file_extent_offset(leaf, fi);
if (compress_type != BTRFS_COMPRESS_NONE) {
extent_map_set_compression(em, compress_type);
em->block_start = bytenr;
@@ -1317,8 +1322,10 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
ASSERT(extent_start == 0);
em->block_start = EXTENT_MAP_INLINE;
+ em->disk_bytenr = EXTENT_MAP_INLINE;
em->start = 0;
em->len = fs_info->sectorsize;
+ em->offset = 0;
/*
* Initialize orig_start and block_len with the same values
* as in inode.c:btrfs_get_extent().
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 7c42565da70c..5133c6705d74 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2350,6 +2350,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
hole_em->orig_start = offset;
hole_em->block_start = EXTENT_MAP_HOLE;
+ hole_em->disk_bytenr = EXTENT_MAP_HOLE;
hole_em->block_len = 0;
hole_em->disk_num_bytes = 0;
hole_em->generation = trans->transid;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8ac489fb5e39..7afcdea27782 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -141,6 +141,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 orig_start, u64 block_start,
u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
+ struct btrfs_file_extent *file_extent,
int type);
static int data_reloc_print_warning_inode(u64 inum, u64 offset, u64 num_bytes,
@@ -1152,6 +1153,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_ordered_extent *ordered;
+ struct btrfs_file_extent file_extent;
struct btrfs_key ins;
struct page *locked_page = NULL;
struct extent_state *cached = NULL;
@@ -1198,6 +1200,13 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
lock_extent(io_tree, start, end, &cached);
/* Here we're doing allocation and writeback of the compressed pages */
+ file_extent.disk_bytenr = ins.objectid;
+ file_extent.disk_num_bytes = ins.offset;
+ file_extent.ram_bytes = async_extent->ram_size;
+ file_extent.num_bytes = async_extent->ram_size;
+ file_extent.offset = 0;
+ file_extent.compression = async_extent->compress_type;
+
em = create_io_em(inode, start,
async_extent->ram_size, /* len */
start, /* orig_start */
@@ -1206,6 +1215,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
ins.offset, /* orig_block_len */
async_extent->ram_size, /* ram_bytes */
async_extent->compress_type,
+ &file_extent,
BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
ret = PTR_ERR(em);
@@ -1395,6 +1405,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
while (num_bytes > 0) {
struct btrfs_ordered_extent *ordered;
+ struct btrfs_file_extent file_extent;
cur_alloc_size = num_bytes;
ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size,
@@ -1431,6 +1442,12 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
extent_reserved = true;
ram_size = ins.offset;
+ file_extent.disk_bytenr = ins.objectid;
+ file_extent.disk_num_bytes = ins.offset;
+ file_extent.num_bytes = ins.offset;
+ file_extent.ram_bytes = ins.offset;
+ file_extent.offset = 0;
+ file_extent.compression = BTRFS_COMPRESS_NONE;
lock_extent(&inode->io_tree, start, start + ram_size - 1,
&cached);
@@ -1442,6 +1459,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
ins.offset, /* orig_block_len */
ram_size, /* ram_bytes */
BTRFS_COMPRESS_NONE, /* compress_type */
+ &file_extent,
BTRFS_ORDERED_REGULAR /* type */);
if (IS_ERR(em)) {
unlock_extent(&inode->io_tree, start,
@@ -2180,6 +2198,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
nocow_args.num_bytes, /* block_len */
nocow_args.disk_num_bytes, /* orig_block_len */
ram_bytes, BTRFS_COMPRESS_NONE,
+ &nocow_args.file_extent,
BTRFS_ORDERED_PREALLOC);
if (IS_ERR(em)) {
unlock_extent(&inode->io_tree, cur_offset,
@@ -5012,6 +5031,7 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
hole_em->orig_start = cur_offset;
hole_em->block_start = EXTENT_MAP_HOLE;
+ hole_em->disk_bytenr = EXTENT_MAP_HOLE;
hole_em->block_len = 0;
hole_em->disk_num_bytes = 0;
hole_em->ram_bytes = hole_size;
@@ -6880,6 +6900,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
}
em->start = EXTENT_MAP_HOLE;
em->orig_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
em->len = (u64)-1;
em->block_len = (u64)-1;
@@ -7045,7 +7066,8 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
const u64 block_len,
const u64 orig_block_len,
const u64 ram_bytes,
- const int type)
+ const int type,
+ struct btrfs_file_extent *file_extent)
{
struct extent_map *em = NULL;
struct btrfs_ordered_extent *ordered;
@@ -7054,7 +7076,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
em = create_io_em(inode, start, len, orig_start, block_start,
block_len, orig_block_len, ram_bytes,
BTRFS_COMPRESS_NONE, /* compress_type */
- type);
+ file_extent, type);
if (IS_ERR(em))
goto out;
}
@@ -7085,6 +7107,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
{
struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info;
+ struct btrfs_file_extent file_extent;
struct extent_map *em;
struct btrfs_key ins;
u64 alloc_hint;
@@ -7103,9 +7126,16 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
if (ret)
return ERR_PTR(ret);
+ file_extent.disk_bytenr = ins.objectid;
+ file_extent.disk_num_bytes = ins.offset;
+ file_extent.num_bytes = ins.offset;
+ file_extent.ram_bytes = ins.offset;
+ file_extent.offset = 0;
+ file_extent.compression = BTRFS_COMPRESS_NONE;
em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start,
ins.objectid, ins.offset, ins.offset,
- ins.offset, BTRFS_ORDERED_REGULAR);
+ ins.offset, BTRFS_ORDERED_REGULAR,
+ &file_extent);
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
if (IS_ERR(em))
btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset,
@@ -7348,6 +7378,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 orig_start, u64 block_start,
u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
+ struct btrfs_file_extent *file_extent,
int type)
{
struct extent_map *em;
@@ -7405,9 +7436,11 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
em->len = len;
em->block_len = block_len;
em->block_start = block_start;
+ em->disk_bytenr = file_extent->disk_bytenr;
em->disk_num_bytes = disk_num_bytes;
em->ram_bytes = ram_bytes;
em->generation = -1;
+ em->offset = file_extent->offset;
em->flags |= EXTENT_FLAG_PINNED;
if (type == BTRFS_ORDERED_COMPRESSED)
extent_map_set_compression(em, compress_type);
@@ -7431,6 +7464,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
{
const bool nowait = (iomap_flags & IOMAP_NOWAIT);
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
+ struct btrfs_file_extent file_extent;
struct extent_map *em = *map;
int type;
u64 block_start, orig_start, orig_block_len, ram_bytes;
@@ -7461,7 +7495,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
block_start = em->block_start + (start - em->start);
if (can_nocow_extent(inode, start, &len, &orig_start,
- &orig_block_len, &ram_bytes, NULL, false, false) == 1) {
+ &orig_block_len, &ram_bytes,
+ &file_extent, false, false) == 1) {
bg = btrfs_inc_nocow_writers(fs_info, block_start);
if (bg)
can_nocow = true;
@@ -7489,7 +7524,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
orig_start, block_start,
len, orig_block_len,
- ram_bytes, type);
+ ram_bytes, type,
+ &file_extent);
btrfs_dec_nocow_writers(bg);
if (type == BTRFS_ORDERED_PREALLOC) {
free_extent_map(em);
@@ -9629,6 +9665,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->orig_start = cur_offset;
em->len = ins.offset;
em->block_start = ins.objectid;
+ em->disk_bytenr = ins.objectid;
+ em->offset = 0;
em->block_len = ins.offset;
em->disk_num_bytes = ins.offset;
em->ram_bytes = ins.offset;
@@ -10195,6 +10233,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
struct extent_changeset *data_reserved = NULL;
struct extent_state *cached_state = NULL;
struct btrfs_ordered_extent *ordered;
+ struct btrfs_file_extent file_extent;
int compression;
size_t orig_count;
u64 start, end;
@@ -10370,10 +10409,16 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
goto out_delalloc_release;
extent_reserved = true;
+ file_extent.disk_bytenr = ins.objectid;
+ file_extent.disk_num_bytes = ins.offset;
+ file_extent.num_bytes = num_bytes;
+ file_extent.ram_bytes = ram_bytes;
+ file_extent.offset = encoded->unencoded_offset;
+ file_extent.compression = compression;
em = create_io_em(inode, start, num_bytes,
start - encoded->unencoded_offset, ins.objectid,
ins.offset, ins.offset, ram_bytes, compression,
- BTRFS_ORDERED_COMPRESSED);
+ &file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
ret = PTR_ERR(em);
goto out_free_reserved;
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (2 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 03/11] btrfs: introduce new members for extent_map Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 16:57 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 05/11] btrfs: remove extent_map::orig_start member Qu Wenruo
` (8 subsequent siblings)
12 siblings, 1 reply; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Since extent_map structure has the all the needed members to represent a
file extent directly, we can apply all the file extent sanity checks to an extent
map.
The new sanity checks would cross check both the old members
(block_start/block_len/orig_start) and the new members
(disk_bytenr/disk_num_bytes/offset).
There is a special case for offset/orig_start/start cross check, we only
do such sanity check for compressed extent, as only compressed
read/encoded write really utilize orig_start.
This can be proved by the cleanup patch of orig_start.
The checks happens at the following timing:
- add_extent_mapping()
This is for newly added extent map
- replace_extent_mapping()
This is for btrfs_drop_extent_map_range() and split_extent_map()
- try_merge_map()
For a lot of call sites we have to properly populate all the members to
pass the sanity check, meanwhile the following code needs extra
modification:
- setup_file_extents() from inode-tests
The file extents layout of setup_file_extents() is already too invalid
that tree-checker would reject most of them in real world.
However there is just a special unaligned regular extent which has
mismatched disk_num_bytes (4096) and ram_bytes (4096 - 1).
So instead of dropping the whole test case, here we just unify
disk_num_bytes and ram_bytes to 4096 - 1.
- test_case_7() from extent-map-tests
An extent is inserted with 16K length, but on-disk extent size is
only 4K.
This means it must be a compressed extent, so set the compressed flag
for it.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/extent_map.c | 60 +++++++++++++++++++++++++++++++
fs/btrfs/relocation.c | 4 +++
fs/btrfs/tests/extent-map-tests.c | 56 ++++++++++++++++++++++++++++-
fs/btrfs/tests/inode-tests.c | 2 +-
4 files changed, 120 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index c7d2393692e6..b157f30ac241 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -283,8 +283,62 @@ static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *nex
next->offset = new_offset;
}
+static void dump_extent_map(struct btrfs_fs_info *fs_info,
+ const char *prefix, struct extent_map *em)
+{
+ if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
+ return;
+ btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu orig_start=%llu block_start=%llu block_len=%llu flags=0x%x\n",
+ prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
+ em->ram_bytes, em->offset, em->orig_start, em->block_start,
+ em->block_len, em->flags);
+ ASSERT(0);
+}
+
+/* Internal sanity checks for btrfs debug builds. */
+static void validate_extent_map(struct btrfs_fs_info *fs_info,
+ struct extent_map *em)
+{
+ if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
+ return;
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
+ if (em->disk_num_bytes == 0)
+ dump_extent_map(fs_info, "zero disk_num_bytes", em);
+ if (em->offset + em->len > em->ram_bytes)
+ dump_extent_map(fs_info, "ram_bytes too small", em);
+ if (em->offset + em->len > em->disk_num_bytes &&
+ !extent_map_is_compressed(em))
+ dump_extent_map(fs_info, "disk_num_bytes too small", em);
+
+ if (extent_map_is_compressed(em)) {
+ if (em->block_start != em->disk_bytenr)
+ dump_extent_map(fs_info,
+ "mismatch block_start/disk_bytenr/offset", em);
+ if (em->disk_num_bytes != em->block_len)
+ dump_extent_map(fs_info,
+ "mismatch disk_num_bytes/block_len", em);
+ /*
+ * Here we only check the start/orig_start/offset for
+ * compressed extents as that's the only case where
+ * orig_start is utilized.
+ */
+ if (em->orig_start != em->start - em->offset)
+ dump_extent_map(fs_info,
+ "mismatch orig_start/offset/start", em);
+
+ } else if (em->block_start != em->disk_bytenr + em->offset) {
+ dump_extent_map(fs_info,
+ "mismatch block_start/disk_bytenr/offset", em);
+ }
+ } else if (em->offset) {
+ dump_extent_map(fs_info,
+ "non-zero offset for hole/inline", em);
+ }
+}
+
static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
{
+ struct btrfs_fs_info *fs_info = inode->root->fs_info;
struct extent_map_tree *tree = &inode->extent_tree;
struct extent_map *merge = NULL;
struct rb_node *rb;
@@ -319,6 +373,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
merge_ondisk_extents(merge, em);
em->flags |= EXTENT_FLAG_MERGED;
+ validate_extent_map(fs_info, em);
rb_erase(&merge->rb_node, &tree->root);
RB_CLEAR_NODE(&merge->rb_node);
free_extent_map(merge);
@@ -334,6 +389,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
em->block_len += merge->block_len;
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
merge_ondisk_extents(em, merge);
+ validate_extent_map(fs_info, em);
rb_erase(&merge->rb_node, &tree->root);
RB_CLEAR_NODE(&merge->rb_node);
em->generation = max(em->generation, merge->generation);
@@ -445,6 +501,7 @@ static int add_extent_mapping(struct btrfs_inode *inode,
lockdep_assert_held_write(&tree->lock);
+ validate_extent_map(fs_info, em);
ret = tree_insert(&tree->root, em);
if (ret)
return ret;
@@ -548,10 +605,13 @@ static void replace_extent_mapping(struct btrfs_inode *inode,
struct extent_map *new,
int modified)
{
+ struct btrfs_fs_info *fs_info = inode->root->fs_info;
struct extent_map_tree *tree = &inode->extent_tree;
lockdep_assert_held_write(&tree->lock);
+ validate_extent_map(fs_info, new);
+
WARN_ON(cur->flags & EXTENT_FLAG_PINNED);
ASSERT(extent_map_in_tree(cur));
if (!(cur->flags & EXTENT_FLAG_LOGGING))
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 5f1a909a1d91..151ed1ebd291 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2911,9 +2911,13 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
return -ENOMEM;
em->start = start;
+ em->orig_start = start;
em->len = end + 1 - start;
em->block_len = em->len;
em->block_start = block_start;
+ em->disk_bytenr = block_start;
+ em->disk_num_bytes = em->len;
+ em->ram_bytes = em->len;
em->flags |= EXTENT_FLAG_PINNED;
lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state);
diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
index c511a1297956..e73ac7a0869c 100644
--- a/fs/btrfs/tests/extent-map-tests.c
+++ b/fs/btrfs/tests/extent-map-tests.c
@@ -78,6 +78,9 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->len = SZ_16K;
em->block_start = 0;
em->block_len = SZ_16K;
+ em->disk_bytenr = 0;
+ em->disk_num_bytes = SZ_16K;
+ em->ram_bytes = SZ_16K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -96,9 +99,13 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_16K;
+ em->orig_start = SZ_16K;
em->len = SZ_4K;
em->block_start = SZ_32K; /* avoid merging */
em->block_len = SZ_4K;
+ em->disk_bytenr = SZ_32K; /* avoid merging */
+ em->disk_num_bytes = SZ_4K;
+ em->ram_bytes = SZ_4K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -117,9 +124,13 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 8K), should return [0, 16K) instead. */
em->start = start;
+ em->orig_start = start;
em->len = len;
em->block_start = start;
em->block_len = len;
+ em->disk_bytenr = start;
+ em->disk_num_bytes = len;
+ em->ram_bytes = len;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -174,6 +185,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->len = SZ_1K;
em->block_start = EXTENT_MAP_INLINE;
em->block_len = (u64)-1;
+ em->disk_bytenr = EXTENT_MAP_INLINE;
+ em->disk_num_bytes = 0;
+ em->ram_bytes = SZ_1K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -192,9 +206,13 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_4K;
+ em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
em->block_len = SZ_4K;
+ em->disk_bytenr = SZ_4K;
+ em->disk_num_bytes = SZ_4K;
+ em->ram_bytes = SZ_4K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -216,6 +234,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->len = SZ_1K;
em->block_start = EXTENT_MAP_INLINE;
em->block_len = (u64)-1;
+ em->disk_bytenr = EXTENT_MAP_INLINE;
+ em->disk_num_bytes = 0;
+ em->ram_bytes = SZ_1K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -262,9 +283,13 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
/* Add [4K, 8K) */
em->start = SZ_4K;
+ em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
em->block_len = SZ_4K;
+ em->disk_bytenr = SZ_4K;
+ em->disk_num_bytes = SZ_4K;
+ em->ram_bytes = SZ_4K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -286,6 +311,9 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
em->len = SZ_16K;
em->block_start = 0;
em->block_len = SZ_16K;
+ em->disk_bytenr = 0;
+ em->disk_num_bytes = SZ_16K;
+ em->ram_bytes = SZ_16K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, start, len);
write_unlock(&em_tree->lock);
@@ -372,6 +400,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
em->len = SZ_8K;
em->block_start = 0;
em->block_len = SZ_8K;
+ em->disk_bytenr = 0;
+ em->disk_num_bytes = SZ_8K;
+ em->ram_bytes = SZ_8K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -390,9 +421,13 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
/* Add [8K, 32K) */
em->start = SZ_8K;
+ em->orig_start = SZ_8K;
em->len = 24 * SZ_1K;
em->block_start = SZ_16K; /* avoid merging */
em->block_len = 24 * SZ_1K;
+ em->disk_bytenr = SZ_16K; /* avoid merging */
+ em->disk_num_bytes = 24 * SZ_1K;
+ em->ram_bytes = 24 * SZ_1K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -410,9 +445,13 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
}
/* Add [0K, 32K) */
em->start = 0;
+ em->orig_start = 0;
em->len = SZ_32K;
em->block_start = 0;
em->block_len = SZ_32K;
+ em->disk_bytenr = 0;
+ em->disk_num_bytes = SZ_32K;
+ em->ram_bytes = SZ_32K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, start, len);
write_unlock(&em_tree->lock);
@@ -494,9 +533,13 @@ static int add_compressed_extent(struct btrfs_inode *inode,
}
em->start = start;
+ em->orig_start = start;
em->len = len;
em->block_start = block_start;
em->block_len = SZ_4K;
+ em->disk_bytenr = block_start;
+ em->disk_num_bytes = SZ_4K;
+ em->ram_bytes = len;
em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
@@ -715,9 +758,13 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_4K;
+ em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_16K;
em->block_len = SZ_16K;
+ em->disk_bytenr = SZ_16K;
+ em->disk_num_bytes = SZ_16K;
+ em->ram_bytes = SZ_16K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, 0, SZ_8K);
write_unlock(&em_tree->lock);
@@ -771,7 +818,10 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->len = SZ_16K;
em->block_start = 0;
em->block_len = SZ_4K;
- em->flags |= EXTENT_FLAG_PINNED;
+ em->disk_bytenr = 0;
+ em->disk_num_bytes = SZ_4K;
+ em->ram_bytes = SZ_16K;
+ em->flags |= (EXTENT_FLAG_PINNED | EXTENT_FLAG_COMPRESS_ZLIB);
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
@@ -790,9 +840,13 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* [32K, 48K), not pinned */
em->start = SZ_32K;
+ em->orig_start = SZ_32K;
em->len = SZ_16K;
em->block_start = SZ_32K;
em->block_len = SZ_16K;
+ em->disk_bytenr = SZ_32K;
+ em->disk_num_bytes = SZ_16K;
+ em->ram_bytes = SZ_16K;
write_lock(&em_tree->lock);
ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
write_unlock(&em_tree->lock);
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
index 99da9d34b77a..0895c6e06812 100644
--- a/fs/btrfs/tests/inode-tests.c
+++ b/fs/btrfs/tests/inode-tests.c
@@ -117,7 +117,7 @@ static void setup_file_extents(struct btrfs_root *root, u32 sectorsize)
/* Now for a regular extent */
insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0,
- disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
+ disk_bytenr, sectorsize - 1, BTRFS_FILE_EXTENT_REG, 0, slot);
slot++;
disk_bytenr += sectorsize;
offset += sectorsize - 1;
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 05/11] btrfs: remove extent_map::orig_start member
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (3 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 06/11] btrfs: remove extent_map::block_len member Qu Wenruo
` (7 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Since we have extent_map::offset, the old extent_map::orig_start is just
extent_map::start - extent_map::offset for non-hole/inline extents.
And since the new extent_map::offset is already verified by
validate_extent_map() meanwhile the old orig_start is not, let's
just remove the old member from all call sites.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/btrfs_inode.h | 2 +-
fs/btrfs/compression.c | 2 +-
fs/btrfs/defrag.c | 1 -
fs/btrfs/extent_map.c | 21 +-------
fs/btrfs/extent_map.h | 9 ----
fs/btrfs/file-item.c | 5 +-
fs/btrfs/file.c | 3 +-
fs/btrfs/inode.c | 37 +++++---------
fs/btrfs/relocation.c | 1 -
fs/btrfs/tests/extent-map-tests.c | 9 ----
fs/btrfs/tests/inode-tests.c | 84 +++++++++++++------------------
fs/btrfs/tree-log.c | 2 +-
include/trace/events/btrfs.h | 6 +--
13 files changed, 56 insertions(+), 126 deletions(-)
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 9ada4185ff93..269ee9ac859e 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -529,7 +529,7 @@ struct btrfs_file_extent {
};
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
- u64 *orig_start, u64 *orig_block_len,
+ u64 *orig_block_len,
u64 *ram_bytes, struct btrfs_file_extent *file_extent,
bool nowait, bool strict);
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 7b4843df0752..4f6d748aa99e 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -590,7 +590,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
cb = alloc_compressed_bio(inode, file_offset, REQ_OP_READ,
end_bbio_compressed_read);
- cb->start = em->orig_start;
+ cb->start = em->start - em->offset;
em_len = em->len;
em_start = em->start;
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index 242c5469f4ba..025e7f853a68 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -707,7 +707,6 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
*/
if (key.offset > start) {
em->start = start;
- em->orig_start = start;
em->block_start = EXTENT_MAP_HOLE;
em->disk_bytenr = EXTENT_MAP_HOLE;
em->disk_num_bytes = 0;
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index b157f30ac241..91be54f79d21 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -288,9 +288,9 @@ static void dump_extent_map(struct btrfs_fs_info *fs_info,
{
if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
return;
- btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu orig_start=%llu block_start=%llu block_len=%llu flags=0x%x\n",
+ btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu block_start=%llu block_len=%llu flags=0x%x\n",
prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
- em->ram_bytes, em->offset, em->orig_start, em->block_start,
+ em->ram_bytes, em->offset, em->block_start,
em->block_len, em->flags);
ASSERT(0);
}
@@ -317,15 +317,6 @@ static void validate_extent_map(struct btrfs_fs_info *fs_info,
if (em->disk_num_bytes != em->block_len)
dump_extent_map(fs_info,
"mismatch disk_num_bytes/block_len", em);
- /*
- * Here we only check the start/orig_start/offset for
- * compressed extents as that's the only case where
- * orig_start is utilized.
- */
- if (em->orig_start != em->start - em->offset)
- dump_extent_map(fs_info,
- "mismatch orig_start/offset/start", em);
-
} else if (em->block_start != em->disk_bytenr + em->offset) {
dump_extent_map(fs_info,
"mismatch block_start/disk_bytenr/offset", em);
@@ -363,7 +354,6 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
merge = rb_entry(rb, struct extent_map, rb_node);
if (rb && can_merge_extent_map(merge) && mergeable_maps(merge, em)) {
em->start = merge->start;
- em->orig_start = merge->orig_start;
em->len += merge->len;
em->block_len += merge->block_len;
em->block_start = merge->block_start;
@@ -898,7 +888,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->len = start - em->start;
if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- split->orig_start = em->orig_start;
split->block_start = em->block_start;
if (compressed)
@@ -911,7 +900,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->offset = em->offset;
split->ram_bytes = em->ram_bytes;
} else {
- split->orig_start = split->start;
split->block_len = 0;
split->block_start = em->block_start;
split->disk_bytenr = em->disk_bytenr;
@@ -948,19 +936,16 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->ram_bytes = em->ram_bytes;
if (compressed) {
split->block_len = em->block_len;
- split->orig_start = em->orig_start;
} else {
const u64 diff = end - em->start;
split->block_len = split->len;
split->block_start += diff;
- split->orig_start = em->orig_start;
}
} else {
split->disk_num_bytes = 0;
split->offset = 0;
split->ram_bytes = split->len;
- split->orig_start = split->start;
split->block_len = 0;
}
@@ -1118,7 +1103,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_pre->disk_bytenr = new_logical;
split_pre->disk_num_bytes = split_pre->len;
split_pre->offset = 0;
- split_pre->orig_start = split_pre->start;
split_pre->block_start = new_logical;
split_pre->block_len = split_pre->len;
split_pre->ram_bytes = split_pre->len;
@@ -1138,7 +1122,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_mid->disk_bytenr = em->block_start + pre;
split_mid->disk_num_bytes = split_mid->len;
split_mid->offset = 0;
- split_mid->orig_start = split_mid->start;
split_mid->block_start = em->block_start + pre;
split_mid->block_len = split_mid->len;
split_mid->ram_bytes = split_mid->len;
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 0b1a8e409377..5ae3d56b4351 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -61,15 +61,6 @@ struct extent_map {
*/
u64 len;
- /*
- * The file offset of the original file extent before splitting.
- *
- * This is an in-memory only member, matching
- * extent_map::start - btrfs_file_extent_item::offset for
- * regular/preallocated extents. EXTENT_MAP_HOLE otherwise.
- */
- u64 orig_start;
-
/*
* The bytenr of the full on-disk extent.
*
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 1298afea9503..06d23951901c 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -1293,8 +1293,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
type == BTRFS_FILE_EXTENT_PREALLOC) {
em->start = extent_start;
em->len = btrfs_file_extent_end(path) - extent_start;
- em->orig_start = extent_start -
- btrfs_file_extent_offset(leaf, fi);
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
if (bytenr == 0) {
em->block_start = EXTENT_MAP_HOLE;
@@ -1327,10 +1325,9 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->len = fs_info->sectorsize;
em->offset = 0;
/*
- * Initialize orig_start and block_len with the same values
+ * Initialize block_len with the same values
* as in inode.c:btrfs_get_extent().
*/
- em->orig_start = EXTENT_MAP_HOLE;
em->block_len = (u64)-1;
extent_map_set_compression(em, compress_type);
} else {
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 5133c6705d74..707012fc2d43 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1104,7 +1104,7 @@ int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
&cached_state);
}
ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
- NULL, NULL, NULL, NULL, nowait, false);
+ NULL, NULL, NULL, nowait, false);
if (ret <= 0)
btrfs_drew_write_unlock(&root->snapshot_lock);
else
@@ -2347,7 +2347,6 @@ static int fill_holes(struct btrfs_trans_handle *trans,
hole_em->start = offset;
hole_em->len = end - offset;
hole_em->ram_bytes = hole_em->len;
- hole_em->orig_start = offset;
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7afcdea27782..066f14c78bc9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -138,7 +138,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
u64 end, struct writeback_control *wbc,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 orig_start, u64 block_start,
+ u64 len, u64 block_start,
u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
@@ -1209,7 +1209,6 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
em = create_io_em(inode, start,
async_extent->ram_size, /* len */
- start, /* orig_start */
ins.objectid, /* block_start */
ins.offset, /* block_len */
ins.offset, /* orig_block_len */
@@ -1453,7 +1452,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
&cached);
em = create_io_em(inode, start, ins.offset, /* len */
- start, /* orig_start */
ins.objectid, /* block_start */
ins.offset, /* block_len */
ins.offset, /* orig_block_len */
@@ -2189,11 +2187,9 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
is_prealloc = extent_type == BTRFS_FILE_EXTENT_PREALLOC;
if (is_prealloc) {
- u64 orig_start = found_key.offset - nocow_args.extent_offset;
struct extent_map *em;
em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
- orig_start,
nocow_args.disk_bytenr, /* block_start */
nocow_args.num_bytes, /* block_len */
nocow_args.disk_num_bytes, /* orig_block_len */
@@ -5028,7 +5024,6 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
}
hole_em->start = cur_offset;
hole_em->len = hole_size;
- hole_em->orig_start = cur_offset;
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
@@ -6899,7 +6894,6 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
goto out;
}
em->start = EXTENT_MAP_HOLE;
- em->orig_start = EXTENT_MAP_HOLE;
em->disk_bytenr = EXTENT_MAP_HOLE;
em->len = (u64)-1;
em->block_len = (u64)-1;
@@ -6992,7 +6986,6 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
/* New extent overlaps with existing one */
em->start = start;
- em->orig_start = start;
em->len = found_key.offset - start;
em->block_start = EXTENT_MAP_HOLE;
goto insert;
@@ -7028,7 +7021,6 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
}
not_found:
em->start = start;
- em->orig_start = start;
em->len = len;
em->block_start = EXTENT_MAP_HOLE;
insert:
@@ -7061,7 +7053,6 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_dio_data *dio_data,
const u64 start,
const u64 len,
- const u64 orig_start,
const u64 block_start,
const u64 block_len,
const u64 orig_block_len,
@@ -7073,7 +7064,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_ordered_extent *ordered;
if (type != BTRFS_ORDERED_NOCOW) {
- em = create_io_em(inode, start, len, orig_start, block_start,
+ em = create_io_em(inode, start, len, block_start,
block_len, orig_block_len, ram_bytes,
BTRFS_COMPRESS_NONE, /* compress_type */
file_extent, type);
@@ -7132,7 +7123,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
file_extent.ram_bytes = ins.offset;
file_extent.offset = 0;
file_extent.compression = BTRFS_COMPRESS_NONE;
- em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start,
+ em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
ins.objectid, ins.offset, ins.offset,
ins.offset, BTRFS_ORDERED_REGULAR,
&file_extent);
@@ -7178,7 +7169,7 @@ static bool btrfs_extent_readonly(struct btrfs_fs_info *fs_info, u64 bytenr)
* any ordered extents.
*/
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
- u64 *orig_start, u64 *orig_block_len,
+ u64 *orig_block_len,
u64 *ram_bytes, struct btrfs_file_extent *file_extent,
bool nowait, bool strict)
{
@@ -7265,8 +7256,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
}
}
- if (orig_start)
- *orig_start = key.offset - nocow_args.extent_offset;
if (orig_block_len)
*orig_block_len = nocow_args.disk_num_bytes;
if (file_extent)
@@ -7375,7 +7364,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 orig_start, u64 block_start,
+ u64 len, u64 block_start,
u64 block_len, u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
@@ -7413,7 +7402,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
ASSERT(ram_bytes == len);
/* Since it's a new extent, we should not have any offset. */
- ASSERT(orig_start == start);
+ ASSERT(file_extent->offset == 0);
break;
case BTRFS_ORDERED_COMPRESSED:
/* Must be compressed. */
@@ -7432,7 +7421,6 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
return ERR_PTR(-ENOMEM);
em->start = start;
- em->orig_start = orig_start;
em->len = len;
em->block_len = block_len;
em->block_start = block_start;
@@ -7467,7 +7455,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
struct btrfs_file_extent file_extent;
struct extent_map *em = *map;
int type;
- u64 block_start, orig_start, orig_block_len, ram_bytes;
+ u64 block_start, orig_block_len, ram_bytes;
struct btrfs_block_group *bg;
bool can_nocow = false;
bool space_reserved = false;
@@ -7494,7 +7482,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
len = min(len, em->len - (start - em->start));
block_start = em->block_start + (start - em->start);
- if (can_nocow_extent(inode, start, &len, &orig_start,
+ if (can_nocow_extent(inode, start, &len,
&orig_block_len, &ram_bytes,
&file_extent, false, false) == 1) {
bg = btrfs_inc_nocow_writers(fs_info, block_start);
@@ -7522,7 +7510,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
space_reserved = true;
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
- orig_start, block_start,
+ block_start,
len, orig_block_len,
ram_bytes, type,
&file_extent);
@@ -9662,7 +9650,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
}
em->start = cur_offset;
- em->orig_start = cur_offset;
em->len = ins.offset;
em->block_start = ins.objectid;
em->disk_bytenr = ins.objectid;
@@ -10171,7 +10158,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
disk_io_size = em->block_len;
count = em->block_len;
encoded->unencoded_len = em->ram_bytes;
- encoded->unencoded_offset = iocb->ki_pos - em->orig_start;
+ encoded->unencoded_offset = iocb->ki_pos - (em->start - em->offset);
ret = btrfs_encoded_io_compression_from_extent(fs_info,
extent_map_compression(em));
if (ret < 0)
@@ -10416,7 +10403,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
file_extent.offset = encoded->unencoded_offset;
file_extent.compression = compression;
em = create_io_em(inode, start, num_bytes,
- start - encoded->unencoded_offset, ins.objectid,
+ ins.objectid,
ins.offset, ins.offset, ram_bytes, compression,
&file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
@@ -10748,7 +10735,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
free_extent_map(em);
em = NULL;
- ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, NULL, false, true);
+ ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, false, true);
if (ret < 0) {
goto out;
} else if (ret) {
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 151ed1ebd291..21061a0b2e7c 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2911,7 +2911,6 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
return -ENOMEM;
em->start = start;
- em->orig_start = start;
em->len = end + 1 - start;
em->block_len = em->len;
em->block_start = block_start;
diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
index e73ac7a0869c..65c6921ff4a2 100644
--- a/fs/btrfs/tests/extent-map-tests.c
+++ b/fs/btrfs/tests/extent-map-tests.c
@@ -99,7 +99,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_16K;
- em->orig_start = SZ_16K;
em->len = SZ_4K;
em->block_start = SZ_32K; /* avoid merging */
em->block_len = SZ_4K;
@@ -124,7 +123,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 8K), should return [0, 16K) instead. */
em->start = start;
- em->orig_start = start;
em->len = len;
em->block_start = start;
em->block_len = len;
@@ -206,7 +204,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_4K;
- em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
em->block_len = SZ_4K;
@@ -283,7 +280,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
/* Add [4K, 8K) */
em->start = SZ_4K;
- em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
em->block_len = SZ_4K;
@@ -421,7 +417,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
/* Add [8K, 32K) */
em->start = SZ_8K;
- em->orig_start = SZ_8K;
em->len = 24 * SZ_1K;
em->block_start = SZ_16K; /* avoid merging */
em->block_len = 24 * SZ_1K;
@@ -445,7 +440,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
}
/* Add [0K, 32K) */
em->start = 0;
- em->orig_start = 0;
em->len = SZ_32K;
em->block_start = 0;
em->block_len = SZ_32K;
@@ -533,7 +527,6 @@ static int add_compressed_extent(struct btrfs_inode *inode,
}
em->start = start;
- em->orig_start = start;
em->len = len;
em->block_start = block_start;
em->block_len = SZ_4K;
@@ -758,7 +751,6 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
}
em->start = SZ_4K;
- em->orig_start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_16K;
em->block_len = SZ_16K;
@@ -840,7 +832,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* [32K, 48K), not pinned */
em->start = SZ_32K;
- em->orig_start = SZ_32K;
em->len = SZ_16K;
em->block_start = SZ_32K;
em->block_len = SZ_16K;
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
index 0895c6e06812..fc390c18ac95 100644
--- a/fs/btrfs/tests/inode-tests.c
+++ b/fs/btrfs/tests/inode-tests.c
@@ -358,9 +358,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
offset = em->start + em->len;
@@ -386,9 +385,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
disk_bytenr = em->block_start;
@@ -437,9 +435,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != orig_start) {
- test_err("wrong orig offset, want %llu, have %llu",
- orig_start, em->orig_start);
+ if (em->start - em->offset != orig_start) {
+ test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
+ em->start, em->offset, orig_start);
goto out;
}
disk_bytenr += (em->start - orig_start);
@@ -472,9 +470,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
prealloc_only, em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
offset = em->start + em->len;
@@ -501,9 +498,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
prealloc_only, em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
disk_bytenr = em->block_start;
@@ -530,15 +526,14 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != orig_start) {
- test_err("unexpected orig offset, wanted %llu, have %llu",
- orig_start, em->orig_start);
+ if (em->start - em->offset != orig_start) {
+ test_err("unexpected offset, wanted %llu, have %llu",
+ em->start - orig_start, em->offset);
goto out;
}
- if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
+ if (em->block_start != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
- disk_bytenr + (em->start - em->orig_start),
- em->block_start);
+ disk_bytenr + em->offset, em->block_start);
goto out;
}
offset = em->start + em->len;
@@ -564,15 +559,14 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
prealloc_only, em->flags);
goto out;
}
- if (em->orig_start != orig_start) {
- test_err("wrong orig offset, want %llu, have %llu", orig_start,
- em->orig_start);
+ if (em->start - em->offset != orig_start) {
+ test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
+ em->start, em->offset, orig_start);
goto out;
}
- if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
+ if (em->block_start != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
- disk_bytenr + (em->start - em->orig_start),
- em->block_start);
+ disk_bytenr + em->offset, em->block_start);
goto out;
}
offset = em->start + em->len;
@@ -599,9 +593,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
compressed_only, em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu",
- em->start, em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
if (extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
@@ -633,9 +626,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
compressed_only, em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu",
- em->start, em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
if (extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
@@ -667,9 +659,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
offset = em->start + em->len;
@@ -696,9 +687,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
compressed_only, em->flags);
goto out;
}
- if (em->orig_start != orig_start) {
- test_err("wrong orig offset, want %llu, have %llu",
- em->start, orig_start);
+ if (em->start - em->offset != orig_start) {
+ test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
+ em->start, em->offset, orig_start);
goto out;
}
if (extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
@@ -729,9 +720,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
offset = em->start + em->len;
@@ -762,9 +752,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
vacancy_only, em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
offset = em->start + em->len;
@@ -789,9 +778,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("unexpected flags set, want 0 have %u", em->flags);
goto out;
}
- if (em->orig_start != em->start) {
- test_err("wrong orig offset, want %llu, have %llu", em->start,
- em->orig_start);
+ if (em->offset != 0) {
+ test_err("wrong orig offset, want 0, have %llu", em->offset);
goto out;
}
ret = 0;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f237b5ed80ec..d6a3151d6c37 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4691,7 +4691,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
struct extent_buffer *leaf;
struct btrfs_key key;
enum btrfs_compression_type compress_type;
- u64 extent_offset = em->start - em->orig_start;
+ u64 extent_offset = em->offset;
u64 block_len;
int ret;
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index d2d94d7c3fb5..cbac7cd11995 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -291,7 +291,6 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__field( u64, ino )
__field( u64, start )
__field( u64, len )
- __field( u64, orig_start )
__field( u64, block_start )
__field( u64, block_len )
__field( u32, flags )
@@ -303,7 +302,6 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__entry->ino = btrfs_ino(inode);
__entry->start = map->start;
__entry->len = map->len;
- __entry->orig_start = map->orig_start;
__entry->block_start = map->block_start;
__entry->block_len = map->block_len;
__entry->flags = map->flags;
@@ -311,13 +309,11 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
),
TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu len=%llu "
- "orig_start=%llu block_start=%llu(%s) "
- "block_len=%llu flags=%s refs=%u",
+ "block_start=%llu(%s) block_len=%llu flags=%s refs=%u",
show_root_type(__entry->root_objectid),
__entry->ino,
__entry->start,
__entry->len,
- __entry->orig_start,
show_map_type(__entry->block_start),
__entry->block_len,
show_map_flags(__entry->flags),
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 06/11] btrfs: remove extent_map::block_len member
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (4 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 05/11] btrfs: remove extent_map::orig_start member Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 07/11] btrfs: remove extent_map::block_start member Qu Wenruo
` (6 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
The extent_map::block_len is either extent_map::len (non-compressed
extent) or extent_map::disk_num_bytes (compressed extent).
Since we already have sanity checks to do the cross-check between the
new and old members, we can drop the old extent_map::block_len now.
For most call sites, they can manually select extent_map::len or
extent_map::disk_num_bytes, since most if not all of them have checked
if the extent is compressed.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/compression.c | 2 +-
fs/btrfs/extent_map.c | 40 +++++++++++-------------------
fs/btrfs/extent_map.h | 9 -------
fs/btrfs/file-item.c | 7 ------
fs/btrfs/file.c | 1 -
fs/btrfs/inode.c | 36 +++++++++------------------
fs/btrfs/relocation.c | 1 -
fs/btrfs/tests/extent-map-tests.c | 41 ++++++++++---------------------
fs/btrfs/tree-log.c | 4 +--
include/trace/events/btrfs.h | 5 +---
10 files changed, 42 insertions(+), 104 deletions(-)
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 4f6d748aa99e..cd88432e7072 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -585,7 +585,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
}
ASSERT(extent_map_is_compressed(em));
- compressed_len = em->block_len;
+ compressed_len = em->disk_num_bytes;
cb = alloc_compressed_bio(inode, file_offset, REQ_OP_READ,
end_bbio_compressed_read);
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 91be54f79d21..0c100fe47c43 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -183,11 +183,18 @@ static struct rb_node *__tree_search(struct rb_root *root, u64 offset,
return NULL;
}
+static inline u64 extent_map_block_len(const struct extent_map *em)
+{
+ if (extent_map_is_compressed(em))
+ return em->disk_num_bytes;
+ return em->len;
+}
+
static inline u64 extent_map_block_end(const struct extent_map *em)
{
- if (em->block_start + em->block_len < em->block_start)
+ if (em->block_start + extent_map_block_len(em) < em->block_start)
return (u64)-1;
- return em->block_start + em->block_len;
+ return em->block_start + extent_map_block_len(em);
}
static bool can_merge_extent_map(const struct extent_map *em)
@@ -288,10 +295,10 @@ static void dump_extent_map(struct btrfs_fs_info *fs_info,
{
if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
return;
- btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu block_start=%llu block_len=%llu flags=0x%x\n",
+ btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu block_start=%llu flags=0x%x\n",
prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
em->ram_bytes, em->offset, em->block_start,
- em->block_len, em->flags);
+ em->flags);
ASSERT(0);
}
@@ -314,9 +321,6 @@ static void validate_extent_map(struct btrfs_fs_info *fs_info,
if (em->block_start != em->disk_bytenr)
dump_extent_map(fs_info,
"mismatch block_start/disk_bytenr/offset", em);
- if (em->disk_num_bytes != em->block_len)
- dump_extent_map(fs_info,
- "mismatch disk_num_bytes/block_len", em);
} else if (em->block_start != em->disk_bytenr + em->offset) {
dump_extent_map(fs_info,
"mismatch block_start/disk_bytenr/offset", em);
@@ -355,7 +359,6 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
if (rb && can_merge_extent_map(merge) && mergeable_maps(merge, em)) {
em->start = merge->start;
em->len += merge->len;
- em->block_len += merge->block_len;
em->block_start = merge->block_start;
em->generation = max(em->generation, merge->generation);
@@ -376,7 +379,6 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
merge = rb_entry(rb, struct extent_map, rb_node);
if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
em->len += merge->len;
- em->block_len += merge->block_len;
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
merge_ondisk_extents(em, merge);
validate_extent_map(fs_info, em);
@@ -670,7 +672,6 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
if (em->block_start < EXTENT_MAP_LAST_BYTE &&
!extent_map_is_compressed(em)) {
em->block_start += start_diff;
- em->block_len = em->len;
em->offset += start_diff;
}
return add_extent_mapping(inode, em, 0);
@@ -890,17 +891,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
if (em->block_start < EXTENT_MAP_LAST_BYTE) {
split->block_start = em->block_start;
- if (compressed)
- split->block_len = em->block_len;
- else
- split->block_len = split->len;
split->disk_bytenr = em->disk_bytenr;
- split->disk_num_bytes = max(split->block_len,
- em->disk_num_bytes);
+ split->disk_num_bytes = em->disk_num_bytes;
split->offset = em->offset;
split->ram_bytes = em->ram_bytes;
} else {
- split->block_len = 0;
split->block_start = em->block_start;
split->disk_bytenr = em->disk_bytenr;
split->disk_num_bytes = 0;
@@ -930,23 +925,18 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->generation = gen;
if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- split->disk_num_bytes = max(em->block_len,
- em->disk_num_bytes);
+ split->disk_num_bytes = em->disk_num_bytes;
split->offset = em->offset + end - em->start;
split->ram_bytes = em->ram_bytes;
- if (compressed) {
- split->block_len = em->block_len;
- } else {
+ if (!compressed) {
const u64 diff = end - em->start;
- split->block_len = split->len;
split->block_start += diff;
}
} else {
split->disk_num_bytes = 0;
split->offset = 0;
split->ram_bytes = split->len;
- split->block_len = 0;
}
if (extent_map_in_tree(em)) {
@@ -1104,7 +1094,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_pre->disk_num_bytes = split_pre->len;
split_pre->offset = 0;
split_pre->block_start = new_logical;
- split_pre->block_len = split_pre->len;
split_pre->ram_bytes = split_pre->len;
split_pre->flags = flags;
split_pre->generation = em->generation;
@@ -1123,7 +1112,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_mid->disk_num_bytes = split_mid->len;
split_mid->offset = 0;
split_mid->block_start = em->block_start + pre;
- split_mid->block_len = split_mid->len;
split_mid->ram_bytes = split_mid->len;
split_mid->flags = flags;
split_mid->generation = em->generation;
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 5ae3d56b4351..5312bb542af0 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -102,15 +102,6 @@ struct extent_map {
*/
u64 block_start;
- /*
- * The on-disk length for the file extent.
- *
- * For compressed extents it matches btrfs_file_extent_item::disk_num_bytes.
- * For uncompressed extents it matches extent_map::len.
- * For holes and inline extents it's -1 and shouldn't be used.
- */
- u64 block_len;
-
/*
* Generation of the extent map, for merged em it's the highest
* generation of all merged ems.
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 06d23951901c..397df6588ce2 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -1307,11 +1307,9 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
if (compress_type != BTRFS_COMPRESS_NONE) {
extent_map_set_compression(em, compress_type);
em->block_start = bytenr;
- em->block_len = em->disk_num_bytes;
} else {
bytenr += btrfs_file_extent_offset(leaf, fi);
em->block_start = bytenr;
- em->block_len = em->len;
if (type == BTRFS_FILE_EXTENT_PREALLOC)
em->flags |= EXTENT_FLAG_PREALLOC;
}
@@ -1324,11 +1322,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->start = 0;
em->len = fs_info->sectorsize;
em->offset = 0;
- /*
- * Initialize block_len with the same values
- * as in inode.c:btrfs_get_extent().
- */
- em->block_len = (u64)-1;
extent_map_set_compression(em, compress_type);
} else {
btrfs_err(fs_info,
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 707012fc2d43..7033ea619073 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2350,7 +2350,6 @@ static int fill_holes(struct btrfs_trans_handle *trans,
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
- hole_em->block_len = 0;
hole_em->disk_num_bytes = 0;
hole_em->generation = trans->transid;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 066f14c78bc9..00bb64fdf938 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -139,7 +139,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 block_start,
- u64 block_len, u64 disk_num_bytes,
+ u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
int type);
@@ -1210,7 +1210,6 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
em = create_io_em(inode, start,
async_extent->ram_size, /* len */
ins.objectid, /* block_start */
- ins.offset, /* block_len */
ins.offset, /* orig_block_len */
async_extent->ram_size, /* ram_bytes */
async_extent->compress_type,
@@ -1453,7 +1452,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
em = create_io_em(inode, start, ins.offset, /* len */
ins.objectid, /* block_start */
- ins.offset, /* block_len */
ins.offset, /* orig_block_len */
ram_size, /* ram_bytes */
BTRFS_COMPRESS_NONE, /* compress_type */
@@ -2191,7 +2189,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
nocow_args.disk_bytenr, /* block_start */
- nocow_args.num_bytes, /* block_len */
nocow_args.disk_num_bytes, /* orig_block_len */
ram_bytes, BTRFS_COMPRESS_NONE,
&nocow_args.file_extent,
@@ -5027,7 +5024,6 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
- hole_em->block_len = 0;
hole_em->disk_num_bytes = 0;
hole_em->ram_bytes = hole_size;
hole_em->generation = btrfs_get_fs_generation(fs_info);
@@ -6896,7 +6892,6 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
em->start = EXTENT_MAP_HOLE;
em->disk_bytenr = EXTENT_MAP_HOLE;
em->len = (u64)-1;
- em->block_len = (u64)-1;
path = btrfs_alloc_path();
if (!path) {
@@ -7054,7 +7049,6 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
const u64 start,
const u64 len,
const u64 block_start,
- const u64 block_len,
const u64 orig_block_len,
const u64 ram_bytes,
const int type,
@@ -7065,14 +7059,14 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
if (type != BTRFS_ORDERED_NOCOW) {
em = create_io_em(inode, start, len, block_start,
- block_len, orig_block_len, ram_bytes,
+ orig_block_len, ram_bytes,
BTRFS_COMPRESS_NONE, /* compress_type */
file_extent, type);
if (IS_ERR(em))
goto out;
}
ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
- block_start, block_len, 0,
+ block_start, len, 0,
(1 << type) |
(1 << BTRFS_ORDERED_DIRECT),
BTRFS_COMPRESS_NONE);
@@ -7124,7 +7118,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
file_extent.offset = 0;
file_extent.compression = BTRFS_COMPRESS_NONE;
em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
- ins.objectid, ins.offset, ins.offset,
+ ins.objectid, ins.offset,
ins.offset, BTRFS_ORDERED_REGULAR,
&file_extent);
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
@@ -7365,7 +7359,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
u64 len, u64 block_start,
- u64 block_len, u64 disk_num_bytes,
+ u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
int type)
@@ -7387,16 +7381,10 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
switch (type) {
case BTRFS_ORDERED_PREALLOC:
- /* Uncompressed extents. */
- ASSERT(block_len == len);
-
/* We're only referring part of a larger preallocated extent. */
- ASSERT(block_len <= ram_bytes);
+ ASSERT(len <= ram_bytes);
break;
case BTRFS_ORDERED_REGULAR:
- /* Uncompressed extents. */
- ASSERT(block_len == len);
-
/* COW results a new extent matching our file extent size. */
ASSERT(disk_num_bytes == len);
ASSERT(ram_bytes == len);
@@ -7422,7 +7410,6 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
em->start = start;
em->len = len;
- em->block_len = block_len;
em->block_start = block_start;
em->disk_bytenr = file_extent->disk_bytenr;
em->disk_num_bytes = disk_num_bytes;
@@ -7511,7 +7498,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
block_start,
- len, orig_block_len,
+ orig_block_len,
ram_bytes, type,
&file_extent);
btrfs_dec_nocow_writers(bg);
@@ -9654,7 +9641,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->block_start = ins.objectid;
em->disk_bytenr = ins.objectid;
em->offset = 0;
- em->block_len = ins.offset;
em->disk_num_bytes = ins.offset;
em->ram_bytes = ins.offset;
em->flags |= EXTENT_FLAG_PREALLOC;
@@ -10151,12 +10137,12 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
* Bail if the buffer isn't large enough to return the whole
* compressed extent.
*/
- if (em->block_len > count) {
+ if (em->disk_num_bytes > count) {
ret = -ENOBUFS;
goto out_em;
}
- disk_io_size = em->block_len;
- count = em->block_len;
+ disk_io_size = em->disk_num_bytes;
+ count = em->disk_num_bytes;
encoded->unencoded_len = em->ram_bytes;
encoded->unencoded_offset = iocb->ki_pos - (em->start - em->offset);
ret = btrfs_encoded_io_compression_from_extent(fs_info,
@@ -10404,7 +10390,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
file_extent.compression = compression;
em = create_io_em(inode, start, num_bytes,
ins.objectid,
- ins.offset, ins.offset, ram_bytes, compression,
+ ins.offset, ram_bytes, compression,
&file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
ret = PTR_ERR(em);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 21061a0b2e7c..68fe52ab445d 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2912,7 +2912,6 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
em->start = start;
em->len = end + 1 - start;
- em->block_len = em->len;
em->block_start = block_start;
em->disk_bytenr = block_start;
em->disk_num_bytes = em->len;
diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
index 65c6921ff4a2..0dd270d6c506 100644
--- a/fs/btrfs/tests/extent-map-tests.c
+++ b/fs/btrfs/tests/extent-map-tests.c
@@ -28,9 +28,10 @@ static int free_extent_map_tree(struct btrfs_inode *inode)
if (refcount_read(&em->refs) != 1) {
ret = -EINVAL;
test_err(
-"em leak: em (start %llu len %llu block_start %llu block_len %llu) refs %d",
+"em leak: em (start %llu len %llu block_start %llu disk_num_bytes %llu offset %llu) refs %d",
em->start, em->len, em->block_start,
- em->block_len, refcount_read(&em->refs));
+ em->disk_num_bytes, em->offset,
+ refcount_read(&em->refs));
refcount_set(&em->refs, 1);
}
@@ -77,7 +78,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = 0;
em->len = SZ_16K;
em->block_start = 0;
- em->block_len = SZ_16K;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -101,7 +101,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_16K;
em->len = SZ_4K;
em->block_start = SZ_32K; /* avoid merging */
- em->block_len = SZ_4K;
em->disk_bytenr = SZ_32K; /* avoid merging */
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -125,7 +124,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = start;
em->len = len;
em->block_start = start;
- em->block_len = len;
em->disk_bytenr = start;
em->disk_num_bytes = len;
em->ram_bytes = len;
@@ -143,11 +141,11 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
goto out;
}
if (em->start != 0 || extent_map_end(em) != SZ_16K ||
- em->block_start != 0 || em->block_len != SZ_16K) {
+ em->block_start != 0 || em->disk_num_bytes != SZ_16K) {
test_err(
-"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
+"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu",
start, start + len, ret, em->start, em->len,
- em->block_start, em->block_len);
+ em->block_start, em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -182,7 +180,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = 0;
em->len = SZ_1K;
em->block_start = EXTENT_MAP_INLINE;
- em->block_len = (u64)-1;
em->disk_bytenr = EXTENT_MAP_INLINE;
em->disk_num_bytes = 0;
em->ram_bytes = SZ_1K;
@@ -206,7 +203,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
- em->block_len = SZ_4K;
em->disk_bytenr = SZ_4K;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -230,7 +226,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = 0;
em->len = SZ_1K;
em->block_start = EXTENT_MAP_INLINE;
- em->block_len = (u64)-1;
em->disk_bytenr = EXTENT_MAP_INLINE;
em->disk_num_bytes = 0;
em->ram_bytes = SZ_1K;
@@ -247,11 +242,10 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
goto out;
}
if (em->start != 0 || extent_map_end(em) != SZ_1K ||
- em->block_start != EXTENT_MAP_INLINE || em->block_len != (u64)-1) {
+ em->block_start != EXTENT_MAP_INLINE) {
test_err(
-"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
- ret, em->start, em->len, em->block_start,
- em->block_len);
+"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu",
+ ret, em->start, em->len, em->block_start);
ret = -EINVAL;
}
free_extent_map(em);
@@ -282,7 +276,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
em->start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_4K;
- em->block_len = SZ_4K;
em->disk_bytenr = SZ_4K;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -306,7 +299,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
em->start = 0;
em->len = SZ_16K;
em->block_start = 0;
- em->block_len = SZ_16K;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -329,11 +321,11 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
* em->start.
*/
if (start < em->start || start + len > extent_map_end(em) ||
- em->start != em->block_start || em->len != em->block_len) {
+ em->start != em->block_start) {
test_err(
"case3 [%llu %llu): ret %d em (start %llu len %llu block_start %llu block_len %llu)",
start, start + len, ret, em->start, em->len,
- em->block_start, em->block_len);
+ em->block_start, em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -395,7 +387,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
em->start = 0;
em->len = SZ_8K;
em->block_start = 0;
- em->block_len = SZ_8K;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_8K;
em->ram_bytes = SZ_8K;
@@ -419,7 +410,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
em->start = SZ_8K;
em->len = 24 * SZ_1K;
em->block_start = SZ_16K; /* avoid merging */
- em->block_len = 24 * SZ_1K;
em->disk_bytenr = SZ_16K; /* avoid merging */
em->disk_num_bytes = 24 * SZ_1K;
em->ram_bytes = 24 * SZ_1K;
@@ -442,7 +432,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
em->start = 0;
em->len = SZ_32K;
em->block_start = 0;
- em->block_len = SZ_32K;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_32K;
em->ram_bytes = SZ_32K;
@@ -462,9 +451,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
}
if (start < em->start || start + len > extent_map_end(em)) {
test_err(
-"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu block_start %llu block_len %llu)",
+"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu)",
start, start + len, ret, em->start, em->len, em->block_start,
- em->block_len);
+ em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -529,7 +518,6 @@ static int add_compressed_extent(struct btrfs_inode *inode,
em->start = start;
em->len = len;
em->block_start = block_start;
- em->block_len = SZ_4K;
em->disk_bytenr = block_start;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = len;
@@ -753,7 +741,6 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_4K;
em->len = SZ_4K;
em->block_start = SZ_16K;
- em->block_len = SZ_16K;
em->disk_bytenr = SZ_16K;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -809,7 +796,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = 0;
em->len = SZ_16K;
em->block_start = 0;
- em->block_len = SZ_4K;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_16K;
@@ -834,7 +820,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_32K;
em->len = SZ_16K;
em->block_start = SZ_32K;
- em->block_len = SZ_16K;
em->disk_bytenr = SZ_32K;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index d6a3151d6c37..1d04f0cb6f53 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4651,7 +4651,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
/* If we're compressed we have to save the entire range of csums. */
if (extent_map_is_compressed(em)) {
csum_offset = 0;
- csum_len = max(em->block_len, em->disk_num_bytes);
+ csum_len = em->disk_num_bytes;
} else {
csum_offset = mod_start - em->start;
csum_len = mod_len;
@@ -4701,7 +4701,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
else
btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_REG);
- block_len = max(em->block_len, em->disk_num_bytes);
+ block_len = em->disk_num_bytes;
compress_type = extent_map_compression(em);
if (compress_type != BTRFS_COMPRESS_NONE) {
btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start);
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index cbac7cd11995..a1804239812c 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -292,7 +292,6 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__field( u64, start )
__field( u64, len )
__field( u64, block_start )
- __field( u64, block_len )
__field( u32, flags )
__field( int, refs )
),
@@ -303,19 +302,17 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__entry->start = map->start;
__entry->len = map->len;
__entry->block_start = map->block_start;
- __entry->block_len = map->block_len;
__entry->flags = map->flags;
__entry->refs = refcount_read(&map->refs);
),
TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu len=%llu "
- "block_start=%llu(%s) block_len=%llu flags=%s refs=%u",
+ "block_start=%llu(%s) flags=%s refs=%u",
show_root_type(__entry->root_objectid),
__entry->ino,
__entry->start,
__entry->len,
show_map_type(__entry->block_start),
- __entry->block_len,
show_map_flags(__entry->flags),
__entry->refs)
);
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 07/11] btrfs: remove extent_map::block_start member
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (5 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 06/11] btrfs: remove extent_map::block_len member Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 17:56 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 08/11] btrfs: cleanup duplicated parameters related to can_nocow_file_extent_args Qu Wenruo
` (5 subsequent siblings)
12 siblings, 1 reply; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
The member extent_map::block_start can be calculated from
extent_map::disk_bytenr + extent_map::offset for regular extents.
And otherwise just extent_map::disk_bytenr.
And this is already validated by the validate_extent_map().
Now we can remove the member.
However there is a special case in btrfs_create_dio_extent() where we
for NOCOW/PREALLOC ordered extents can not directly use the resulted
btrfs_file_extent, as btrfs_split_ordered_extent() can not handle them
yet.
So for that call site, we pass file_extent->disk_bytenr +
file_extent->num_bytes as disk_bytenr for the ordered extent, and 0 for
offset.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/compression.c | 3 +-
fs/btrfs/defrag.c | 9 ++-
fs/btrfs/extent_io.c | 10 ++--
fs/btrfs/extent_map.c | 55 +++++------------
fs/btrfs/extent_map.h | 22 ++++---
fs/btrfs/file-item.c | 4 --
fs/btrfs/file.c | 11 ++--
fs/btrfs/inode.c | 80 ++++++++++++++-----------
fs/btrfs/relocation.c | 1 -
fs/btrfs/tests/extent-map-tests.c | 48 ++++++---------
fs/btrfs/tests/inode-tests.c | 99 ++++++++++++++++---------------
fs/btrfs/tree-log.c | 17 +++---
fs/btrfs/zoned.c | 4 +-
include/trace/events/btrfs.h | 11 +---
14 files changed, 168 insertions(+), 206 deletions(-)
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index cd88432e7072..07b31d1c0926 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -507,7 +507,8 @@ static noinline int add_ra_bio_pages(struct inode *inode,
*/
if (!em || cur < em->start ||
(cur + fs_info->sectorsize > extent_map_end(em)) ||
- (em->block_start >> SECTOR_SHIFT) != orig_bio->bi_iter.bi_sector) {
+ (extent_map_block_start(em) >> SECTOR_SHIFT) !=
+ orig_bio->bi_iter.bi_sector) {
free_extent_map(em);
unlock_extent(tree, cur, page_end, NULL);
unlock_page(page);
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index 025e7f853a68..6fb94e897fc5 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -707,7 +707,6 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
*/
if (key.offset > start) {
em->start = start;
- em->block_start = EXTENT_MAP_HOLE;
em->disk_bytenr = EXTENT_MAP_HOLE;
em->disk_num_bytes = 0;
em->ram_bytes = 0;
@@ -828,7 +827,7 @@ static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em,
*/
next = defrag_lookup_extent(inode, em->start + em->len, newer_than, locked);
/* No more em or hole */
- if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
+ if (!next || next->disk_bytenr >= EXTENT_MAP_LAST_BYTE)
goto out;
if (next->flags & EXTENT_FLAG_PREALLOC)
goto out;
@@ -995,12 +994,12 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
* This is for users who want to convert inline extents to
* regular ones through max_inline= mount option.
*/
- if (em->block_start == EXTENT_MAP_INLINE &&
+ if (em->disk_bytenr == EXTENT_MAP_INLINE &&
em->len <= inode->root->fs_info->max_inline)
goto next;
/* Skip holes and preallocated extents. */
- if (em->block_start == EXTENT_MAP_HOLE ||
+ if (em->disk_bytenr == EXTENT_MAP_HOLE ||
(em->flags & EXTENT_FLAG_PREALLOC))
goto next;
@@ -1065,7 +1064,7 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
* So if an inline extent passed all above checks, just add it
* for defrag, and be converted to regular extents.
*/
- if (em->block_start == EXTENT_MAP_INLINE)
+ if (em->disk_bytenr == EXTENT_MAP_INLINE)
goto add;
next_mergeable = defrag_check_next_extent(&inode->vfs_inode, em,
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index bf50301ee528..063d7954c9ed 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1083,10 +1083,10 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
iosize = min(extent_map_end(em) - cur, end - cur + 1);
iosize = ALIGN(iosize, blocksize);
if (compress_type != BTRFS_COMPRESS_NONE)
- disk_bytenr = em->block_start;
+ disk_bytenr = em->disk_bytenr;
else
- disk_bytenr = em->block_start + extent_offset;
- block_start = em->block_start;
+ disk_bytenr = extent_map_block_start(em) + extent_offset;
+ block_start = extent_map_block_start(em);
if (em->flags & EXTENT_FLAG_PREALLOC)
block_start = EXTENT_MAP_HOLE;
@@ -1405,8 +1405,8 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
ASSERT(IS_ALIGNED(em->start, fs_info->sectorsize));
ASSERT(IS_ALIGNED(em->len, fs_info->sectorsize));
- block_start = em->block_start;
- disk_bytenr = em->block_start + extent_offset;
+ block_start = extent_map_block_start(em);
+ disk_bytenr = extent_map_block_start(em) + extent_offset;
ASSERT(!extent_map_is_compressed(em));
ASSERT(block_start != EXTENT_MAP_HOLE);
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 0c100fe47c43..38a1f07581b0 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -192,9 +192,10 @@ static inline u64 extent_map_block_len(const struct extent_map *em)
static inline u64 extent_map_block_end(const struct extent_map *em)
{
- if (em->block_start + extent_map_block_len(em) < em->block_start)
+ if (extent_map_block_start(em) + extent_map_block_len(em) <
+ extent_map_block_start(em))
return (u64)-1;
- return em->block_start + extent_map_block_len(em);
+ return extent_map_block_start(em) + extent_map_block_len(em);
}
static bool can_merge_extent_map(const struct extent_map *em)
@@ -229,11 +230,11 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
if (prev->flags != next->flags)
return false;
- if (next->block_start < EXTENT_MAP_LAST_BYTE - 1)
- return next->block_start == extent_map_block_end(prev);
+ if (next->disk_bytenr < EXTENT_MAP_LAST_BYTE - 1)
+ return extent_map_block_start(next) == extent_map_block_end(prev);
/* HOLES and INLINE extents. */
- return next->block_start == prev->block_start;
+ return next->disk_bytenr == prev->disk_bytenr;
}
/*
@@ -295,10 +296,9 @@ static void dump_extent_map(struct btrfs_fs_info *fs_info,
{
if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
return;
- btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu block_start=%llu flags=0x%x\n",
+ btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu flags=0x%x\n",
prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
- em->ram_bytes, em->offset, em->block_start,
- em->flags);
+ em->ram_bytes, em->offset, em->flags);
ASSERT(0);
}
@@ -316,15 +316,6 @@ static void validate_extent_map(struct btrfs_fs_info *fs_info,
if (em->offset + em->len > em->disk_num_bytes &&
!extent_map_is_compressed(em))
dump_extent_map(fs_info, "disk_num_bytes too small", em);
-
- if (extent_map_is_compressed(em)) {
- if (em->block_start != em->disk_bytenr)
- dump_extent_map(fs_info,
- "mismatch block_start/disk_bytenr/offset", em);
- } else if (em->block_start != em->disk_bytenr + em->offset) {
- dump_extent_map(fs_info,
- "mismatch block_start/disk_bytenr/offset", em);
- }
} else if (em->offset) {
dump_extent_map(fs_info,
"non-zero offset for hole/inline", em);
@@ -359,7 +350,6 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
if (rb && can_merge_extent_map(merge) && mergeable_maps(merge, em)) {
em->start = merge->start;
em->len += merge->len;
- em->block_start = merge->block_start;
em->generation = max(em->generation, merge->generation);
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
@@ -669,11 +659,9 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
start_diff = start - em->start;
em->start = start;
em->len = end - start;
- if (em->block_start < EXTENT_MAP_LAST_BYTE &&
- !extent_map_is_compressed(em)) {
- em->block_start += start_diff;
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE &&
+ !extent_map_is_compressed(em))
em->offset += start_diff;
- }
return add_extent_mapping(inode, em, 0);
}
@@ -708,7 +696,7 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode,
* Tree-checker should have rejected any inline extent with non-zero
* file offset. Here just do a sanity check.
*/
- if (em->block_start == EXTENT_MAP_INLINE)
+ if (em->disk_bytenr == EXTENT_MAP_INLINE)
ASSERT(em->start == 0);
ret = add_extent_mapping(inode, em, 0);
@@ -842,7 +830,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
u64 gen;
unsigned long flags;
bool modified;
- bool compressed;
if (em_end < end) {
next_em = next_extent_map(em);
@@ -876,7 +863,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
goto remove_em;
gen = em->generation;
- compressed = extent_map_is_compressed(em);
if (em->start < start) {
if (!split) {
@@ -888,15 +874,12 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
split->start = em->start;
split->len = start - em->start;
- if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- split->block_start = em->block_start;
-
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
split->disk_bytenr = em->disk_bytenr;
split->disk_num_bytes = em->disk_num_bytes;
split->offset = em->offset;
split->ram_bytes = em->ram_bytes;
} else {
- split->block_start = em->block_start;
split->disk_bytenr = em->disk_bytenr;
split->disk_num_bytes = 0;
split->offset = 0;
@@ -919,20 +902,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
}
split->start = end;
split->len = em_end - end;
- split->block_start = em->block_start;
split->disk_bytenr = em->disk_bytenr;
split->flags = flags;
split->generation = gen;
- if (em->block_start < EXTENT_MAP_LAST_BYTE) {
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
split->disk_num_bytes = em->disk_num_bytes;
split->offset = em->offset + end - em->start;
split->ram_bytes = em->ram_bytes;
- if (!compressed) {
- const u64 diff = end - em->start;
-
- split->block_start += diff;
- }
} else {
split->disk_num_bytes = 0;
split->offset = 0;
@@ -1079,7 +1056,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
ASSERT(em->len == len);
ASSERT(!extent_map_is_compressed(em));
- ASSERT(em->block_start < EXTENT_MAP_LAST_BYTE);
+ ASSERT(em->disk_bytenr < EXTENT_MAP_LAST_BYTE);
ASSERT(em->flags & EXTENT_FLAG_PINNED);
ASSERT(!(em->flags & EXTENT_FLAG_LOGGING));
ASSERT(!list_empty(&em->list));
@@ -1093,7 +1070,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
split_pre->disk_bytenr = new_logical;
split_pre->disk_num_bytes = split_pre->len;
split_pre->offset = 0;
- split_pre->block_start = new_logical;
split_pre->ram_bytes = split_pre->len;
split_pre->flags = flags;
split_pre->generation = em->generation;
@@ -1108,10 +1084,9 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
/* Insert the middle extent_map. */
split_mid->start = em->start + pre;
split_mid->len = em->len - pre;
- split_mid->disk_bytenr = em->block_start + pre;
+ split_mid->disk_bytenr = extent_map_block_start(em) + pre;
split_mid->disk_num_bytes = split_mid->len;
split_mid->offset = 0;
- split_mid->block_start = em->block_start + pre;
split_mid->ram_bytes = split_mid->len;
split_mid->flags = flags;
split_mid->generation = em->generation;
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 5312bb542af0..2bcf7149b44c 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -90,18 +90,6 @@ struct extent_map {
*/
u64 ram_bytes;
- /*
- * The on-disk logical bytenr for the file extent.
- *
- * For compressed extents it matches btrfs_file_extent_item::disk_bytenr.
- * For uncompressed extents it matches
- * btrfs_file_extent_item::disk_bytenr + btrfs_file_extent_item::offset
- *
- * For holes it is EXTENT_MAP_HOLE and for inline extents it is
- * EXTENT_MAP_INLINE.
- */
- u64 block_start;
-
/*
* Generation of the extent map, for merged em it's the highest
* generation of all merged ems.
@@ -162,6 +150,16 @@ static inline int extent_map_in_tree(const struct extent_map *em)
return !RB_EMPTY_NODE(&em->rb_node);
}
+static inline u64 extent_map_block_start(const struct extent_map *em)
+{
+ if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
+ if (extent_map_is_compressed(em))
+ return em->disk_bytenr;
+ return em->disk_bytenr + em->offset;
+ }
+ return em->disk_bytenr;
+}
+
static inline u64 extent_map_end(const struct extent_map *em)
{
if (em->start + em->len < em->start)
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 397df6588ce2..55703c833f3d 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -1295,7 +1295,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->len = btrfs_file_extent_end(path) - extent_start;
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
if (bytenr == 0) {
- em->block_start = EXTENT_MAP_HOLE;
em->disk_bytenr = EXTENT_MAP_HOLE;
em->disk_num_bytes = 0;
em->offset = 0;
@@ -1306,10 +1305,8 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
em->offset = btrfs_file_extent_offset(leaf, fi);
if (compress_type != BTRFS_COMPRESS_NONE) {
extent_map_set_compression(em, compress_type);
- em->block_start = bytenr;
} else {
bytenr += btrfs_file_extent_offset(leaf, fi);
- em->block_start = bytenr;
if (type == BTRFS_FILE_EXTENT_PREALLOC)
em->flags |= EXTENT_FLAG_PREALLOC;
}
@@ -1317,7 +1314,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
/* Tree-checker has ensured this. */
ASSERT(extent_start == 0);
- em->block_start = EXTENT_MAP_INLINE;
em->disk_bytenr = EXTENT_MAP_INLINE;
em->start = 0;
em->len = fs_info->sectorsize;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 7033ea619073..f0cb7b29cab2 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2348,7 +2348,6 @@ static int fill_holes(struct btrfs_trans_handle *trans,
hole_em->len = end - offset;
hole_em->ram_bytes = hole_em->len;
- hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
hole_em->disk_num_bytes = 0;
hole_em->generation = trans->transid;
@@ -2381,7 +2380,7 @@ static int find_first_non_hole(struct btrfs_inode *inode, u64 *start, u64 *len)
return PTR_ERR(em);
/* Hole or vacuum extent(only exists in no-hole mode) */
- if (em->block_start == EXTENT_MAP_HOLE) {
+ if (em->disk_bytenr == EXTENT_MAP_HOLE) {
ret = 1;
*len = em->start + em->len > *start + *len ?
0 : *start + *len - em->start - em->len;
@@ -3038,7 +3037,7 @@ static int btrfs_zero_range_check_range_boundary(struct btrfs_inode *inode,
if (IS_ERR(em))
return PTR_ERR(em);
- if (em->block_start == EXTENT_MAP_HOLE)
+ if (em->disk_bytenr == EXTENT_MAP_HOLE)
ret = RANGE_BOUNDARY_HOLE;
else if (em->flags & EXTENT_FLAG_PREALLOC)
ret = RANGE_BOUNDARY_PREALLOC_EXTENT;
@@ -3102,7 +3101,7 @@ static int btrfs_zero_range(struct inode *inode,
ASSERT(IS_ALIGNED(alloc_start, sectorsize));
len = offset + len - alloc_start;
offset = alloc_start;
- alloc_hint = em->block_start + em->len;
+ alloc_hint = extent_map_block_start(em) + em->len;
}
free_extent_map(em);
@@ -3120,7 +3119,7 @@ static int btrfs_zero_range(struct inode *inode,
mode);
goto out;
}
- if (len < sectorsize && em->block_start != EXTENT_MAP_HOLE) {
+ if (len < sectorsize && em->disk_bytenr != EXTENT_MAP_HOLE) {
free_extent_map(em);
ret = btrfs_truncate_block(BTRFS_I(inode), offset, len,
0);
@@ -3333,7 +3332,7 @@ static long btrfs_fallocate(struct file *file, int mode,
last_byte = min(extent_map_end(em), alloc_end);
actual_end = min_t(u64, extent_map_end(em), offset + len);
last_byte = ALIGN(last_byte, blocksize);
- if (em->block_start == EXTENT_MAP_HOLE ||
+ if (em->disk_bytenr == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size &&
!(em->flags & EXTENT_FLAG_PREALLOC))) {
const u64 range_len = last_byte - cur_offset;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 00bb64fdf938..1b78769d1e41 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -138,7 +138,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
u64 end, struct writeback_control *wbc,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 block_start,
+ u64 len,
u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
@@ -1209,7 +1209,6 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
em = create_io_em(inode, start,
async_extent->ram_size, /* len */
- ins.objectid, /* block_start */
ins.offset, /* orig_block_len */
async_extent->ram_size, /* ram_bytes */
async_extent->compress_type,
@@ -1287,15 +1286,15 @@ static u64 get_extent_allocation_hint(struct btrfs_inode *inode, u64 start,
* first block in this inode and use that as a hint. If that
* block is also bogus then just don't worry about it.
*/
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
free_extent_map(em);
em = search_extent_mapping(em_tree, 0, 0);
- if (em && em->block_start < EXTENT_MAP_LAST_BYTE)
- alloc_hint = em->block_start;
+ if (em && em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
+ alloc_hint = extent_map_block_start(em);
if (em)
free_extent_map(em);
} else {
- alloc_hint = em->block_start;
+ alloc_hint = extent_map_block_start(em);
free_extent_map(em);
}
}
@@ -1451,7 +1450,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
&cached);
em = create_io_em(inode, start, ins.offset, /* len */
- ins.objectid, /* block_start */
ins.offset, /* orig_block_len */
ram_size, /* ram_bytes */
BTRFS_COMPRESS_NONE, /* compress_type */
@@ -2188,7 +2186,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
struct extent_map *em;
em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
- nocow_args.disk_bytenr, /* block_start */
nocow_args.disk_num_bytes, /* orig_block_len */
ram_bytes, BTRFS_COMPRESS_NONE,
&nocow_args.file_extent,
@@ -2703,7 +2700,7 @@ static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
if (IS_ERR(em))
return PTR_ERR(em);
- if (em->block_start != EXTENT_MAP_HOLE)
+ if (extent_map_block_start(em) != EXTENT_MAP_HOLE)
goto next;
em_len = em->len;
@@ -5022,7 +5019,6 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
hole_em->start = cur_offset;
hole_em->len = hole_size;
- hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
hole_em->disk_num_bytes = 0;
hole_em->ram_bytes = hole_size;
@@ -6879,7 +6875,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
if (em) {
if (em->start > start || em->start + em->len <= start)
free_extent_map(em);
- else if (em->block_start == EXTENT_MAP_INLINE && page)
+ else if (em->disk_bytenr == EXTENT_MAP_INLINE && page)
free_extent_map(em);
else
goto out;
@@ -6982,7 +6978,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
/* New extent overlaps with existing one */
em->start = start;
em->len = found_key.offset - start;
- em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
goto insert;
}
@@ -7006,7 +7002,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
*
* Other members are not utilized for inline extents.
*/
- ASSERT(em->block_start == EXTENT_MAP_INLINE);
+ ASSERT(em->disk_bytenr == EXTENT_MAP_INLINE);
ASSERT(em->len == fs_info->sectorsize);
ret = read_inline_extent(inode, path, page);
@@ -7017,7 +7013,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
not_found:
em->start = start;
em->len = len;
- em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
insert:
ret = 0;
btrfs_release_path(path);
@@ -7048,7 +7044,6 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_dio_data *dio_data,
const u64 start,
const u64 len,
- const u64 block_start,
const u64 orig_block_len,
const u64 ram_bytes,
const int type,
@@ -7058,15 +7053,34 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_ordered_extent *ordered;
if (type != BTRFS_ORDERED_NOCOW) {
- em = create_io_em(inode, start, len, block_start,
+ em = create_io_em(inode, start, len,
orig_block_len, ram_bytes,
BTRFS_COMPRESS_NONE, /* compress_type */
file_extent, type);
if (IS_ERR(em))
goto out;
}
+
+ /*
+ * For regular writes, file_extent->offset is always 0,
+ * thus we really only need file_extent->disk_bytenr, every other length
+ * (disk_num_bytes/ram_bytes) should match @len and
+ * file_extent->num_bytes.
+ *
+ * For NOCOW, we don't really care about the numbers except
+ * @start and @len, as we won't insert a file extent
+ * item at all.
+ *
+ * For PREALLOC, we do not use ordered extent members, but
+ * btrfs_mark_extent_written() handles everything.
+ *
+ * So here we always passing 0 as offset for the ordered extent,
+ * or btrfs_split_ordered_extent() can not handle it correctly.
+ */
ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
- block_start, len, 0,
+ file_extent->disk_bytenr +
+ file_extent->offset,
+ len, 0,
(1 << type) |
(1 << BTRFS_ORDERED_DIRECT),
BTRFS_COMPRESS_NONE);
@@ -7118,7 +7132,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
file_extent.offset = 0;
file_extent.compression = BTRFS_COMPRESS_NONE;
em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
- ins.objectid, ins.offset,
+ ins.offset,
ins.offset, BTRFS_ORDERED_REGULAR,
&file_extent);
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
@@ -7358,7 +7372,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 block_start,
+ u64 len,
u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
@@ -7410,7 +7424,6 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
em->start = start;
em->len = len;
- em->block_start = block_start;
em->disk_bytenr = file_extent->disk_bytenr;
em->disk_num_bytes = disk_num_bytes;
em->ram_bytes = ram_bytes;
@@ -7461,13 +7474,13 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
*/
if ((em->flags & EXTENT_FLAG_PREALLOC) ||
((BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) &&
- em->block_start != EXTENT_MAP_HOLE)) {
+ em->disk_bytenr != EXTENT_MAP_HOLE)) {
if (em->flags & EXTENT_FLAG_PREALLOC)
type = BTRFS_ORDERED_PREALLOC;
else
type = BTRFS_ORDERED_NOCOW;
len = min(len, em->len - (start - em->start));
- block_start = em->block_start + (start - em->start);
+ block_start = extent_map_block_start(em) + (start - em->start);
if (can_nocow_extent(inode, start, &len,
&orig_block_len, &ram_bytes,
@@ -7497,7 +7510,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
space_reserved = true;
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
- block_start,
orig_block_len,
ram_bytes, type,
&file_extent);
@@ -7700,7 +7712,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
* the generic code.
*/
if (extent_map_is_compressed(em) ||
- em->block_start == EXTENT_MAP_INLINE) {
+ em->disk_bytenr == EXTENT_MAP_INLINE) {
free_extent_map(em);
/*
* If we are in a NOWAIT context, return -EAGAIN in order to
@@ -7794,12 +7806,12 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
* We trim the extents (and move the addr) even though iomap code does
* that, since we have locked only the parts we are performing I/O in.
*/
- if ((em->block_start == EXTENT_MAP_HOLE) ||
+ if ((em->disk_bytenr == EXTENT_MAP_HOLE) ||
((em->flags & EXTENT_FLAG_PREALLOC) && !write)) {
iomap->addr = IOMAP_NULL_ADDR;
iomap->type = IOMAP_HOLE;
} else {
- iomap->addr = em->block_start + (start - em->start);
+ iomap->addr = extent_map_block_start(em) + (start - em->start);
iomap->type = IOMAP_MAPPED;
}
iomap->offset = start;
@@ -9638,7 +9650,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->start = cur_offset;
em->len = ins.offset;
- em->block_start = ins.objectid;
em->disk_bytenr = ins.objectid;
em->offset = 0;
em->disk_num_bytes = ins.offset;
@@ -10104,7 +10115,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
goto out_unlock_extent;
}
- if (em->block_start == EXTENT_MAP_INLINE) {
+ if (em->disk_bytenr == EXTENT_MAP_INLINE) {
u64 extent_start = em->start;
/*
@@ -10125,14 +10136,14 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
*/
encoded->len = min_t(u64, extent_map_end(em),
inode->vfs_inode.i_size) - iocb->ki_pos;
- if (em->block_start == EXTENT_MAP_HOLE ||
+ if (em->disk_bytenr == EXTENT_MAP_HOLE ||
(em->flags & EXTENT_FLAG_PREALLOC)) {
disk_bytenr = EXTENT_MAP_HOLE;
count = min_t(u64, count, encoded->len);
encoded->len = count;
encoded->unencoded_len = count;
} else if (extent_map_is_compressed(em)) {
- disk_bytenr = em->block_start;
+ disk_bytenr = em->disk_bytenr;
/*
* Bail if the buffer isn't large enough to return the whole
* compressed extent.
@@ -10151,7 +10162,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
goto out_em;
encoded->compression = ret;
} else {
- disk_bytenr = em->block_start + (start - em->start);
+ disk_bytenr = extent_map_block_start(em) + (start - em->start);
if (encoded->len > count)
encoded->len = count;
/*
@@ -10389,7 +10400,6 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
file_extent.offset = encoded->unencoded_offset;
file_extent.compression = compression;
em = create_io_em(inode, start, num_bytes,
- ins.objectid,
ins.offset, ram_bytes, compression,
&file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
@@ -10693,12 +10703,12 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
goto out;
}
- if (em->block_start == EXTENT_MAP_HOLE) {
+ if (em->disk_bytenr == EXTENT_MAP_HOLE) {
btrfs_warn(fs_info, "swapfile must not have holes");
ret = -EINVAL;
goto out;
}
- if (em->block_start == EXTENT_MAP_INLINE) {
+ if (em->disk_bytenr == EXTENT_MAP_INLINE) {
/*
* It's unlikely we'll ever actually find ourselves
* here, as a file small enough to fit inline won't be
@@ -10716,7 +10726,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
goto out;
}
- logical_block_start = em->block_start + (start - em->start);
+ logical_block_start = extent_map_block_start(em) + (start - em->start);
len = min(len, em->len - (start - em->start));
free_extent_map(em);
em = NULL;
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 68fe52ab445d..bcb665613e78 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2912,7 +2912,6 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
em->start = start;
em->len = end + 1 - start;
- em->block_start = block_start;
em->disk_bytenr = block_start;
em->disk_num_bytes = em->len;
em->ram_bytes = em->len;
diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
index 0dd270d6c506..ebec4ab361b8 100644
--- a/fs/btrfs/tests/extent-map-tests.c
+++ b/fs/btrfs/tests/extent-map-tests.c
@@ -28,8 +28,8 @@ static int free_extent_map_tree(struct btrfs_inode *inode)
if (refcount_read(&em->refs) != 1) {
ret = -EINVAL;
test_err(
-"em leak: em (start %llu len %llu block_start %llu disk_num_bytes %llu offset %llu) refs %d",
- em->start, em->len, em->block_start,
+"em leak: em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu offset %llu) refs %d",
+ em->start, em->len, em->disk_bytenr,
em->disk_num_bytes, em->offset,
refcount_read(&em->refs));
@@ -77,7 +77,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 16K) */
em->start = 0;
em->len = SZ_16K;
- em->block_start = 0;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -100,7 +99,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_16K;
em->len = SZ_4K;
- em->block_start = SZ_32K; /* avoid merging */
em->disk_bytenr = SZ_32K; /* avoid merging */
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -123,7 +121,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 8K), should return [0, 16K) instead. */
em->start = start;
em->len = len;
- em->block_start = start;
em->disk_bytenr = start;
em->disk_num_bytes = len;
em->ram_bytes = len;
@@ -141,11 +138,11 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
goto out;
}
if (em->start != 0 || extent_map_end(em) != SZ_16K ||
- em->block_start != 0 || em->disk_num_bytes != SZ_16K) {
+ em->disk_bytenr != 0 || em->disk_num_bytes != SZ_16K) {
test_err(
-"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu",
+"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu",
start, start + len, ret, em->start, em->len,
- em->block_start, em->disk_num_bytes);
+ em->disk_bytenr, em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -179,7 +176,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 1K) */
em->start = 0;
em->len = SZ_1K;
- em->block_start = EXTENT_MAP_INLINE;
em->disk_bytenr = EXTENT_MAP_INLINE;
em->disk_num_bytes = 0;
em->ram_bytes = SZ_1K;
@@ -202,7 +198,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_4K;
em->len = SZ_4K;
- em->block_start = SZ_4K;
em->disk_bytenr = SZ_4K;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -225,7 +220,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* Add [0, 1K) */
em->start = 0;
em->len = SZ_1K;
- em->block_start = EXTENT_MAP_INLINE;
em->disk_bytenr = EXTENT_MAP_INLINE;
em->disk_num_bytes = 0;
em->ram_bytes = SZ_1K;
@@ -242,10 +236,10 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
goto out;
}
if (em->start != 0 || extent_map_end(em) != SZ_1K ||
- em->block_start != EXTENT_MAP_INLINE) {
+ em->disk_bytenr != EXTENT_MAP_INLINE) {
test_err(
-"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu",
- ret, em->start, em->len, em->block_start);
+"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu",
+ ret, em->start, em->len, em->disk_bytenr);
ret = -EINVAL;
}
free_extent_map(em);
@@ -275,7 +269,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
/* Add [4K, 8K) */
em->start = SZ_4K;
em->len = SZ_4K;
- em->block_start = SZ_4K;
em->disk_bytenr = SZ_4K;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_4K;
@@ -298,7 +291,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
/* Add [0, 16K) */
em->start = 0;
em->len = SZ_16K;
- em->block_start = 0;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -321,11 +313,11 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
* em->start.
*/
if (start < em->start || start + len > extent_map_end(em) ||
- em->start != em->block_start) {
+ em->start != extent_map_block_start(em)) {
test_err(
-"case3 [%llu %llu): ret %d em (start %llu len %llu block_start %llu block_len %llu)",
+"case3 [%llu %llu): ret %d em (start %llu len %llu disk_bytenr %llu block_len %llu)",
start, start + len, ret, em->start, em->len,
- em->block_start, em->disk_num_bytes);
+ em->disk_bytenr, em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -386,7 +378,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
/* Add [0K, 8K) */
em->start = 0;
em->len = SZ_8K;
- em->block_start = 0;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_8K;
em->ram_bytes = SZ_8K;
@@ -409,7 +400,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
/* Add [8K, 32K) */
em->start = SZ_8K;
em->len = 24 * SZ_1K;
- em->block_start = SZ_16K; /* avoid merging */
em->disk_bytenr = SZ_16K; /* avoid merging */
em->disk_num_bytes = 24 * SZ_1K;
em->ram_bytes = 24 * SZ_1K;
@@ -431,7 +421,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
/* Add [0K, 32K) */
em->start = 0;
em->len = SZ_32K;
- em->block_start = 0;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_32K;
em->ram_bytes = SZ_32K;
@@ -451,9 +440,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
}
if (start < em->start || start + len > extent_map_end(em)) {
test_err(
-"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu)",
- start, start + len, ret, em->start, em->len, em->block_start,
- em->disk_num_bytes);
+"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu)",
+ start, start + len, ret, em->start, em->len,
+ em->disk_bytenr, em->disk_num_bytes);
ret = -EINVAL;
}
free_extent_map(em);
@@ -517,7 +506,6 @@ static int add_compressed_extent(struct btrfs_inode *inode,
em->start = start;
em->len = len;
- em->block_start = block_start;
em->disk_bytenr = block_start;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = len;
@@ -740,7 +728,6 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
em->start = SZ_4K;
em->len = SZ_4K;
- em->block_start = SZ_16K;
em->disk_bytenr = SZ_16K;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -795,7 +782,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* [0, 16K), pinned */
em->start = 0;
em->len = SZ_16K;
- em->block_start = 0;
em->disk_bytenr = 0;
em->disk_num_bytes = SZ_4K;
em->ram_bytes = SZ_16K;
@@ -819,7 +805,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
/* [32K, 48K), not pinned */
em->start = SZ_32K;
em->len = SZ_16K;
- em->block_start = SZ_32K;
em->disk_bytenr = SZ_32K;
em->disk_num_bytes = SZ_16K;
em->ram_bytes = SZ_16K;
@@ -885,8 +870,9 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
goto out;
}
- if (em->block_start != SZ_32K + SZ_4K) {
- test_err("em->block_start is %llu, expected 36K", em->block_start);
+ if (extent_map_block_start(em) != SZ_32K + SZ_4K) {
+ test_err("em->block_start is %llu, expected 36K",
+ extent_map_block_start(em));
goto out;
}
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
index fc390c18ac95..b8f0d67f4cf6 100644
--- a/fs/btrfs/tests/inode-tests.c
+++ b/fs/btrfs/tests/inode-tests.c
@@ -264,8 +264,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_HOLE) {
- test_err("expected a hole, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_HOLE) {
+ test_err("expected a hole, got %llu", em->disk_bytenr);
goto out;
}
free_extent_map(em);
@@ -283,8 +283,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_INLINE) {
- test_err("expected an inline, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_INLINE) {
+ test_err("expected an inline, got %llu", em->disk_bytenr);
goto out;
}
@@ -321,8 +321,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_HOLE) {
- test_err("expected a hole, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_HOLE) {
+ test_err("expected a hole, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != 4) {
@@ -344,8 +344,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize - 1) {
@@ -371,8 +371,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -389,7 +389,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
- disk_bytenr = em->block_start;
+ disk_bytenr = extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
free_extent_map(em);
@@ -399,8 +399,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_HOLE) {
- test_err("expected a hole, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_HOLE) {
+ test_err("expected a hole, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -421,8 +421,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != 2 * sectorsize) {
@@ -441,9 +441,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
goto out;
}
disk_bytenr += (em->start - orig_start);
- if (em->block_start != disk_bytenr) {
+ if (extent_map_block_start(em) != disk_bytenr) {
test_err("wrong block start, want %llu, have %llu",
- disk_bytenr, em->block_start);
+ disk_bytenr, extent_map_block_start(em));
goto out;
}
offset = em->start + em->len;
@@ -455,8 +455,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -483,8 +483,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -502,7 +502,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("wrong offset, want 0, have %llu", em->offset);
goto out;
}
- disk_bytenr = em->block_start;
+ disk_bytenr = extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
free_extent_map(em);
@@ -512,8 +512,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_HOLE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_HOLE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -531,9 +531,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
em->start - orig_start, em->offset);
goto out;
}
- if (em->block_start != disk_bytenr + em->offset) {
+ if (extent_map_block_start(em) != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
- disk_bytenr + em->offset, em->block_start);
+ disk_bytenr + em->offset, extent_map_block_start(em));
goto out;
}
offset = em->start + em->len;
@@ -544,8 +544,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != 2 * sectorsize) {
@@ -564,9 +564,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
em->start, em->offset, orig_start);
goto out;
}
- if (em->block_start != disk_bytenr + em->offset) {
+ if (extent_map_block_start(em) != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
- disk_bytenr + em->offset, em->block_start);
+ disk_bytenr + em->offset, extent_map_block_start(em));
goto out;
}
offset = em->start + em->len;
@@ -578,8 +578,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != 2 * sectorsize) {
@@ -611,8 +611,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -635,7 +635,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
BTRFS_COMPRESS_ZLIB, extent_map_compression(em));
goto out;
}
- disk_bytenr = em->block_start;
+ disk_bytenr = extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
free_extent_map(em);
@@ -645,8 +645,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -671,9 +671,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != disk_bytenr) {
+ if (extent_map_block_start(em) != disk_bytenr) {
test_err("block start does not match, want %llu got %llu",
- disk_bytenr, em->block_start);
+ disk_bytenr, extent_map_block_start(em));
goto out;
}
if (em->start != offset || em->len != 2 * sectorsize) {
@@ -706,8 +706,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -732,8 +732,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_HOLE) {
- test_err("expected a hole extent, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_HOLE) {
+ test_err("expected a hole extent, got %llu", em->disk_bytenr);
goto out;
}
/*
@@ -764,8 +764,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
+ test_err("expected a real extent, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != offset || em->len != sectorsize) {
@@ -843,8 +843,8 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != EXTENT_MAP_HOLE) {
- test_err("expected a hole, got %llu", em->block_start);
+ if (em->disk_bytenr != EXTENT_MAP_HOLE) {
+ test_err("expected a hole, got %llu", em->disk_bytenr);
goto out;
}
if (em->start != 0 || em->len != sectorsize) {
@@ -865,8 +865,9 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
test_err("got an error when we shouldn't have");
goto out;
}
- if (em->block_start != sectorsize) {
- test_err("expected a real extent, got %llu", em->block_start);
+ if (extent_map_block_start(em) != sectorsize) {
+ test_err("expected a real extent, got %llu",
+ extent_map_block_start(em));
goto out;
}
if (em->start != sectorsize || em->len != sectorsize) {
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 1d04f0cb6f53..f1e006a5fc4c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4578,6 +4578,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
{
struct btrfs_ordered_extent *ordered;
struct btrfs_root *csum_root;
+ u64 block_start;
u64 csum_offset;
u64 csum_len;
u64 mod_start = em->start;
@@ -4587,7 +4588,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
if (inode->flags & BTRFS_INODE_NODATASUM ||
(em->flags & EXTENT_FLAG_PREALLOC) ||
- em->block_start == EXTENT_MAP_HOLE)
+ em->disk_bytenr == EXTENT_MAP_HOLE)
return 0;
list_for_each_entry(ordered, &ctx->ordered_extents, log_list) {
@@ -4658,9 +4659,10 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
}
/* block start is already adjusted for the file extent offset. */
- csum_root = btrfs_csum_root(trans->fs_info, em->block_start);
- ret = btrfs_lookup_csums_list(csum_root, em->block_start + csum_offset,
- em->block_start + csum_offset +
+ block_start = extent_map_block_start(em);
+ csum_root = btrfs_csum_root(trans->fs_info, block_start);
+ ret = btrfs_lookup_csums_list(csum_root, block_start + csum_offset,
+ block_start + csum_offset +
csum_len - 1, &ordered_sums, false);
if (ret < 0)
return ret;
@@ -4692,6 +4694,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
struct btrfs_key key;
enum btrfs_compression_type compress_type;
u64 extent_offset = em->offset;
+ u64 block_start = extent_map_block_start(em);
u64 block_len;
int ret;
@@ -4704,10 +4707,10 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
block_len = em->disk_num_bytes;
compress_type = extent_map_compression(em);
if (compress_type != BTRFS_COMPRESS_NONE) {
- btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start);
+ btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start);
btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
- } else if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start -
+ } else if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
+ btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start -
extent_offset);
btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
}
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index c52a0063f7db..da9de81f340e 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -1773,7 +1773,9 @@ static void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered,
write_lock(&em_tree->lock);
em = search_extent_mapping(em_tree, ordered->file_offset,
ordered->num_bytes);
- em->block_start = logical;
+ /* The em should be a new COW extent, thus it should not have an offset. */
+ ASSERT(em->offset == 0);
+ em->disk_bytenr = logical;
free_extent_map(em);
write_unlock(&em_tree->lock);
}
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index a1804239812c..ca0f99689a2d 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -291,7 +291,6 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__field( u64, ino )
__field( u64, start )
__field( u64, len )
- __field( u64, block_start )
__field( u32, flags )
__field( int, refs )
),
@@ -301,18 +300,16 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
__entry->ino = btrfs_ino(inode);
__entry->start = map->start;
__entry->len = map->len;
- __entry->block_start = map->block_start;
__entry->flags = map->flags;
__entry->refs = refcount_read(&map->refs);
),
TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu len=%llu "
- "block_start=%llu(%s) flags=%s refs=%u",
+ "flags=%s refs=%u",
show_root_type(__entry->root_objectid),
__entry->ino,
__entry->start,
__entry->len,
- show_map_type(__entry->block_start),
show_map_flags(__entry->flags),
__entry->refs)
);
@@ -2608,7 +2605,6 @@ TRACE_EVENT(btrfs_extent_map_shrinker_remove_em,
__field( u64, root_id )
__field( u64, start )
__field( u64, len )
- __field( u64, block_start )
__field( u32, flags )
),
@@ -2617,15 +2613,12 @@ TRACE_EVENT(btrfs_extent_map_shrinker_remove_em,
__entry->root_id = inode->root->root_key.objectid;
__entry->start = em->start;
__entry->len = em->len;
- __entry->block_start = em->block_start;
__entry->flags = em->flags;
),
- TP_printk_btrfs(
-"ino=%llu root=%llu(%s) start=%llu len=%llu block_start=%llu(%s) flags=%s",
+ TP_printk_btrfs("ino=%llu root=%llu(%s) start=%llu len=%llu flags=%s",
__entry->ino, show_root_type(__entry->root_id),
__entry->start, __entry->len,
- show_map_type(__entry->block_start),
show_map_flags(__entry->flags))
);
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 08/11] btrfs: cleanup duplicated parameters related to can_nocow_file_extent_args
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (6 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 07/11] btrfs: remove extent_map::block_start member Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent Qu Wenruo
` (4 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs
The following functions and structures can be simplified using the
btrfs_file_extent structure:
- can_nocow_extent()
No need to return ram_bytes/orig_block_len through the parameter list,
the @file_extent parameter contains all needed info.
- can_nocow_file_extent_args
The following members are no longer needed:
* disk_bytenr
This one is confusing as it's not really the
btrfs_file_extent_item::disk_bytenr, but where the IO would be,
thus it's file_extent::disk_bytenr + file_extent::offset now.
* num_bytes
Now file_extent::num_bytes.
* extent_offset
Now file_extent::offset.
* disk_num_bytes
Now file_extent::disk_num_bytes.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/btrfs_inode.h | 3 +-
fs/btrfs/file.c | 2 +-
fs/btrfs/inode.c | 84 ++++++++++++++++++------------------------
3 files changed, 38 insertions(+), 51 deletions(-)
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 269ee9ac859e..dbc85efdf68a 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -529,8 +529,7 @@ struct btrfs_file_extent {
};
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
- u64 *orig_block_len,
- u64 *ram_bytes, struct btrfs_file_extent *file_extent,
+ struct btrfs_file_extent *file_extent,
bool nowait, bool strict);
void btrfs_del_delalloc_inode(struct btrfs_inode *inode);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index f0cb7b29cab2..eaeefb683b4e 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1104,7 +1104,7 @@ int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
&cached_state);
}
ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
- NULL, NULL, NULL, nowait, false);
+ NULL, nowait, false);
if (ret <= 0)
btrfs_drew_write_unlock(&root->snapshot_lock);
else
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1b78769d1e41..445c19d96d10 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1860,15 +1860,10 @@ struct can_nocow_file_extent_args {
*/
bool free_path;
- /* Output fields. Only set when can_nocow_file_extent() returns 1. */
-
- u64 disk_bytenr;
- u64 disk_num_bytes;
- u64 extent_offset;
- /* Number of bytes that can be written to in NOCOW mode. */
- u64 num_bytes;
-
- /* The expected file extent for the NOCOW write. */
+ /*
+ * Output fields. Only set when can_nocow_file_extent() returns 1.
+ * The expected file extent for the NOCOW write.
+ */
struct btrfs_file_extent file_extent;
};
@@ -1891,6 +1886,7 @@ static int can_nocow_file_extent(struct btrfs_path *path,
struct btrfs_root *root = inode->root;
struct btrfs_file_extent_item *fi;
struct btrfs_root *csum_root;
+ u64 io_start;
u64 extent_end;
u8 extent_type;
int can_nocow = 0;
@@ -1903,11 +1899,6 @@ static int can_nocow_file_extent(struct btrfs_path *path,
if (extent_type == BTRFS_FILE_EXTENT_INLINE)
goto out;
- /* Can't access these fields unless we know it's not an inline extent. */
- args->disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
- args->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
- args->extent_offset = btrfs_file_extent_offset(leaf, fi);
-
if (!(inode->flags & BTRFS_INODE_NODATACOW) &&
extent_type == BTRFS_FILE_EXTENT_REG)
goto out;
@@ -1923,7 +1914,7 @@ static int can_nocow_file_extent(struct btrfs_path *path,
goto out;
/* An explicit hole, must COW. */
- if (args->disk_bytenr == 0)
+ if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0)
goto out;
/* Compressed/encrypted/encoded extents must be COWed. */
@@ -1948,8 +1939,8 @@ static int can_nocow_file_extent(struct btrfs_path *path,
btrfs_release_path(path);
ret = btrfs_cross_ref_exist(root, btrfs_ino(inode),
- key->offset - args->extent_offset,
- args->disk_bytenr, args->strict, path);
+ key->offset - args->file_extent.offset,
+ args->file_extent.disk_bytenr, args->strict, path);
WARN_ON_ONCE(ret > 0 && is_freespace_inode);
if (ret != 0)
goto out;
@@ -1970,21 +1961,18 @@ static int can_nocow_file_extent(struct btrfs_path *path,
atomic_read(&root->snapshot_force_cow))
goto out;
- args->disk_bytenr += args->extent_offset;
- args->disk_bytenr += args->start - key->offset;
- args->num_bytes = min(args->end + 1, extent_end) - args->start;
-
- args->file_extent.num_bytes = args->num_bytes;
+ args->file_extent.num_bytes = min(args->end + 1, extent_end) - args->start;
args->file_extent.offset += args->start - key->offset;
+ io_start = args->file_extent.disk_bytenr + args->file_extent.offset;
/*
* Force COW if csums exist in the range. This ensures that csums for a
* given extent are either valid or do not exist.
*/
- csum_root = btrfs_csum_root(root->fs_info, args->disk_bytenr);
- ret = btrfs_lookup_csums_list(csum_root, args->disk_bytenr,
- args->disk_bytenr + args->num_bytes - 1,
+ csum_root = btrfs_csum_root(root->fs_info, io_start);
+ ret = btrfs_lookup_csums_list(csum_root, io_start,
+ io_start + args->file_extent.num_bytes - 1,
NULL, nowait);
WARN_ON_ONCE(ret > 0 && is_freespace_inode);
if (ret != 0)
@@ -2043,7 +2031,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
struct extent_buffer *leaf;
struct extent_state *cached_state = NULL;
u64 extent_end;
- u64 ram_bytes;
u64 nocow_end;
int extent_type;
bool is_prealloc;
@@ -2122,7 +2109,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
ret = -EUCLEAN;
goto error;
}
- ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
extent_end = btrfs_file_extent_end(path);
/*
@@ -2142,7 +2128,9 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
goto must_cow;
ret = 0;
- nocow_bg = btrfs_inc_nocow_writers(fs_info, nocow_args.disk_bytenr);
+ nocow_bg = btrfs_inc_nocow_writers(fs_info,
+ nocow_args.file_extent.disk_bytenr +
+ nocow_args.file_extent.offset);
if (!nocow_bg) {
must_cow:
/*
@@ -2178,16 +2166,18 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
}
}
- nocow_end = cur_offset + nocow_args.num_bytes - 1;
+ nocow_end = cur_offset + nocow_args.file_extent.num_bytes - 1;
lock_extent(&inode->io_tree, cur_offset, nocow_end, &cached_state);
is_prealloc = extent_type == BTRFS_FILE_EXTENT_PREALLOC;
if (is_prealloc) {
struct extent_map *em;
- em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
- nocow_args.disk_num_bytes, /* orig_block_len */
- ram_bytes, BTRFS_COMPRESS_NONE,
+ em = create_io_em(inode, cur_offset,
+ nocow_args.file_extent.num_bytes,
+ nocow_args.file_extent.disk_num_bytes,
+ nocow_args.file_extent.ram_bytes,
+ BTRFS_COMPRESS_NONE,
&nocow_args.file_extent,
BTRFS_ORDERED_PREALLOC);
if (IS_ERR(em)) {
@@ -2201,8 +2191,11 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
}
ordered = btrfs_alloc_ordered_extent(inode, cur_offset,
- nocow_args.num_bytes, nocow_args.num_bytes,
- nocow_args.disk_bytenr, nocow_args.num_bytes, 0,
+ nocow_args.file_extent.num_bytes,
+ nocow_args.file_extent.num_bytes,
+ nocow_args.file_extent.disk_bytenr +
+ nocow_args.file_extent.offset,
+ nocow_args.file_extent.num_bytes, 0,
is_prealloc
? (1 << BTRFS_ORDERED_PREALLOC)
: (1 << BTRFS_ORDERED_NOCOW),
@@ -7177,8 +7170,7 @@ static bool btrfs_extent_readonly(struct btrfs_fs_info *fs_info, u64 bytenr)
* any ordered extents.
*/
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
- u64 *orig_block_len,
- u64 *ram_bytes, struct btrfs_file_extent *file_extent,
+ struct btrfs_file_extent *file_extent,
bool nowait, bool strict)
{
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
@@ -7229,8 +7221,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
found_type = btrfs_file_extent_type(leaf, fi);
- if (ram_bytes)
- *ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
nocow_args.start = offset;
nocow_args.end = offset + *len - 1;
@@ -7248,14 +7238,15 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
}
ret = 0;
- if (btrfs_extent_readonly(fs_info, nocow_args.disk_bytenr))
+ if (btrfs_extent_readonly(fs_info,
+ nocow_args.file_extent.disk_bytenr + nocow_args.file_extent.offset))
goto out;
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) &&
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
u64 range_end;
- range_end = round_up(offset + nocow_args.num_bytes,
+ range_end = round_up(offset + nocow_args.file_extent.num_bytes,
root->fs_info->sectorsize) - 1;
ret = test_range_bit_exists(io_tree, offset, range_end, EXTENT_DELALLOC);
if (ret) {
@@ -7264,13 +7255,11 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
}
}
- if (orig_block_len)
- *orig_block_len = nocow_args.disk_num_bytes;
if (file_extent)
memcpy(file_extent, &nocow_args.file_extent,
sizeof(*file_extent));
- *len = nocow_args.num_bytes;
+ *len = nocow_args.file_extent.num_bytes;
ret = 1;
out:
btrfs_free_path(path);
@@ -7455,7 +7444,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
struct btrfs_file_extent file_extent;
struct extent_map *em = *map;
int type;
- u64 block_start, orig_block_len, ram_bytes;
+ u64 block_start;
struct btrfs_block_group *bg;
bool can_nocow = false;
bool space_reserved = false;
@@ -7483,7 +7472,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
block_start = extent_map_block_start(em) + (start - em->start);
if (can_nocow_extent(inode, start, &len,
- &orig_block_len, &ram_bytes,
&file_extent, false, false) == 1) {
bg = btrfs_inc_nocow_writers(fs_info, block_start);
if (bg)
@@ -7510,8 +7498,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
space_reserved = true;
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
- orig_block_len,
- ram_bytes, type,
+ file_extent.disk_num_bytes,
+ file_extent.ram_bytes, type,
&file_extent);
btrfs_dec_nocow_writers(bg);
if (type == BTRFS_ORDERED_PREALLOC) {
@@ -10731,7 +10719,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
free_extent_map(em);
em = NULL;
- ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, false, true);
+ ret = can_nocow_extent(inode, start, &len, NULL, false, true);
if (ret < 0) {
goto out;
} else if (ret) {
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (7 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 08/11] btrfs: cleanup duplicated parameters related to can_nocow_file_extent_args Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 18:17 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 10/11] btrfs: cleanup duplicated parameters related to create_io_em() Qu Wenruo
` (3 subsequent siblings)
12 siblings, 1 reply; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs
All parameters after @filepos of btrfs_alloc_ordered_extent() can be
replaced with btrfs_file_extent structure.
This patch does the cleanup, meanwhile some points to note:
- Move btrfs_file_extent structure to ordered-data.h
The structure is needed by both btrfs_alloc_ordered_extent() and
can_nocow_extent(), but since btrfs_inode.h includes
ordered-data.h, so we need to move the structure to ordered-data.h.
- Move the special handling of NOCOW/PREALLOC into
btrfs_alloc_ordered_extent()
This is to allow btrfs_split_ordered_extent() to properly split them
for DIO.
For now just move the handling into btrfs_alloc_ordered_extent() to
simplify the callers.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/btrfs_inode.h | 14 -----------
fs/btrfs/inode.c | 56 ++++++++---------------------------------
fs/btrfs/ordered-data.c | 34 ++++++++++++++++++++-----
fs/btrfs/ordered-data.h | 19 +++++++++++---
4 files changed, 54 insertions(+), 69 deletions(-)
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index dbc85efdf68a..97ce56a60672 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -514,20 +514,6 @@ int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page,
u32 pgoff, u8 *csum, const u8 * const csum_expected);
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
u32 bio_offset, struct bio_vec *bv);
-
-/*
- * This represents details about the target file extent item of a write
- * operation.
- */
-struct btrfs_file_extent {
- u64 disk_bytenr;
- u64 disk_num_bytes;
- u64 num_bytes;
- u64 ram_bytes;
- u64 offset;
- u8 compression;
-};
-
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
struct btrfs_file_extent *file_extent,
bool nowait, bool strict);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 445c19d96d10..35f03149b777 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1220,14 +1220,8 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
}
free_extent_map(em);
- ordered = btrfs_alloc_ordered_extent(inode, start, /* file_offset */
- async_extent->ram_size, /* num_bytes */
- async_extent->ram_size, /* ram_bytes */
- ins.objectid, /* disk_bytenr */
- ins.offset, /* disk_num_bytes */
- 0, /* offset */
- 1 << BTRFS_ORDERED_COMPRESSED,
- async_extent->compress_type);
+ ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
+ 1 << BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(ordered)) {
btrfs_drop_extent_map_range(inode, start, end, false);
ret = PTR_ERR(ordered);
@@ -1463,10 +1457,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
}
free_extent_map(em);
- ordered = btrfs_alloc_ordered_extent(inode, start, ram_size,
- ram_size, ins.objectid, cur_alloc_size,
- 0, 1 << BTRFS_ORDERED_REGULAR,
- BTRFS_COMPRESS_NONE);
+ ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
+ 1 << BTRFS_ORDERED_REGULAR);
if (IS_ERR(ordered)) {
unlock_extent(&inode->io_tree, start,
start + ram_size - 1, &cached);
@@ -2191,15 +2183,10 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
}
ordered = btrfs_alloc_ordered_extent(inode, cur_offset,
- nocow_args.file_extent.num_bytes,
- nocow_args.file_extent.num_bytes,
- nocow_args.file_extent.disk_bytenr +
- nocow_args.file_extent.offset,
- nocow_args.file_extent.num_bytes, 0,
+ &nocow_args.file_extent,
is_prealloc
? (1 << BTRFS_ORDERED_PREALLOC)
- : (1 << BTRFS_ORDERED_NOCOW),
- BTRFS_COMPRESS_NONE);
+ : (1 << BTRFS_ORDERED_NOCOW));
btrfs_dec_nocow_writers(nocow_bg);
if (IS_ERR(ordered)) {
if (is_prealloc) {
@@ -7054,29 +7041,9 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
goto out;
}
- /*
- * For regular writes, file_extent->offset is always 0,
- * thus we really only need file_extent->disk_bytenr, every other length
- * (disk_num_bytes/ram_bytes) should match @len and
- * file_extent->num_bytes.
- *
- * For NOCOW, we don't really care about the numbers except
- * @start and @len, as we won't insert a file extent
- * item at all.
- *
- * For PREALLOC, we do not use ordered extent members, but
- * btrfs_mark_extent_written() handles everything.
- *
- * So here we always passing 0 as offset for the ordered extent,
- * or btrfs_split_ordered_extent() can not handle it correctly.
- */
- ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
- file_extent->disk_bytenr +
- file_extent->offset,
- len, 0,
+ ordered = btrfs_alloc_ordered_extent(inode, start, file_extent,
(1 << type) |
- (1 << BTRFS_ORDERED_DIRECT),
- BTRFS_COMPRESS_NONE);
+ (1 << BTRFS_ORDERED_DIRECT));
if (IS_ERR(ordered)) {
if (em) {
free_extent_map(em);
@@ -10396,12 +10363,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
}
free_extent_map(em);
- ordered = btrfs_alloc_ordered_extent(inode, start, num_bytes, ram_bytes,
- ins.objectid, ins.offset,
- encoded->unencoded_offset,
+ ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
(1 << BTRFS_ORDERED_ENCODED) |
- (1 << BTRFS_ORDERED_COMPRESSED),
- compression);
+ (1 << BTRFS_ORDERED_COMPRESSED));
if (IS_ERR(ordered)) {
btrfs_drop_extent_map_range(inode, start, end, false);
ret = PTR_ERR(ordered);
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index d446d89c2c34..5c2fb0a7c5c8 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -264,17 +264,39 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry)
*/
struct btrfs_ordered_extent *btrfs_alloc_ordered_extent(
struct btrfs_inode *inode, u64 file_offset,
- u64 num_bytes, u64 ram_bytes, u64 disk_bytenr,
- u64 disk_num_bytes, u64 offset, unsigned long flags,
- int compress_type)
+ struct btrfs_file_extent *file_extent,
+ unsigned long flags)
{
struct btrfs_ordered_extent *entry;
ASSERT((flags & ~BTRFS_ORDERED_TYPE_FLAGS) == 0);
- entry = alloc_ordered_extent(inode, file_offset, num_bytes, ram_bytes,
- disk_bytenr, disk_num_bytes, offset, flags,
- compress_type);
+ /*
+ * For regular writes, we just use the members in @file_extent.
+ *
+ * For NOCOW, we don't really care about the numbers except
+ * @start and file_extent->num_bytes, as we won't insert a file extent
+ * item at all.
+ *
+ * For PREALLOC, we do not use ordered extent members, but
+ * btrfs_mark_extent_written() handles everything.
+ *
+ * So here we always passing 0 as offset for NOCOW/PREALLOC ordered
+ * extents, or btrfs_split_ordered_extent() can not handle it correctly.
+ */
+ if (flags & ((1 << BTRFS_ORDERED_NOCOW) | (1 << BTRFS_ORDERED_PREALLOC)))
+ entry = alloc_ordered_extent(inode, file_offset,
+ file_extent->num_bytes, file_extent->num_bytes,
+ file_extent->disk_bytenr + file_extent->offset,
+ file_extent->num_bytes, 0, flags,
+ file_extent->compression);
+ else
+ entry = alloc_ordered_extent(inode, file_offset,
+ file_extent->num_bytes, file_extent->ram_bytes,
+ file_extent->disk_bytenr,
+ file_extent->disk_num_bytes,
+ file_extent->offset, flags,
+ file_extent->compression);
if (!IS_ERR(entry))
insert_ordered_extent(entry);
return entry;
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 2ec329e2f0f3..31e65f2f4990 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -171,11 +171,24 @@ void btrfs_mark_ordered_io_finished(struct btrfs_inode *inode,
bool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode,
struct btrfs_ordered_extent **cached,
u64 file_offset, u64 io_size);
+
+/*
+ * This represents details about the target file extent item of a write
+ * operation.
+ */
+struct btrfs_file_extent {
+ u64 disk_bytenr;
+ u64 disk_num_bytes;
+ u64 num_bytes;
+ u64 ram_bytes;
+ u64 offset;
+ u8 compression;
+};
+
struct btrfs_ordered_extent *btrfs_alloc_ordered_extent(
struct btrfs_inode *inode, u64 file_offset,
- u64 num_bytes, u64 ram_bytes, u64 disk_bytenr,
- u64 disk_num_bytes, u64 offset, unsigned long flags,
- int compress_type);
+ struct btrfs_file_extent *file_extent,
+ unsigned long flags);
void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry,
struct btrfs_ordered_sum *sum);
struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode,
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 10/11] btrfs: cleanup duplicated parameters related to create_io_em()
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (8 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 11/11] btrfs: cleanup duplicated parameters related to btrfs_create_dio_extent() Qu Wenruo
` (2 subsequent siblings)
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs
Most parameters of create_io_em() can be replaced by the members with
the same name inside btrfs_file_extent.
Do a straight parameters cleanup here.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/inode.c | 55 ++++++++++++------------------------------------
1 file changed, 14 insertions(+), 41 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 35f03149b777..ecafaa181201 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -138,9 +138,6 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
u64 end, struct writeback_control *wbc,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len,
- u64 disk_num_bytes,
- u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
int type);
@@ -1207,13 +1204,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
file_extent.offset = 0;
file_extent.compression = async_extent->compress_type;
- em = create_io_em(inode, start,
- async_extent->ram_size, /* len */
- ins.offset, /* orig_block_len */
- async_extent->ram_size, /* ram_bytes */
- async_extent->compress_type,
- &file_extent,
- BTRFS_ORDERED_COMPRESSED);
+ em = create_io_em(inode, start, &file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
ret = PTR_ERR(em);
goto out_free_reserve;
@@ -1443,12 +1434,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
lock_extent(&inode->io_tree, start, start + ram_size - 1,
&cached);
- em = create_io_em(inode, start, ins.offset, /* len */
- ins.offset, /* orig_block_len */
- ram_size, /* ram_bytes */
- BTRFS_COMPRESS_NONE, /* compress_type */
- &file_extent,
- BTRFS_ORDERED_REGULAR /* type */);
+ em = create_io_em(inode, start, &file_extent, BTRFS_ORDERED_REGULAR);
if (IS_ERR(em)) {
unlock_extent(&inode->io_tree, start,
start + ram_size - 1, &cached);
@@ -2165,12 +2151,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
if (is_prealloc) {
struct extent_map *em;
- em = create_io_em(inode, cur_offset,
- nocow_args.file_extent.num_bytes,
- nocow_args.file_extent.disk_num_bytes,
- nocow_args.file_extent.ram_bytes,
- BTRFS_COMPRESS_NONE,
- &nocow_args.file_extent,
+ em = create_io_em(inode, cur_offset, &nocow_args.file_extent,
BTRFS_ORDERED_PREALLOC);
if (IS_ERR(em)) {
unlock_extent(&inode->io_tree, cur_offset,
@@ -7033,10 +7014,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_ordered_extent *ordered;
if (type != BTRFS_ORDERED_NOCOW) {
- em = create_io_em(inode, start, len,
- orig_block_len, ram_bytes,
- BTRFS_COMPRESS_NONE, /* compress_type */
- file_extent, type);
+ em = create_io_em(inode, start, file_extent, type);
if (IS_ERR(em))
goto out;
}
@@ -7328,9 +7306,6 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len,
- u64 disk_num_bytes,
- u64 ram_bytes, int compress_type,
struct btrfs_file_extent *file_extent,
int type)
{
@@ -7352,25 +7327,25 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
switch (type) {
case BTRFS_ORDERED_PREALLOC:
/* We're only referring part of a larger preallocated extent. */
- ASSERT(len <= ram_bytes);
+ ASSERT(file_extent->num_bytes <= file_extent->ram_bytes);
break;
case BTRFS_ORDERED_REGULAR:
/* COW results a new extent matching our file extent size. */
- ASSERT(disk_num_bytes == len);
- ASSERT(ram_bytes == len);
+ ASSERT(file_extent->disk_num_bytes == file_extent->num_bytes);
+ ASSERT(file_extent->ram_bytes == file_extent->num_bytes);
/* Since it's a new extent, we should not have any offset. */
ASSERT(file_extent->offset == 0);
break;
case BTRFS_ORDERED_COMPRESSED:
/* Must be compressed. */
- ASSERT(compress_type != BTRFS_COMPRESS_NONE);
+ ASSERT(file_extent->compression != BTRFS_COMPRESS_NONE);
/*
* Encoded write can make us to refer to part of the
* uncompressed extent.
*/
- ASSERT(len <= ram_bytes);
+ ASSERT(file_extent->num_bytes <= file_extent->ram_bytes);
break;
}
@@ -7379,15 +7354,15 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
return ERR_PTR(-ENOMEM);
em->start = start;
- em->len = len;
+ em->len = file_extent->num_bytes;
em->disk_bytenr = file_extent->disk_bytenr;
- em->disk_num_bytes = disk_num_bytes;
- em->ram_bytes = ram_bytes;
+ em->disk_num_bytes = file_extent->disk_num_bytes;
+ em->ram_bytes = file_extent->ram_bytes;
em->generation = -1;
em->offset = file_extent->offset;
em->flags |= EXTENT_FLAG_PINNED;
if (type == BTRFS_ORDERED_COMPRESSED)
- extent_map_set_compression(em, compress_type);
+ extent_map_set_compression(em, file_extent->compression);
ret = btrfs_replace_extent_map_range(inode, em, true);
if (ret) {
@@ -10354,9 +10329,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
file_extent.ram_bytes = ram_bytes;
file_extent.offset = encoded->unencoded_offset;
file_extent.compression = compression;
- em = create_io_em(inode, start, num_bytes,
- ins.offset, ram_bytes, compression,
- &file_extent, BTRFS_ORDERED_COMPRESSED);
+ em = create_io_em(inode, start, &file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
ret = PTR_ERR(em);
goto out_free_reserved;
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 11/11] btrfs: cleanup duplicated parameters related to btrfs_create_dio_extent()
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (9 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 10/11] btrfs: cleanup duplicated parameters related to create_io_em() Qu Wenruo
@ 2024-05-23 5:03 ` Qu Wenruo
2024-05-23 10:23 ` [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Johannes Thumshirn
2024-05-23 18:26 ` Filipe Manana
12 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 5:03 UTC (permalink / raw)
To: linux-btrfs
The following 3 parameters can be cleaned up using btrfs_file_extent
structure:
- len
btrfs_file_extent::num_bytes
- orig_block_len
btrfs_file_extent::disk_num_bytes
- ram_bytes
btrfs_file_extent::ram_bytes
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/inode.c | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ecafaa181201..0ec275b24adc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7004,11 +7004,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_dio_data *dio_data,
const u64 start,
- const u64 len,
- const u64 orig_block_len,
- const u64 ram_bytes,
- const int type,
- struct btrfs_file_extent *file_extent)
+ struct btrfs_file_extent *file_extent,
+ const int type)
{
struct extent_map *em = NULL;
struct btrfs_ordered_extent *ordered;
@@ -7026,7 +7023,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
if (em) {
free_extent_map(em);
btrfs_drop_extent_map_range(inode, start,
- start + len - 1, false);
+ start + file_extent->num_bytes - 1, false);
}
em = ERR_CAST(ordered);
} else {
@@ -7069,10 +7066,8 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
file_extent.ram_bytes = ins.offset;
file_extent.offset = 0;
file_extent.compression = BTRFS_COMPRESS_NONE;
- em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
- ins.offset,
- ins.offset, BTRFS_ORDERED_REGULAR,
- &file_extent);
+ em = btrfs_create_dio_extent(inode, dio_data, start, &file_extent,
+ BTRFS_ORDERED_REGULAR);
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
if (IS_ERR(em))
btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset,
@@ -7439,10 +7434,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
}
space_reserved = true;
- em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
- file_extent.disk_num_bytes,
- file_extent.ram_bytes, type,
- &file_extent);
+ em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start,
+ &file_extent, type);
btrfs_dec_nocow_writers(bg);
if (type == BTRFS_ORDERED_PREALLOC) {
free_extent_map(em);
--
2.45.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (10 preceding siblings ...)
2024-05-23 5:03 ` [PATCH v3 11/11] btrfs: cleanup duplicated parameters related to btrfs_create_dio_extent() Qu Wenruo
@ 2024-05-23 10:23 ` Johannes Thumshirn
2024-05-23 18:26 ` Filipe Manana
12 siblings, 0 replies; 22+ messages in thread
From: Johannes Thumshirn @ 2024-05-23 10:23 UTC (permalink / raw)
To: Qu Wenruo, linux-btrfs@vger.kernel.org
Looks good to me,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 03/11] btrfs: introduce new members for extent_map
2024-05-23 5:03 ` [PATCH v3 03/11] btrfs: introduce new members for extent_map Qu Wenruo
@ 2024-05-23 16:53 ` Filipe Manana
2024-05-23 23:19 ` Qu Wenruo
2024-05-23 18:21 ` Filipe Manana
1 sibling, 1 reply; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 16:53 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, David Sterba
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> Introduce two new members for extent_map:
>
> - disk_bytenr
> - offset
>
> Both are matching the members with the same name inside
> btrfs_file_extent_items.
>
> For now this patch only touches those members when:
>
> - Reading btrfs_file_extent_items from disk
> - Inserting new holes
> - Merging two extent maps
> With the new disk_bytenr and disk_num_bytes, doing merging would be a
> little more complex, as we have 3 different cases:
>
> * Both extent maps are referring to the same data extents
> |<----- data extent A ----->|
> |<- em 1 ->|<- em 2 ->|
>
> * Both extent maps are referring to different data extents
> |<-- data extent A -->|<-- data extent B -->|
> |<- em 1 ->|<- em 2 ->|
>
> * One of the extent maps is referring to a merged and larger data
> extent that covers both extent maps
>
> This is not really valid case other than some selftests.
> So this test case would be removed.
>
> A new helper merge_ondisk_extents() would be introduced to handle
> above valid cases.
>
> To properly assign values for those new members, a new btrfs_file_extent
> parameter is introduced to all the involved call sites.
>
> - For NOCOW writes the btrfs_file_extent would be exposed from
> can_nocow_file_extent().
>
> - For other writes, the members can be easily calculated
> As most of them have 0 offset and utilizing the whole on-disk data
> extent.
> The exception is encoded write, but thankfully that interface provided
> offset directly and all other needed info.
>
> For now, both the old members (block_start/block_len/orig_start) are
> co-existing with the new members (disk_bytenr/offset), meanwhile all the
> critical code is still using the old members only.
>
> The cleanup would happen later after all the older and newer members are
> properly validated.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
> fs/btrfs/defrag.c | 4 +++
> fs/btrfs/extent_map.c | 78 ++++++++++++++++++++++++++++++++++++++++---
> fs/btrfs/extent_map.h | 17 ++++++++++
> fs/btrfs/file-item.c | 9 ++++-
> fs/btrfs/file.c | 1 +
> fs/btrfs/inode.c | 57 +++++++++++++++++++++++++++----
> 6 files changed, 155 insertions(+), 11 deletions(-)
>
> diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
> index 407ccec3e57e..242c5469f4ba 100644
> --- a/fs/btrfs/defrag.c
> +++ b/fs/btrfs/defrag.c
> @@ -709,6 +709,10 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
> em->start = start;
> em->orig_start = start;
> em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> + em->disk_num_bytes = 0;
> + em->ram_bytes = 0;
> + em->offset = 0;
> em->len = key.offset - start;
> break;
> }
> diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
> index a9d60d1eade9..c7d2393692e6 100644
> --- a/fs/btrfs/extent_map.c
> +++ b/fs/btrfs/extent_map.c
> @@ -229,6 +229,60 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
> return next->block_start == prev->block_start;
> }
>
> +/*
> + * Handle the ondisk data extents merge for @prev and @next.
> + *
> + * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
> + * For now only uncompressed regular extent can be merged.
> + *
> + * @prev and @next will be both updated to point to the new merged range.
> + * Thus one of them should be removed by the caller.
> + */
> +static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
> +{
> + u64 new_disk_bytenr;
> + u64 new_disk_num_bytes;
> + u64 new_offset;
> +
> + /* @prev and @next should not be compressed. */
> + ASSERT(!extent_map_is_compressed(prev));
> + ASSERT(!extent_map_is_compressed(next));
> +
> + /*
> + * There are two different cases where @prev and @next can be merged.
> + *
> + * 1) They are referring to the same data extent
> + * |<----- data extent A ----->|
> + * |<- prev ->|<- next ->|
> + *
> + * 2) They are referring to different data extents but still adjacent
> + *
> + * |<-- data extent A -->|<-- data extent B -->|
> + * |<- prev ->|<- next ->|
> + *
> + * The calculation here always merge the data extents first, then update
> + * @offset using the new data extents.
> + *
> + * For case 1), the merged data extent would be the same.
> + * For case 2), we just merge the two data extents into one.
> + */
> + new_disk_bytenr = min(prev->disk_bytenr, next->disk_bytenr);
> + new_disk_num_bytes = max(prev->disk_bytenr + prev->disk_num_bytes,
> + next->disk_bytenr + next->disk_num_bytes) -
> + new_disk_bytenr;
> + new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
> +
> + prev->disk_bytenr = new_disk_bytenr;
> + prev->disk_num_bytes = new_disk_num_bytes;
> + prev->ram_bytes = new_disk_num_bytes;
> + prev->offset = new_offset;
> +
> + next->disk_bytenr = new_disk_bytenr;
> + next->disk_num_bytes = new_disk_num_bytes;
> + next->ram_bytes = new_disk_num_bytes;
> + next->offset = new_offset;
> +}
> +
> static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> {
> struct extent_map_tree *tree = &inode->extent_tree;
> @@ -260,6 +314,9 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> em->block_len += merge->block_len;
> em->block_start = merge->block_start;
> em->generation = max(em->generation, merge->generation);
> +
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> + merge_ondisk_extents(merge, em);
> em->flags |= EXTENT_FLAG_MERGED;
>
> rb_erase(&merge->rb_node, &tree->root);
> @@ -275,6 +332,8 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
> em->len += merge->len;
> em->block_len += merge->block_len;
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> + merge_ondisk_extents(em, merge);
> rb_erase(&merge->rb_node, &tree->root);
> RB_CLEAR_NODE(&merge->rb_node);
> em->generation = max(em->generation, merge->generation);
> @@ -562,6 +621,7 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
> !extent_map_is_compressed(em)) {
> em->block_start += start_diff;
> em->block_len = em->len;
> + em->offset += start_diff;
> }
> return add_extent_mapping(inode, em, 0);
> }
> @@ -785,14 +845,18 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->block_len = em->block_len;
> else
> split->block_len = split->len;
> + split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = max(split->block_len,
> em->disk_num_bytes);
> + split->offset = em->offset;
> split->ram_bytes = em->ram_bytes;
> } else {
> split->orig_start = split->start;
> split->block_len = 0;
> split->block_start = em->block_start;
> + split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = 0;
> + split->offset = 0;
> split->ram_bytes = split->len;
> }
>
> @@ -813,13 +877,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->start = end;
> split->len = em_end - end;
> split->block_start = em->block_start;
> + split->disk_bytenr = em->disk_bytenr;
> split->flags = flags;
> split->generation = gen;
>
> if (em->block_start < EXTENT_MAP_LAST_BYTE) {
> split->disk_num_bytes = max(em->block_len,
> em->disk_num_bytes);
> -
> + split->offset = em->offset + end - em->start;
> split->ram_bytes = em->ram_bytes;
> if (compressed) {
> split->block_len = em->block_len;
> @@ -832,10 +897,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->orig_start = em->orig_start;
> }
> } else {
> + split->disk_num_bytes = 0;
> + split->offset = 0;
> split->ram_bytes = split->len;
> split->orig_start = split->start;
> split->block_len = 0;
> - split->disk_num_bytes = 0;
Why move the assignment of ->disk_num_bytes ?
This is sort of distracting, doing unnecessary changes.
> }
>
> if (extent_map_in_tree(em)) {
> @@ -989,10 +1055,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> /* First, replace the em with a new extent_map starting from * em->start */
> split_pre->start = em->start;
> split_pre->len = pre;
> + split_pre->disk_bytenr = new_logical;
We are already setting disk_bytenr to the same value a few lines below.
> + split_pre->disk_num_bytes = split_pre->len;
> + split_pre->offset = 0;
> split_pre->orig_start = split_pre->start;
> split_pre->block_start = new_logical;
> split_pre->block_len = split_pre->len;
> - split_pre->disk_num_bytes = split_pre->block_len;
Here, where slit_pre->block_len has the same value as split->pre_len.
This sort of apparently accidental change makes it harder to review.
> split_pre->ram_bytes = split_pre->len;
> split_pre->flags = flags;
> split_pre->generation = em->generation;
> @@ -1007,10 +1075,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> /* Insert the middle extent_map. */
> split_mid->start = em->start + pre;
> split_mid->len = em->len - pre;
> + split_mid->disk_bytenr = em->block_start + pre;
Same here.
> + split_mid->disk_num_bytes = split_mid->len;
> + split_mid->offset = 0;
> split_mid->orig_start = split_mid->start;
> split_mid->block_start = em->block_start + pre;
> split_mid->block_len = split_mid->len;
> - split_mid->disk_num_bytes = split_mid->block_len;
Which relates to this.
Otherwise it looks fine, and could be fixed up when cherry picked to for-next.
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Thanks.
> split_mid->ram_bytes = split_mid->len;
> split_mid->flags = flags;
> split_mid->generation = em->generation;
> diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
> index 2b7bbffd594b..0b1a8e409377 100644
> --- a/fs/btrfs/extent_map.h
> +++ b/fs/btrfs/extent_map.h
> @@ -70,12 +70,29 @@ struct extent_map {
> */
> u64 orig_start;
>
> + /*
> + * The bytenr of the full on-disk extent.
> + *
> + * For regular extents it's btrfs_file_extent_item::disk_bytenr.
> + * For holes it's EXTENT_MAP_HOLE and for inline extents it's
> + * EXTENT_MAP_INLINE.
> + */
> + u64 disk_bytenr;
> +
> /*
> * The full on-disk extent length, matching
> * btrfs_file_extent_item::disk_num_bytes.
> */
> u64 disk_num_bytes;
>
> + /*
> + * Offset inside the decompressed extent.
> + *
> + * For regular extents it's btrfs_file_extent_item::offset.
> + * For holes and inline extents it's 0.
> + */
> + u64 offset;
> +
> /*
> * The decompressed size of the whole on-disk extent, matching
> * btrfs_file_extent_item::ram_bytes.
> diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
> index 430dce44ebd2..1298afea9503 100644
> --- a/fs/btrfs/file-item.c
> +++ b/fs/btrfs/file-item.c
> @@ -1295,12 +1295,17 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> em->len = btrfs_file_extent_end(path) - extent_start;
> em->orig_start = extent_start -
> btrfs_file_extent_offset(leaf, fi);
> - em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
> bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
> if (bytenr == 0) {
> em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> + em->disk_num_bytes = 0;
> + em->offset = 0;
> return;
> }
> + em->disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
> + em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
> + em->offset = btrfs_file_extent_offset(leaf, fi);
> if (compress_type != BTRFS_COMPRESS_NONE) {
> extent_map_set_compression(em, compress_type);
> em->block_start = bytenr;
> @@ -1317,8 +1322,10 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> ASSERT(extent_start == 0);
>
> em->block_start = EXTENT_MAP_INLINE;
> + em->disk_bytenr = EXTENT_MAP_INLINE;
> em->start = 0;
> em->len = fs_info->sectorsize;
> + em->offset = 0;
> /*
> * Initialize orig_start and block_len with the same values
> * as in inode.c:btrfs_get_extent().
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 7c42565da70c..5133c6705d74 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -2350,6 +2350,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
> hole_em->orig_start = offset;
>
> hole_em->block_start = EXTENT_MAP_HOLE;
> + hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->block_len = 0;
> hole_em->disk_num_bytes = 0;
> hole_em->generation = trans->transid;
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 8ac489fb5e39..7afcdea27782 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -141,6 +141,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> u64 len, u64 orig_start, u64 block_start,
> u64 block_len, u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> + struct btrfs_file_extent *file_extent,
> int type);
>
> static int data_reloc_print_warning_inode(u64 inum, u64 offset, u64 num_bytes,
> @@ -1152,6 +1153,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> struct btrfs_root *root = inode->root;
> struct btrfs_fs_info *fs_info = root->fs_info;
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
> struct btrfs_key ins;
> struct page *locked_page = NULL;
> struct extent_state *cached = NULL;
> @@ -1198,6 +1200,13 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> lock_extent(io_tree, start, end, &cached);
>
> /* Here we're doing allocation and writeback of the compressed pages */
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.ram_bytes = async_extent->ram_size;
> + file_extent.num_bytes = async_extent->ram_size;
> + file_extent.offset = 0;
> + file_extent.compression = async_extent->compress_type;
> +
> em = create_io_em(inode, start,
> async_extent->ram_size, /* len */
> start, /* orig_start */
> @@ -1206,6 +1215,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> ins.offset, /* orig_block_len */
> async_extent->ram_size, /* ram_bytes */
> async_extent->compress_type,
> + &file_extent,
> BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(em)) {
> ret = PTR_ERR(em);
> @@ -1395,6 +1405,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
>
> while (num_bytes > 0) {
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
>
> cur_alloc_size = num_bytes;
> ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size,
> @@ -1431,6 +1442,12 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> extent_reserved = true;
>
> ram_size = ins.offset;
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = ins.offset;
> + file_extent.ram_bytes = ins.offset;
> + file_extent.offset = 0;
> + file_extent.compression = BTRFS_COMPRESS_NONE;
>
> lock_extent(&inode->io_tree, start, start + ram_size - 1,
> &cached);
> @@ -1442,6 +1459,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> ins.offset, /* orig_block_len */
> ram_size, /* ram_bytes */
> BTRFS_COMPRESS_NONE, /* compress_type */
> + &file_extent,
> BTRFS_ORDERED_REGULAR /* type */);
> if (IS_ERR(em)) {
> unlock_extent(&inode->io_tree, start,
> @@ -2180,6 +2198,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
> nocow_args.num_bytes, /* block_len */
> nocow_args.disk_num_bytes, /* orig_block_len */
> ram_bytes, BTRFS_COMPRESS_NONE,
> + &nocow_args.file_extent,
> BTRFS_ORDERED_PREALLOC);
> if (IS_ERR(em)) {
> unlock_extent(&inode->io_tree, cur_offset,
> @@ -5012,6 +5031,7 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
> hole_em->orig_start = cur_offset;
>
> hole_em->block_start = EXTENT_MAP_HOLE;
> + hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->block_len = 0;
> hole_em->disk_num_bytes = 0;
> hole_em->ram_bytes = hole_size;
> @@ -6880,6 +6900,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> }
> em->start = EXTENT_MAP_HOLE;
> em->orig_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> em->len = (u64)-1;
> em->block_len = (u64)-1;
>
> @@ -7045,7 +7066,8 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> const u64 block_len,
> const u64 orig_block_len,
> const u64 ram_bytes,
> - const int type)
> + const int type,
> + struct btrfs_file_extent *file_extent)
> {
> struct extent_map *em = NULL;
> struct btrfs_ordered_extent *ordered;
> @@ -7054,7 +7076,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> em = create_io_em(inode, start, len, orig_start, block_start,
> block_len, orig_block_len, ram_bytes,
> BTRFS_COMPRESS_NONE, /* compress_type */
> - type);
> + file_extent, type);
> if (IS_ERR(em))
> goto out;
> }
> @@ -7085,6 +7107,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
> {
> struct btrfs_root *root = inode->root;
> struct btrfs_fs_info *fs_info = root->fs_info;
> + struct btrfs_file_extent file_extent;
> struct extent_map *em;
> struct btrfs_key ins;
> u64 alloc_hint;
> @@ -7103,9 +7126,16 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
> if (ret)
> return ERR_PTR(ret);
>
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = ins.offset;
> + file_extent.ram_bytes = ins.offset;
> + file_extent.offset = 0;
> + file_extent.compression = BTRFS_COMPRESS_NONE;
> em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start,
> ins.objectid, ins.offset, ins.offset,
> - ins.offset, BTRFS_ORDERED_REGULAR);
> + ins.offset, BTRFS_ORDERED_REGULAR,
> + &file_extent);
> btrfs_dec_block_group_reservations(fs_info, ins.objectid);
> if (IS_ERR(em))
> btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset,
> @@ -7348,6 +7378,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> u64 len, u64 orig_start, u64 block_start,
> u64 block_len, u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> + struct btrfs_file_extent *file_extent,
> int type)
> {
> struct extent_map *em;
> @@ -7405,9 +7436,11 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> em->len = len;
> em->block_len = block_len;
> em->block_start = block_start;
> + em->disk_bytenr = file_extent->disk_bytenr;
> em->disk_num_bytes = disk_num_bytes;
> em->ram_bytes = ram_bytes;
> em->generation = -1;
> + em->offset = file_extent->offset;
> em->flags |= EXTENT_FLAG_PINNED;
> if (type == BTRFS_ORDERED_COMPRESSED)
> extent_map_set_compression(em, compress_type);
> @@ -7431,6 +7464,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> {
> const bool nowait = (iomap_flags & IOMAP_NOWAIT);
> struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
> + struct btrfs_file_extent file_extent;
> struct extent_map *em = *map;
> int type;
> u64 block_start, orig_start, orig_block_len, ram_bytes;
> @@ -7461,7 +7495,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> block_start = em->block_start + (start - em->start);
>
> if (can_nocow_extent(inode, start, &len, &orig_start,
> - &orig_block_len, &ram_bytes, NULL, false, false) == 1) {
> + &orig_block_len, &ram_bytes,
> + &file_extent, false, false) == 1) {
> bg = btrfs_inc_nocow_writers(fs_info, block_start);
> if (bg)
> can_nocow = true;
> @@ -7489,7 +7524,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
> orig_start, block_start,
> len, orig_block_len,
> - ram_bytes, type);
> + ram_bytes, type,
> + &file_extent);
> btrfs_dec_nocow_writers(bg);
> if (type == BTRFS_ORDERED_PREALLOC) {
> free_extent_map(em);
> @@ -9629,6 +9665,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
> em->orig_start = cur_offset;
> em->len = ins.offset;
> em->block_start = ins.objectid;
> + em->disk_bytenr = ins.objectid;
> + em->offset = 0;
> em->block_len = ins.offset;
> em->disk_num_bytes = ins.offset;
> em->ram_bytes = ins.offset;
> @@ -10195,6 +10233,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> struct extent_changeset *data_reserved = NULL;
> struct extent_state *cached_state = NULL;
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
> int compression;
> size_t orig_count;
> u64 start, end;
> @@ -10370,10 +10409,16 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> goto out_delalloc_release;
> extent_reserved = true;
>
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = num_bytes;
> + file_extent.ram_bytes = ram_bytes;
> + file_extent.offset = encoded->unencoded_offset;
> + file_extent.compression = compression;
> em = create_io_em(inode, start, num_bytes,
> start - encoded->unencoded_offset, ins.objectid,
> ins.offset, ins.offset, ram_bytes, compression,
> - BTRFS_ORDERED_COMPRESSED);
> + &file_extent, BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(em)) {
> ret = PTR_ERR(em);
> goto out_free_reserved;
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps
2024-05-23 5:03 ` [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps Qu Wenruo
@ 2024-05-23 16:57 ` Filipe Manana
0 siblings, 0 replies; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 16:57 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, David Sterba
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> Since extent_map structure has the all the needed members to represent a
> file extent directly, we can apply all the file extent sanity checks to an extent
> map.
>
> The new sanity checks would cross check both the old members
> (block_start/block_len/orig_start) and the new members
> (disk_bytenr/disk_num_bytes/offset).
>
> There is a special case for offset/orig_start/start cross check, we only
> do such sanity check for compressed extent, as only compressed
> read/encoded write really utilize orig_start.
> This can be proved by the cleanup patch of orig_start.
>
> The checks happens at the following timing:
>
> - add_extent_mapping()
> This is for newly added extent map
>
> - replace_extent_mapping()
> This is for btrfs_drop_extent_map_range() and split_extent_map()
>
> - try_merge_map()
>
> For a lot of call sites we have to properly populate all the members to
> pass the sanity check, meanwhile the following code needs extra
> modification:
>
> - setup_file_extents() from inode-tests
> The file extents layout of setup_file_extents() is already too invalid
> that tree-checker would reject most of them in real world.
>
> However there is just a special unaligned regular extent which has
> mismatched disk_num_bytes (4096) and ram_bytes (4096 - 1).
> So instead of dropping the whole test case, here we just unify
> disk_num_bytes and ram_bytes to 4096 - 1.
>
> - test_case_7() from extent-map-tests
> An extent is inserted with 16K length, but on-disk extent size is
> only 4K.
> This means it must be a compressed extent, so set the compressed flag
> for it.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
> fs/btrfs/extent_map.c | 60 +++++++++++++++++++++++++++++++
> fs/btrfs/relocation.c | 4 +++
> fs/btrfs/tests/extent-map-tests.c | 56 ++++++++++++++++++++++++++++-
> fs/btrfs/tests/inode-tests.c | 2 +-
> 4 files changed, 120 insertions(+), 2 deletions(-)
>
> diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
> index c7d2393692e6..b157f30ac241 100644
> --- a/fs/btrfs/extent_map.c
> +++ b/fs/btrfs/extent_map.c
> @@ -283,8 +283,62 @@ static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *nex
> next->offset = new_offset;
> }
>
> +static void dump_extent_map(struct btrfs_fs_info *fs_info,
> + const char *prefix, struct extent_map *em)
> +{
> + if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
> + return;
> + btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu orig_start=%llu block_start=%llu block_len=%llu flags=0x%x\n",
> + prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
> + em->ram_bytes, em->offset, em->orig_start, em->block_start,
> + em->block_len, em->flags);
> + ASSERT(0);
> +}
> +
> +/* Internal sanity checks for btrfs debug builds. */
> +static void validate_extent_map(struct btrfs_fs_info *fs_info,
> + struct extent_map *em)
> +{
> + if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
> + return;
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
> + if (em->disk_num_bytes == 0)
> + dump_extent_map(fs_info, "zero disk_num_bytes", em);
> + if (em->offset + em->len > em->ram_bytes)
> + dump_extent_map(fs_info, "ram_bytes too small", em);
> + if (em->offset + em->len > em->disk_num_bytes &&
> + !extent_map_is_compressed(em))
> + dump_extent_map(fs_info, "disk_num_bytes too small", em);
> +
> + if (extent_map_is_compressed(em)) {
> + if (em->block_start != em->disk_bytenr)
> + dump_extent_map(fs_info,
> + "mismatch block_start/disk_bytenr/offset", em);
> + if (em->disk_num_bytes != em->block_len)
> + dump_extent_map(fs_info,
> + "mismatch disk_num_bytes/block_len", em);
> + /*
> + * Here we only check the start/orig_start/offset for
> + * compressed extents as that's the only case where
> + * orig_start is utilized.
> + */
> + if (em->orig_start != em->start - em->offset)
> + dump_extent_map(fs_info,
> + "mismatch orig_start/offset/start", em);
> +
> + } else if (em->block_start != em->disk_bytenr + em->offset) {
> + dump_extent_map(fs_info,
> + "mismatch block_start/disk_bytenr/offset", em);
> + }
> + } else if (em->offset) {
> + dump_extent_map(fs_info,
> + "non-zero offset for hole/inline", em);
> + }
I think I mentioned this before, but since these are all unexpected to
happen and we're in a critical section that can have a lot of
concurrency, adding unlikely() here would be good to have.
You can do that afterwards in a separate patch. I know some of these
checks get removed in later patches.
Reviewed-by: Filipe Manana <fdmanana@suse.com>
> +}
> +
> static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> {
> + struct btrfs_fs_info *fs_info = inode->root->fs_info;
> struct extent_map_tree *tree = &inode->extent_tree;
> struct extent_map *merge = NULL;
> struct rb_node *rb;
> @@ -319,6 +373,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> merge_ondisk_extents(merge, em);
> em->flags |= EXTENT_FLAG_MERGED;
>
> + validate_extent_map(fs_info, em);
> rb_erase(&merge->rb_node, &tree->root);
> RB_CLEAR_NODE(&merge->rb_node);
> free_extent_map(merge);
> @@ -334,6 +389,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> em->block_len += merge->block_len;
> if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> merge_ondisk_extents(em, merge);
> + validate_extent_map(fs_info, em);
> rb_erase(&merge->rb_node, &tree->root);
> RB_CLEAR_NODE(&merge->rb_node);
> em->generation = max(em->generation, merge->generation);
> @@ -445,6 +501,7 @@ static int add_extent_mapping(struct btrfs_inode *inode,
>
> lockdep_assert_held_write(&tree->lock);
>
> + validate_extent_map(fs_info, em);
> ret = tree_insert(&tree->root, em);
> if (ret)
> return ret;
> @@ -548,10 +605,13 @@ static void replace_extent_mapping(struct btrfs_inode *inode,
> struct extent_map *new,
> int modified)
> {
> + struct btrfs_fs_info *fs_info = inode->root->fs_info;
> struct extent_map_tree *tree = &inode->extent_tree;
>
> lockdep_assert_held_write(&tree->lock);
>
> + validate_extent_map(fs_info, new);
> +
> WARN_ON(cur->flags & EXTENT_FLAG_PINNED);
> ASSERT(extent_map_in_tree(cur));
> if (!(cur->flags & EXTENT_FLAG_LOGGING))
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 5f1a909a1d91..151ed1ebd291 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -2911,9 +2911,13 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
> return -ENOMEM;
>
> em->start = start;
> + em->orig_start = start;
> em->len = end + 1 - start;
> em->block_len = em->len;
> em->block_start = block_start;
> + em->disk_bytenr = block_start;
> + em->disk_num_bytes = em->len;
> + em->ram_bytes = em->len;
> em->flags |= EXTENT_FLAG_PINNED;
>
> lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state);
> diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
> index c511a1297956..e73ac7a0869c 100644
> --- a/fs/btrfs/tests/extent-map-tests.c
> +++ b/fs/btrfs/tests/extent-map-tests.c
> @@ -78,6 +78,9 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> em->len = SZ_16K;
> em->block_start = 0;
> em->block_len = SZ_16K;
> + em->disk_bytenr = 0;
> + em->disk_num_bytes = SZ_16K;
> + em->ram_bytes = SZ_16K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -96,9 +99,13 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> }
>
> em->start = SZ_16K;
> + em->orig_start = SZ_16K;
> em->len = SZ_4K;
> em->block_start = SZ_32K; /* avoid merging */
> em->block_len = SZ_4K;
> + em->disk_bytenr = SZ_32K; /* avoid merging */
> + em->disk_num_bytes = SZ_4K;
> + em->ram_bytes = SZ_4K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -117,9 +124,13 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
>
> /* Add [0, 8K), should return [0, 16K) instead. */
> em->start = start;
> + em->orig_start = start;
> em->len = len;
> em->block_start = start;
> em->block_len = len;
> + em->disk_bytenr = start;
> + em->disk_num_bytes = len;
> + em->ram_bytes = len;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -174,6 +185,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> em->len = SZ_1K;
> em->block_start = EXTENT_MAP_INLINE;
> em->block_len = (u64)-1;
> + em->disk_bytenr = EXTENT_MAP_INLINE;
> + em->disk_num_bytes = 0;
> + em->ram_bytes = SZ_1K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -192,9 +206,13 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> }
>
> em->start = SZ_4K;
> + em->orig_start = SZ_4K;
> em->len = SZ_4K;
> em->block_start = SZ_4K;
> em->block_len = SZ_4K;
> + em->disk_bytenr = SZ_4K;
> + em->disk_num_bytes = SZ_4K;
> + em->ram_bytes = SZ_4K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -216,6 +234,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> em->len = SZ_1K;
> em->block_start = EXTENT_MAP_INLINE;
> em->block_len = (u64)-1;
> + em->disk_bytenr = EXTENT_MAP_INLINE;
> + em->disk_num_bytes = 0;
> + em->ram_bytes = SZ_1K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -262,9 +283,13 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
>
> /* Add [4K, 8K) */
> em->start = SZ_4K;
> + em->orig_start = SZ_4K;
> em->len = SZ_4K;
> em->block_start = SZ_4K;
> em->block_len = SZ_4K;
> + em->disk_bytenr = SZ_4K;
> + em->disk_num_bytes = SZ_4K;
> + em->ram_bytes = SZ_4K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -286,6 +311,9 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
> em->len = SZ_16K;
> em->block_start = 0;
> em->block_len = SZ_16K;
> + em->disk_bytenr = 0;
> + em->disk_num_bytes = SZ_16K;
> + em->ram_bytes = SZ_16K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, start, len);
> write_unlock(&em_tree->lock);
> @@ -372,6 +400,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> em->len = SZ_8K;
> em->block_start = 0;
> em->block_len = SZ_8K;
> + em->disk_bytenr = 0;
> + em->disk_num_bytes = SZ_8K;
> + em->ram_bytes = SZ_8K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -390,9 +421,13 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
>
> /* Add [8K, 32K) */
> em->start = SZ_8K;
> + em->orig_start = SZ_8K;
> em->len = 24 * SZ_1K;
> em->block_start = SZ_16K; /* avoid merging */
> em->block_len = 24 * SZ_1K;
> + em->disk_bytenr = SZ_16K; /* avoid merging */
> + em->disk_num_bytes = 24 * SZ_1K;
> + em->ram_bytes = 24 * SZ_1K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -410,9 +445,13 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> }
> /* Add [0K, 32K) */
> em->start = 0;
> + em->orig_start = 0;
> em->len = SZ_32K;
> em->block_start = 0;
> em->block_len = SZ_32K;
> + em->disk_bytenr = 0;
> + em->disk_num_bytes = SZ_32K;
> + em->ram_bytes = SZ_32K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, start, len);
> write_unlock(&em_tree->lock);
> @@ -494,9 +533,13 @@ static int add_compressed_extent(struct btrfs_inode *inode,
> }
>
> em->start = start;
> + em->orig_start = start;
> em->len = len;
> em->block_start = block_start;
> em->block_len = SZ_4K;
> + em->disk_bytenr = block_start;
> + em->disk_num_bytes = SZ_4K;
> + em->ram_bytes = len;
> em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> @@ -715,9 +758,13 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> }
>
> em->start = SZ_4K;
> + em->orig_start = SZ_4K;
> em->len = SZ_4K;
> em->block_start = SZ_16K;
> em->block_len = SZ_16K;
> + em->disk_bytenr = SZ_16K;
> + em->disk_num_bytes = SZ_16K;
> + em->ram_bytes = SZ_16K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, 0, SZ_8K);
> write_unlock(&em_tree->lock);
> @@ -771,7 +818,10 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> em->len = SZ_16K;
> em->block_start = 0;
> em->block_len = SZ_4K;
> - em->flags |= EXTENT_FLAG_PINNED;
> + em->disk_bytenr = 0;
> + em->disk_num_bytes = SZ_4K;
> + em->ram_bytes = SZ_16K;
> + em->flags |= (EXTENT_FLAG_PINNED | EXTENT_FLAG_COMPRESS_ZLIB);
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> @@ -790,9 +840,13 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
>
> /* [32K, 48K), not pinned */
> em->start = SZ_32K;
> + em->orig_start = SZ_32K;
> em->len = SZ_16K;
> em->block_start = SZ_32K;
> em->block_len = SZ_16K;
> + em->disk_bytenr = SZ_32K;
> + em->disk_num_bytes = SZ_16K;
> + em->ram_bytes = SZ_16K;
> write_lock(&em_tree->lock);
> ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
> write_unlock(&em_tree->lock);
> diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
> index 99da9d34b77a..0895c6e06812 100644
> --- a/fs/btrfs/tests/inode-tests.c
> +++ b/fs/btrfs/tests/inode-tests.c
> @@ -117,7 +117,7 @@ static void setup_file_extents(struct btrfs_root *root, u32 sectorsize)
>
> /* Now for a regular extent */
> insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0,
> - disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
> + disk_bytenr, sectorsize - 1, BTRFS_FILE_EXTENT_REG, 0, slot);
> slot++;
> disk_bytenr += sectorsize;
> offset += sectorsize - 1;
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 07/11] btrfs: remove extent_map::block_start member
2024-05-23 5:03 ` [PATCH v3 07/11] btrfs: remove extent_map::block_start member Qu Wenruo
@ 2024-05-23 17:56 ` Filipe Manana
2024-05-23 23:23 ` Qu Wenruo
0 siblings, 1 reply; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 17:56 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, David Sterba
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> The member extent_map::block_start can be calculated from
> extent_map::disk_bytenr + extent_map::offset for regular extents.
> And otherwise just extent_map::disk_bytenr.
>
> And this is already validated by the validate_extent_map().
> Now we can remove the member.
>
> However there is a special case in btrfs_create_dio_extent() where we
> for NOCOW/PREALLOC ordered extents can not directly use the resulted
> btrfs_file_extent, as btrfs_split_ordered_extent() can not handle them
> yet.
> So for that call site, we pass file_extent->disk_bytenr +
> file_extent->num_bytes as disk_bytenr for the ordered extent, and 0 for
> offset.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
> fs/btrfs/compression.c | 3 +-
> fs/btrfs/defrag.c | 9 ++-
> fs/btrfs/extent_io.c | 10 ++--
> fs/btrfs/extent_map.c | 55 +++++------------
> fs/btrfs/extent_map.h | 22 ++++---
> fs/btrfs/file-item.c | 4 --
> fs/btrfs/file.c | 11 ++--
> fs/btrfs/inode.c | 80 ++++++++++++++-----------
> fs/btrfs/relocation.c | 1 -
> fs/btrfs/tests/extent-map-tests.c | 48 ++++++---------
> fs/btrfs/tests/inode-tests.c | 99 ++++++++++++++++---------------
> fs/btrfs/tree-log.c | 17 +++---
> fs/btrfs/zoned.c | 4 +-
> include/trace/events/btrfs.h | 11 +---
> 14 files changed, 168 insertions(+), 206 deletions(-)
>
> diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
> index cd88432e7072..07b31d1c0926 100644
> --- a/fs/btrfs/compression.c
> +++ b/fs/btrfs/compression.c
> @@ -507,7 +507,8 @@ static noinline int add_ra_bio_pages(struct inode *inode,
> */
> if (!em || cur < em->start ||
> (cur + fs_info->sectorsize > extent_map_end(em)) ||
> - (em->block_start >> SECTOR_SHIFT) != orig_bio->bi_iter.bi_sector) {
> + (extent_map_block_start(em) >> SECTOR_SHIFT) !=
> + orig_bio->bi_iter.bi_sector) {
> free_extent_map(em);
> unlock_extent(tree, cur, page_end, NULL);
> unlock_page(page);
> diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
> index 025e7f853a68..6fb94e897fc5 100644
> --- a/fs/btrfs/defrag.c
> +++ b/fs/btrfs/defrag.c
> @@ -707,7 +707,6 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
> */
> if (key.offset > start) {
> em->start = start;
> - em->block_start = EXTENT_MAP_HOLE;
> em->disk_bytenr = EXTENT_MAP_HOLE;
> em->disk_num_bytes = 0;
> em->ram_bytes = 0;
> @@ -828,7 +827,7 @@ static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em,
> */
> next = defrag_lookup_extent(inode, em->start + em->len, newer_than, locked);
> /* No more em or hole */
> - if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
> + if (!next || next->disk_bytenr >= EXTENT_MAP_LAST_BYTE)
> goto out;
> if (next->flags & EXTENT_FLAG_PREALLOC)
> goto out;
> @@ -995,12 +994,12 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
> * This is for users who want to convert inline extents to
> * regular ones through max_inline= mount option.
> */
> - if (em->block_start == EXTENT_MAP_INLINE &&
> + if (em->disk_bytenr == EXTENT_MAP_INLINE &&
> em->len <= inode->root->fs_info->max_inline)
> goto next;
>
> /* Skip holes and preallocated extents. */
> - if (em->block_start == EXTENT_MAP_HOLE ||
> + if (em->disk_bytenr == EXTENT_MAP_HOLE ||
> (em->flags & EXTENT_FLAG_PREALLOC))
> goto next;
>
> @@ -1065,7 +1064,7 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
> * So if an inline extent passed all above checks, just add it
> * for defrag, and be converted to regular extents.
> */
> - if (em->block_start == EXTENT_MAP_INLINE)
> + if (em->disk_bytenr == EXTENT_MAP_INLINE)
> goto add;
>
> next_mergeable = defrag_check_next_extent(&inode->vfs_inode, em,
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index bf50301ee528..063d7954c9ed 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -1083,10 +1083,10 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
> iosize = min(extent_map_end(em) - cur, end - cur + 1);
> iosize = ALIGN(iosize, blocksize);
> if (compress_type != BTRFS_COMPRESS_NONE)
> - disk_bytenr = em->block_start;
> + disk_bytenr = em->disk_bytenr;
> else
> - disk_bytenr = em->block_start + extent_offset;
> - block_start = em->block_start;
> + disk_bytenr = extent_map_block_start(em) + extent_offset;
> + block_start = extent_map_block_start(em);
> if (em->flags & EXTENT_FLAG_PREALLOC)
> block_start = EXTENT_MAP_HOLE;
>
> @@ -1405,8 +1405,8 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
> ASSERT(IS_ALIGNED(em->start, fs_info->sectorsize));
> ASSERT(IS_ALIGNED(em->len, fs_info->sectorsize));
>
> - block_start = em->block_start;
> - disk_bytenr = em->block_start + extent_offset;
> + block_start = extent_map_block_start(em);
> + disk_bytenr = extent_map_block_start(em) + extent_offset;
>
> ASSERT(!extent_map_is_compressed(em));
> ASSERT(block_start != EXTENT_MAP_HOLE);
> diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
> index 0c100fe47c43..38a1f07581b0 100644
> --- a/fs/btrfs/extent_map.c
> +++ b/fs/btrfs/extent_map.c
> @@ -192,9 +192,10 @@ static inline u64 extent_map_block_len(const struct extent_map *em)
>
> static inline u64 extent_map_block_end(const struct extent_map *em)
> {
> - if (em->block_start + extent_map_block_len(em) < em->block_start)
> + if (extent_map_block_start(em) + extent_map_block_len(em) <
> + extent_map_block_start(em))
> return (u64)-1;
> - return em->block_start + extent_map_block_len(em);
> + return extent_map_block_start(em) + extent_map_block_len(em);
> }
>
> static bool can_merge_extent_map(const struct extent_map *em)
> @@ -229,11 +230,11 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
> if (prev->flags != next->flags)
> return false;
>
> - if (next->block_start < EXTENT_MAP_LAST_BYTE - 1)
> - return next->block_start == extent_map_block_end(prev);
> + if (next->disk_bytenr < EXTENT_MAP_LAST_BYTE - 1)
> + return extent_map_block_start(next) == extent_map_block_end(prev);
>
> /* HOLES and INLINE extents. */
> - return next->block_start == prev->block_start;
> + return next->disk_bytenr == prev->disk_bytenr;
> }
>
> /*
> @@ -295,10 +296,9 @@ static void dump_extent_map(struct btrfs_fs_info *fs_info,
> {
> if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
> return;
> - btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu block_start=%llu flags=0x%x\n",
> + btrfs_crit(fs_info, "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu flags=0x%x\n",
> prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
> - em->ram_bytes, em->offset, em->block_start,
> - em->flags);
> + em->ram_bytes, em->offset, em->flags);
> ASSERT(0);
> }
>
> @@ -316,15 +316,6 @@ static void validate_extent_map(struct btrfs_fs_info *fs_info,
> if (em->offset + em->len > em->disk_num_bytes &&
> !extent_map_is_compressed(em))
> dump_extent_map(fs_info, "disk_num_bytes too small", em);
> -
> - if (extent_map_is_compressed(em)) {
> - if (em->block_start != em->disk_bytenr)
> - dump_extent_map(fs_info,
> - "mismatch block_start/disk_bytenr/offset", em);
> - } else if (em->block_start != em->disk_bytenr + em->offset) {
> - dump_extent_map(fs_info,
> - "mismatch block_start/disk_bytenr/offset", em);
> - }
> } else if (em->offset) {
> dump_extent_map(fs_info,
> "non-zero offset for hole/inline", em);
> @@ -359,7 +350,6 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> if (rb && can_merge_extent_map(merge) && mergeable_maps(merge, em)) {
> em->start = merge->start;
> em->len += merge->len;
> - em->block_start = merge->block_start;
> em->generation = max(em->generation, merge->generation);
>
> if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> @@ -669,11 +659,9 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
> start_diff = start - em->start;
> em->start = start;
> em->len = end - start;
> - if (em->block_start < EXTENT_MAP_LAST_BYTE &&
> - !extent_map_is_compressed(em)) {
> - em->block_start += start_diff;
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE &&
> + !extent_map_is_compressed(em))
> em->offset += start_diff;
> - }
> return add_extent_mapping(inode, em, 0);
> }
>
> @@ -708,7 +696,7 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode,
> * Tree-checker should have rejected any inline extent with non-zero
> * file offset. Here just do a sanity check.
> */
> - if (em->block_start == EXTENT_MAP_INLINE)
> + if (em->disk_bytenr == EXTENT_MAP_INLINE)
> ASSERT(em->start == 0);
>
> ret = add_extent_mapping(inode, em, 0);
> @@ -842,7 +830,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> u64 gen;
> unsigned long flags;
> bool modified;
> - bool compressed;
>
> if (em_end < end) {
> next_em = next_extent_map(em);
> @@ -876,7 +863,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> goto remove_em;
>
> gen = em->generation;
> - compressed = extent_map_is_compressed(em);
>
> if (em->start < start) {
> if (!split) {
> @@ -888,15 +874,12 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->start = em->start;
> split->len = start - em->start;
>
> - if (em->block_start < EXTENT_MAP_LAST_BYTE) {
> - split->block_start = em->block_start;
> -
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
> split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = em->disk_num_bytes;
> split->offset = em->offset;
> split->ram_bytes = em->ram_bytes;
> } else {
> - split->block_start = em->block_start;
> split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = 0;
> split->offset = 0;
> @@ -919,20 +902,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> }
> split->start = end;
> split->len = em_end - end;
> - split->block_start = em->block_start;
> split->disk_bytenr = em->disk_bytenr;
> split->flags = flags;
> split->generation = gen;
>
> - if (em->block_start < EXTENT_MAP_LAST_BYTE) {
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
> split->disk_num_bytes = em->disk_num_bytes;
> split->offset = em->offset + end - em->start;
> split->ram_bytes = em->ram_bytes;
> - if (!compressed) {
> - const u64 diff = end - em->start;
> -
> - split->block_start += diff;
> - }
> } else {
> split->disk_num_bytes = 0;
> split->offset = 0;
> @@ -1079,7 +1056,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
>
> ASSERT(em->len == len);
> ASSERT(!extent_map_is_compressed(em));
> - ASSERT(em->block_start < EXTENT_MAP_LAST_BYTE);
> + ASSERT(em->disk_bytenr < EXTENT_MAP_LAST_BYTE);
> ASSERT(em->flags & EXTENT_FLAG_PINNED);
> ASSERT(!(em->flags & EXTENT_FLAG_LOGGING));
> ASSERT(!list_empty(&em->list));
> @@ -1093,7 +1070,6 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> split_pre->disk_bytenr = new_logical;
> split_pre->disk_num_bytes = split_pre->len;
> split_pre->offset = 0;
> - split_pre->block_start = new_logical;
> split_pre->ram_bytes = split_pre->len;
> split_pre->flags = flags;
> split_pre->generation = em->generation;
> @@ -1108,10 +1084,9 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> /* Insert the middle extent_map. */
> split_mid->start = em->start + pre;
> split_mid->len = em->len - pre;
> - split_mid->disk_bytenr = em->block_start + pre;
> + split_mid->disk_bytenr = extent_map_block_start(em) + pre;
> split_mid->disk_num_bytes = split_mid->len;
> split_mid->offset = 0;
> - split_mid->block_start = em->block_start + pre;
> split_mid->ram_bytes = split_mid->len;
> split_mid->flags = flags;
> split_mid->generation = em->generation;
> diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
> index 5312bb542af0..2bcf7149b44c 100644
> --- a/fs/btrfs/extent_map.h
> +++ b/fs/btrfs/extent_map.h
> @@ -90,18 +90,6 @@ struct extent_map {
> */
> u64 ram_bytes;
>
> - /*
> - * The on-disk logical bytenr for the file extent.
> - *
> - * For compressed extents it matches btrfs_file_extent_item::disk_bytenr.
> - * For uncompressed extents it matches
> - * btrfs_file_extent_item::disk_bytenr + btrfs_file_extent_item::offset
> - *
> - * For holes it is EXTENT_MAP_HOLE and for inline extents it is
> - * EXTENT_MAP_INLINE.
> - */
> - u64 block_start;
> -
> /*
> * Generation of the extent map, for merged em it's the highest
> * generation of all merged ems.
> @@ -162,6 +150,16 @@ static inline int extent_map_in_tree(const struct extent_map *em)
> return !RB_EMPTY_NODE(&em->rb_node);
> }
>
> +static inline u64 extent_map_block_start(const struct extent_map *em)
> +{
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
> + if (extent_map_is_compressed(em))
> + return em->disk_bytenr;
> + return em->disk_bytenr + em->offset;
> + }
> + return em->disk_bytenr;
> +}
> +
> static inline u64 extent_map_end(const struct extent_map *em)
> {
> if (em->start + em->len < em->start)
> diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
> index 397df6588ce2..55703c833f3d 100644
> --- a/fs/btrfs/file-item.c
> +++ b/fs/btrfs/file-item.c
> @@ -1295,7 +1295,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> em->len = btrfs_file_extent_end(path) - extent_start;
> bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
> if (bytenr == 0) {
> - em->block_start = EXTENT_MAP_HOLE;
> em->disk_bytenr = EXTENT_MAP_HOLE;
> em->disk_num_bytes = 0;
> em->offset = 0;
> @@ -1306,10 +1305,8 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> em->offset = btrfs_file_extent_offset(leaf, fi);
> if (compress_type != BTRFS_COMPRESS_NONE) {
> extent_map_set_compression(em, compress_type);
> - em->block_start = bytenr;
> } else {
> bytenr += btrfs_file_extent_offset(leaf, fi);
> - em->block_start = bytenr;
> if (type == BTRFS_FILE_EXTENT_PREALLOC)
> em->flags |= EXTENT_FLAG_PREALLOC;
> }
> @@ -1317,7 +1314,6 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> /* Tree-checker has ensured this. */
> ASSERT(extent_start == 0);
>
> - em->block_start = EXTENT_MAP_INLINE;
> em->disk_bytenr = EXTENT_MAP_INLINE;
> em->start = 0;
> em->len = fs_info->sectorsize;
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 7033ea619073..f0cb7b29cab2 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -2348,7 +2348,6 @@ static int fill_holes(struct btrfs_trans_handle *trans,
> hole_em->len = end - offset;
> hole_em->ram_bytes = hole_em->len;
>
> - hole_em->block_start = EXTENT_MAP_HOLE;
> hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->disk_num_bytes = 0;
> hole_em->generation = trans->transid;
> @@ -2381,7 +2380,7 @@ static int find_first_non_hole(struct btrfs_inode *inode, u64 *start, u64 *len)
> return PTR_ERR(em);
>
> /* Hole or vacuum extent(only exists in no-hole mode) */
> - if (em->block_start == EXTENT_MAP_HOLE) {
> + if (em->disk_bytenr == EXTENT_MAP_HOLE) {
> ret = 1;
> *len = em->start + em->len > *start + *len ?
> 0 : *start + *len - em->start - em->len;
> @@ -3038,7 +3037,7 @@ static int btrfs_zero_range_check_range_boundary(struct btrfs_inode *inode,
> if (IS_ERR(em))
> return PTR_ERR(em);
>
> - if (em->block_start == EXTENT_MAP_HOLE)
> + if (em->disk_bytenr == EXTENT_MAP_HOLE)
> ret = RANGE_BOUNDARY_HOLE;
> else if (em->flags & EXTENT_FLAG_PREALLOC)
> ret = RANGE_BOUNDARY_PREALLOC_EXTENT;
> @@ -3102,7 +3101,7 @@ static int btrfs_zero_range(struct inode *inode,
> ASSERT(IS_ALIGNED(alloc_start, sectorsize));
> len = offset + len - alloc_start;
> offset = alloc_start;
> - alloc_hint = em->block_start + em->len;
> + alloc_hint = extent_map_block_start(em) + em->len;
> }
> free_extent_map(em);
>
> @@ -3120,7 +3119,7 @@ static int btrfs_zero_range(struct inode *inode,
> mode);
> goto out;
> }
> - if (len < sectorsize && em->block_start != EXTENT_MAP_HOLE) {
> + if (len < sectorsize && em->disk_bytenr != EXTENT_MAP_HOLE) {
> free_extent_map(em);
> ret = btrfs_truncate_block(BTRFS_I(inode), offset, len,
> 0);
> @@ -3333,7 +3332,7 @@ static long btrfs_fallocate(struct file *file, int mode,
> last_byte = min(extent_map_end(em), alloc_end);
> actual_end = min_t(u64, extent_map_end(em), offset + len);
> last_byte = ALIGN(last_byte, blocksize);
> - if (em->block_start == EXTENT_MAP_HOLE ||
> + if (em->disk_bytenr == EXTENT_MAP_HOLE ||
> (cur_offset >= inode->i_size &&
> !(em->flags & EXTENT_FLAG_PREALLOC))) {
> const u64 range_len = last_byte - cur_offset;
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 00bb64fdf938..1b78769d1e41 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -138,7 +138,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
> u64 end, struct writeback_control *wbc,
> bool pages_dirty);
> static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> - u64 len, u64 block_start,
> + u64 len,
> u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> struct btrfs_file_extent *file_extent,
> @@ -1209,7 +1209,6 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
>
> em = create_io_em(inode, start,
> async_extent->ram_size, /* len */
> - ins.objectid, /* block_start */
> ins.offset, /* orig_block_len */
> async_extent->ram_size, /* ram_bytes */
> async_extent->compress_type,
> @@ -1287,15 +1286,15 @@ static u64 get_extent_allocation_hint(struct btrfs_inode *inode, u64 start,
> * first block in this inode and use that as a hint. If that
> * block is also bogus then just don't worry about it.
> */
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> free_extent_map(em);
> em = search_extent_mapping(em_tree, 0, 0);
> - if (em && em->block_start < EXTENT_MAP_LAST_BYTE)
> - alloc_hint = em->block_start;
> + if (em && em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> + alloc_hint = extent_map_block_start(em);
> if (em)
> free_extent_map(em);
> } else {
> - alloc_hint = em->block_start;
> + alloc_hint = extent_map_block_start(em);
> free_extent_map(em);
> }
> }
> @@ -1451,7 +1450,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> &cached);
>
> em = create_io_em(inode, start, ins.offset, /* len */
> - ins.objectid, /* block_start */
> ins.offset, /* orig_block_len */
> ram_size, /* ram_bytes */
> BTRFS_COMPRESS_NONE, /* compress_type */
> @@ -2188,7 +2186,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
> struct extent_map *em;
>
> em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
> - nocow_args.disk_bytenr, /* block_start */
> nocow_args.disk_num_bytes, /* orig_block_len */
> ram_bytes, BTRFS_COMPRESS_NONE,
> &nocow_args.file_extent,
> @@ -2703,7 +2700,7 @@ static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
> if (IS_ERR(em))
> return PTR_ERR(em);
>
> - if (em->block_start != EXTENT_MAP_HOLE)
> + if (extent_map_block_start(em) != EXTENT_MAP_HOLE)
This should be: if (em->disk_bytenr != EXTENT_MAP_HOLE)
Everything else looks fine. Thanks.
> goto next;
>
> em_len = em->len;
> @@ -5022,7 +5019,6 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
> hole_em->start = cur_offset;
> hole_em->len = hole_size;
>
> - hole_em->block_start = EXTENT_MAP_HOLE;
> hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->disk_num_bytes = 0;
> hole_em->ram_bytes = hole_size;
> @@ -6879,7 +6875,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> if (em) {
> if (em->start > start || em->start + em->len <= start)
> free_extent_map(em);
> - else if (em->block_start == EXTENT_MAP_INLINE && page)
> + else if (em->disk_bytenr == EXTENT_MAP_INLINE && page)
> free_extent_map(em);
> else
> goto out;
> @@ -6982,7 +6978,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> /* New extent overlaps with existing one */
> em->start = start;
> em->len = found_key.offset - start;
> - em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> goto insert;
> }
>
> @@ -7006,7 +7002,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> *
> * Other members are not utilized for inline extents.
> */
> - ASSERT(em->block_start == EXTENT_MAP_INLINE);
> + ASSERT(em->disk_bytenr == EXTENT_MAP_INLINE);
> ASSERT(em->len == fs_info->sectorsize);
>
> ret = read_inline_extent(inode, path, page);
> @@ -7017,7 +7013,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> not_found:
> em->start = start;
> em->len = len;
> - em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> insert:
> ret = 0;
> btrfs_release_path(path);
> @@ -7048,7 +7044,6 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> struct btrfs_dio_data *dio_data,
> const u64 start,
> const u64 len,
> - const u64 block_start,
> const u64 orig_block_len,
> const u64 ram_bytes,
> const int type,
> @@ -7058,15 +7053,34 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> struct btrfs_ordered_extent *ordered;
>
> if (type != BTRFS_ORDERED_NOCOW) {
> - em = create_io_em(inode, start, len, block_start,
> + em = create_io_em(inode, start, len,
> orig_block_len, ram_bytes,
> BTRFS_COMPRESS_NONE, /* compress_type */
> file_extent, type);
> if (IS_ERR(em))
> goto out;
> }
> +
> + /*
> + * For regular writes, file_extent->offset is always 0,
> + * thus we really only need file_extent->disk_bytenr, every other length
> + * (disk_num_bytes/ram_bytes) should match @len and
> + * file_extent->num_bytes.
> + *
> + * For NOCOW, we don't really care about the numbers except
> + * @start and @len, as we won't insert a file extent
> + * item at all.
> + *
> + * For PREALLOC, we do not use ordered extent members, but
> + * btrfs_mark_extent_written() handles everything.
> + *
> + * So here we always passing 0 as offset for the ordered extent,
> + * or btrfs_split_ordered_extent() can not handle it correctly.
> + */
> ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
> - block_start, len, 0,
> + file_extent->disk_bytenr +
> + file_extent->offset,
> + len, 0,
> (1 << type) |
> (1 << BTRFS_ORDERED_DIRECT),
> BTRFS_COMPRESS_NONE);
> @@ -7118,7 +7132,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
> file_extent.offset = 0;
> file_extent.compression = BTRFS_COMPRESS_NONE;
> em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
> - ins.objectid, ins.offset,
> + ins.offset,
> ins.offset, BTRFS_ORDERED_REGULAR,
> &file_extent);
> btrfs_dec_block_group_reservations(fs_info, ins.objectid);
> @@ -7358,7 +7372,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
>
> /* The callers of this must take lock_extent() */
> static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> - u64 len, u64 block_start,
> + u64 len,
> u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> struct btrfs_file_extent *file_extent,
> @@ -7410,7 +7424,6 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
>
> em->start = start;
> em->len = len;
> - em->block_start = block_start;
> em->disk_bytenr = file_extent->disk_bytenr;
> em->disk_num_bytes = disk_num_bytes;
> em->ram_bytes = ram_bytes;
> @@ -7461,13 +7474,13 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> */
> if ((em->flags & EXTENT_FLAG_PREALLOC) ||
> ((BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) &&
> - em->block_start != EXTENT_MAP_HOLE)) {
> + em->disk_bytenr != EXTENT_MAP_HOLE)) {
> if (em->flags & EXTENT_FLAG_PREALLOC)
> type = BTRFS_ORDERED_PREALLOC;
> else
> type = BTRFS_ORDERED_NOCOW;
> len = min(len, em->len - (start - em->start));
> - block_start = em->block_start + (start - em->start);
> + block_start = extent_map_block_start(em) + (start - em->start);
>
> if (can_nocow_extent(inode, start, &len,
> &orig_block_len, &ram_bytes,
> @@ -7497,7 +7510,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> space_reserved = true;
>
> em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
> - block_start,
> orig_block_len,
> ram_bytes, type,
> &file_extent);
> @@ -7700,7 +7712,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
> * the generic code.
> */
> if (extent_map_is_compressed(em) ||
> - em->block_start == EXTENT_MAP_INLINE) {
> + em->disk_bytenr == EXTENT_MAP_INLINE) {
> free_extent_map(em);
> /*
> * If we are in a NOWAIT context, return -EAGAIN in order to
> @@ -7794,12 +7806,12 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
> * We trim the extents (and move the addr) even though iomap code does
> * that, since we have locked only the parts we are performing I/O in.
> */
> - if ((em->block_start == EXTENT_MAP_HOLE) ||
> + if ((em->disk_bytenr == EXTENT_MAP_HOLE) ||
> ((em->flags & EXTENT_FLAG_PREALLOC) && !write)) {
> iomap->addr = IOMAP_NULL_ADDR;
> iomap->type = IOMAP_HOLE;
> } else {
> - iomap->addr = em->block_start + (start - em->start);
> + iomap->addr = extent_map_block_start(em) + (start - em->start);
> iomap->type = IOMAP_MAPPED;
> }
> iomap->offset = start;
> @@ -9638,7 +9650,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
>
> em->start = cur_offset;
> em->len = ins.offset;
> - em->block_start = ins.objectid;
> em->disk_bytenr = ins.objectid;
> em->offset = 0;
> em->disk_num_bytes = ins.offset;
> @@ -10104,7 +10115,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
> goto out_unlock_extent;
> }
>
> - if (em->block_start == EXTENT_MAP_INLINE) {
> + if (em->disk_bytenr == EXTENT_MAP_INLINE) {
> u64 extent_start = em->start;
>
> /*
> @@ -10125,14 +10136,14 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
> */
> encoded->len = min_t(u64, extent_map_end(em),
> inode->vfs_inode.i_size) - iocb->ki_pos;
> - if (em->block_start == EXTENT_MAP_HOLE ||
> + if (em->disk_bytenr == EXTENT_MAP_HOLE ||
> (em->flags & EXTENT_FLAG_PREALLOC)) {
> disk_bytenr = EXTENT_MAP_HOLE;
> count = min_t(u64, count, encoded->len);
> encoded->len = count;
> encoded->unencoded_len = count;
> } else if (extent_map_is_compressed(em)) {
> - disk_bytenr = em->block_start;
> + disk_bytenr = em->disk_bytenr;
> /*
> * Bail if the buffer isn't large enough to return the whole
> * compressed extent.
> @@ -10151,7 +10162,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
> goto out_em;
> encoded->compression = ret;
> } else {
> - disk_bytenr = em->block_start + (start - em->start);
> + disk_bytenr = extent_map_block_start(em) + (start - em->start);
> if (encoded->len > count)
> encoded->len = count;
> /*
> @@ -10389,7 +10400,6 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> file_extent.offset = encoded->unencoded_offset;
> file_extent.compression = compression;
> em = create_io_em(inode, start, num_bytes,
> - ins.objectid,
> ins.offset, ram_bytes, compression,
> &file_extent, BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(em)) {
> @@ -10693,12 +10703,12 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
> goto out;
> }
>
> - if (em->block_start == EXTENT_MAP_HOLE) {
> + if (em->disk_bytenr == EXTENT_MAP_HOLE) {
> btrfs_warn(fs_info, "swapfile must not have holes");
> ret = -EINVAL;
> goto out;
> }
> - if (em->block_start == EXTENT_MAP_INLINE) {
> + if (em->disk_bytenr == EXTENT_MAP_INLINE) {
> /*
> * It's unlikely we'll ever actually find ourselves
> * here, as a file small enough to fit inline won't be
> @@ -10716,7 +10726,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
> goto out;
> }
>
> - logical_block_start = em->block_start + (start - em->start);
> + logical_block_start = extent_map_block_start(em) + (start - em->start);
> len = min(len, em->len - (start - em->start));
> free_extent_map(em);
> em = NULL;
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 68fe52ab445d..bcb665613e78 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -2912,7 +2912,6 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
>
> em->start = start;
> em->len = end + 1 - start;
> - em->block_start = block_start;
> em->disk_bytenr = block_start;
> em->disk_num_bytes = em->len;
> em->ram_bytes = em->len;
> diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c
> index 0dd270d6c506..ebec4ab361b8 100644
> --- a/fs/btrfs/tests/extent-map-tests.c
> +++ b/fs/btrfs/tests/extent-map-tests.c
> @@ -28,8 +28,8 @@ static int free_extent_map_tree(struct btrfs_inode *inode)
> if (refcount_read(&em->refs) != 1) {
> ret = -EINVAL;
> test_err(
> -"em leak: em (start %llu len %llu block_start %llu disk_num_bytes %llu offset %llu) refs %d",
> - em->start, em->len, em->block_start,
> +"em leak: em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu offset %llu) refs %d",
> + em->start, em->len, em->disk_bytenr,
> em->disk_num_bytes, em->offset,
> refcount_read(&em->refs));
>
> @@ -77,7 +77,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* Add [0, 16K) */
> em->start = 0;
> em->len = SZ_16K;
> - em->block_start = 0;
> em->disk_bytenr = 0;
> em->disk_num_bytes = SZ_16K;
> em->ram_bytes = SZ_16K;
> @@ -100,7 +99,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
>
> em->start = SZ_16K;
> em->len = SZ_4K;
> - em->block_start = SZ_32K; /* avoid merging */
> em->disk_bytenr = SZ_32K; /* avoid merging */
> em->disk_num_bytes = SZ_4K;
> em->ram_bytes = SZ_4K;
> @@ -123,7 +121,6 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* Add [0, 8K), should return [0, 16K) instead. */
> em->start = start;
> em->len = len;
> - em->block_start = start;
> em->disk_bytenr = start;
> em->disk_num_bytes = len;
> em->ram_bytes = len;
> @@ -141,11 +138,11 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> goto out;
> }
> if (em->start != 0 || extent_map_end(em) != SZ_16K ||
> - em->block_start != 0 || em->disk_num_bytes != SZ_16K) {
> + em->disk_bytenr != 0 || em->disk_num_bytes != SZ_16K) {
> test_err(
> -"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu",
> +"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu",
> start, start + len, ret, em->start, em->len,
> - em->block_start, em->disk_num_bytes);
> + em->disk_bytenr, em->disk_num_bytes);
> ret = -EINVAL;
> }
> free_extent_map(em);
> @@ -179,7 +176,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* Add [0, 1K) */
> em->start = 0;
> em->len = SZ_1K;
> - em->block_start = EXTENT_MAP_INLINE;
> em->disk_bytenr = EXTENT_MAP_INLINE;
> em->disk_num_bytes = 0;
> em->ram_bytes = SZ_1K;
> @@ -202,7 +198,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
>
> em->start = SZ_4K;
> em->len = SZ_4K;
> - em->block_start = SZ_4K;
> em->disk_bytenr = SZ_4K;
> em->disk_num_bytes = SZ_4K;
> em->ram_bytes = SZ_4K;
> @@ -225,7 +220,6 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* Add [0, 1K) */
> em->start = 0;
> em->len = SZ_1K;
> - em->block_start = EXTENT_MAP_INLINE;
> em->disk_bytenr = EXTENT_MAP_INLINE;
> em->disk_num_bytes = 0;
> em->ram_bytes = SZ_1K;
> @@ -242,10 +236,10 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> goto out;
> }
> if (em->start != 0 || extent_map_end(em) != SZ_1K ||
> - em->block_start != EXTENT_MAP_INLINE) {
> + em->disk_bytenr != EXTENT_MAP_INLINE) {
> test_err(
> -"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu",
> - ret, em->start, em->len, em->block_start);
> +"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu",
> + ret, em->start, em->len, em->disk_bytenr);
> ret = -EINVAL;
> }
> free_extent_map(em);
> @@ -275,7 +269,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
> /* Add [4K, 8K) */
> em->start = SZ_4K;
> em->len = SZ_4K;
> - em->block_start = SZ_4K;
> em->disk_bytenr = SZ_4K;
> em->disk_num_bytes = SZ_4K;
> em->ram_bytes = SZ_4K;
> @@ -298,7 +291,6 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
> /* Add [0, 16K) */
> em->start = 0;
> em->len = SZ_16K;
> - em->block_start = 0;
> em->disk_bytenr = 0;
> em->disk_num_bytes = SZ_16K;
> em->ram_bytes = SZ_16K;
> @@ -321,11 +313,11 @@ static int __test_case_3(struct btrfs_fs_info *fs_info,
> * em->start.
> */
> if (start < em->start || start + len > extent_map_end(em) ||
> - em->start != em->block_start) {
> + em->start != extent_map_block_start(em)) {
> test_err(
> -"case3 [%llu %llu): ret %d em (start %llu len %llu block_start %llu block_len %llu)",
> +"case3 [%llu %llu): ret %d em (start %llu len %llu disk_bytenr %llu block_len %llu)",
> start, start + len, ret, em->start, em->len,
> - em->block_start, em->disk_num_bytes);
> + em->disk_bytenr, em->disk_num_bytes);
> ret = -EINVAL;
> }
> free_extent_map(em);
> @@ -386,7 +378,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> /* Add [0K, 8K) */
> em->start = 0;
> em->len = SZ_8K;
> - em->block_start = 0;
> em->disk_bytenr = 0;
> em->disk_num_bytes = SZ_8K;
> em->ram_bytes = SZ_8K;
> @@ -409,7 +400,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> /* Add [8K, 32K) */
> em->start = SZ_8K;
> em->len = 24 * SZ_1K;
> - em->block_start = SZ_16K; /* avoid merging */
> em->disk_bytenr = SZ_16K; /* avoid merging */
> em->disk_num_bytes = 24 * SZ_1K;
> em->ram_bytes = 24 * SZ_1K;
> @@ -431,7 +421,6 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> /* Add [0K, 32K) */
> em->start = 0;
> em->len = SZ_32K;
> - em->block_start = 0;
> em->disk_bytenr = 0;
> em->disk_num_bytes = SZ_32K;
> em->ram_bytes = SZ_32K;
> @@ -451,9 +440,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info,
> }
> if (start < em->start || start + len > extent_map_end(em)) {
> test_err(
> -"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu block_start %llu disk_num_bytes %llu)",
> - start, start + len, ret, em->start, em->len, em->block_start,
> - em->disk_num_bytes);
> +"case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu)",
> + start, start + len, ret, em->start, em->len,
> + em->disk_bytenr, em->disk_num_bytes);
> ret = -EINVAL;
> }
> free_extent_map(em);
> @@ -517,7 +506,6 @@ static int add_compressed_extent(struct btrfs_inode *inode,
>
> em->start = start;
> em->len = len;
> - em->block_start = block_start;
> em->disk_bytenr = block_start;
> em->disk_num_bytes = SZ_4K;
> em->ram_bytes = len;
> @@ -740,7 +728,6 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
>
> em->start = SZ_4K;
> em->len = SZ_4K;
> - em->block_start = SZ_16K;
> em->disk_bytenr = SZ_16K;
> em->disk_num_bytes = SZ_16K;
> em->ram_bytes = SZ_16K;
> @@ -795,7 +782,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* [0, 16K), pinned */
> em->start = 0;
> em->len = SZ_16K;
> - em->block_start = 0;
> em->disk_bytenr = 0;
> em->disk_num_bytes = SZ_4K;
> em->ram_bytes = SZ_16K;
> @@ -819,7 +805,6 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> /* [32K, 48K), not pinned */
> em->start = SZ_32K;
> em->len = SZ_16K;
> - em->block_start = SZ_32K;
> em->disk_bytenr = SZ_32K;
> em->disk_num_bytes = SZ_16K;
> em->ram_bytes = SZ_16K;
> @@ -885,8 +870,9 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
> goto out;
> }
>
> - if (em->block_start != SZ_32K + SZ_4K) {
> - test_err("em->block_start is %llu, expected 36K", em->block_start);
> + if (extent_map_block_start(em) != SZ_32K + SZ_4K) {
> + test_err("em->block_start is %llu, expected 36K",
> + extent_map_block_start(em));
> goto out;
> }
>
> diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
> index fc390c18ac95..b8f0d67f4cf6 100644
> --- a/fs/btrfs/tests/inode-tests.c
> +++ b/fs/btrfs/tests/inode-tests.c
> @@ -264,8 +264,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_HOLE) {
> - test_err("expected a hole, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_HOLE) {
> + test_err("expected a hole, got %llu", em->disk_bytenr);
> goto out;
> }
> free_extent_map(em);
> @@ -283,8 +283,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_INLINE) {
> - test_err("expected an inline, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_INLINE) {
> + test_err("expected an inline, got %llu", em->disk_bytenr);
> goto out;
> }
>
> @@ -321,8 +321,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_HOLE) {
> - test_err("expected a hole, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_HOLE) {
> + test_err("expected a hole, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != 4) {
> @@ -344,8 +344,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize - 1) {
> @@ -371,8 +371,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -389,7 +389,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("wrong offset, want 0, have %llu", em->offset);
> goto out;
> }
> - disk_bytenr = em->block_start;
> + disk_bytenr = extent_map_block_start(em);
> orig_start = em->start;
> offset = em->start + em->len;
> free_extent_map(em);
> @@ -399,8 +399,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_HOLE) {
> - test_err("expected a hole, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_HOLE) {
> + test_err("expected a hole, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -421,8 +421,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != 2 * sectorsize) {
> @@ -441,9 +441,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> goto out;
> }
> disk_bytenr += (em->start - orig_start);
> - if (em->block_start != disk_bytenr) {
> + if (extent_map_block_start(em) != disk_bytenr) {
> test_err("wrong block start, want %llu, have %llu",
> - disk_bytenr, em->block_start);
> + disk_bytenr, extent_map_block_start(em));
> goto out;
> }
> offset = em->start + em->len;
> @@ -455,8 +455,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -483,8 +483,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -502,7 +502,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("wrong offset, want 0, have %llu", em->offset);
> goto out;
> }
> - disk_bytenr = em->block_start;
> + disk_bytenr = extent_map_block_start(em);
> orig_start = em->start;
> offset = em->start + em->len;
> free_extent_map(em);
> @@ -512,8 +512,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_HOLE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_HOLE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -531,9 +531,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> em->start - orig_start, em->offset);
> goto out;
> }
> - if (em->block_start != disk_bytenr + em->offset) {
> + if (extent_map_block_start(em) != disk_bytenr + em->offset) {
> test_err("unexpected block start, wanted %llu, have %llu",
> - disk_bytenr + em->offset, em->block_start);
> + disk_bytenr + em->offset, extent_map_block_start(em));
> goto out;
> }
> offset = em->start + em->len;
> @@ -544,8 +544,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != 2 * sectorsize) {
> @@ -564,9 +564,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> em->start, em->offset, orig_start);
> goto out;
> }
> - if (em->block_start != disk_bytenr + em->offset) {
> + if (extent_map_block_start(em) != disk_bytenr + em->offset) {
> test_err("unexpected block start, wanted %llu, have %llu",
> - disk_bytenr + em->offset, em->block_start);
> + disk_bytenr + em->offset, extent_map_block_start(em));
> goto out;
> }
> offset = em->start + em->len;
> @@ -578,8 +578,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != 2 * sectorsize) {
> @@ -611,8 +611,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -635,7 +635,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> BTRFS_COMPRESS_ZLIB, extent_map_compression(em));
> goto out;
> }
> - disk_bytenr = em->block_start;
> + disk_bytenr = extent_map_block_start(em);
> orig_start = em->start;
> offset = em->start + em->len;
> free_extent_map(em);
> @@ -645,8 +645,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -671,9 +671,9 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != disk_bytenr) {
> + if (extent_map_block_start(em) != disk_bytenr) {
> test_err("block start does not match, want %llu got %llu",
> - disk_bytenr, em->block_start);
> + disk_bytenr, extent_map_block_start(em));
> goto out;
> }
> if (em->start != offset || em->len != 2 * sectorsize) {
> @@ -706,8 +706,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -732,8 +732,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_HOLE) {
> - test_err("expected a hole extent, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_HOLE) {
> + test_err("expected a hole extent, got %llu", em->disk_bytenr);
> goto out;
> }
> /*
> @@ -764,8 +764,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
> + test_err("expected a real extent, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != offset || em->len != sectorsize) {
> @@ -843,8 +843,8 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != EXTENT_MAP_HOLE) {
> - test_err("expected a hole, got %llu", em->block_start);
> + if (em->disk_bytenr != EXTENT_MAP_HOLE) {
> + test_err("expected a hole, got %llu", em->disk_bytenr);
> goto out;
> }
> if (em->start != 0 || em->len != sectorsize) {
> @@ -865,8 +865,9 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
> test_err("got an error when we shouldn't have");
> goto out;
> }
> - if (em->block_start != sectorsize) {
> - test_err("expected a real extent, got %llu", em->block_start);
> + if (extent_map_block_start(em) != sectorsize) {
> + test_err("expected a real extent, got %llu",
> + extent_map_block_start(em));
> goto out;
> }
> if (em->start != sectorsize || em->len != sectorsize) {
> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
> index 1d04f0cb6f53..f1e006a5fc4c 100644
> --- a/fs/btrfs/tree-log.c
> +++ b/fs/btrfs/tree-log.c
> @@ -4578,6 +4578,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
> {
> struct btrfs_ordered_extent *ordered;
> struct btrfs_root *csum_root;
> + u64 block_start;
> u64 csum_offset;
> u64 csum_len;
> u64 mod_start = em->start;
> @@ -4587,7 +4588,7 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
>
> if (inode->flags & BTRFS_INODE_NODATASUM ||
> (em->flags & EXTENT_FLAG_PREALLOC) ||
> - em->block_start == EXTENT_MAP_HOLE)
> + em->disk_bytenr == EXTENT_MAP_HOLE)
> return 0;
>
> list_for_each_entry(ordered, &ctx->ordered_extents, log_list) {
> @@ -4658,9 +4659,10 @@ static int log_extent_csums(struct btrfs_trans_handle *trans,
> }
>
> /* block start is already adjusted for the file extent offset. */
> - csum_root = btrfs_csum_root(trans->fs_info, em->block_start);
> - ret = btrfs_lookup_csums_list(csum_root, em->block_start + csum_offset,
> - em->block_start + csum_offset +
> + block_start = extent_map_block_start(em);
> + csum_root = btrfs_csum_root(trans->fs_info, block_start);
> + ret = btrfs_lookup_csums_list(csum_root, block_start + csum_offset,
> + block_start + csum_offset +
> csum_len - 1, &ordered_sums, false);
> if (ret < 0)
> return ret;
> @@ -4692,6 +4694,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
> struct btrfs_key key;
> enum btrfs_compression_type compress_type;
> u64 extent_offset = em->offset;
> + u64 block_start = extent_map_block_start(em);
> u64 block_len;
> int ret;
>
> @@ -4704,10 +4707,10 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
> block_len = em->disk_num_bytes;
> compress_type = extent_map_compression(em);
> if (compress_type != BTRFS_COMPRESS_NONE) {
> - btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start);
> + btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start);
> btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
> - } else if (em->block_start < EXTENT_MAP_LAST_BYTE) {
> - btrfs_set_stack_file_extent_disk_bytenr(&fi, em->block_start -
> + } else if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
> + btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start -
> extent_offset);
> btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
> }
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index c52a0063f7db..da9de81f340e 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -1773,7 +1773,9 @@ static void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered,
> write_lock(&em_tree->lock);
> em = search_extent_mapping(em_tree, ordered->file_offset,
> ordered->num_bytes);
> - em->block_start = logical;
> + /* The em should be a new COW extent, thus it should not have an offset. */
> + ASSERT(em->offset == 0);
> + em->disk_bytenr = logical;
> free_extent_map(em);
> write_unlock(&em_tree->lock);
> }
> diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
> index a1804239812c..ca0f99689a2d 100644
> --- a/include/trace/events/btrfs.h
> +++ b/include/trace/events/btrfs.h
> @@ -291,7 +291,6 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
> __field( u64, ino )
> __field( u64, start )
> __field( u64, len )
> - __field( u64, block_start )
> __field( u32, flags )
> __field( int, refs )
> ),
> @@ -301,18 +300,16 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
> __entry->ino = btrfs_ino(inode);
> __entry->start = map->start;
> __entry->len = map->len;
> - __entry->block_start = map->block_start;
> __entry->flags = map->flags;
> __entry->refs = refcount_read(&map->refs);
> ),
>
> TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu len=%llu "
> - "block_start=%llu(%s) flags=%s refs=%u",
> + "flags=%s refs=%u",
> show_root_type(__entry->root_objectid),
> __entry->ino,
> __entry->start,
> __entry->len,
> - show_map_type(__entry->block_start),
> show_map_flags(__entry->flags),
> __entry->refs)
> );
> @@ -2608,7 +2605,6 @@ TRACE_EVENT(btrfs_extent_map_shrinker_remove_em,
> __field( u64, root_id )
> __field( u64, start )
> __field( u64, len )
> - __field( u64, block_start )
> __field( u32, flags )
> ),
>
> @@ -2617,15 +2613,12 @@ TRACE_EVENT(btrfs_extent_map_shrinker_remove_em,
> __entry->root_id = inode->root->root_key.objectid;
> __entry->start = em->start;
> __entry->len = em->len;
> - __entry->block_start = em->block_start;
> __entry->flags = em->flags;
> ),
>
> - TP_printk_btrfs(
> -"ino=%llu root=%llu(%s) start=%llu len=%llu block_start=%llu(%s) flags=%s",
> + TP_printk_btrfs("ino=%llu root=%llu(%s) start=%llu len=%llu flags=%s",
> __entry->ino, show_root_type(__entry->root_id),
> __entry->start, __entry->len,
> - show_map_type(__entry->block_start),
> show_map_flags(__entry->flags))
> );
>
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent
2024-05-23 5:03 ` [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent Qu Wenruo
@ 2024-05-23 18:17 ` Filipe Manana
0 siblings, 0 replies; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 18:17 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> All parameters after @filepos of btrfs_alloc_ordered_extent() can be
> replaced with btrfs_file_extent structure.
>
> This patch does the cleanup, meanwhile some points to note:
>
> - Move btrfs_file_extent structure to ordered-data.h
> The structure is needed by both btrfs_alloc_ordered_extent() and
> can_nocow_extent(), but since btrfs_inode.h includes
> ordered-data.h, so we need to move the structure to ordered-data.h.
>
> - Move the special handling of NOCOW/PREALLOC into
> btrfs_alloc_ordered_extent()
> This is to allow btrfs_split_ordered_extent() to properly split them
> for DIO.
> For now just move the handling into btrfs_alloc_ordered_extent() to
> simplify the callers.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> fs/btrfs/btrfs_inode.h | 14 -----------
> fs/btrfs/inode.c | 56 ++++++++---------------------------------
> fs/btrfs/ordered-data.c | 34 ++++++++++++++++++++-----
> fs/btrfs/ordered-data.h | 19 +++++++++++---
> 4 files changed, 54 insertions(+), 69 deletions(-)
>
> diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
> index dbc85efdf68a..97ce56a60672 100644
> --- a/fs/btrfs/btrfs_inode.h
> +++ b/fs/btrfs/btrfs_inode.h
> @@ -514,20 +514,6 @@ int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page,
> u32 pgoff, u8 *csum, const u8 * const csum_expected);
> bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
> u32 bio_offset, struct bio_vec *bv);
> -
> -/*
> - * This represents details about the target file extent item of a write
> - * operation.
> - */
> -struct btrfs_file_extent {
> - u64 disk_bytenr;
> - u64 disk_num_bytes;
> - u64 num_bytes;
> - u64 ram_bytes;
> - u64 offset;
> - u8 compression;
> -};
> -
> noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
> struct btrfs_file_extent *file_extent,
> bool nowait, bool strict);
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 445c19d96d10..35f03149b777 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -1220,14 +1220,8 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> }
> free_extent_map(em);
>
> - ordered = btrfs_alloc_ordered_extent(inode, start, /* file_offset */
> - async_extent->ram_size, /* num_bytes */
> - async_extent->ram_size, /* ram_bytes */
> - ins.objectid, /* disk_bytenr */
> - ins.offset, /* disk_num_bytes */
> - 0, /* offset */
> - 1 << BTRFS_ORDERED_COMPRESSED,
> - async_extent->compress_type);
> + ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
> + 1 << BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(ordered)) {
> btrfs_drop_extent_map_range(inode, start, end, false);
> ret = PTR_ERR(ordered);
> @@ -1463,10 +1457,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> }
> free_extent_map(em);
>
> - ordered = btrfs_alloc_ordered_extent(inode, start, ram_size,
> - ram_size, ins.objectid, cur_alloc_size,
> - 0, 1 << BTRFS_ORDERED_REGULAR,
> - BTRFS_COMPRESS_NONE);
> + ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
> + 1 << BTRFS_ORDERED_REGULAR);
> if (IS_ERR(ordered)) {
> unlock_extent(&inode->io_tree, start,
> start + ram_size - 1, &cached);
> @@ -2191,15 +2183,10 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
> }
>
> ordered = btrfs_alloc_ordered_extent(inode, cur_offset,
> - nocow_args.file_extent.num_bytes,
> - nocow_args.file_extent.num_bytes,
> - nocow_args.file_extent.disk_bytenr +
> - nocow_args.file_extent.offset,
> - nocow_args.file_extent.num_bytes, 0,
> + &nocow_args.file_extent,
> is_prealloc
> ? (1 << BTRFS_ORDERED_PREALLOC)
> - : (1 << BTRFS_ORDERED_NOCOW),
> - BTRFS_COMPRESS_NONE);
> + : (1 << BTRFS_ORDERED_NOCOW));
> btrfs_dec_nocow_writers(nocow_bg);
> if (IS_ERR(ordered)) {
> if (is_prealloc) {
> @@ -7054,29 +7041,9 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> goto out;
> }
>
> - /*
> - * For regular writes, file_extent->offset is always 0,
> - * thus we really only need file_extent->disk_bytenr, every other length
> - * (disk_num_bytes/ram_bytes) should match @len and
> - * file_extent->num_bytes.
> - *
> - * For NOCOW, we don't really care about the numbers except
> - * @start and @len, as we won't insert a file extent
> - * item at all.
> - *
> - * For PREALLOC, we do not use ordered extent members, but
> - * btrfs_mark_extent_written() handles everything.
> - *
> - * So here we always passing 0 as offset for the ordered extent,
> - * or btrfs_split_ordered_extent() can not handle it correctly.
> - */
> - ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
> - file_extent->disk_bytenr +
> - file_extent->offset,
> - len, 0,
> + ordered = btrfs_alloc_ordered_extent(inode, start, file_extent,
> (1 << type) |
> - (1 << BTRFS_ORDERED_DIRECT),
> - BTRFS_COMPRESS_NONE);
> + (1 << BTRFS_ORDERED_DIRECT));
> if (IS_ERR(ordered)) {
> if (em) {
> free_extent_map(em);
> @@ -10396,12 +10363,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> }
> free_extent_map(em);
>
> - ordered = btrfs_alloc_ordered_extent(inode, start, num_bytes, ram_bytes,
> - ins.objectid, ins.offset,
> - encoded->unencoded_offset,
> + ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent,
> (1 << BTRFS_ORDERED_ENCODED) |
> - (1 << BTRFS_ORDERED_COMPRESSED),
> - compression);
> + (1 << BTRFS_ORDERED_COMPRESSED));
> if (IS_ERR(ordered)) {
> btrfs_drop_extent_map_range(inode, start, end, false);
> ret = PTR_ERR(ordered);
> diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
> index d446d89c2c34..5c2fb0a7c5c8 100644
> --- a/fs/btrfs/ordered-data.c
> +++ b/fs/btrfs/ordered-data.c
> @@ -264,17 +264,39 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry)
> */
> struct btrfs_ordered_extent *btrfs_alloc_ordered_extent(
> struct btrfs_inode *inode, u64 file_offset,
> - u64 num_bytes, u64 ram_bytes, u64 disk_bytenr,
> - u64 disk_num_bytes, u64 offset, unsigned long flags,
> - int compress_type)
> + struct btrfs_file_extent *file_extent,
Btw, this can be made const.
> + unsigned long flags)
> {
> struct btrfs_ordered_extent *entry;
>
> ASSERT((flags & ~BTRFS_ORDERED_TYPE_FLAGS) == 0);
>
> - entry = alloc_ordered_extent(inode, file_offset, num_bytes, ram_bytes,
> - disk_bytenr, disk_num_bytes, offset, flags,
> - compress_type);
> + /*
> + * For regular writes, we just use the members in @file_extent.
> + *
> + * For NOCOW, we don't really care about the numbers except
> + * @start and file_extent->num_bytes, as we won't insert a file extent
> + * item at all.
> + *
> + * For PREALLOC, we do not use ordered extent members, but
> + * btrfs_mark_extent_written() handles everything.
> + *
> + * So here we always passing 0 as offset for NOCOW/PREALLOC ordered
> + * extents, or btrfs_split_ordered_extent() can not handle it correctly.
> + */
> + if (flags & ((1 << BTRFS_ORDERED_NOCOW) | (1 << BTRFS_ORDERED_PREALLOC)))
> + entry = alloc_ordered_extent(inode, file_offset,
> + file_extent->num_bytes, file_extent->num_bytes,
> + file_extent->disk_bytenr + file_extent->offset,
> + file_extent->num_bytes, 0, flags,
> + file_extent->compression);
> + else
> + entry = alloc_ordered_extent(inode, file_offset,
> + file_extent->num_bytes, file_extent->ram_bytes,
> + file_extent->disk_bytenr,
> + file_extent->disk_num_bytes,
> + file_extent->offset, flags,
> + file_extent->compression);
> if (!IS_ERR(entry))
> insert_ordered_extent(entry);
> return entry;
> diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
> index 2ec329e2f0f3..31e65f2f4990 100644
> --- a/fs/btrfs/ordered-data.h
> +++ b/fs/btrfs/ordered-data.h
> @@ -171,11 +171,24 @@ void btrfs_mark_ordered_io_finished(struct btrfs_inode *inode,
> bool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode,
> struct btrfs_ordered_extent **cached,
> u64 file_offset, u64 io_size);
> +
> +/*
> + * This represents details about the target file extent item of a write
> + * operation.
> + */
> +struct btrfs_file_extent {
> + u64 disk_bytenr;
> + u64 disk_num_bytes;
> + u64 num_bytes;
> + u64 ram_bytes;
> + u64 offset;
> + u8 compression;
> +};
> +
> struct btrfs_ordered_extent *btrfs_alloc_ordered_extent(
> struct btrfs_inode *inode, u64 file_offset,
> - u64 num_bytes, u64 ram_bytes, u64 disk_bytenr,
> - u64 disk_num_bytes, u64 offset, unsigned long flags,
> - int compress_type);
> + struct btrfs_file_extent *file_extent,
Same here, const.
Otherwise it looks good, thanks.
Reviewed-by: Filipe Manana <fdmanana@suse.com>
> + unsigned long flags);
> void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry,
> struct btrfs_ordered_sum *sum);
> struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode,
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 03/11] btrfs: introduce new members for extent_map
2024-05-23 5:03 ` [PATCH v3 03/11] btrfs: introduce new members for extent_map Qu Wenruo
2024-05-23 16:53 ` Filipe Manana
@ 2024-05-23 18:21 ` Filipe Manana
1 sibling, 0 replies; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 18:21 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, David Sterba
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> Introduce two new members for extent_map:
>
> - disk_bytenr
> - offset
>
> Both are matching the members with the same name inside
> btrfs_file_extent_items.
>
> For now this patch only touches those members when:
>
> - Reading btrfs_file_extent_items from disk
> - Inserting new holes
> - Merging two extent maps
> With the new disk_bytenr and disk_num_bytes, doing merging would be a
> little more complex, as we have 3 different cases:
>
> * Both extent maps are referring to the same data extents
> |<----- data extent A ----->|
> |<- em 1 ->|<- em 2 ->|
>
> * Both extent maps are referring to different data extents
> |<-- data extent A -->|<-- data extent B -->|
> |<- em 1 ->|<- em 2 ->|
>
> * One of the extent maps is referring to a merged and larger data
> extent that covers both extent maps
>
> This is not really valid case other than some selftests.
> So this test case would be removed.
>
> A new helper merge_ondisk_extents() would be introduced to handle
> above valid cases.
>
> To properly assign values for those new members, a new btrfs_file_extent
> parameter is introduced to all the involved call sites.
>
> - For NOCOW writes the btrfs_file_extent would be exposed from
> can_nocow_file_extent().
>
> - For other writes, the members can be easily calculated
> As most of them have 0 offset and utilizing the whole on-disk data
> extent.
> The exception is encoded write, but thankfully that interface provided
> offset directly and all other needed info.
>
> For now, both the old members (block_start/block_len/orig_start) are
> co-existing with the new members (disk_bytenr/offset), meanwhile all the
> critical code is still using the old members only.
>
> The cleanup would happen later after all the older and newer members are
> properly validated.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
> fs/btrfs/defrag.c | 4 +++
> fs/btrfs/extent_map.c | 78 ++++++++++++++++++++++++++++++++++++++++---
> fs/btrfs/extent_map.h | 17 ++++++++++
> fs/btrfs/file-item.c | 9 ++++-
> fs/btrfs/file.c | 1 +
> fs/btrfs/inode.c | 57 +++++++++++++++++++++++++++----
> 6 files changed, 155 insertions(+), 11 deletions(-)
>
> diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
> index 407ccec3e57e..242c5469f4ba 100644
> --- a/fs/btrfs/defrag.c
> +++ b/fs/btrfs/defrag.c
> @@ -709,6 +709,10 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
> em->start = start;
> em->orig_start = start;
> em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> + em->disk_num_bytes = 0;
> + em->ram_bytes = 0;
> + em->offset = 0;
> em->len = key.offset - start;
> break;
> }
> diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
> index a9d60d1eade9..c7d2393692e6 100644
> --- a/fs/btrfs/extent_map.c
> +++ b/fs/btrfs/extent_map.c
> @@ -229,6 +229,60 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
> return next->block_start == prev->block_start;
> }
>
> +/*
> + * Handle the ondisk data extents merge for @prev and @next.
> + *
> + * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
> + * For now only uncompressed regular extent can be merged.
> + *
> + * @prev and @next will be both updated to point to the new merged range.
> + * Thus one of them should be removed by the caller.
> + */
> +static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
> +{
> + u64 new_disk_bytenr;
> + u64 new_disk_num_bytes;
> + u64 new_offset;
> +
> + /* @prev and @next should not be compressed. */
> + ASSERT(!extent_map_is_compressed(prev));
> + ASSERT(!extent_map_is_compressed(next));
> +
> + /*
> + * There are two different cases where @prev and @next can be merged.
> + *
> + * 1) They are referring to the same data extent
> + * |<----- data extent A ----->|
> + * |<- prev ->|<- next ->|
> + *
> + * 2) They are referring to different data extents but still adjacent
> + *
> + * |<-- data extent A -->|<-- data extent B -->|
> + * |<- prev ->|<- next ->|
> + *
> + * The calculation here always merge the data extents first, then update
> + * @offset using the new data extents.
> + *
> + * For case 1), the merged data extent would be the same.
> + * For case 2), we just merge the two data extents into one.
> + */
> + new_disk_bytenr = min(prev->disk_bytenr, next->disk_bytenr);
> + new_disk_num_bytes = max(prev->disk_bytenr + prev->disk_num_bytes,
> + next->disk_bytenr + next->disk_num_bytes) -
> + new_disk_bytenr;
> + new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
> +
> + prev->disk_bytenr = new_disk_bytenr;
> + prev->disk_num_bytes = new_disk_num_bytes;
> + prev->ram_bytes = new_disk_num_bytes;
> + prev->offset = new_offset;
> +
> + next->disk_bytenr = new_disk_bytenr;
> + next->disk_num_bytes = new_disk_num_bytes;
> + next->ram_bytes = new_disk_num_bytes;
> + next->offset = new_offset;
> +}
> +
> static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> {
> struct extent_map_tree *tree = &inode->extent_tree;
> @@ -260,6 +314,9 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> em->block_len += merge->block_len;
> em->block_start = merge->block_start;
> em->generation = max(em->generation, merge->generation);
> +
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> + merge_ondisk_extents(merge, em);
> em->flags |= EXTENT_FLAG_MERGED;
>
> rb_erase(&merge->rb_node, &tree->root);
> @@ -275,6 +332,8 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
> if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
> em->len += merge->len;
> em->block_len += merge->block_len;
> + if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
> + merge_ondisk_extents(em, merge);
> rb_erase(&merge->rb_node, &tree->root);
> RB_CLEAR_NODE(&merge->rb_node);
> em->generation = max(em->generation, merge->generation);
> @@ -562,6 +621,7 @@ static noinline int merge_extent_mapping(struct btrfs_inode *inode,
> !extent_map_is_compressed(em)) {
> em->block_start += start_diff;
> em->block_len = em->len;
> + em->offset += start_diff;
> }
> return add_extent_mapping(inode, em, 0);
> }
> @@ -785,14 +845,18 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->block_len = em->block_len;
> else
> split->block_len = split->len;
> + split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = max(split->block_len,
> em->disk_num_bytes);
> + split->offset = em->offset;
> split->ram_bytes = em->ram_bytes;
> } else {
> split->orig_start = split->start;
> split->block_len = 0;
> split->block_start = em->block_start;
> + split->disk_bytenr = em->disk_bytenr;
> split->disk_num_bytes = 0;
> + split->offset = 0;
> split->ram_bytes = split->len;
> }
>
> @@ -813,13 +877,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->start = end;
> split->len = em_end - end;
> split->block_start = em->block_start;
> + split->disk_bytenr = em->disk_bytenr;
> split->flags = flags;
> split->generation = gen;
>
> if (em->block_start < EXTENT_MAP_LAST_BYTE) {
> split->disk_num_bytes = max(em->block_len,
> em->disk_num_bytes);
> -
> + split->offset = em->offset + end - em->start;
> split->ram_bytes = em->ram_bytes;
> if (compressed) {
> split->block_len = em->block_len;
> @@ -832,10 +897,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> split->orig_start = em->orig_start;
> }
> } else {
> + split->disk_num_bytes = 0;
> + split->offset = 0;
> split->ram_bytes = split->len;
> split->orig_start = split->start;
> split->block_len = 0;
> - split->disk_num_bytes = 0;
> }
>
> if (extent_map_in_tree(em)) {
> @@ -989,10 +1055,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> /* First, replace the em with a new extent_map starting from * em->start */
> split_pre->start = em->start;
> split_pre->len = pre;
> + split_pre->disk_bytenr = new_logical;
> + split_pre->disk_num_bytes = split_pre->len;
> + split_pre->offset = 0;
> split_pre->orig_start = split_pre->start;
> split_pre->block_start = new_logical;
> split_pre->block_len = split_pre->len;
> - split_pre->disk_num_bytes = split_pre->block_len;
> split_pre->ram_bytes = split_pre->len;
> split_pre->flags = flags;
> split_pre->generation = em->generation;
> @@ -1007,10 +1075,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
> /* Insert the middle extent_map. */
> split_mid->start = em->start + pre;
> split_mid->len = em->len - pre;
> + split_mid->disk_bytenr = em->block_start + pre;
> + split_mid->disk_num_bytes = split_mid->len;
> + split_mid->offset = 0;
> split_mid->orig_start = split_mid->start;
> split_mid->block_start = em->block_start + pre;
> split_mid->block_len = split_mid->len;
> - split_mid->disk_num_bytes = split_mid->block_len;
> split_mid->ram_bytes = split_mid->len;
> split_mid->flags = flags;
> split_mid->generation = em->generation;
> diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
> index 2b7bbffd594b..0b1a8e409377 100644
> --- a/fs/btrfs/extent_map.h
> +++ b/fs/btrfs/extent_map.h
> @@ -70,12 +70,29 @@ struct extent_map {
> */
> u64 orig_start;
>
> + /*
> + * The bytenr of the full on-disk extent.
> + *
> + * For regular extents it's btrfs_file_extent_item::disk_bytenr.
> + * For holes it's EXTENT_MAP_HOLE and for inline extents it's
> + * EXTENT_MAP_INLINE.
> + */
> + u64 disk_bytenr;
> +
> /*
> * The full on-disk extent length, matching
> * btrfs_file_extent_item::disk_num_bytes.
> */
> u64 disk_num_bytes;
>
> + /*
> + * Offset inside the decompressed extent.
> + *
> + * For regular extents it's btrfs_file_extent_item::offset.
> + * For holes and inline extents it's 0.
> + */
> + u64 offset;
> +
> /*
> * The decompressed size of the whole on-disk extent, matching
> * btrfs_file_extent_item::ram_bytes.
> diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
> index 430dce44ebd2..1298afea9503 100644
> --- a/fs/btrfs/file-item.c
> +++ b/fs/btrfs/file-item.c
> @@ -1295,12 +1295,17 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> em->len = btrfs_file_extent_end(path) - extent_start;
> em->orig_start = extent_start -
> btrfs_file_extent_offset(leaf, fi);
> - em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
> bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
> if (bytenr == 0) {
> em->block_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> + em->disk_num_bytes = 0;
> + em->offset = 0;
> return;
> }
> + em->disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
> + em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
> + em->offset = btrfs_file_extent_offset(leaf, fi);
> if (compress_type != BTRFS_COMPRESS_NONE) {
> extent_map_set_compression(em, compress_type);
> em->block_start = bytenr;
> @@ -1317,8 +1322,10 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
> ASSERT(extent_start == 0);
>
> em->block_start = EXTENT_MAP_INLINE;
> + em->disk_bytenr = EXTENT_MAP_INLINE;
> em->start = 0;
> em->len = fs_info->sectorsize;
> + em->offset = 0;
> /*
> * Initialize orig_start and block_len with the same values
> * as in inode.c:btrfs_get_extent().
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 7c42565da70c..5133c6705d74 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -2350,6 +2350,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
> hole_em->orig_start = offset;
>
> hole_em->block_start = EXTENT_MAP_HOLE;
> + hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->block_len = 0;
> hole_em->disk_num_bytes = 0;
> hole_em->generation = trans->transid;
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 8ac489fb5e39..7afcdea27782 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -141,6 +141,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> u64 len, u64 orig_start, u64 block_start,
> u64 block_len, u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> + struct btrfs_file_extent *file_extent,
Can be made const.
> int type);
>
> static int data_reloc_print_warning_inode(u64 inum, u64 offset, u64 num_bytes,
> @@ -1152,6 +1153,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> struct btrfs_root *root = inode->root;
> struct btrfs_fs_info *fs_info = root->fs_info;
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
> struct btrfs_key ins;
> struct page *locked_page = NULL;
> struct extent_state *cached = NULL;
> @@ -1198,6 +1200,13 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> lock_extent(io_tree, start, end, &cached);
>
> /* Here we're doing allocation and writeback of the compressed pages */
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.ram_bytes = async_extent->ram_size;
> + file_extent.num_bytes = async_extent->ram_size;
> + file_extent.offset = 0;
> + file_extent.compression = async_extent->compress_type;
> +
> em = create_io_em(inode, start,
> async_extent->ram_size, /* len */
> start, /* orig_start */
> @@ -1206,6 +1215,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
> ins.offset, /* orig_block_len */
> async_extent->ram_size, /* ram_bytes */
> async_extent->compress_type,
> + &file_extent,
> BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(em)) {
> ret = PTR_ERR(em);
> @@ -1395,6 +1405,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
>
> while (num_bytes > 0) {
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
>
> cur_alloc_size = num_bytes;
> ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size,
> @@ -1431,6 +1442,12 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> extent_reserved = true;
>
> ram_size = ins.offset;
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = ins.offset;
> + file_extent.ram_bytes = ins.offset;
> + file_extent.offset = 0;
> + file_extent.compression = BTRFS_COMPRESS_NONE;
>
> lock_extent(&inode->io_tree, start, start + ram_size - 1,
> &cached);
> @@ -1442,6 +1459,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
> ins.offset, /* orig_block_len */
> ram_size, /* ram_bytes */
> BTRFS_COMPRESS_NONE, /* compress_type */
> + &file_extent,
> BTRFS_ORDERED_REGULAR /* type */);
> if (IS_ERR(em)) {
> unlock_extent(&inode->io_tree, start,
> @@ -2180,6 +2198,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
> nocow_args.num_bytes, /* block_len */
> nocow_args.disk_num_bytes, /* orig_block_len */
> ram_bytes, BTRFS_COMPRESS_NONE,
> + &nocow_args.file_extent,
> BTRFS_ORDERED_PREALLOC);
> if (IS_ERR(em)) {
> unlock_extent(&inode->io_tree, cur_offset,
> @@ -5012,6 +5031,7 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
> hole_em->orig_start = cur_offset;
>
> hole_em->block_start = EXTENT_MAP_HOLE;
> + hole_em->disk_bytenr = EXTENT_MAP_HOLE;
> hole_em->block_len = 0;
> hole_em->disk_num_bytes = 0;
> hole_em->ram_bytes = hole_size;
> @@ -6880,6 +6900,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
> }
> em->start = EXTENT_MAP_HOLE;
> em->orig_start = EXTENT_MAP_HOLE;
> + em->disk_bytenr = EXTENT_MAP_HOLE;
> em->len = (u64)-1;
> em->block_len = (u64)-1;
>
> @@ -7045,7 +7066,8 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> const u64 block_len,
> const u64 orig_block_len,
> const u64 ram_bytes,
> - const int type)
> + const int type,
> + struct btrfs_file_extent *file_extent)
Can be made const too.
> {
> struct extent_map *em = NULL;
> struct btrfs_ordered_extent *ordered;
> @@ -7054,7 +7076,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
> em = create_io_em(inode, start, len, orig_start, block_start,
> block_len, orig_block_len, ram_bytes,
> BTRFS_COMPRESS_NONE, /* compress_type */
> - type);
> + file_extent, type);
> if (IS_ERR(em))
> goto out;
> }
> @@ -7085,6 +7107,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
> {
> struct btrfs_root *root = inode->root;
> struct btrfs_fs_info *fs_info = root->fs_info;
> + struct btrfs_file_extent file_extent;
> struct extent_map *em;
> struct btrfs_key ins;
> u64 alloc_hint;
> @@ -7103,9 +7126,16 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
> if (ret)
> return ERR_PTR(ret);
>
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = ins.offset;
> + file_extent.ram_bytes = ins.offset;
> + file_extent.offset = 0;
> + file_extent.compression = BTRFS_COMPRESS_NONE;
> em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start,
> ins.objectid, ins.offset, ins.offset,
> - ins.offset, BTRFS_ORDERED_REGULAR);
> + ins.offset, BTRFS_ORDERED_REGULAR,
> + &file_extent);
> btrfs_dec_block_group_reservations(fs_info, ins.objectid);
> if (IS_ERR(em))
> btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset,
> @@ -7348,6 +7378,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> u64 len, u64 orig_start, u64 block_start,
> u64 block_len, u64 disk_num_bytes,
> u64 ram_bytes, int compress_type,
> + struct btrfs_file_extent *file_extent,
> int type)
> {
> struct extent_map *em;
> @@ -7405,9 +7436,11 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
> em->len = len;
> em->block_len = block_len;
> em->block_start = block_start;
> + em->disk_bytenr = file_extent->disk_bytenr;
> em->disk_num_bytes = disk_num_bytes;
> em->ram_bytes = ram_bytes;
> em->generation = -1;
> + em->offset = file_extent->offset;
> em->flags |= EXTENT_FLAG_PINNED;
> if (type == BTRFS_ORDERED_COMPRESSED)
> extent_map_set_compression(em, compress_type);
> @@ -7431,6 +7464,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> {
> const bool nowait = (iomap_flags & IOMAP_NOWAIT);
> struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
> + struct btrfs_file_extent file_extent;
> struct extent_map *em = *map;
> int type;
> u64 block_start, orig_start, orig_block_len, ram_bytes;
> @@ -7461,7 +7495,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> block_start = em->block_start + (start - em->start);
>
> if (can_nocow_extent(inode, start, &len, &orig_start,
> - &orig_block_len, &ram_bytes, NULL, false, false) == 1) {
> + &orig_block_len, &ram_bytes,
> + &file_extent, false, false) == 1) {
> bg = btrfs_inc_nocow_writers(fs_info, block_start);
> if (bg)
> can_nocow = true;
> @@ -7489,7 +7524,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
> em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
> orig_start, block_start,
> len, orig_block_len,
> - ram_bytes, type);
> + ram_bytes, type,
> + &file_extent);
> btrfs_dec_nocow_writers(bg);
> if (type == BTRFS_ORDERED_PREALLOC) {
> free_extent_map(em);
> @@ -9629,6 +9665,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
> em->orig_start = cur_offset;
> em->len = ins.offset;
> em->block_start = ins.objectid;
> + em->disk_bytenr = ins.objectid;
> + em->offset = 0;
> em->block_len = ins.offset;
> em->disk_num_bytes = ins.offset;
> em->ram_bytes = ins.offset;
> @@ -10195,6 +10233,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> struct extent_changeset *data_reserved = NULL;
> struct extent_state *cached_state = NULL;
> struct btrfs_ordered_extent *ordered;
> + struct btrfs_file_extent file_extent;
> int compression;
> size_t orig_count;
> u64 start, end;
> @@ -10370,10 +10409,16 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
> goto out_delalloc_release;
> extent_reserved = true;
>
> + file_extent.disk_bytenr = ins.objectid;
> + file_extent.disk_num_bytes = ins.offset;
> + file_extent.num_bytes = num_bytes;
> + file_extent.ram_bytes = ram_bytes;
> + file_extent.offset = encoded->unencoded_offset;
> + file_extent.compression = compression;
> em = create_io_em(inode, start, num_bytes,
> start - encoded->unencoded_offset, ins.objectid,
> ins.offset, ins.offset, ram_bytes, compression,
> - BTRFS_ORDERED_COMPRESSED);
> + &file_extent, BTRFS_ORDERED_COMPRESSED);
> if (IS_ERR(em)) {
> ret = PTR_ERR(em);
> goto out_free_reserved;
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
` (11 preceding siblings ...)
2024-05-23 10:23 ` [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Johannes Thumshirn
@ 2024-05-23 18:26 ` Filipe Manana
12 siblings, 0 replies; 22+ messages in thread
From: Filipe Manana @ 2024-05-23 18:26 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Thu, May 23, 2024 at 6:04 AM Qu Wenruo <wqu@suse.com> wrote:
>
> [CHANGELOG]
> v3:
> - Rebased to the latest for-next
> There is a small conflicts with the extent map tree members changes,
> no big deal.
>
> - Fix an error where original code is checking
> btrfs_file_extent_disk_bytenr()
> The newer code is checking disk_num_bytes, which is wrong.
>
> - Various commit messages/comments update
> Mostly some grammar fixes and removal of rants on the btrfs_file_extent
> member mismatches for btrfs_alloc_ordered_extent().
> However a comment is still left inside btrfs_alloc_ordered_extent()
> for NOCOW/PREALLOC as a reminder for further cleanup.
I went through each new patch version, and it looks good.
I replied to some individual patches with minor things that can be
fixed at commit time when adding to for-next in case you don't send a
new version.
For patch 7/11 there's one issue.
Otherwise looks great, so after the 7/11 fix you can add:
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Thanks!
>
> v2:
> - Rebased to the latest for-next
> There is a conflicts with extent locking, and maybe some other
> hidden conflicts for NOCOW/PREALLOC?
> As previously the patchset passes fstests auto group, but after
> the merging with other patches, it always crashes as btrfs/060.
>
> - Fix an error in the final cleanup patch
> It's the NOCOW/PREALLOC shenanigans again, in the buffered NOCOW path,
> that we have to use the old inaccurate numbers for NOCOW/PREALLOC OEs.
>
> - Split the final cleanup into 4 patches
> Most cleanups are very straightforward, but the cleanup for
> btrfs_alloc_ordered_extent() needs extra special handling for
> NOCOW/PREALLOC.
>
> v1:
> - Rebased to the latest for-next
> To resolve the conflicts with the recently introduced extent map
> shrinker
>
> - A new cleanup patch to remove the recursive header inclusion
>
> - Use a new structure to pass the file extent item related members
> around
>
> - Add a new comment on why we're intentionally passing incorrect
> numbers for NOCOW/PREALLOC ordered extents inside
> btrfs_create_dio_extent()
>
> [REPO]
> https://github.com/adam900710/linux/tree/em_cleanup
>
> This series introduce two new members (disk_bytenr/offset) to
> extent_map, and removes three old members
> (block_start/block_len/offset), finally rename one member
> (orig_block_len -> disk_num_bytes).
>
> This should save us one u64 for extent_map, although with the recent
> extent map shrinker, the saving is not that useful.
>
> But to make things safe to migrate, I introduce extra sanity checks for
> extent_map, and do cross check for both old and new members.
>
> The extra sanity checks already exposed one bug (thankfully harmless)
> causing em::block_start to be incorrect.
>
> But so far, the patchset is fine for default fstests run.
>
> Furthermore, since we're already having too long parameter lists for
> extent_map/ordered_extent/can_nocow_extent, here is a new structure,
> btrfs_file_extent, a memory-access-friendly structure to represent a
> btrfs_file_extent_item.
>
> With the help of that structure, we can use that to represent a file
> extent item without a super long parameter list.
>
> The patchset would rename orig_block_len to disk_num_bytes first.
> Then introduce the new member, the extra sanity checks, and introduce the
> new btrfs_file_extent structure and use that to remove the older 3 members
> from extent_map.
>
> After all above works done, use btrfs_file_extent to further cleanup
> can_nocow_file_extent_args()/btrfs_alloc_ordered_extent()/create_io_em()/
> btrfs_create_dio_extent().
>
> The cleanup is in fact pretty tricky, the current code base never
> expects correct numbers for NOCOW/PREALLOC OEs, thus we have to keep the
> old but incorrect numbers just for NOCOW/PREALLOC.
>
> I will address the NOCOW/PREALLOC shenanigans the future, but
> after the huge cleanup across multiple core structures.
>
> Qu Wenruo (11):
> btrfs: rename extent_map::orig_block_len to disk_num_bytes
> btrfs: export the expected file extent through can_nocow_extent()
> btrfs: introduce new members for extent_map
> btrfs: introduce extra sanity checks for extent maps
> btrfs: remove extent_map::orig_start member
> btrfs: remove extent_map::block_len member
> btrfs: remove extent_map::block_start member
> btrfs: cleanup duplicated parameters related to
> can_nocow_file_extent_args
> btrfs: cleanup duplicated parameters related to
> btrfs_alloc_ordered_extent
> btrfs: cleanup duplicated parameters related to create_io_em()
> btrfs: cleanup duplicated parameters related to
> btrfs_create_dio_extent()
>
> fs/btrfs/btrfs_inode.h | 4 +-
> fs/btrfs/compression.c | 7 +-
> fs/btrfs/defrag.c | 14 +-
> fs/btrfs/extent_io.c | 10 +-
> fs/btrfs/extent_map.c | 192 +++++++++++++------
> fs/btrfs/extent_map.h | 51 +++--
> fs/btrfs/file-item.c | 23 +--
> fs/btrfs/file.c | 18 +-
> fs/btrfs/inode.c | 308 +++++++++++++-----------------
> fs/btrfs/ordered-data.c | 34 +++-
> fs/btrfs/ordered-data.h | 19 +-
> fs/btrfs/relocation.c | 5 +-
> fs/btrfs/tests/extent-map-tests.c | 114 ++++++-----
> fs/btrfs/tests/inode-tests.c | 177 ++++++++---------
> fs/btrfs/tree-log.c | 23 ++-
> fs/btrfs/zoned.c | 4 +-
> include/trace/events/btrfs.h | 18 +-
> 17 files changed, 541 insertions(+), 480 deletions(-)
>
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 03/11] btrfs: introduce new members for extent_map
2024-05-23 16:53 ` Filipe Manana
@ 2024-05-23 23:19 ` Qu Wenruo
2024-05-24 10:59 ` David Sterba
0 siblings, 1 reply; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 23:19 UTC (permalink / raw)
To: Filipe Manana, Qu Wenruo; +Cc: linux-btrfs, David Sterba
在 2024/5/24 02:23, Filipe Manana 写道:
[...]
>> @@ -832,10 +897,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
>> split->orig_start = em->orig_start;
>> }
>> } else {
>> + split->disk_num_bytes = 0;
>> + split->offset = 0;
>> split->ram_bytes = split->len;
>> split->orig_start = split->start;
>> split->block_len = 0;
>> - split->disk_num_bytes = 0;
>
> Why move the assignment of ->disk_num_bytes ?
> This is sort of distracting, doing unnecessary changes.
It's to group the newer members together, and to follow the new trend to
put them in disk_bytenr disk_num_bytes offset ram_bytes order.
I know with structures, there is really no need to keep any order
between the member assignment, but with fixed ordering, it would be
better in the long run.
And unfortunately the cost is that, the first patch doing the
re-ordering the members would be harder to review.
>
>> }
>>
>> if (extent_map_in_tree(em)) {
>> @@ -989,10 +1055,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
>> /* First, replace the em with a new extent_map starting from * em->start */
>> split_pre->start = em->start;
>> split_pre->len = pre;
>> + split_pre->disk_bytenr = new_logical;
>
> We are already setting disk_bytenr to the same value a few lines below.'
Sorry, I didn't see any location touching disk_bytenr, either inside the
patch, nor else where, especially the disk_bytenr is a new member.
>
>> + split_pre->disk_num_bytes = split_pre->len;
>> + split_pre->offset = 0;
>> split_pre->orig_start = split_pre->start;
>> split_pre->block_start = new_logical;
>> split_pre->block_len = split_pre->len;
>> - split_pre->disk_num_bytes = split_pre->block_len;
>
> Here, where slit_pre->block_len has the same value as split->pre_len.
> This sort of apparently accidental change makes it harder to review.
Again, to keep a consistent order of members.
>
>> split_pre->ram_bytes = split_pre->len;
>> split_pre->flags = flags;
>> split_pre->generation = em->generation;
>> @@ -1007,10 +1075,12 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
>> /* Insert the middle extent_map. */
>> split_mid->start = em->start + pre;
>> split_mid->len = em->len - pre;
>> + split_mid->disk_bytenr = em->block_start + pre;
>
> Same here.
>
>> + split_mid->disk_num_bytes = split_mid->len;
>> + split_mid->offset = 0;
>> split_mid->orig_start = split_mid->start;
>> split_mid->block_start = em->block_start + pre;
>> split_mid->block_len = split_mid->len;
>> - split_mid->disk_num_bytes = split_mid->block_len;
>
> Which relates to this.
>
> Otherwise it looks fine, and could be fixed up when cherry picked to for-next.
So although it's indeed harder to review, we would have a very
consistent order when assigning those members.
Thankfully this is only a one time pain, there should be no more member
order related problems.
Thanks,
Qu
>
> Reviewed-by: Filipe Manana <fdmanana@suse.com>
>
> Thanks.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 07/11] btrfs: remove extent_map::block_start member
2024-05-23 17:56 ` Filipe Manana
@ 2024-05-23 23:23 ` Qu Wenruo
0 siblings, 0 replies; 22+ messages in thread
From: Qu Wenruo @ 2024-05-23 23:23 UTC (permalink / raw)
To: Filipe Manana, Qu Wenruo; +Cc: linux-btrfs, David Sterba
在 2024/5/24 03:26, Filipe Manana 写道:
>> @@ -2703,7 +2700,7 @@ static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
>> if (IS_ERR(em))
>> return PTR_ERR(em);
>>
>> - if (em->block_start != EXTENT_MAP_HOLE)
>> + if (extent_map_block_start(em) != EXTENT_MAP_HOLE)
> This should be: if (em->disk_bytenr != EXTENT_MAP_HOLE)
That's fine, the extent_map_block_start() would handle it correctly, as
for any disk_bytenr >= EXTENT_MAP_LAST_BYTE, it would return the
disk_bytenr directly.
But yes, we can save one if() check and would update it.
Thanks,
Qu
>
> Everything else looks fine. Thanks.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3 03/11] btrfs: introduce new members for extent_map
2024-05-23 23:19 ` Qu Wenruo
@ 2024-05-24 10:59 ` David Sterba
0 siblings, 0 replies; 22+ messages in thread
From: David Sterba @ 2024-05-24 10:59 UTC (permalink / raw)
To: Qu Wenruo; +Cc: Filipe Manana, Qu Wenruo, linux-btrfs, David Sterba
On Fri, May 24, 2024 at 08:49:25AM +0930, Qu Wenruo wrote:
>
>
> 在 2024/5/24 02:23, Filipe Manana 写道:
> [...]
> >> @@ -832,10 +897,11 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
> >> split->orig_start = em->orig_start;
> >> }
> >> } else {
> >> + split->disk_num_bytes = 0;
> >> + split->offset = 0;
> >> split->ram_bytes = split->len;
> >> split->orig_start = split->start;
> >> split->block_len = 0;
> >> - split->disk_num_bytes = 0;
> >
> > Why move the assignment of ->disk_num_bytes ?
> > This is sort of distracting, doing unnecessary changes.
>
> It's to group the newer members together, and to follow the new trend to
> put them in disk_bytenr disk_num_bytes offset ram_bytes order.
>
> I know with structures, there is really no need to keep any order
> between the member assignment, but with fixed ordering, it would be
> better in the long run.
I agree this pays of in the long run. The most prominent example is
ordering of the btrfs_key initialization, if it's always
objectid/type/offset it's does not slow down reading, it's enough to
read the values. Admittedly for the extent_map it's not the same because
there are more members. The important thing is to keep the same order
everywhere.
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2024-05-24 10:59 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-23 5:03 [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 01/11] btrfs: rename extent_map::orig_block_len to disk_num_bytes Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 02/11] btrfs: export the expected file extent through can_nocow_extent() Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 03/11] btrfs: introduce new members for extent_map Qu Wenruo
2024-05-23 16:53 ` Filipe Manana
2024-05-23 23:19 ` Qu Wenruo
2024-05-24 10:59 ` David Sterba
2024-05-23 18:21 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 04/11] btrfs: introduce extra sanity checks for extent maps Qu Wenruo
2024-05-23 16:57 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 05/11] btrfs: remove extent_map::orig_start member Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 06/11] btrfs: remove extent_map::block_len member Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 07/11] btrfs: remove extent_map::block_start member Qu Wenruo
2024-05-23 17:56 ` Filipe Manana
2024-05-23 23:23 ` Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 08/11] btrfs: cleanup duplicated parameters related to can_nocow_file_extent_args Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 09/11] btrfs: cleanup duplicated parameters related to btrfs_alloc_ordered_extent Qu Wenruo
2024-05-23 18:17 ` Filipe Manana
2024-05-23 5:03 ` [PATCH v3 10/11] btrfs: cleanup duplicated parameters related to create_io_em() Qu Wenruo
2024-05-23 5:03 ` [PATCH v3 11/11] btrfs: cleanup duplicated parameters related to btrfs_create_dio_extent() Qu Wenruo
2024-05-23 10:23 ` [PATCH v3 00/11] btrfs: extent-map: unify the members with btrfs_ordered_extent Johannes Thumshirn
2024-05-23 18:26 ` Filipe Manana
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox