summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Munz <[email protected]>2026-08-02 09:35:26 +0000
committerTom Rini <[email protected]>2026-08-10 12:38:57 -0600
commita11f8659f451c5601bac6fdf5b48594d347db38d (patch)
treef7e6dbe9fa6db1399c1c6c1d037aa8f66d7999fb
parent1a5c8af2d4e4b4029739eb8787ce259d74977dfd (diff)
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 <[email protected]> Reviewed-by: Qu Wenruo <[email protected]>
-rw-r--r--fs/btrfs/btrfs.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
index b2856be0662..f5f6d638ffd 100644
--- a/fs/btrfs/btrfs.c
+++ b/fs/btrfs/btrfs.c
@@ -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,