Re: [PATCH v2 2/5] btrfs: split btrfs_insert_delayed_dir_index() into prealloc and commit phases

From: Qu Wenruo

Date: Tue Aug 04 2026 - 19:15:31 EST




在 2026/8/5 01:14, Jeff Layton 写道:
Split btrfs_insert_delayed_dir_index() into three functions using a new
btrfs_dir_index_prealloc struct to bundle the pre-allocated resources:

- btrfs_prealloc_delayed_dir_index(): performs the two GFP_NOFS
allocations (delayed node + delayed item) that can fail with -ENOMEM.
- btrfs_insert_delayed_dir_index_prealloc(): populates the item data,
inserts into the rb-tree, and reserves metadata space. Cannot fail
with -ENOMEM since all allocations were done in the prealloc step.
- btrfs_free_delayed_dir_index_prealloc(): frees pre-allocated
resources when the caller's btree insertion fails.

The original btrfs_insert_delayed_dir_index() is refactored into a thin
wrapper that calls the prealloc and commit functions.

This split allows callers to move the fallible memory allocations before
the point of no return (the DIR_ITEM btree insertion), so that -ENOMEM
can be returned cleanly without aborting the transaction.

Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
fs/btrfs/delayed-inode.c | 111 +++++++++++++++++++++++++++++++++++++----------
fs/btrfs/delayed-inode.h | 17 ++++++++
2 files changed, 104 insertions(+), 24 deletions(-)

diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index db2ffab0941a..95d2dca80444 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -6,6 +6,7 @@
#include <linux/slab.h>
#include <linux/iversion.h>
+#include <linux/error-injection.h>
#include "ctree.h"
#include "fs.h"
#include "messages.h"
@@ -1469,35 +1470,74 @@ static void btrfs_release_dir_index_item_space(struct btrfs_trans_handle *trans)
trans->bytes_reserved -= bytes;
}
-/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected). */
-int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
- const char *name, int name_len,
- struct btrfs_inode *dir,
- const struct btrfs_disk_key *disk_key, u8 flags,
- u64 index)
+/*
+ * Pre-allocate a delayed node and delayed item for a dir index insertion.
+ * Call this before modifying the btree so that ENOMEM can be returned
+ * before any on-disk state has changed.
+ *
+ * Returns 0 on success, -ENOMEM on allocation failure.
+ */
+int btrfs_prealloc_delayed_dir_index(struct btrfs_inode *dir,
+ const char *name, int name_len,
+ struct btrfs_dir_index_prealloc *prealloc)

We can directly return a btrfs_dir_index_prealloc pointer, which reduce the parameter list.

Otherwise looks good to me.

Reviewed-by: Qu Wenruo <wqu@xxxxxxxx>

Thanks,
Qu