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:
+42
-33
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user