* [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging
@ 2022-02-03 14:55 fdmanana
2022-02-03 14:55 ` [PATCH 1/6] btrfs: remove unnecessary leaf free space checks when pushing items fdmanana
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
This is a mix of small improvements around logging extents, replacing
extents in a log tree or subvolume tree, while others are more generic
ones, and some cleanups. They are grouped in the same patchset, but they
are all independent of each other.
Filipe Manana (6):
btrfs: remove unnecessary leaf free space checks when pushing items
btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
btrfs: avoid unnecessary computation when deleting items from a leaf
btrfs: remove constraint on number of visited leaves when replacing extents
btrfs: remove useless path release in the fast fsync path
btrfs: prepare extents to be logged before locking a log tree path
fs/btrfs/ctree.c | 66 ++++++++++++++++++++++++++-------------------
fs/btrfs/file.c | 5 +---
fs/btrfs/tree-log.c | 65 +++++++++++++++++++-------------------------
3 files changed, 67 insertions(+), 69 deletions(-)
--
2.33.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/6] btrfs: remove unnecessary leaf free space checks when pushing items
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-03 14:55 ` [PATCH 2/6] btrfs: avoid unnecessary COW of leaves when deleting items from a leaf fdmanana
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When trying to push items from a leaf into its left and right neighbours,
we lock the left or right leaf, check if it has the required minimum free
space, COW the leaf and then check again if it has the minimum required
free space. This second check is pointless:
1) Most and foremost because it's not neeed. We have a write lock on the
leaf and on its parent node, so no one can come in and change either
the pre-COW or post-COW version of the leaf for the whole duration of
the push_leaf_left() and push_leaf_right() calls;
2) The call to btrfs_leaf_free_space() is not trivial, it has a fair
amount of arithmetic operations and access to fields in the leaf's
header and items, so it's not very cheap.
So remove the duplicated free space checks.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
The last patch in the series has some performance test result in its
changelog.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/ctree.c | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a7db3f6f1b7b..cf3d57082524 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2990,16 +2990,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
if (free_space < data_size)
goto out_unlock;
- /* cow and double check */
ret = btrfs_cow_block(trans, root, right, upper,
slot + 1, &right, BTRFS_NESTING_RIGHT_COW);
if (ret)
goto out_unlock;
- free_space = btrfs_leaf_free_space(right);
- if (free_space < data_size)
- goto out_unlock;
-
left_nritems = btrfs_header_nritems(left);
if (left_nritems == 0)
goto out_unlock;
@@ -3224,7 +3219,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
goto out;
}
- /* cow and double check */
ret = btrfs_cow_block(trans, root, left,
path->nodes[1], slot - 1, &left,
BTRFS_NESTING_LEFT_COW);
@@ -3235,12 +3229,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
goto out;
}
- free_space = btrfs_leaf_free_space(left);
- if (free_space < data_size) {
- ret = 1;
- goto out;
- }
-
if (check_sibling_keys(left, right)) {
ret = -EUCLEAN;
goto out;
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/6] btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
2022-02-03 14:55 ` [PATCH 1/6] btrfs: remove unnecessary leaf free space checks when pushing items fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-03 14:55 ` [PATCH 3/6] btrfs: avoid unnecessary computation " fdmanana
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When we delete items from a leaf, if we end up with more than two thirds
of unused leaf space, we try to delete the leaf by moving all its items
into its left and right neighbour leaves. Sometimes that is not possible
because there is not enough free space in the left and right leaves, and
in that case we end up not deleting our leaf.
The way we are doing this is not ideal and can be improved in the
following ways:
1) When we call push_leaf_left(), we pass a value of 1 byte to the data
size parameter of push_leaf_left(). This is not realistic value because
no item can have a size less than 25 bytes, which is the size of struct
btrfs_item. This means that means that if the left leaf has not enough
free space to push any item, we end up COWing it even if we end up not
changing its content at all.
COWing that leaf means allocating a new metadata extent, marking it
dirty and doing more IO when comitting a transaction or when syncing a
log tree. For a log tree case, it's particularly more important to
avoid the useless COW operation, as more IO can imply a higher latency
for an fsync operation.
So instead of passing 1 as the minimim data size for push_leaf_left(),
pass the size of the first item in our leaf, as we don't want to COW
the left leaf if we can't at least push the first item of our leaf;
2) When we call push_leaf_right(), we also pass a value of 1 byte as the
data size parameter of push_leaf_right(). Like the previous case, it
will also result in COWing the right leaf even if we are not able to
move any items into it, since there can't be any item with a size
smaller than 25 bytes (the size of struct btrfs_item).
So instead of passing 1 as the minimum data size to push_leaf_right(),
pass a size that corresponds to the sum of the size of all the
remaining items in our leaf. We are not interested in moving less than
that, because if we do, we are not able to delete our leaf and we have
COWed the right leaf for nothing. Plus, moving only some of the items
of our leaf, it means an even less balanced tree.
Just like the previous case, we want to avoid the useless COW of the
right leaf, this way we don't have to spend time allocating one new
metadata extent, and doing more IO when comitting a transaction or
syncing a log tree. For the log tree case it's specially more important
because more IO can result in a higher latency for a fsync operation.
So adjust the minimum data size passed to push_leaf_left() and
push_leaf_right() as mentioned above.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
Not being able to delete a leaf that became less than 1/3 full after
deleting items from it is actually common. For example, for the fio test
mentioned in the changelog of patch 6/6, we are only able to delete a
leaf at btrfs_del_items() about 5.3% of the time, due to its left and
right neighbour leaves not having enough free space to push all the
remaining items into them.
The last patch in the series has some performance test result in its
changelog.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/ctree.c | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index cf3d57082524..5322140f4d22 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -4215,24 +4215,50 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
fixup_low_keys(path, &disk_key, 1);
}
- /* delete the leaf if it is mostly empty */
+ /*
+ * Try to delete the leaf if it is mostly empty. We do this by
+ * trying to move all its items into its left and right neighbours.
+ * If we can't move all the items, then we don't delete it - it's
+ * not ideal, but future insertions might fill the leaf with more
+ * items, or items from other leaves might be moved later into our
+ * leaf due to deletions on those leaves.
+ */
if (used < BTRFS_LEAF_DATA_SIZE(fs_info) / 3) {
+ u32 min_push_space;
+
/* push_leaf_left fixes the path.
* make sure the path still points to our leaf
* for possible call to del_ptr below
*/
slot = path->slots[1];
atomic_inc(&leaf->refs);
-
- wret = push_leaf_left(trans, root, path, 1, 1,
- 1, (u32)-1);
+ /*
+ * We want to be able to at least push one item to the
+ * left neighbour leaf, and that's the first item.
+ */
+ min_push_space = sizeof(struct btrfs_item) +
+ btrfs_item_size(leaf, 0);
+ wret = push_leaf_left(trans, root, path, 0,
+ min_push_space, 1, (u32)-1);
if (wret < 0 && wret != -ENOSPC)
ret = wret;
if (path->nodes[0] == leaf &&
btrfs_header_nritems(leaf)) {
- wret = push_leaf_right(trans, root, path, 1,
- 1, 1, 0);
+ /*
+ * If we were not able to push all items from our
+ * leaf to its left neighbour, then attempt to
+ * either push all the remaining items to the
+ * right neighbour or none. There's no advantage
+ * in pushing only some items, instead of all, as
+ * it's pointless to end up with a leaf having
+ * too few items while the neighbours can be full
+ * or nearly full.
+ */
+ nritems = btrfs_header_nritems(leaf);
+ min_push_space = leaf_space_used(leaf, 0, nritems);
+ wret = push_leaf_right(trans, root, path, 0,
+ min_push_space, 1, 0);
if (wret < 0 && wret != -ENOSPC)
ret = wret;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/6] btrfs: avoid unnecessary computation when deleting items from a leaf
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
2022-02-03 14:55 ` [PATCH 1/6] btrfs: remove unnecessary leaf free space checks when pushing items fdmanana
2022-02-03 14:55 ` [PATCH 2/6] btrfs: avoid unnecessary COW of leaves when deleting items from a leaf fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-03 14:55 ` [PATCH 4/6] btrfs: remove constraint on number of visited leaves when replacing extents fdmanana
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When deleting items from a leaf, we always compute the sum of the data
sizes of the items that are going to be deleted. However we only use
that sum when the last item to delete is behind the last item in the
leaf. This unnecessarily wastes CPU time when we are deleting either
the whole leaf or from some slot > 0 up to the last item in the leaf,
and both of these cases are common (e.g. truncation operation, either
as a result of truncate(2) or when logging inodes, deleting checksums
after removing a large enough extent, etc).
So compute only the sum of the data sizes if the last item to be
deleted does not match the last item in the leaf.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
The last patch in the series has some performance test result in its
changelog.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/ctree.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 5322140f4d22..1bb5335c6d75 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -4158,24 +4158,22 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
{
struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *leaf;
- u32 last_off;
- u32 dsize = 0;
int ret = 0;
int wret;
- int i;
u32 nritems;
leaf = path->nodes[0];
- last_off = btrfs_item_offset(leaf, slot + nr - 1);
-
- for (i = 0; i < nr; i++)
- dsize += btrfs_item_size(leaf, slot + i);
-
nritems = btrfs_header_nritems(leaf);
if (slot + nr != nritems) {
- int data_end = leaf_data_end(leaf);
+ const u32 last_off = btrfs_item_offset(leaf, slot + nr - 1);
+ const int data_end = leaf_data_end(leaf);
struct btrfs_map_token token;
+ u32 dsize = 0;
+ int i;
+
+ for (i = 0; i < nr; i++)
+ dsize += btrfs_item_size(leaf, slot + i);
memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET +
data_end + dsize,
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/6] btrfs: remove constraint on number of visited leaves when replacing extents
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
` (2 preceding siblings ...)
2022-02-03 14:55 ` [PATCH 3/6] btrfs: avoid unnecessary computation " fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-03 14:55 ` [PATCH 5/6] btrfs: remove useless path release in the fast fsync path fdmanana
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
At btrfs_drop_extents(), we try to replace a range of file extent items
with a new file extent in a single btree search, to avoid the need to do
a search for deletion, followed by a path release and followed by yet
another search for insertion.
When I originally added that optimization, in commit 1acae57b161ef1
("Btrfs: faster file extent item replace operations"), I left a constraint
to do the fast replace only if we visited a single leaf. That was because
in the most common case we find all file extent items that need to be
deleted (or trimmed) in a single leaf, however it can work for other
common cases like when we need to delete a few file extent items located
at the end of a leaf and a few more located at the beginning of the next
leaf. The key for the new file extent item is greater than the key of
any deleted or trimmed file extent item from previous leaves, so we are
fine to use the last leaf that we found as long as we are holding a
write lock on it - even if the new key ends up at slot 0, as if that's
the case, the btree search has obtained a write lock on any upper nodes
that need to have a key pointer updated.
So removed the constraint that limits the optimization to the case where
we visited only a single leaf.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
The last patch in the series has some performance test result in its
changelog.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/file.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 11204dbbe053..c462896122dc 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -718,7 +718,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
int modify_tree = -1;
int update_refs;
int found = 0;
- int leafs_visited = 0;
struct btrfs_path *path = args->path;
args->bytes_found = 0;
@@ -756,7 +755,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
path->slots[0]--;
}
ret = 0;
- leafs_visited++;
next_slot:
leaf = path->nodes[0];
if (path->slots[0] >= btrfs_header_nritems(leaf)) {
@@ -768,7 +766,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
ret = 0;
break;
}
- leafs_visited++;
leaf = path->nodes[0];
recow = 1;
}
@@ -1014,7 +1011,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
* which case it unlocked our path, so check path->locks[0] matches a
* write lock.
*/
- if (!ret && args->replace_extent && leafs_visited == 1 &&
+ if (!ret && args->replace_extent &&
path->locks[0] == BTRFS_WRITE_LOCK &&
btrfs_leaf_free_space(leaf) >=
sizeof(struct btrfs_item) + args->extent_item_size) {
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/6] btrfs: remove useless path release in the fast fsync path
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
` (3 preceding siblings ...)
2022-02-03 14:55 ` [PATCH 4/6] btrfs: remove constraint on number of visited leaves when replacing extents fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-03 14:55 ` [PATCH 6/6] btrfs: prepare extents to be logged before locking a log tree path fdmanana
2022-02-04 16:36 ` [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging David Sterba
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
There's no point in calling btrfs_release_path() after finishing the loop
that logs the modified extents, since log_one_extent() returns with the
path released. In case the list of extents is empty, the path is already
released, so there's no need for that case as well.
So just remove that unnecessary btrfs_release_path() call.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
The last patch in the series has some performance test result in its
changelog.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 1c8c8e826b7e..492dbc92d37e 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4946,7 +4946,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
WARN_ON(!list_empty(&extents));
write_unlock(&tree->lock);
- btrfs_release_path(path);
if (!ret)
ret = btrfs_log_prealloc_extents(trans, inode, path);
if (ret)
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/6] btrfs: prepare extents to be logged before locking a log tree path
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
` (4 preceding siblings ...)
2022-02-03 14:55 ` [PATCH 5/6] btrfs: remove useless path release in the fast fsync path fdmanana
@ 2022-02-03 14:55 ` fdmanana
2022-02-04 16:36 ` [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging David Sterba
6 siblings, 0 replies; 9+ messages in thread
From: fdmanana @ 2022-02-03 14:55 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When we want to log an extent, in the fast fsync path, we obtain a path
to the leaf that will hold the file extent item either through a deletion
search, via btrfs_drop_extents(), or through an insertion search using
btrfs_insert_empty_item(). After that we fill the file extent item's
fields one by one directly on the leaf.
Instead of doing that, we could prepare the file extent item before
obtaining a btree path, and then copy the prepared extent item with a
single operation once we get the path. This helps avoid some contention
on the log tree, since we are holding write locks for longer than
necessary, especially in the case where the path is obtained via
btrfs_drop_extents() through a deletion search, which always keeps a
write lock on the nodes at levels 1 and 2 (besides the leaf).
This change does that, we prepare the file extent item that is going to
be inserted before acquiring a path, and then copy it into a leaf using
a single copy operation once we get a path.
This change if part of a patchset that is comprised of the following
patches:
1/6 btrfs: remove unnecessary leaf free space checks when pushing items
2/6 btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
3/6 btrfs: avoid unnecessary computation when deleting items from a leaf
4/6 btrfs: remove constraint on number of visited leaves when replacing extents
5/6 btrfs: remove useless path release in the fast fsync path
6/6 btrfs: prepare extents to be logged before locking a log tree path
The following test was run to measure the impact of the whole patchset:
$ cat test.sh
#!/bin/bash
DEV=/dev/sdi
MNT=/mnt/sdi
MOUNT_OPTIONS="-o ssd"
MKFS_OPTIONS="-R free-space-tree -O no-holes"
NUM_JOBS=8
FILE_SIZE=128M
RUN_TIME=200
cat <<EOF > /tmp/fio-job.ini
[writers]
rw=randwrite
fsync=1
fallocate=none
group_reporting=1
direct=0
bssplit=4k/20:8k/20:16k/20:32k/10:64k/10:128k/5:256k/5:512k/5:1m/5
ioengine=sync
filesize=$FILE_SIZE
runtime=$RUN_TIME
time_based
directory=$MNT
numjobs=$NUM_JOBS
thread
EOF
echo "performance" | \
tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
echo
echo "Using config:"
echo
cat /tmp/fio-job.ini
echo
umount $MNT &> /dev/null
mkfs.btrfs -f $MKFS_OPTIONS $DEV
mount $MOUNT_OPTIONS $DEV $MNT
fio /tmp/fio-job.ini
umount $MNT
The test ran inside a VM (8 cores, 32G of ram) with the target disk
mapping to a raw nvme device, and using a non-debug kernel config
(Debian's default config).
Before the patchset:
WRITE: bw=116MiB/s (122MB/s), 116MiB/s-116MiB/s (122MB/s-122MB/s), io=22.7GiB (24.4GB), run=200013-200013msec
After the patchset:
WRITE: bw=125MiB/s (131MB/s), 125MiB/s-125MiB/s (131MB/s-131MB/s), io=24.3GiB (26.1GB), run=200007-200007msec
A 7.8% gain on througput and +7.0% more IO done in the same period of
time (200 seconds).
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 64 +++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 37 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 492dbc92d37e..e9b6eba7c42d 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4657,14 +4657,34 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
{
struct btrfs_drop_extents_args drop_args = { 0 };
struct btrfs_root *log = inode->root->log_root;
- struct btrfs_file_extent_item *fi;
+ struct btrfs_file_extent_item fi = { 0 };
struct extent_buffer *leaf;
- struct btrfs_map_token token;
struct btrfs_key key;
u64 extent_offset = em->start - em->orig_start;
u64 block_len;
int ret;
+ btrfs_set_stack_file_extent_generation(&fi, trans->transid);
+ if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
+ btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_PREALLOC);
+ else
+ btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_REG);
+
+ block_len = max(em->block_len, em->orig_block_len);
+ if (em->compress_type != BTRFS_COMPRESS_NONE) {
+ btrfs_set_stack_file_extent_disk_bytenr(&fi, em->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 -
+ extent_offset);
+ btrfs_set_stack_file_extent_disk_num_bytes(&fi, block_len);
+ }
+
+ btrfs_set_stack_file_extent_offset(&fi, extent_offset);
+ btrfs_set_stack_file_extent_num_bytes(&fi, em->len);
+ btrfs_set_stack_file_extent_ram_bytes(&fi, em->ram_bytes);
+ btrfs_set_stack_file_extent_compression(&fi, em->compress_type);
+
ret = log_extent_csums(trans, inode, log, em, ctx);
if (ret)
return ret;
@@ -4683,7 +4703,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
drop_args.start = em->start;
drop_args.end = em->start + em->len;
drop_args.replace_extent = true;
- drop_args.extent_item_size = sizeof(*fi);
+ drop_args.extent_item_size = sizeof(fi);
ret = btrfs_drop_extents(trans, log, inode, &drop_args);
if (ret)
return ret;
@@ -4695,44 +4715,14 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
key.offset = em->start;
ret = btrfs_insert_empty_item(trans, log, path, &key,
- sizeof(*fi));
+ sizeof(fi));
if (ret)
return ret;
}
leaf = path->nodes[0];
- btrfs_init_map_token(&token, leaf);
- fi = btrfs_item_ptr(leaf, path->slots[0],
- struct btrfs_file_extent_item);
-
- btrfs_set_token_file_extent_generation(&token, fi, trans->transid);
- if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
- btrfs_set_token_file_extent_type(&token, fi,
- BTRFS_FILE_EXTENT_PREALLOC);
- else
- btrfs_set_token_file_extent_type(&token, fi,
- BTRFS_FILE_EXTENT_REG);
-
- block_len = max(em->block_len, em->orig_block_len);
- if (em->compress_type != BTRFS_COMPRESS_NONE) {
- btrfs_set_token_file_extent_disk_bytenr(&token, fi,
- em->block_start);
- btrfs_set_token_file_extent_disk_num_bytes(&token, fi, block_len);
- } else if (em->block_start < EXTENT_MAP_LAST_BYTE) {
- btrfs_set_token_file_extent_disk_bytenr(&token, fi,
- em->block_start -
- extent_offset);
- btrfs_set_token_file_extent_disk_num_bytes(&token, fi, block_len);
- } else {
- btrfs_set_token_file_extent_disk_bytenr(&token, fi, 0);
- btrfs_set_token_file_extent_disk_num_bytes(&token, fi, 0);
- }
-
- btrfs_set_token_file_extent_offset(&token, fi, extent_offset);
- btrfs_set_token_file_extent_num_bytes(&token, fi, em->len);
- btrfs_set_token_file_extent_ram_bytes(&token, fi, em->ram_bytes);
- btrfs_set_token_file_extent_compression(&token, fi, em->compress_type);
- btrfs_set_token_file_extent_encryption(&token, fi, 0);
- btrfs_set_token_file_extent_other_encoding(&token, fi, 0);
+ write_extent_buffer(leaf, &fi,
+ btrfs_item_ptr_offset(leaf, path->slots[0]),
+ sizeof(fi));
btrfs_mark_buffer_dirty(leaf);
btrfs_release_path(path);
--
2.33.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
` (5 preceding siblings ...)
2022-02-03 14:55 ` [PATCH 6/6] btrfs: prepare extents to be logged before locking a log tree path fdmanana
@ 2022-02-04 16:36 ` David Sterba
2022-02-08 15:44 ` David Sterba
6 siblings, 1 reply; 9+ messages in thread
From: David Sterba @ 2022-02-04 16:36 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs
On Thu, Feb 03, 2022 at 02:55:44PM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> This is a mix of small improvements around logging extents, replacing
> extents in a log tree or subvolume tree, while others are more generic
> ones, and some cleanups. They are grouped in the same patchset, but they
> are all independent of each other.
>
> Filipe Manana (6):
> btrfs: remove unnecessary leaf free space checks when pushing items
> btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
> btrfs: avoid unnecessary computation when deleting items from a leaf
> btrfs: remove constraint on number of visited leaves when replacing extents
> btrfs: remove useless path release in the fast fsync path
> btrfs: prepare extents to be logged before locking a log tree path
Added as topic branch to for-next, thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging
2022-02-04 16:36 ` [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging David Sterba
@ 2022-02-08 15:44 ` David Sterba
0 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-02-08 15:44 UTC (permalink / raw)
To: dsterba, fdmanana, linux-btrfs
On Fri, Feb 04, 2022 at 05:36:01PM +0100, David Sterba wrote:
> On Thu, Feb 03, 2022 at 02:55:44PM +0000, fdmanana@kernel.org wrote:
> > From: Filipe Manana <fdmanana@suse.com>
> >
> > This is a mix of small improvements around logging extents, replacing
> > extents in a log tree or subvolume tree, while others are more generic
> > ones, and some cleanups. They are grouped in the same patchset, but they
> > are all independent of each other.
> >
> > Filipe Manana (6):
> > btrfs: remove unnecessary leaf free space checks when pushing items
> > btrfs: avoid unnecessary COW of leaves when deleting items from a leaf
> > btrfs: avoid unnecessary computation when deleting items from a leaf
> > btrfs: remove constraint on number of visited leaves when replacing extents
> > btrfs: remove useless path release in the fast fsync path
> > btrfs: prepare extents to be logged before locking a log tree path
>
> Added as topic branch to for-next, thanks.
Moved to misc-next.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-02-08 15:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-03 14:55 [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging fdmanana
2022-02-03 14:55 ` [PATCH 1/6] btrfs: remove unnecessary leaf free space checks when pushing items fdmanana
2022-02-03 14:55 ` [PATCH 2/6] btrfs: avoid unnecessary COW of leaves when deleting items from a leaf fdmanana
2022-02-03 14:55 ` [PATCH 3/6] btrfs: avoid unnecessary computation " fdmanana
2022-02-03 14:55 ` [PATCH 4/6] btrfs: remove constraint on number of visited leaves when replacing extents fdmanana
2022-02-03 14:55 ` [PATCH 5/6] btrfs: remove useless path release in the fast fsync path fdmanana
2022-02-03 14:55 ` [PATCH 6/6] btrfs: prepare extents to be logged before locking a log tree path fdmanana
2022-02-04 16:36 ` [PATCH 0/6] btrfs: some minor improvements and cleanups mostly around extent logging David Sterba
2022-02-08 15:44 ` David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).