Skip to content

Commit 8865716

Browse files
ukzhengkdave
authored andcommitted
btrfs-progs: re-enable tree search v2 ioctl
Commit d73e698 ("btrfs-progs: temporarily disable usage of v2 of search tree ioctl") turned off TREE_SEARCH_V2 detection because it led to an infinite loop in load_chunk_info() (reachable via 'btrfs filesystem usage', reproducible by mkfs-tests/001): from the second item in the returned buffer the data read back as all zeros while nr_items was non-zero, so the search key never advanced. The root cause is the type of the variable-sized buffer buf in struct btrfs_ioctl_search_args_v2: it is declared as __u64[], but the buffer holds a packed byte stream addressed by byte offsets. Adding such an offset to a __u64 pointer in btrfs_tree_search_data() scaled it by 8, so every item after the first landed past the valid data and read zeros, which fed a zeroed key back into the search and spun forever. Declare buf as __u8 in all in-tree copies of the struct so the offset arithmetic is in bytes, and restore the tree search autodetection so callers use the v2 ioctl when supported. The struct size is unchanged: buf stays 8-byte aligned after the __u64 buf_size. Considering a lot of subcommands are utilizing tree-search ioctl, hide the v2 tree search behind experimental build first, only after we have confirmed everything is fine move it out of experimental builds. Suggested-by: Qu Wenruo <wqu@suse.com> Signed-off-by: You-Kai Zheng <ykzheng@synology.com> [ Hide the v2 tree search behind experimental builds ] Signed-off-by: Qu Wenruo <wqu@suse.com>
1 parent 0dd8a92 commit 8865716

4 files changed

Lines changed: 5 additions & 9 deletions

File tree

common/fsfeatures.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,15 +708,11 @@ int btrfs_tree_search_ioctl(int fd, struct btrfs_tree_search_args *sa)
708708
{
709709
/* On first use check the supported status and save it. */
710710
if (!tree_search_v2_initialized) {
711-
#if 0
712-
/*
713-
* Keep using v1 until v2 is fully tested, in some cases it
714-
* does not return properly formatted results in the buffer.
715-
*/
711+
#ifdef EXPERIMENTAL
716712
if (btrfs_tree_search2_ioctl_supported(fd) == 1)
717713
tree_search_v2_supported = true;
718-
#endif
719714
tree_search_v2_initialized = true;
715+
#endif
720716
}
721717
sa->use_v2 = tree_search_v2_supported;
722718

kernel-shared/uapi/btrfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ struct btrfs_ioctl_search_args_v2 {
626626
__u64 buf_size; /* in - size of buffer
627627
* out - on EOVERFLOW: needed size
628628
* to store item */
629-
__u64 buf[]; /* out - found items */
629+
__u8 buf[]; /* out - found items */
630630
};
631631
_static_assert(sizeof(struct btrfs_ioctl_search_args_v2) == 112);
632632

libbtrfs/ioctl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ struct btrfs_ioctl_search_args_v2 {
385385
__u64 buf_size; /* in - size of buffer
386386
* out - on EOVERFLOW: needed size
387387
* to store item */
388-
__u64 buf[0]; /* out - found items */
388+
__u8 buf[0]; /* out - found items */
389389
};
390390

391391
/* With a @src_length of zero, the range from @src_offset->EOF is cloned! */

libbtrfsutil/btrfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ struct btrfs_ioctl_search_args_v2 {
590590
__u64 buf_size; /* in - size of buffer
591591
* out - on EOVERFLOW: needed size
592592
* to store item */
593-
__u64 buf[0]; /* out - found items */
593+
__u8 buf[0]; /* out - found items */
594594
};
595595

596596
/* With a @src_length of zero, the range from @src_offset->EOF is cloned! */

0 commit comments

Comments
 (0)