Skip to content

Commit

Permalink
btrfs: pass struct btrfs_inode to btrfs_read_locked_inode()
Browse files Browse the repository at this point in the history
[ Upstream commit d36f84a ]

Pass a struct btrfs_inode to btrfs_read_locked_inode() as it's an
internal interface, allowing to remove some use of BTRFS_I.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: 48c1d1b ("btrfs: fix the inode leak in btrfs_iget()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
David Sterba authored and Greg Kroah-Hartman committed May 9, 2025
1 parent ae58472 commit 569c6cd
Showing 1 changed file with 58 additions and 61 deletions.
119 changes: 58 additions & 61 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3846,12 +3846,13 @@ 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 *path)
static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path *path)
{
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *leaf;
struct btrfs_inode_item *inode_item;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct inode *vfs_inode = &inode->vfs_inode;
struct btrfs_key location;
unsigned long ptr;
int maybe_acls;
Expand All @@ -3860,17 +3861,17 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
bool filled = false;
int first_xattr_slot;

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

ret = btrfs_fill_inode(inode, &rdev);
ret = btrfs_fill_inode(vfs_inode, &rdev);
if (!ret)
filled = true;

ASSERT(path);

btrfs_get_inode_key(BTRFS_I(inode), &location);
btrfs_get_inode_key(inode, &location);

ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
if (ret) {
Expand All @@ -3890,42 +3891,41 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)

inode_item = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_inode_item);
inode->i_mode = btrfs_inode_mode(leaf, inode_item);
set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
btrfs_i_size_write(BTRFS_I(inode), btrfs_inode_size(leaf, inode_item));
btrfs_inode_set_file_extent_range(BTRFS_I(inode), 0,
round_up(i_size_read(inode), fs_info->sectorsize));

inode_set_atime(inode, btrfs_timespec_sec(leaf, &inode_item->atime),
vfs_inode->i_mode = btrfs_inode_mode(leaf, inode_item);
set_nlink(vfs_inode, btrfs_inode_nlink(leaf, inode_item));
i_uid_write(vfs_inode, btrfs_inode_uid(leaf, inode_item));
i_gid_write(vfs_inode, btrfs_inode_gid(leaf, inode_item));
btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
btrfs_inode_set_file_extent_range(inode, 0,
round_up(i_size_read(vfs_inode), fs_info->sectorsize));

inode_set_atime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->atime),
btrfs_timespec_nsec(leaf, &inode_item->atime));

inode_set_mtime(inode, btrfs_timespec_sec(leaf, &inode_item->mtime),
inode_set_mtime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->mtime),
btrfs_timespec_nsec(leaf, &inode_item->mtime));

inode_set_ctime(inode, btrfs_timespec_sec(leaf, &inode_item->ctime),
inode_set_ctime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->ctime),
btrfs_timespec_nsec(leaf, &inode_item->ctime));

BTRFS_I(inode)->i_otime_sec = btrfs_timespec_sec(leaf, &inode_item->otime);
BTRFS_I(inode)->i_otime_nsec = btrfs_timespec_nsec(leaf, &inode_item->otime);
inode->i_otime_sec = btrfs_timespec_sec(leaf, &inode_item->otime);
inode->i_otime_nsec = btrfs_timespec_nsec(leaf, &inode_item->otime);

inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
BTRFS_I(inode)->last_trans = btrfs_inode_transid(leaf, inode_item);
inode_set_bytes(vfs_inode, btrfs_inode_nbytes(leaf, inode_item));
inode->generation = btrfs_inode_generation(leaf, inode_item);
inode->last_trans = btrfs_inode_transid(leaf, inode_item);

inode_set_iversion_queried(inode,
btrfs_inode_sequence(leaf, inode_item));
inode->i_generation = BTRFS_I(inode)->generation;
inode->i_rdev = 0;
inode_set_iversion_queried(vfs_inode, btrfs_inode_sequence(leaf, inode_item));
vfs_inode->i_generation = inode->generation;
vfs_inode->i_rdev = 0;
rdev = btrfs_inode_rdev(leaf, inode_item);

if (S_ISDIR(inode->i_mode))
BTRFS_I(inode)->index_cnt = (u64)-1;
if (S_ISDIR(vfs_inode->i_mode))
inode->index_cnt = (u64)-1;

btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),
&BTRFS_I(inode)->flags, &BTRFS_I(inode)->ro_flags);
btrfs_update_inode_mapping_flags(BTRFS_I(inode));
&inode->flags, &inode->ro_flags);
btrfs_update_inode_mapping_flags(inode);

cache_index:
/*
Expand All @@ -3937,9 +3937,8 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
* This is required for both inode re-read from disk and delayed inode
* in the delayed_nodes xarray.
*/
if (BTRFS_I(inode)->last_trans == btrfs_get_fs_generation(fs_info))
set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
&BTRFS_I(inode)->runtime_flags);
if (inode->last_trans == btrfs_get_fs_generation(fs_info))
set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags);

/*
* We don't persist the id of the transaction where an unlink operation
Expand Down Expand Up @@ -3968,88 +3967,86 @@ static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *path)
* transaction commits on fsync if our inode is a directory, or if our
* inode is not a directory, logging its parent unnecessarily.
*/
BTRFS_I(inode)->last_unlink_trans = BTRFS_I(inode)->last_trans;
inode->last_unlink_trans = inode->last_trans;

/*
* Same logic as for last_unlink_trans. We don't persist the generation
* of the last transaction where this inode was used for a reflink
* operation, so after eviction and reloading the inode we must be
* pessimistic and assume the last transaction that modified the inode.
*/
BTRFS_I(inode)->last_reflink_trans = BTRFS_I(inode)->last_trans;
inode->last_reflink_trans = inode->last_trans;

path->slots[0]++;
if (inode->i_nlink != 1 ||
if (vfs_inode->i_nlink != 1 ||
path->slots[0] >= btrfs_header_nritems(leaf))
goto cache_acl;

btrfs_item_key_to_cpu(leaf, &location, path->slots[0]);
if (location.objectid != btrfs_ino(BTRFS_I(inode)))
if (location.objectid != btrfs_ino(inode))
goto cache_acl;

ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
if (location.type == BTRFS_INODE_REF_KEY) {
struct btrfs_inode_ref *ref;

ref = (struct btrfs_inode_ref *)ptr;
BTRFS_I(inode)->dir_index = btrfs_inode_ref_index(leaf, ref);
inode->dir_index = btrfs_inode_ref_index(leaf, ref);
} else if (location.type == BTRFS_INODE_EXTREF_KEY) {
struct btrfs_inode_extref *extref;

extref = (struct btrfs_inode_extref *)ptr;
BTRFS_I(inode)->dir_index = btrfs_inode_extref_index(leaf,
extref);
inode->dir_index = btrfs_inode_extref_index(leaf, extref);
}
cache_acl:
/*
* try to precache a NULL acl entry for files that don't have
* any xattrs or acls
*/
maybe_acls = acls_after_inode_item(leaf, path->slots[0],
btrfs_ino(BTRFS_I(inode)), &first_xattr_slot);
btrfs_ino(inode), &first_xattr_slot);
if (first_xattr_slot != -1) {
path->slots[0] = first_xattr_slot;
ret = btrfs_load_inode_props(inode, path);
ret = btrfs_load_inode_props(vfs_inode, path);
if (ret)
btrfs_err(fs_info,
"error loading props for ino %llu (root %llu): %d",
btrfs_ino(BTRFS_I(inode)),
btrfs_root_id(root), ret);
btrfs_ino(inode), btrfs_root_id(root), ret);
}

if (!maybe_acls)
cache_no_acl(inode);
cache_no_acl(vfs_inode);

switch (inode->i_mode & S_IFMT) {
switch (vfs_inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_mapping->a_ops = &btrfs_aops;
inode->i_fop = &btrfs_file_operations;
inode->i_op = &btrfs_file_inode_operations;
vfs_inode->i_mapping->a_ops = &btrfs_aops;
vfs_inode->i_fop = &btrfs_file_operations;
vfs_inode->i_op = &btrfs_file_inode_operations;
break;
case S_IFDIR:
inode->i_fop = &btrfs_dir_file_operations;
inode->i_op = &btrfs_dir_inode_operations;
vfs_inode->i_fop = &btrfs_dir_file_operations;
vfs_inode->i_op = &btrfs_dir_inode_operations;
break;
case S_IFLNK:
inode->i_op = &btrfs_symlink_inode_operations;
inode_nohighmem(inode);
inode->i_mapping->a_ops = &btrfs_aops;
vfs_inode->i_op = &btrfs_symlink_inode_operations;
inode_nohighmem(vfs_inode);
vfs_inode->i_mapping->a_ops = &btrfs_aops;
break;
default:
inode->i_op = &btrfs_special_inode_operations;
init_special_inode(inode, inode->i_mode, rdev);
vfs_inode->i_op = &btrfs_special_inode_operations;
init_special_inode(vfs_inode, vfs_inode->i_mode, rdev);
break;
}

btrfs_sync_inode_flags_to_i_flags(inode);
btrfs_sync_inode_flags_to_i_flags(vfs_inode);

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

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

Expand Down Expand Up @@ -5636,7 +5633,7 @@ struct inode *btrfs_iget_path(u64 ino, struct btrfs_root *root,
if (!(inode->i_state & I_NEW))
return inode;

ret = btrfs_read_locked_inode(inode, path);
ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
if (ret)
return ERR_PTR(ret);

Expand Down Expand Up @@ -5664,7 +5661,7 @@ struct inode *btrfs_iget(u64 ino, struct btrfs_root *root)
if (!path)
return ERR_PTR(-ENOMEM);

ret = btrfs_read_locked_inode(inode, path);
ret = btrfs_read_locked_inode(BTRFS_I(inode), path);
btrfs_free_path(path);
if (ret)
return ERR_PTR(ret);
Expand Down

0 comments on commit 569c6cd

Please sign in to comment.