fs: btrfs: deduplicate the inode size lookup

btrfs_readdir() and btrfs_size() both open code the same search for an
inode item to read its size field. Move it into one helper.

Signed-off-by: Cole Munz <Munzzyy1@proton.me>
Reviewed-by: Qu Wenruo <wqu@suse.com>
This commit is contained in:
Cole Munz
2026-08-10 12:38:57 -06:00
committed by Tom Rini
parent 1a5c8af2d4
commit a11f8659f4
+42 -33
View File
@@ -88,14 +88,42 @@ static unsigned int btrfs_dirent_type_to_fs_type(u8 dirent_type)
}
}
/*
* Read the size stored in an inode item. A missing item is -ENOENT and
* leaves *size untouched.
*/
static int btrfs_get_inode_size(struct btrfs_root *root, u64 ino, u64 *size)
{
struct btrfs_inode_item *ii;
struct btrfs_path path;
struct btrfs_key key;
int ret;
key.objectid = ino;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
btrfs_init_path(&path);
ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
if (ret < 0)
return ret;
if (ret > 0)
ret = -ENOENT;
if (!ret) {
ii = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_inode_item);
*size = btrfs_inode_size(path.nodes[0], ii);
}
btrfs_release_path(&path);
return ret;
}
int btrfs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
{
struct btrfs_dir_stream *dirs = container_of(fs_dirs, struct btrfs_dir_stream, parent);
struct btrfs_fs_info *fs_info = current_fs_info;
struct fs_dirent *dent = &dirs->dirent;
struct btrfs_inode_item *ii;
struct btrfs_root *root;
struct btrfs_path path;
struct btrfs_key location;
struct btrfs_key key;
u8 type;
@@ -127,16 +155,13 @@ int btrfs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
* layer prints it, so look it up.
*/
if (location.type == BTRFS_INODE_ITEM_KEY) {
btrfs_init_path(&path);
ret = btrfs_search_slot(NULL, root, &location, &path, 0, 0);
if (ret == 0) {
ii = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_inode_item);
dent->size = btrfs_inode_size(path.nodes[0], ii);
}
btrfs_release_path(&path);
if (ret < 0)
u64 size;
ret = btrfs_get_inode_size(root, location.objectid, &size);
if (ret < 0 && ret != -ENOENT)
return ret;
if (!ret)
dent->size = size;
}
*dentp = dent;
@@ -173,10 +198,8 @@ int btrfs_exists(const char *file)
int btrfs_size(const char *file, loff_t *size)
{
struct btrfs_fs_info *fs_info = current_fs_info;
struct btrfs_inode_item *ii;
struct btrfs_root *root;
struct btrfs_path path;
struct btrfs_key key;
u64 isize;
u64 ino;
u8 type;
int ret;
@@ -191,27 +214,13 @@ int btrfs_size(const char *file, loff_t *size)
printf("Not a regular file: %s\n", file);
return -ENOENT;
}
btrfs_init_path(&path);
key.objectid = ino;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
if (ret < 0) {
printf("Cannot lookup ino %llu\n", ino);
ret = btrfs_get_inode_size(root, ino, &isize);
if (ret) {
printf("Cannot read size of ino %llu\n", ino);
return ret;
}
if (ret > 0) {
printf("Ino %llu does not exist\n", ino);
ret = -ENOENT;
goto out;
}
ii = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_inode_item);
*size = btrfs_inode_size(path.nodes[0], ii);
out:
btrfs_release_path(&path);
return ret;
*size = isize;
return 0;
}
int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,