@@ -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,
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(-)