summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2022-08-17 14:22:38 +0300
committerDavid Sterba <dsterba@suse.com>2022-09-26 13:27:56 +0300
commit009d9bea49b4c78769da52b800412fb163ff0ae7 (patch)
tree5cc0dd749202370a014f0dae53deb2e7f9109fc5
parent4008481343aa4d2587c6f2fa75759eda1f3fff41 (diff)
downloadlinux-009d9bea49b4c78769da52b800412fb163ff0ae7.tar.xz
btrfs: avoid memory allocation at log_new_dir_dentries() for common case
At log_new_dir_dentries() we always start by allocating a list element for the starting inode and then do a while loop with the condition being a list emptiness check. This however is not needed, we can avoid allocating this initial list element and then just check for the list emptiness at the end of the loop's body. So just do that to save one memory allocation from the kmalloc-32 slab. This allows for not doing any memory allocation when we don't have any subdirectory to log, which is a very common case. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/tree-log.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 0f084abfb14d..ea807231ce05 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -6117,6 +6117,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
struct btrfs_path *path;
LIST_HEAD(dir_list);
struct btrfs_dir_list *dir_elem;
+ u64 ino = btrfs_ino(start_inode);
int ret = 0;
/*
@@ -6131,28 +6132,13 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
if (!path)
return -ENOMEM;
- dir_elem = kmalloc(sizeof(*dir_elem), GFP_NOFS);
- if (!dir_elem) {
- btrfs_free_path(path);
- return -ENOMEM;
- }
- dir_elem->ino = btrfs_ino(start_inode);
- list_add_tail(&dir_elem->list, &dir_list);
-
- while (!list_empty(&dir_list)) {
+ while (true) {
struct extent_buffer *leaf;
struct btrfs_key min_key;
- u64 ino;
bool continue_curr_inode = true;
int nritems;
int i;
- dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list,
- list);
- ino = dir_elem->ino;
- list_del(&dir_elem->list);
- kfree(dir_elem);
-
min_key.objectid = ino;
min_key.type = BTRFS_DIR_INDEX_KEY;
min_key.offset = 0;
@@ -6163,7 +6149,7 @@ again:
break;
} else if (ret > 0) {
ret = 0;
- continue;
+ goto next;
}
leaf = path->nodes[0];
@@ -6226,6 +6212,15 @@ again:
min_key.offset++;
goto again;
}
+
+next:
+ if (list_empty(&dir_list))
+ break;
+
+ dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list, list);
+ ino = dir_elem->ino;
+ list_del(&dir_elem->list);
+ kfree(dir_elem);
}
out:
btrfs_free_path(path);