Commit 009d9bea authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

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: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 40084813
...@@ -6117,6 +6117,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, ...@@ -6117,6 +6117,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
struct btrfs_path *path; struct btrfs_path *path;
LIST_HEAD(dir_list); LIST_HEAD(dir_list);
struct btrfs_dir_list *dir_elem; struct btrfs_dir_list *dir_elem;
u64 ino = btrfs_ino(start_inode);
int ret = 0; int ret = 0;
/* /*
...@@ -6131,28 +6132,13 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, ...@@ -6131,28 +6132,13 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
if (!path) if (!path)
return -ENOMEM; return -ENOMEM;
dir_elem = kmalloc(sizeof(*dir_elem), GFP_NOFS); while (true) {
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)) {
struct extent_buffer *leaf; struct extent_buffer *leaf;
struct btrfs_key min_key; struct btrfs_key min_key;
u64 ino;
bool continue_curr_inode = true; bool continue_curr_inode = true;
int nritems; int nritems;
int i; 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.objectid = ino;
min_key.type = BTRFS_DIR_INDEX_KEY; min_key.type = BTRFS_DIR_INDEX_KEY;
min_key.offset = 0; min_key.offset = 0;
...@@ -6163,7 +6149,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, ...@@ -6163,7 +6149,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
break; break;
} else if (ret > 0) { } else if (ret > 0) {
ret = 0; ret = 0;
continue; goto next;
} }
leaf = path->nodes[0]; leaf = path->nodes[0];
...@@ -6226,6 +6212,15 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, ...@@ -6226,6 +6212,15 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
min_key.offset++; min_key.offset++;
goto again; 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: out:
btrfs_free_path(path); btrfs_free_path(path);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment