mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-23 14:45:19 +00:00
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:
parent
005aeb8cb0
commit
f3ece218b6
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user