diff mbox series

[v4,2/2] btrfs: remove conditional path allocation

Message ID 070163e08339759d751bf956bd7084772efbb074.1724970046.git.loemra.dev@gmail.com (mailing list archive)
State New, archived
Headers show
Series btrfs: iget_path cleanup | expand

Commit Message

Leo Martins Aug. 30, 2024, 8:24 p.m. UTC
Remove conditional path allocation from btrfs_read_locked_inode. Add
an ASSERT(path) to indicate it should never be called with a NULL path.

Call btrfs_read_locked_inode directly from btrfs_iget. This causes
code duplication between btrfs_iget and btrfs_iget_path, but I
think this is justifiable as it removes the need for conditionally
allocating the path inside of read_locked_inode. This makes the code
easier to reason about and makes it clear who has the responsibility of
allocating and freeing the path.

Signed-off-by: Leo Martins <loemra.dev@gmail.com>
---
 fs/btrfs/inode.c | 46 +++++++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index df0fe5e79ea2..a4b4e4190624 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3821,10 +3821,9 @@  static int btrfs_add_inode_to_root(struct btrfs_inode *inode, bool prealloc)
  * on failure clean up the inode
  */
 static int btrfs_read_locked_inode(struct inode *inode,
-				   struct btrfs_path *in_path)
+				   struct btrfs_path *path)
 {
 	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
-	struct btrfs_path *path = in_path;
 	struct extent_buffer *leaf;
 	struct btrfs_inode_item *inode_item;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3844,18 +3843,12 @@  static int btrfs_read_locked_inode(struct inode *inode,
 	if (!ret)
 		filled = true;
 
-	if (!path) {
-		path = btrfs_alloc_path();
-		if (!path)
-			goto error;
-	}
+	ASSERT(path);
 
 	btrfs_get_inode_key(BTRFS_I(inode), &location);
 
 	ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
 	if (ret) {
-		if (path != in_path)
-			btrfs_free_path(path);
 		/*
 		 * ret > 0 can come from btrfs_search_slot called by
 		 * btrfs_lookup_inode(), this means the inode was not found.
@@ -3997,8 +3990,6 @@  static int btrfs_read_locked_inode(struct inode *inode,
 				  btrfs_ino(BTRFS_I(inode)),
 				  btrfs_root_id(root), ret);
 	}
-	if (path != in_path)
-		btrfs_free_path(path);
 
 	if (!maybe_acls)
 		cache_no_acl(inode);
@@ -5608,9 +5599,8 @@  static struct inode *btrfs_iget_locked(u64 ino, struct btrfs_root *root)
 
 /*
  * Get an inode object given its inode number and corresponding root.
- * Path can be preallocated to prevent recursing back to iget through
- * allocator. NULL is also valid but may require an additional allocation
- * later.
+ * Path is preallocated to prevent recursing back to iget through
+ * allocator.
  */
 struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
 			      struct btrfs_path *path)
@@ -5633,9 +5623,35 @@  struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
 	return inode;
 }
 
+/*
+ * Get an inode object given its inode number and corresponding root.
+ */
 struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
 {
-	return btrfs_iget_path(ino, root, NULL);
+	struct inode *inode;
+	struct btrfs_path *path;
+	int ret;
+
+	inode = btrfs_iget_locked(ino, root);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	if (!(inode->i_state & I_NEW))
+		return inode;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return ERR_PTR(-ENOMEM);
+
+	ret = btrfs_read_locked_inode(inode, path);
+
+	btrfs_free_path(path);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	unlock_new_inode(inode);
+	return inode;
 }
 
 static struct inode *new_simple_dir(struct inode *dir,