Skip to content

Commit

Permalink
btrfs: push cleanup into btrfs_read_locked_inode()
Browse files Browse the repository at this point in the history
Move btrfs_add_inode_to_root() so it can be called from
btrfs_read_locked_inode(), no changes were made to the function.

Move cleanup code from btrfs_iget_path() to btrfs_read_locked_inode.
This improves readability and improves a leaky abstraction. Previously
btrfs_iget_path() had to handle a positive error case as a result of a
call to btrfs_search_slot(), but it makes more sense to handle this
closer to the source of the call.

Signed-off-by: Leo Martins <loemra.dev@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
loemraw authored and kdave committed Nov 11, 2024
1 parent df3b8ca commit 6967399
Showing 1 changed file with 53 additions and 48 deletions.
101 changes: 53 additions & 48 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3759,8 +3759,41 @@ static int btrfs_init_file_extent_tree(struct btrfs_inode *inode)
return 0;
}

static int btrfs_add_inode_to_root(struct btrfs_inode *inode, bool prealloc)
{
struct btrfs_root *root = inode->root;
struct btrfs_inode *existing;
const u64 ino = btrfs_ino(inode);
int ret;

if (inode_unhashed(&inode->vfs_inode))
return 0;

if (prealloc) {
ret = xa_reserve(&root->inodes, ino, GFP_NOFS);
if (ret)
return ret;
}

existing = xa_store(&root->inodes, ino, inode, GFP_ATOMIC);

if (xa_is_err(existing)) {
ret = xa_err(existing);
ASSERT(ret != -EINVAL);
ASSERT(ret != -ENOMEM);
return ret;
} else if (existing) {
WARN_ON(!(existing->vfs_inode.i_state & (I_WILL_FREE | I_FREEING)));
}

return 0;
}

/*
* read an inode from the btree into the in-memory inode
* Read a locked inode from the btree into the in-memory inode and add it to
* its root list/tree.
*
* On failure clean up the inode.
*/
static int btrfs_read_locked_inode(struct inode *inode,
struct btrfs_path *in_path)
Expand All @@ -3780,7 +3813,7 @@ static int btrfs_read_locked_inode(struct inode *inode,

ret = btrfs_init_file_extent_tree(BTRFS_I(inode));
if (ret)
return ret;
goto out;

ret = btrfs_fill_inode(inode, &rdev);
if (!ret)
Expand All @@ -3789,7 +3822,7 @@ static int btrfs_read_locked_inode(struct inode *inode,
if (!path) {
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
goto out;
}

btrfs_get_inode_key(BTRFS_I(inode), &location);
Expand All @@ -3798,7 +3831,13 @@ static int btrfs_read_locked_inode(struct inode *inode,
if (ret) {
if (path != in_path)
btrfs_free_path(path);
return ret;
/*
* ret > 0 can come from btrfs_search_slot called by
* btrfs_lookup_inode(), this means the inode was not found.
*/
if (ret > 0)
ret = -ENOENT;
goto out;
}

leaf = path->nodes[0];
Expand Down Expand Up @@ -3961,7 +4000,15 @@ static int btrfs_read_locked_inode(struct inode *inode,
}

btrfs_sync_inode_flags_to_i_flags(inode);

ret = btrfs_add_inode_to_root(BTRFS_I(inode), true);
if (ret)
goto out;

return 0;
out:
iget_failed(inode);
return ret;
}

/*
Expand Down Expand Up @@ -5470,35 +5517,7 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info,
return err;
}

static int btrfs_add_inode_to_root(struct btrfs_inode *inode, bool prealloc)
{
struct btrfs_root *root = inode->root;
struct btrfs_inode *existing;
const u64 ino = btrfs_ino(inode);
int ret;

if (inode_unhashed(&inode->vfs_inode))
return 0;

if (prealloc) {
ret = xa_reserve(&root->inodes, ino, GFP_NOFS);
if (ret)
return ret;
}

existing = xa_store(&root->inodes, ino, inode, GFP_ATOMIC);

if (xa_is_err(existing)) {
ret = xa_err(existing);
ASSERT(ret != -EINVAL);
ASSERT(ret != -ENOMEM);
return ret;
} else if (existing) {
WARN_ON(!(existing->vfs_inode.i_state & (I_WILL_FREE | I_FREEING)));
}

return 0;
}

static void btrfs_del_inode_from_root(struct btrfs_inode *inode)
{
Expand Down Expand Up @@ -5579,25 +5598,11 @@ struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
return inode;

ret = btrfs_read_locked_inode(inode, path);
/*
* ret > 0 can come from btrfs_search_slot called by
* btrfs_read_locked_inode(), this means the inode item was not found.
*/
if (ret > 0)
ret = -ENOENT;
if (ret < 0)
goto error;

ret = btrfs_add_inode_to_root(BTRFS_I(inode), true);
if (ret < 0)
goto error;
if (ret)
return ERR_PTR(ret);

unlock_new_inode(inode);

return inode;
error:
iget_failed(inode);
return ERR_PTR(ret);
}

struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
Expand Down

0 comments on commit 6967399

Please sign in to comment.