summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2014-11-25 18:46:16 +0100
committerDavid Sterba <dsterba@suse.cz>2014-12-10 15:01:20 +0100
commit8ef9ac8cda38bda25561c2964f0aa81d8dcdf451 (patch)
tree481399f68e3abd063c13995c332bc8748851f174
parent6715de04d9a707aad5eddaeb65132f0c206c7b5f (diff)
downloadbtrfs-progs-8ef9ac8cda38bda25561c2964f0aa81d8dcdf451.tar.gz
btrfs-progs: basic support for TREE_SEARCH_V2 ioctl
Add the interface and helper that checks if the v2 ioctl is supported. Signed-off-by: David Sterba <dsterba@suse.cz>
-rw-r--r--ioctl.h14
-rw-r--r--utils.c40
-rw-r--r--utils.h2
3 files changed, 56 insertions, 0 deletions
diff --git a/ioctl.h b/ioctl.h
index 67c8de9..2c2c7c1 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -279,6 +279,18 @@ struct btrfs_ioctl_search_args {
char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
};
+/*
+ * Extended version of TREE_SEARCH ioctl that can return more than 4k of bytes.
+ * The allocated size of the buffer is set in buf_size.
+ */
+struct btrfs_ioctl_search_args_v2 {
+ struct btrfs_ioctl_search_key key; /* in/out - search parameters */
+ __u64 buf_size; /* in - size of buffer
+ * out - on EOVERFLOW: needed size
+ * to store item */
+ __u64 buf[0]; /* out - found items */
+};
+
#define BTRFS_INO_LOOKUP_PATH_MAX 4080
struct btrfs_ioctl_ino_lookup_args {
__u64 treeid;
@@ -542,6 +554,8 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_defrag_range_args)
#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+ struct btrfs_ioctl_search_args_v2)
#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
struct btrfs_ioctl_ino_lookup_args)
#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64)
diff --git a/utils.c b/utils.c
index 8885669..1dba182 100644
--- a/utils.c
+++ b/utils.c
@@ -2625,3 +2625,43 @@ u64 get_partition_size(char *dev)
return result;
}
+
+int btrfs_tree_search2_ioctl_supported(int fd)
+{
+ struct btrfs_ioctl_search_args_v2 *args2;
+ struct btrfs_ioctl_search_key *sk;
+ int args2_size = 1024;
+ char args2_buf[args2_size];
+ int ret;
+ static int v2_supported = -1;
+
+ if (v2_supported != -1)
+ return v2_supported;
+
+ args2 = (struct btrfs_ioctl_search_args_v2 *)args2_buf;
+ sk = &(args2->key);
+
+ /*
+ * Search for the extent tree item in the root tree.
+ */
+ sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
+ sk->min_objectid = BTRFS_EXTENT_TREE_OBJECTID;
+ sk->max_objectid = BTRFS_EXTENT_TREE_OBJECTID;
+ sk->min_type = BTRFS_ROOT_ITEM_KEY;
+ sk->max_type = BTRFS_ROOT_ITEM_KEY;
+ sk->min_offset = 0;
+ sk->max_offset = (u64)-1;
+ sk->min_transid = 0;
+ sk->max_transid = (u64)-1;
+ sk->nr_items = 1;
+ args2->buf_size = args2_size - sizeof(struct btrfs_ioctl_search_args_v2);
+ ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH_V2, args2);
+ if (ret == -EOPNOTSUPP)
+ v2_supported = 0;
+ else if (ret == 0)
+ v2_supported = 1;
+ else
+ return ret;
+
+ return v2_supported;
+}
diff --git a/utils.h b/utils.h
index 6cbb7b8..0464c2d 100644
--- a/utils.h
+++ b/utils.h
@@ -187,4 +187,6 @@ static inline int count_digits(u64 num)
return ret;
}
+int btrfs_tree_search2_ioctl_supported(int fd);
+
#endif