btrfs-progs: add API for selecting tree search support and ioctl
Add wrappers around v1 and v2 of TREE_SEARCH ioctl so it can be transparently used by code. The structures partially overlap but due to the buffer size the v2 is offset and also needs a filler to expand the flexible buffer. Usage: - define struct btrfs_tree_search_args, all zeros - btrfs_tree_search_sk() reads offset of the search key within the structures - btrfs_tree_search_ioctl() detect support and call the highest supported ioctl version, v2 has been supported since 3.14 but we want to keep backward compatibility - btrfs_tree_search_data() read data from the buffer previously filled by ioctl, a sequence of (search header, data) Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
4ab1159db0
commit
a223764093
|
@ -31,6 +31,7 @@
|
||||||
#include "common/string-utils.h"
|
#include "common/string-utils.h"
|
||||||
#include "common/sysfs-utils.h"
|
#include "common/sysfs-utils.h"
|
||||||
#include "common/messages.h"
|
#include "common/messages.h"
|
||||||
|
#include "common/tree-search.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a root item for temporary tree root
|
* Insert a root item for temporary tree root
|
||||||
|
@ -680,6 +681,29 @@ int btrfs_check_features(const struct btrfs_mkfs_features *features,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tree_search_v2_supported = false;
|
||||||
|
static bool tree_search_v2_initialized = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the highest supported TREE_SEARCH ioctl version, autodetect support.
|
||||||
|
*/
|
||||||
|
int btrfs_tree_search_ioctl(int fd, struct btrfs_tree_search_args *sa)
|
||||||
|
{
|
||||||
|
/* On first use check the supported status and save it. */
|
||||||
|
if (!tree_search_v2_initialized) {
|
||||||
|
if (btrfs_tree_search2_ioctl_supported(fd) == 1)
|
||||||
|
tree_search_v2_supported = true;
|
||||||
|
tree_search_v2_initialized = true;
|
||||||
|
}
|
||||||
|
sa->use_v2 = tree_search_v2_supported;
|
||||||
|
|
||||||
|
if (sa->use_v2) {
|
||||||
|
sa->args2.buf_size = BTRFS_TREE_SEARCH_V2_BUF_SIZE;
|
||||||
|
return ioctl(fd, BTRFS_IOC_TREE_SEARCH_V2, &sa->args2);
|
||||||
|
}
|
||||||
|
return ioctl(fd, BTRFS_IOC_TREE_SEARCH, &sa->args1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the BTRFS_IOC_TREE_SEARCH_V2 ioctl is supported on a given
|
* Check if the BTRFS_IOC_TREE_SEARCH_V2 ioctl is supported on a given
|
||||||
* filesystem, opened at fd
|
* filesystem, opened at fd
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef __COMMON_TREE_SEARCH_H__
|
||||||
|
#define __COMMON_TREE_SEARCH_H__
|
||||||
|
|
||||||
|
#include "kernel-shared/uapi/btrfs_tree.h"
|
||||||
|
#include "kernel-shared/uapi/btrfs.h"
|
||||||
|
|
||||||
|
#define BTRFS_TREE_SEARCH_V2_BUF_SIZE 65536
|
||||||
|
|
||||||
|
struct btrfs_tree_search_args {
|
||||||
|
union {
|
||||||
|
struct btrfs_ioctl_search_args args1;
|
||||||
|
struct btrfs_ioctl_search_args_v2 args2;
|
||||||
|
u8 filler[sizeof(struct btrfs_ioctl_search_args_v2) +
|
||||||
|
BTRFS_TREE_SEARCH_V2_BUF_SIZE];
|
||||||
|
};
|
||||||
|
bool use_v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
int btrfs_tree_search_ioctl(int fd, struct btrfs_tree_search_args *sa);
|
||||||
|
|
||||||
|
static inline struct btrfs_ioctl_search_key *btrfs_tree_search_sk(struct btrfs_tree_search_args *sa)
|
||||||
|
{
|
||||||
|
/* Same offset for v1 and v2. */
|
||||||
|
return &sa->args1.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *btrfs_tree_search_data(struct btrfs_tree_search_args *sa, unsigned long offset) {
|
||||||
|
if (sa->use_v2)
|
||||||
|
return (void *)(sa->args2.buf + offset);
|
||||||
|
return (void *)(sa->args1.buf + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue