btrfs-progs: unify tree search header access

Use a local copy of the search header for proper aligned access instead
of the unaligned helpers, move the definitions to the closest scope.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2024-03-14 15:58:56 +01:00
parent 005aeb8cb0
commit f3ece218b6
6 changed files with 78 additions and 80 deletions

View File

@ -186,21 +186,21 @@ static int load_chunk_info(int fd, struct array *chunkinfos)
off = 0;
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_chunk *item;
struct btrfs_ioctl_search_header *sh;
struct btrfs_ioctl_search_header sh;
sh = btrfs_tree_search_data(&args, off);
off += sizeof(*sh);
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
item = btrfs_tree_search_data(&args, off);
ret = add_info_to_list(chunkinfos, item);
if (ret)
return 1;
off += btrfs_search_header_len(sh);
off += sh.len;
sk->min_objectid = btrfs_search_header_objectid(sh);
sk->min_type = btrfs_search_header_type(sh);
sk->min_offset = btrfs_search_header_offset(sh)+1;
sk->min_objectid = sh.objectid;
sk->min_type = sh.type;
sk->min_offset = sh.offset + 1;
}
if (!sk->min_offset) /* overflow */

View File

@ -581,7 +581,6 @@ static int print_min_dev_size(int fd, u64 devid)
while (1) {
int i;
struct btrfs_ioctl_search_header *sh;
unsigned long off = 0;
ret = btrfs_tree_search_ioctl(fd, &args);
@ -596,31 +595,29 @@ static int print_min_dev_size(int fd, u64 devid)
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_dev_extent *extent;
struct btrfs_ioctl_search_header sh;
u64 len;
sh = btrfs_tree_search_data(&args, off);
off += sizeof(*sh);
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
extent = btrfs_tree_search_data(&args, off);
off += btrfs_search_header_len(sh);
off += sh.len;
sk->min_objectid = btrfs_search_header_objectid(sh);
sk->min_type = btrfs_search_header_type(sh);
sk->min_offset = btrfs_search_header_offset(sh) + 1;
sk->min_objectid = sh.objectid;
sk->min_type = sh.type;
sk->min_offset = sh.offset + 1;
if (btrfs_search_header_objectid(sh) != devid ||
btrfs_search_header_type(sh) != BTRFS_DEV_EXTENT_KEY)
if (sh.objectid != devid || sh.type != BTRFS_DEV_EXTENT_KEY)
continue;
len = btrfs_stack_dev_extent_length(extent);
min_size += len;
ret = add_dev_extent(&extents,
btrfs_search_header_offset(sh),
btrfs_search_header_offset(sh) + len - 1, 0);
ret = add_dev_extent(&extents, sh.offset,
sh.offset + len - 1, 0);
if (!ret && last_pos != (u64)-1 &&
last_pos != btrfs_search_header_offset(sh))
if (!ret && last_pos != (u64)-1 && last_pos != sh.offset)
ret = add_dev_extent(&holes, last_pos,
btrfs_search_header_offset(sh) - 1, 1);
sh.offset - 1, 1);
if (ret) {
errno = -ret;
error("add device extent: %m");
@ -628,7 +625,7 @@ static int print_min_dev_size(int fd, u64 devid)
goto out;
}
last_pos = btrfs_search_header_offset(sh) + len;
last_pos = sh.offset + len;
}
if (sk->min_type != BTRFS_DEV_EXTENT_KEY ||
@ -976,7 +973,6 @@ static u64 fill_usage(int fd, u64 lstart)
{
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header sh;
struct btrfs_block_group_item *item;
int ret;
@ -1004,8 +1000,8 @@ static u64 fill_usage(int fd, u64 lstart)
if (sk->nr_items > 1)
warning("found more than one blockgroup %llu", lstart);
memcpy(&sh, btrfs_tree_search_data(&args, 0), sizeof(sh));
item = btrfs_tree_search_data(&args, sizeof(sh));
/* Only one item, we don't need search header. */
item = btrfs_tree_search_data(&args, sizeof(struct btrfs_ioctl_search_header));
return item->used;
}
@ -1015,7 +1011,6 @@ static int cmd_inspect_list_chunks(const struct cmd_struct *cmd,
{
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header sh;
unsigned long off = 0;
u64 *lnumber = NULL;
unsigned lnumber_size = 128;
@ -1118,6 +1113,7 @@ static int cmd_inspect_list_chunks(const struct cmd_struct *cmd,
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_chunk *item;
struct btrfs_stripe *stripes;
struct btrfs_ioctl_search_header sh;
int sidx;
u64 used = (u64)-1;
@ -1255,7 +1251,7 @@ static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks)
*chunks = NULL;
*num_chunks = 0;
for (;;) {
const struct btrfs_ioctl_search_header *header;
struct btrfs_ioctl_search_header sh;
const struct btrfs_chunk *item;
struct chunk *chunk;
size_t i;
@ -1274,11 +1270,13 @@ static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks)
break;
}
header = btrfs_tree_search_data(&args, buf_off);
if (header->type != BTRFS_CHUNK_ITEM_KEY)
memcpy(&sh, btrfs_tree_search_data(&args, buf_off), sizeof(sh));
buf_off += sizeof(sh);
if (sh.type != BTRFS_CHUNK_ITEM_KEY)
goto next;
item = (void *)(header + 1);
item = btrfs_tree_search_data(&args, buf_off);
if (*num_chunks >= capacity) {
struct chunk *tmp;
@ -1295,7 +1293,7 @@ static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks)
}
chunk = &(*chunks)[*num_chunks];
chunk->offset = header->offset;
chunk->offset = sh.offset;
chunk->length = le64_to_cpu(item->length);
chunk->stripe_len = le64_to_cpu(item->stripe_len);
chunk->type = le64_to_cpu(item->type);
@ -1319,11 +1317,11 @@ static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks)
next:
items_pos++;
buf_off += sizeof(*header) + header->len;
if (header->offset == (u64)-1)
buf_off += sh.len;
if (sh.offset == (u64)-1)
break;
else
sk->min_offset = header->offset + 1;
sk->min_offset = sh.offset + 1;
}
return 0;
}
@ -1394,7 +1392,7 @@ static int map_physical_start(int fd, struct chunk *chunks, size_t num_chunks,
sk->tree_id = ino_args.treeid;
sk->min_objectid = sk->max_objectid = st.st_ino;
for (;;) {
const struct btrfs_ioctl_search_header *header;
struct btrfs_ioctl_search_header sh;
const struct btrfs_file_extent_item *item;
u8 type;
u64 logical_offset = 0;
@ -1414,11 +1412,13 @@ static int map_physical_start(int fd, struct chunk *chunks, size_t num_chunks,
break;
}
header = btrfs_tree_search_data(&args, buf_off);
if (header->type != BTRFS_EXTENT_DATA_KEY)
memcpy(&sh, btrfs_tree_search_data(&args, buf_off), sizeof(sh));
buf_off += sizeof(sh);
if (sh.type != BTRFS_EXTENT_DATA_KEY)
goto next;
item = (void *)(header + 1);
item = btrfs_tree_search_data(&args, buf_off);
type = item->type;
if (type == BTRFS_FILE_EXTENT_REG ||
@ -1497,11 +1497,11 @@ static int map_physical_start(int fd, struct chunk *chunks, size_t num_chunks,
next:
items_pos++;
buf_off += sizeof(*header) + header->len;
if (header->offset == (u64)-1)
buf_off += sh.len;
if (sh.offset == (u64)-1)
break;
else
sk->min_offset = header->offset + 1;
sk->min_offset = sh.offset + 1;
}
return 0;

View File

@ -1262,7 +1262,6 @@ static int __qgroups_search(int fd, struct btrfs_tree_search_args *args,
int ret;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_key filter_key;
struct btrfs_ioctl_search_header *sh;
unsigned long off = 0;
unsigned int i;
struct btrfs_qgroup_status_item *si;
@ -1298,13 +1297,14 @@ static int __qgroups_search(int fd, struct btrfs_tree_search_args *args,
*/
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_key key;
struct btrfs_ioctl_search_header sh;
sh = btrfs_tree_search_data(args, off);
off += sizeof(*sh);
memcpy(&sh, btrfs_tree_search_data(args, off), sizeof(sh));
off += sizeof(sh);
key.objectid = btrfs_search_header_objectid(sh);
key.type = btrfs_search_header_type(sh);
key.offset = btrfs_search_header_offset(sh);
key.objectid = sh.objectid;
key.type = sh.type;
key.offset = sh.offset;
if (!key_in_range(&key, &filter_key))
goto next;
@ -1348,7 +1348,7 @@ static int __qgroups_search(int fd, struct btrfs_tree_search_args *args,
return ret;
next:
off += btrfs_search_header_len(sh);
off += sh.len;
/*
* record the mins in sk so we can make sure the

View File

@ -820,7 +820,6 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
int ret;
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header sh;
struct btrfs_root_ref *ref;
struct btrfs_root_item *ri;
unsigned long off;
@ -860,6 +859,8 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
* read the root_ref item it contains
*/
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_ioctl_search_header sh;
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
if (sh.type == BTRFS_ROOT_BACKREF_KEY) {

View File

@ -948,7 +948,6 @@ static u64 find_root_gen(int fd)
int ret;
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header sh;
unsigned long off = 0;
u64 max_found = 0;
int i;
@ -993,6 +992,7 @@ static u64 find_root_gen(int fd)
off = 0;
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_root_item *item;
struct btrfs_ioctl_search_header sh;
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
@ -1099,7 +1099,7 @@ static char *ino_resolve(int fd, u64 ino, u64 *cache_dirid, char **cache_name)
int ret;
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header *sh;
struct btrfs_ioctl_search_header sh;
int namelen;
memset(&args, 0, sizeof(args));
@ -1127,13 +1127,13 @@ static char *ino_resolve(int fd, u64 ino, u64 *cache_dirid, char **cache_name)
if (sk->nr_items == 0)
return NULL;
sh = btrfs_tree_search_data(&args, 0);
if (btrfs_search_header_type(sh) == BTRFS_INODE_REF_KEY) {
memcpy(&sh, btrfs_tree_search_data(&args, 0), sizeof(sh));
if (sh.type == BTRFS_INODE_REF_KEY) {
struct btrfs_inode_ref *ref;
dirid = btrfs_search_header_offset(sh);
dirid = sh.offset;
ref = (struct btrfs_inode_ref *)(sh + 1);
ref = btrfs_tree_search_data(&args, sizeof(sh));
namelen = btrfs_stack_inode_ref_name_len(ref);
name = (char *)(ref + 1);
@ -1245,7 +1245,6 @@ static int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen)
int ret;
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header sh;
struct btrfs_file_extent_item *item;
unsigned long off = 0;
u64 found_gen;
@ -1292,6 +1291,8 @@ static int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen)
* read the root_ref item it contains
*/
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_ioctl_search_header sh;
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
@ -1318,8 +1319,8 @@ static int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen)
* next search doesn't repeat this root
*/
sk->min_objectid = sh.objectid;
sk->min_offset = sh.offset;
sk->min_type = sh.type;
sk->min_offset = sh.offset;
}
sk->nr_items = 4096;
if (sk->min_offset < (u64)-1)

View File

@ -65,7 +65,6 @@ static int btrfs_read_root_item_raw(int mnt_fd, u64 root_id, size_t buf_len,
int ret;
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_search_header *sh;
unsigned long off = 0;
int found = 0;
int i;
@ -101,30 +100,30 @@ static int btrfs_read_root_item_raw(int mnt_fd, u64 root_id, size_t buf_len,
off = 0;
for (i = 0; i < sk->nr_items; i++) {
struct btrfs_root_item *item;
struct btrfs_ioctl_search_header sh;
sh = btrfs_tree_search_data(&args, off);
off += sizeof(*sh);
memcpy(&sh, btrfs_tree_search_data(&args, off), sizeof(sh));
off += sizeof(sh);
item = btrfs_tree_search_data(&args, off);
off += btrfs_search_header_len(sh);
off += sh.len;
sk->min_objectid = btrfs_search_header_objectid(sh);
sk->min_type = btrfs_search_header_type(sh);
sk->min_offset = btrfs_search_header_offset(sh);
sk->min_objectid = sh.objectid;
sk->min_type = sh.type;
sk->min_offset = sh.offset;
if (btrfs_search_header_objectid(sh) > root_id)
if (sh.objectid > root_id)
break;
if (btrfs_search_header_objectid(sh) == root_id &&
btrfs_search_header_type(sh) == BTRFS_ROOT_ITEM_KEY) {
if (btrfs_search_header_len(sh) > buf_len) {
if (sh.objectid == root_id && sh.type == BTRFS_ROOT_ITEM_KEY) {
if (sh.len > buf_len) {
/* btrfs-progs is too old for kernel */
error(
"buf for read_root_item_raw() is too small, get newer btrfs tools");
return -EOVERFLOW;
}
memcpy(buf, item, btrfs_search_header_len(sh));
*read_len = btrfs_search_header_len(sh);
memcpy(buf, item, sh.len);
*read_len = sh.len;
found = 1;
}
}
@ -196,7 +195,7 @@ static int btrfs_subvolid_resolve_sub(int fd, char *path, size_t *path_len,
struct btrfs_tree_search_args args;
struct btrfs_ioctl_search_key *sk;
struct btrfs_ioctl_ino_lookup_args ino_lookup_arg;
struct btrfs_ioctl_search_header *search_header;
struct btrfs_ioctl_search_header sh;
struct btrfs_root_ref *backref_item;
if (subvol_id == BTRFS_FS_TREE_OBJECTID) {
@ -229,14 +228,12 @@ static int btrfs_subvolid_resolve_sub(int fd, char *path, size_t *path_len,
fprintf(stderr, "failed to lookup subvol_id %llu!\n", subvol_id);
return -ENOENT;
}
search_header = btrfs_tree_search_data(&args, 0);
backref_item = (struct btrfs_root_ref *)(search_header + 1);
if (btrfs_search_header_offset(search_header)
!= BTRFS_FS_TREE_OBJECTID) {
memcpy(&sh, btrfs_tree_search_data(&args, 0), sizeof(sh));
backref_item = btrfs_tree_search_data(&args, sizeof(sh));
if (sh.offset != BTRFS_FS_TREE_OBJECTID) {
int sub_ret;
sub_ret = btrfs_subvolid_resolve_sub(fd, path, path_len,
btrfs_search_header_offset(search_header));
sub_ret = btrfs_subvolid_resolve_sub(fd, path, path_len, sh.offset);
if (sub_ret)
return sub_ret;
if (*path_len < 1)
@ -250,8 +247,7 @@ static int btrfs_subvolid_resolve_sub(int fd, char *path, size_t *path_len,
int len;
memset(&ino_lookup_arg, 0, sizeof(ino_lookup_arg));
ino_lookup_arg.treeid =
btrfs_search_header_offset(search_header);
ino_lookup_arg.treeid = sh.offset;
ino_lookup_arg.objectid =
btrfs_stack_root_ref_dirid(backref_item);
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &ino_lookup_arg);