[PATCH 3/3] Add btrfs ioctl support.
Jeff Mahoney
jeffm at suse.com
Thu Mar 31 01:19:27 UTC 2016
* btrfs.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* defs.h [LINUX] (btrfs_ioctl): New function.
* ioctls.c (ioctl_decode) [LINUX]: Use it to decode BTRFS_* ioctls.
* configure.ac: Add check for struct btrfs_ioctl_feature_flags.
Add check for struct btrfs_ioctl_fs_info_args.nodesize.
Add struct btrfs_ioctl_defrag_range_args.
* xlat/btrfs_balance_flags.in: New file.
* xlat/btrfs_defrag_flags.in: New file.
* xlat/btrfs_dev_replace_cmds.in: New file.
* xlat/btrfs_dev_replace_results.in: New file.
* xlat/btrfs_dev_replace_state.in: New file.
* xlat/btrfs_dev_stats_flags.in: New file.
* xlat/btrfs_dev_stats_values.in: New file.
* xlat/btrfs_features_compat_ro.in: New file.
* xlat/btrfs_features_incompat.in: New file.
* xlat/btrfs_key_types.in: New file.
* xlat/btrfs_qgroup_ctl_cmds.in: New file.
* xlat/btrfs_qgroup_inherit_flags.in: New file.
* xlat/btrfs_qgroup_limit_flags.in: New file.
* xlat/btrfs_qgroup_status_flags.in: New file.
* xlat/btrfs_scrub_flags.in: New file.
* xlat/btrfs_snap_flags_v2.in: New file.
* xlat/btrfs_space_info_flags.in: New file.
* xlat/btrfs_tree_objectids.in: New file.
---
Makefile.am | 1 +
btrfs.c | 1240 ++++++++++++++++++++++++++++++++++++
configure.ac | 15 +
defs.h | 1 +
ioctl.c | 2 +
xlat/btrfs_balance_flags.in | 12 +
xlat/btrfs_defrag_flags.in | 2 +
xlat/btrfs_dev_replace_cmds.in | 3 +
xlat/btrfs_dev_replace_results.in | 4 +
xlat/btrfs_dev_replace_state.in | 5 +
xlat/btrfs_dev_stats_flags.in | 1 +
xlat/btrfs_dev_stats_values.in | 11 +
xlat/btrfs_features_compat.in | 0
xlat/btrfs_features_compat_ro.in | 1 +
xlat/btrfs_features_incompat.in | 10 +
xlat/btrfs_key_types.in | 40 ++
xlat/btrfs_qgroup_ctl_cmds.in | 3 +
xlat/btrfs_qgroup_inherit_flags.in | 1 +
xlat/btrfs_qgroup_limit_flags.in | 6 +
xlat/btrfs_qgroup_status_flags.in | 2 +
xlat/btrfs_scrub_flags.in | 1 +
xlat/btrfs_snap_flags_v2.in | 3 +
xlat/btrfs_space_info_flags.in | 11 +
xlat/btrfs_tree_objectids.in | 12 +
24 files changed, 1387 insertions(+)
create mode 100644 btrfs.c
create mode 100644 xlat/btrfs_balance_flags.in
create mode 100644 xlat/btrfs_defrag_flags.in
create mode 100644 xlat/btrfs_dev_replace_cmds.in
create mode 100644 xlat/btrfs_dev_replace_results.in
create mode 100644 xlat/btrfs_dev_replace_state.in
create mode 100644 xlat/btrfs_dev_stats_flags.in
create mode 100644 xlat/btrfs_dev_stats_values.in
create mode 100644 xlat/btrfs_features_compat.in
create mode 100644 xlat/btrfs_features_compat_ro.in
create mode 100644 xlat/btrfs_features_incompat.in
create mode 100644 xlat/btrfs_key_types.in
create mode 100644 xlat/btrfs_qgroup_ctl_cmds.in
create mode 100644 xlat/btrfs_qgroup_inherit_flags.in
create mode 100644 xlat/btrfs_qgroup_limit_flags.in
create mode 100644 xlat/btrfs_qgroup_status_flags.in
create mode 100644 xlat/btrfs_scrub_flags.in
create mode 100644 xlat/btrfs_snap_flags_v2.in
create mode 100644 xlat/btrfs_space_info_flags.in
create mode 100644 xlat/btrfs_tree_objectids.in
diff --git a/Makefile.am b/Makefile.am
index e15c2d9..cd1857f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -75,6 +75,7 @@ strace_SOURCES = \
bjm.c \
block.c \
bpf.c \
+ btrfs.c \
cacheflush.c \
capability.c \
caps0.h \
diff --git a/btrfs.c b/btrfs.c
new file mode 100644
index 0000000..e24d41f
--- /dev/null
+++ b/btrfs.c
@@ -0,0 +1,1240 @@
+/*
+ * Copyright (c) 2016 Jeff Mahoney <jeffm at suse.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include <linux/fs.h>
+#include <linux/btrfs.h>
+
+#ifndef HAVE_BTRFS_IOCTL_FEATURE_FLAGS
+struct btrfs_ioctl_feature_flags {
+ __u64 compat_flags;
+ __u64 compat_ro_flags;
+ __u64 incompat_flags;
+};
+#endif
+
+#ifndef HAVE_BTRFS_IOCTL_DEFRAG_RANGE_ARGS
+struct btrfs_ioctl_defrag_range_args {
+ __u64 start;
+ __u64 len;
+ __u64 flags;
+ __u32 extent_thresh;
+ __u32 compress_type;
+ __u32 unused[4];
+};
+#endif
+
+#ifndef BTRFS_LABEL_SIZE
+#define BTRFS_LABEL_SIZE 256
+#endif
+
+#ifndef BTRFS_FIRST_FREE_OBJECTID
+#define BTRFS_FIRST_FREE_OBJECTID 256ULL
+#endif
+
+#ifndef BTRFS_IOC_GET_FEATURES
+#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
+ struct btrfs_ioctl_feature_flags)
+#define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
+ struct btrfs_ioctl_feature_flags[2])
+#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
+ struct btrfs_ioctl_feature_flags[3])
+#endif
+
+#include "xlat/btrfs_balance_flags.h"
+#include "xlat/btrfs_defrag_flags.h"
+#include "xlat/btrfs_dev_replace_args.h"
+#include "xlat/btrfs_dev_replace_cmds.h"
+#include "xlat/btrfs_dev_replace_results.h"
+#include "xlat/btrfs_dev_replace_state.h"
+#include "xlat/btrfs_dev_stats_flags.h"
+#include "xlat/btrfs_dev_stats_values.h"
+#include "xlat/btrfs_features_compat.h"
+#include "xlat/btrfs_features_compat_ro.h"
+#include "xlat/btrfs_features_incompat.h"
+#include "xlat/btrfs_key_types.h"
+#include "xlat/btrfs_qgroup_ctl_cmds.h"
+#include "xlat/btrfs_qgroup_inherit_flags.h"
+#include "xlat/btrfs_qgroup_limit_flags.h"
+#include "xlat/btrfs_qgroup_status_flags.h"
+#include "xlat/btrfs_scrub_flags.h"
+#include "xlat/btrfs_snap_flags_v2.h"
+#include "xlat/btrfs_space_info_flags.h"
+#include "xlat/btrfs_tree_objectids.h"
+
+static inline char
+prnibble(char v)
+{
+ if (v >= 10)
+ return 'a' + (v - 10);
+ return '0' + v;
+}
+
+/* Formats uuid, returns 0 if it's all zeroes */
+static int
+btrfs_unparse_uuid(unsigned char *uuid, char *out)
+{
+ int i;
+ int ret = 0;
+ for (i = 0; i < BTRFS_UUID_SIZE; i++) {
+ if (i == 4 || i == 6 || i == 8 || i == 10)
+ *out++ = '-';
+ *out++ = prnibble(uuid[i] >> 4);
+ *out++ = prnibble(uuid[i] & 0xf);
+ if (uuid[i])
+ ret = 1;
+ }
+ out[36] = '\0';
+ return ret;
+}
+
+static void
+print_u64(const char *name, uint64_t value)
+{
+ tprintf(", %s=%" PRIu64, name, value);
+}
+
+#define print_member_u64(obj, name) print_u64(#name, obj->name)
+
+static void
+btrfs_print_balance_args(const char *name, struct btrfs_balance_args *bba)
+{
+ tprintf(", %s={profiles=%" PRI__u64, name, bba->profiles);
+ print_member_u64(bba, usage);
+ print_member_u64(bba, devid);
+ print_member_u64(bba, pstart);
+ print_member_u64(bba, pend);
+ print_member_u64(bba, vstart);
+ print_member_u64(bba, vend);
+ print_member_u64(bba, target);
+ printflags(btrfs_balance_flags, bba->flags, NULL);
+ tprints("}");
+}
+
+static void
+btrfs_print_balance(struct tcb *tcp, const long arg, bool out)
+{
+ struct btrfs_ioctl_balance_args balance_args;
+
+ if (umove_or_printaddr(tcp, arg, &balance_args))
+ return;
+
+ if (syserror(tcp))
+ return;
+
+ tprints("{flags=");
+ printflags(btrfs_balance_flags, balance_args.flags, NULL);
+ if (out)
+ tprintf(", state=%" PRI__u64, balance_args.state);
+
+ if (balance_args.flags & BTRFS_BALANCE_DATA) {
+ tprints(", ");
+ btrfs_print_balance_args("data", &balance_args.data);
+ }
+ if (balance_args.flags & BTRFS_BALANCE_METADATA) {
+ tprints(", ");
+ btrfs_print_balance_args("meta", &balance_args.meta);
+ }
+ if (balance_args.flags & BTRFS_BALANCE_SYSTEM) {
+ tprints(", ");
+ btrfs_print_balance_args("sys", &balance_args.sys);
+ }
+ tprints("}");
+}
+
+static void
+btrfs_print_features(struct btrfs_ioctl_feature_flags *flags)
+{
+ tprints("{compat_flags=");
+ printflags(btrfs_features_compat, flags->compat_flags,
+ "BTRFS_FEATURE_COMPAT_???");
+
+ tprints(", compat_ro_flags=");
+ printflags(btrfs_features_compat_ro, flags->compat_ro_flags,
+ "BTRFS_FEATURE_COMPAT_RO_???");
+
+ tprints(", incompat_flags=");
+ printflags(btrfs_features_incompat, flags->incompat_flags,
+ "BTRFS_FEATURE_INCOMPAT_???");
+ tprints("}");
+}
+
+static void
+btrfs_print_qgroup_limit(struct btrfs_qgroup_limit *lim)
+{
+ tprints("{flags=");
+ printflags(btrfs_qgroup_limit_flags, lim->flags, NULL);
+ tprintf(", max_rfer=%" PRI__u64 ", max_excl=%" PRI__u64
+ ", rsv_rfer=%" PRI__u64 ", rsv_excl=%" PRI__u64 "}",
+ lim->max_rfer, lim->max_excl,
+ lim->rsv_rfer, lim->rsv_excl);
+}
+
+static void
+btrfs_print_key_type(uint32_t type)
+{
+ const char *str = xlookup(btrfs_key_types, type);
+ tprintf("%u", type);
+ if (str)
+ tprintf(" /* %s */", str);
+}
+
+static void
+btrfs_print_objectid(uint64_t objectid)
+{
+ const char *str = xlookup(btrfs_tree_objectids, objectid);
+ tprintf("%" PRIu64, objectid);
+ if (str)
+ tprintf(" /* %s */", str);
+}
+
+int
+btrfs_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
+{
+ int ret = 0;
+
+ switch (code) {
+ /* Take no arguments; Command only. */
+ case BTRFS_IOC_TRANS_START:
+ case BTRFS_IOC_TRANS_END:
+ case BTRFS_IOC_SYNC:
+ case BTRFS_IOC_SCRUB_CANCEL:
+ case BTRFS_IOC_QUOTA_RESCAN_WAIT:
+ break;
+
+ /* take a signed int */
+ case BTRFS_IOC_CLONE: /* also FICLONE */
+ case BTRFS_IOC_BALANCE_CTL:
+ printnum_int(tcp, arg, "%d");
+ break;
+
+ /* returns a 64 */
+ case BTRFS_IOC_START_SYNC: /* R */
+ if (entering(tcp))
+ return 0;
+ /* fallthrough */
+ /* take a u64 */
+ case BTRFS_IOC_DEFAULT_SUBVOL: /* W */
+ case BTRFS_IOC_WAIT_SYNC: /* W */
+ tprints(", ");
+ printnum_int64(tcp, arg, "%" PRI__u64);
+ break;
+
+ /* u64 but describe a flags bitfield; We can make that symbolic */
+ case BTRFS_IOC_SUBVOL_GETFLAGS: { /* R */
+ uint64_t flags;
+ if (entering(tcp))
+ return 0;
+ if (syserror(tcp))
+ break;
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &flags))
+ break;
+ printflags(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
+ break;
+ }
+ case BTRFS_IOC_SUBVOL_SETFLAGS: { /* W */
+ uint64_t flags;
+ if (exiting(tcp))
+ break;
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &flags))
+ break;
+ printflags(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
+ break;
+ }
+
+ /* More complex types */
+ case BTRFS_IOC_BALANCE_V2: /* RW */
+ if (entering(tcp)) {
+ tprints(", ");
+ btrfs_print_balance(tcp, arg, false);
+ return 0;
+ }
+ if (exiting(tcp)) {
+ if (syserror(tcp))
+ break;
+ tprints(" => ");
+ btrfs_print_balance(tcp, arg, true);
+ }
+ break;
+ case BTRFS_IOC_BALANCE_PROGRESS: /* R */
+ if (exiting(tcp)) {
+ tprints(", ");
+ btrfs_print_balance(tcp, arg, true);
+ }
+ break;
+ case BTRFS_IOC_CLONE_RANGE: /* W */
+ if (entering(tcp)) {
+ struct btrfs_ioctl_clone_range_args args;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+ tprintf("{src_fd=%" PRI__s64 ", "
+ "src_offset=%" PRI__u64 ", "
+ "src_length=%" PRI__u64 ", "
+ "dest_offset=%" PRI__u64 "}",
+ args.src_fd, args.src_offset,
+ args.src_length, args.dest_offset);
+ }
+ break;
+
+ case BTRFS_IOC_DEFRAG_RANGE: /* W */
+ if (entering(tcp)) {
+ struct btrfs_ioctl_defrag_range_args args;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+ tprintf("{start=%" PRI__u64 ", len=%" PRI__u64 ", "
+ "flags=", args.start, args.len);
+ printflags(btrfs_defrag_flags, args.flags, NULL);
+ tprintf(", extent_thresh=%u, compress_type=%u}",
+ args.extent_thresh, args.compress_type);
+ }
+ break;
+ case BTRFS_IOC_DEV_INFO: { /* RW */
+ struct btrfs_ioctl_dev_info_args args;
+ char uuid[37];
+ int valid;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+ tprints("{");
+
+ valid = btrfs_unparse_uuid(args.uuid, uuid);
+ if (entering(tcp)) {
+ tprintf("devid=%" PRI__u64, args.devid);
+ if (valid)
+ tprintf(", uuid=%s", uuid);
+ tprints("}");
+ return 0;
+ }
+ if (valid)
+ tprintf("uuid=%s, ", uuid);
+ tprintf("bytes_used=%" PRI__u64 ", "
+ "total_bytes=%" PRI__u64 ", "
+ "path=\"%s\"}",
+ args.bytes_used, args.total_bytes, args.path);
+ break;
+ }
+
+ case BTRFS_IOC_DEV_REPLACE: { /* RW */
+ struct btrfs_ioctl_dev_replace_args args;
+
+ if (entering(tcp))
+ tprints(", ");
+
+ if (syserror(tcp))
+ break;
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ tprints("{cmd=");
+ printxvals(args.cmd, "BTRFS_IOCTL_DEV_REPLACE_CMD_???",
+ btrfs_dev_replace_cmds, NULL);
+ if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_START) {
+ tprintf(", start={srcdevid=%" PRI__u64 ", "
+ "cont_reading_from_srcdev_mode=%" PRI__u64
+ ", srcdev_name=\"%s\", tgtdev_name=\"%s\"}",
+ args.start.srcdevid,
+ args.start.cont_reading_from_srcdev_mode,
+ args.start.srcdev_name,
+ args.start.tgtdev_name);
+ }
+ tprints("}");
+ return 0;
+ }
+
+ tprints(" => {result=");
+ printxvals(args.result, "BTRFS_IOCTL_DEV_REPLACE_RESULT_???",
+ btrfs_dev_replace_results, NULL);
+ if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS) {
+ char buf[10];
+ time_t time;
+ tprints(", ");
+ printxvals(args.status.replace_state,
+ "BTRFS_IOCTL_DEV_REPLACE_STATE_???",
+ btrfs_dev_replace_state, NULL);
+ snprintf(buf, sizeof(buf), ", %" PRI__u64
+ ".%" PRI__u64 "%%",
+ args.status.progress_1000 / 10,
+ args.status.progress_1000 % 10);
+ tprintf(", progress_1000=[%" PRI__u64 "(%s)], ",
+ args.status.progress_1000, buf);
+
+ time = args.status.time_started;
+ strftime(buf, sizeof(buf), "%T",
+ localtime(&time));
+ tprintf("time_started=[%" PRI__u64" (%s)], ",
+ args.status.time_started, buf);
+
+ time = args.status.time_stopped;
+ strftime(buf, sizeof(buf), "%T",
+ localtime(&time));
+ tprintf("time_stopped=[%" PRI__u64" (%s)], ",
+ args.status.time_stopped, buf);
+
+ tprintf("num_write_errors=%" PRI__u64 ", "
+ "num_uncorrectable_read_errors=%" PRI__u64 "}",
+ args.status.num_write_errors,
+ args.status.num_uncorrectable_read_errors);
+ }
+ break;
+ }
+
+ case BTRFS_IOC_GET_FEATURES: { /* R */
+ struct btrfs_ioctl_feature_flags flags;
+ if (entering(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &flags))
+ break;
+
+ btrfs_print_features(&flags);
+ break;
+ }
+ case BTRFS_IOC_SET_FEATURES: { /* W */
+ struct btrfs_ioctl_feature_flags flarg[2];
+ if (exiting(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &flarg))
+ break;
+
+ tprints("[");
+ btrfs_print_features(&flarg[0]);
+ tprints(", ");
+ btrfs_print_features(&flarg[1]);
+ tprints("]");
+ break;
+ }
+
+ case BTRFS_IOC_GET_SUPPORTED_FEATURES: { /* R */
+ struct btrfs_ioctl_feature_flags flarg[3];
+
+ if (entering(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &flarg))
+ break;
+
+ tprints("[ /* supported */ ");
+ btrfs_print_features(&flarg[0]);
+
+ tprints(", /* safe to set */ ");
+ btrfs_print_features(&flarg[1]);
+
+ tprints(", /* safe to clear */ ");
+ btrfs_print_features(&flarg[2]);
+ tprints("]");
+
+ break;
+ }
+
+ case BTRFS_IOC_FS_INFO: { /* R */
+ struct btrfs_ioctl_fs_info_args args;
+ char uuid[37];
+#ifndef HAVE_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
+ __u32 *reserved32;
+#endif
+
+ if (entering(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+#ifndef HAVE_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
+ reserved32 = (__u32 *)args.reserved;
+#endif
+
+ btrfs_unparse_uuid(args.fsid, uuid);
+
+ tprints("{");
+ tprintf("max_id=%" PRI__u64 ", num_devices=%" PRI__u64 ", "
+ "fsid=%s, nodesize=%u, sectorsize=%u, "
+ "clone_alignment=%u",
+ args.max_id,
+ args.num_devices,
+ uuid,
+#ifdef HAVE_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
+ args.nodesize,
+ args.sectorsize,
+ args.clone_alignment);
+#else
+ reserved32[0],
+ reserved32[1],
+ reserved32[2]);
+#endif
+ tprints("}");
+ break;
+ }
+
+ case BTRFS_IOC_GET_DEV_STATS: { /* RW */
+ struct btrfs_ioctl_get_dev_stats args;
+ uint64_t i;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprints("{");
+
+ if (entering(tcp))
+ tprintf("devid=%" PRI__u64 ", ", args.devid);
+
+ tprintf("nr_items=%" PRI__u64, args.nr_items);
+ printflags(btrfs_dev_stats_flags, args.flags, NULL);
+
+ if (entering(tcp)) {
+ tprints("}");
+ return 0;
+ }
+
+ tprints(", [");
+ for (i = 0; i < args.nr_items; i++) {
+ const char *name = xlookup(btrfs_dev_stats_values, i);
+ if (i)
+ tprints(", ");
+ if (name)
+ tprintf("/* %s */ ", name);
+ tprintf("%" PRI__u64, args.values[i]);
+ }
+ tprints("]");
+ break;
+ }
+
+ case BTRFS_IOC_INO_LOOKUP: { /* RW */
+ struct btrfs_ioctl_ino_lookup_args args;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ /* Use subvolume id of the containing root */
+ if (args.treeid == 0)
+ /* abuse of auxstr to retain state */
+ tcp->auxstr = (void *)1;
+
+ tprints("{treeid=");
+ btrfs_print_objectid(args.treeid);
+ tprints(", objectid=");
+ btrfs_print_objectid(args.objectid);
+ tprints("}");
+ return 0;
+ }
+
+ tprints("{");
+ if (tcp->auxstr) {
+ tprints("treeid=");
+ btrfs_print_objectid(args.treeid);
+ tprints(", ");
+ }
+ tcp->auxstr = NULL;
+
+ tprintf("name=\"%s\"}", args.name);
+ break;
+ }
+
+ case BTRFS_IOC_INO_PATHS: { /* RW */
+ struct btrfs_ioctl_ino_path_args args;
+ struct btrfs_data_container fspath;
+ uint64_t i;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprints("{");
+
+ if (entering(tcp)) {
+ tprintf("inum=%" PRI__u64 ", size=%" PRI__u64 "}",
+ args.inum, args.size);
+ return 0;
+ }
+
+ if (umoven_or_printaddr(tcp, args.fspath, args.size, &fspath))
+ break;
+
+ tprintf("fspath={bytes_left=%u, bytes_missing=%u, "
+ "elem_cnt=%u, elem_missed=%u, val=[",
+ fspath.bytes_left, fspath.bytes_missing,
+ fspath.elem_cnt, fspath.elem_missed);
+ for (i = 0; i < fspath.elem_cnt; i++) {
+ uint64_t ptr;
+ char *str;
+ ptr = (uint64_t)(unsigned long)fspath.val;
+ ptr += fspath.val[i];
+ str = (char *)(unsigned long)ptr;
+ if (i)
+ tprints(", ");
+ tprints(str);
+ }
+ tprints("]}");
+
+ break;
+ }
+
+ case BTRFS_IOC_LOGICAL_INO: { /* RW */
+ struct btrfs_ioctl_logical_ino_args args;
+ struct btrfs_data_container *inodes;
+ uint64_t i;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprints("{");
+
+ if (entering(tcp)) {
+ tprintf("logical=%" PRI__u64 ", size=%" PRI__u64 "}",
+ args.logical, args.size);
+ return 0;
+ }
+
+ tprints("inodes=");
+ inodes = malloc(args.size);
+ if (!inodes) {
+ tprintf("%#lx", (unsigned long)args.inodes);
+ break;
+ }
+
+ if (umoven_or_printaddr(tcp, args.inodes, args.size, inodes)) {
+ free(inodes);
+ break;
+ }
+
+ tprintf("{bytes_left=%u, bytes_missing=%u, "
+ "elem_cnt=%u, elem_missed=%u, val=[",
+ inodes->bytes_left, inodes->bytes_missing,
+ inodes->elem_cnt, inodes->elem_missed);
+ for (i = 0; i < inodes->elem_cnt; i += 3) {
+ if (i)
+ tprints(", ");
+ tprintf("{inum=%" PRI__u64 ", offset=%" PRI__u64
+ ", root=%" PRI__u64 "}",
+ inodes->val[i],
+ inodes->val[i+1],
+ inodes->val[i+2]);
+ }
+ tprints("]}");
+ free(inodes);
+
+ break;
+ }
+
+ case BTRFS_IOC_QGROUP_ASSIGN: { /* W */
+ struct btrfs_ioctl_qgroup_assign_args args;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{assign=%" PRI__u64 ", src=%" PRI__u64
+ ", dst=%" PRI__u64 "}",
+ args.assign, args.src, args.dst);
+ break;
+ }
+
+ case BTRFS_IOC_QGROUP_CREATE: { /* W */
+ struct btrfs_ioctl_qgroup_create_args args;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{create=%" PRI__u64 ", qgroupid=%" PRI__u64 "}",
+ args.create, args.qgroupid);
+ break;
+ }
+
+ case BTRFS_IOC_QGROUP_LIMIT: { /* R */
+ struct btrfs_ioctl_qgroup_limit_args args;
+
+ if (entering(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{qgroupid=%" PRI__u64 ", lim=", args.qgroupid);
+ btrfs_print_qgroup_limit(&args.lim);
+ tprints("}");
+ break;
+ }
+
+ case BTRFS_IOC_QUOTA_CTL: { /* W */
+ struct btrfs_ioctl_quota_ctl_args args;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ printxvals(args.cmd, "BTRFS_QUOTA_CTL_???",
+ btrfs_qgroup_ctl_cmds, NULL);
+ tprints("}");
+
+ break;
+ }
+ case BTRFS_IOC_QUOTA_RESCAN: { /* W */
+ struct btrfs_ioctl_quota_rescan_args args;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{flags=%" PRI__u64 "}", args.flags);
+ break;
+ }
+ case BTRFS_IOC_QUOTA_RESCAN_STATUS: { /* R */
+ struct btrfs_ioctl_quota_rescan_args args;
+
+ if (entering(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{flags=%" PRI__u64 ", progress=", args.flags);
+ if (args.progress == -1ULL && abbrev(tcp))
+ tprints("-1");
+ else
+ btrfs_print_objectid(args.progress);
+ tprints("}");
+ break;
+ }
+ case BTRFS_IOC_SET_RECEIVED_SUBVOL: { /* RW */
+ struct btrfs_ioctl_received_subvol_args args;
+ char uuid[37];
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ btrfs_unparse_uuid((unsigned char *)args.uuid, uuid);
+ tprintf("{uuid=%s, stransid=%" PRI__u64
+ ", stime=%" PRI__u64 ".%u, flags=%" PRI__u64 "}",
+ uuid, args.stransid, args.stime.sec,
+ args.stime.nsec, args.flags);
+ return 0;
+ }
+ tprintf("{rtransid=%" PRI__u64
+ ", rtime=%" PRI__u64 ".%u}",
+ args.rtransid, args.rtime.sec, args.rtime.nsec);
+ break;
+ }
+
+ case BTRFS_IOC_FILE_EXTENT_SAME: { /* RW */
+ int i;
+ unsigned size;
+ struct btrfs_ioctl_same_args args;
+ struct btrfs_ioctl_same_extent_info *info;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ tprintf("{logical_offset=%" PRI__u64 ", "
+ "length=%" PRI__u64 ", "
+ "dest_count=%hu, info=",
+ args.logical_offset, args.length,
+ args.dest_count);
+ }
+
+ size = sizeof(*info) * args.dest_count;
+ info = malloc(size);
+ if (!info) {
+ tprintf("%#lx}", arg + sizeof(args));
+ break;
+ }
+
+ if (umoven_or_printaddr(tcp, arg + sizeof(args), size, info)) {
+ tprints("}");
+ free(info);
+ break;
+ }
+
+ if (entering(tcp)) {
+ tprints("[");
+ for (i = 0; i < args.dest_count; i++) {
+ if (i)
+ tprints(", ");
+ tprintf("{fd=%" PRI__s64 ", "
+ "logical_offset=%" PRI__u64 "}",
+ info[i].fd, info[i].logical_offset);
+ }
+ tprints("]");
+ return 0;
+ }
+ tprints("{info=[");
+ for (i = 0; i < args.dest_count; i++) {
+ if (i)
+ tprints(", ");
+ tprintf("{bytes_deduped=%" PRI__u64 ", "
+ "status=%d}",
+ info[i].bytes_deduped, info[i].status);
+ }
+ tprints("]");
+ free(info);
+ break;
+ }
+
+ case BTRFS_IOC_SCRUB: /* RW */
+ case BTRFS_IOC_SCRUB_PROGRESS: { /* RW */
+ struct btrfs_ioctl_scrub_args args;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ tprintf("{devid=%" PRI__u64, args.devid);
+ if (code == BTRFS_IOC_SCRUB) {
+ tprintf(", start=%" PRI__u64 ", end=",
+ args.start);
+ if (args.end == -1ULL && abbrev(tcp))
+ tprints("-1");
+ else
+ tprintf("%" PRI__u64, args.end);
+ tprints(", flags=");
+ printflags(btrfs_scrub_flags, args.flags,
+ "BTRFS_SCRUB_???");
+ }
+ tprints("}");
+ return 0;
+ }
+ tprintf("{data_extents_scrubbed=%" PRI__u64 ", "
+ "tree_extents_scrubbed=%" PRI__u64 ", "
+ "data_bytes_scrubbed=%" PRI__u64 ", "
+ "tree_bytes_scrubbed=%" PRI__u64 ", "
+ "read_errors=%" PRI__u64 ", "
+ "csum_errors=%" PRI__u64 ", "
+ "verify_errors=%" PRI__u64 ", "
+ "no_csum=%" PRI__u64 ", "
+ "csum_discards=%" PRI__u64 ", "
+ "super_errors=%" PRI__u64 ", "
+ "malloc_errors=%" PRI__u64 ", "
+ "uncorrectable_errors=%" PRI__u64 ", "
+ "corrected_errors=%" PRI__u64 ", "
+ "last_physical=%" PRI__u64 ", "
+ "unverified_errors=%" PRI__u64 "}",
+ args.progress.data_extents_scrubbed,
+ args.progress.tree_extents_scrubbed,
+ args.progress.data_bytes_scrubbed,
+ args.progress.tree_bytes_scrubbed,
+ args.progress.read_errors,
+ args.progress.csum_errors,
+ args.progress.verify_errors,
+ args.progress.no_csum,
+ args.progress.csum_discards,
+ args.progress.super_errors,
+ args.progress.malloc_errors,
+ args.progress.uncorrectable_errors,
+ args.progress.corrected_errors,
+ args.progress.last_physical,
+ args.progress.unverified_errors);
+ break;
+ }
+
+ case BTRFS_IOC_TREE_SEARCH: { /* RW */
+ struct btrfs_ioctl_search_args args;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ if (entering(tcp)) {
+ tprintf("{key={tree_id=");
+ btrfs_print_objectid(args.key.tree_id);
+
+ if (args.key.min_objectid !=
+ BTRFS_FIRST_FREE_OBJECTID ||
+ !abbrev(tcp)) {
+ tprints(", min_objectid=");
+ btrfs_print_objectid(args.key.min_objectid);
+ }
+
+ if (args.key.max_objectid !=
+ BTRFS_LAST_FREE_OBJECTID ||
+ !abbrev(tcp)) {
+ tprints(", max_objectid=");
+ btrfs_print_objectid(args.key.max_objectid);
+ }
+
+ if (args.key.min_offset || !abbrev(tcp))
+ tprintf(", min_offset=%" PRI__u64,
+ args.key.min_offset);
+
+ if (args.key.max_offset == -1ULL) {
+ if (!abbrev(tcp))
+ tprints(", max_offset=-1");
+ } else
+ tprintf(", max_offset=%" PRI__u64,
+ args.key.max_offset);
+
+ if (args.key.min_transid || !abbrev(tcp))
+ tprintf(", min_transid=%" PRI__u64,
+ args.key.min_transid);
+
+ if (args.key.max_transid == -1ULL) {
+ if (!abbrev(tcp))
+ tprints(", max_transid=-1");
+ } else
+ tprintf(", max_transid=%" PRI__u64,
+ args.key.max_transid);
+ tprints(", min_type=");
+ btrfs_print_key_type(args.key.min_type);
+ tprints(", max_type=");
+ btrfs_print_key_type(args.key.max_type);
+ tprintf(", nr_items=%u}}", args.key.nr_items);
+ return 0;
+ }
+ tprintf("{key={nr_items=%u}, buf=", args.key.nr_items);
+ if (abbrev(tcp))
+ tprints("...");
+ else {
+ struct btrfs_ioctl_search_header *sh;
+ uint64_t i;
+ uint64_t off = 0;
+ tprints("[");
+ for (i = 0; i < args.key.nr_items; i++) {
+ sh = (struct btrfs_ioctl_search_header *)
+ (args.buf + off);
+ if (i)
+ tprints(", ");
+ tprintf("{transid=%" PRI__u64 ", "
+ "objectid=", sh->transid);
+ btrfs_print_objectid(sh->objectid);
+ tprintf(", offset=%" PRI__u64 ", type=",
+ sh->offset);
+ btrfs_print_key_type(sh->type);
+ tprintf(", len=%u}", sh->len);
+ off += sizeof(*sh) + sh->len;
+ }
+ tprints("]");
+ }
+
+ tprints("}");
+
+ /* We don't need to parse the output buffer */
+ break;
+ }
+
+ case BTRFS_IOC_SEND: { /* W */
+ struct btrfs_ioctl_send_args args;
+ __u64 *sources;
+ size_t size;
+ uint64_t i;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{send_fd=%" PRI__s64 ", clone_sources_count=%" PRI__u64
+ ", clone_sources=", args.send_fd,
+ args.clone_sources_count);
+
+ size = args.clone_sources_count * sizeof(*args.clone_sources);
+ sources = malloc(size);
+ if (!sources) {
+ tprintf("%#lx}", (unsigned long)args.clone_sources);
+ break;
+ }
+
+ if (umoven_or_printaddr(tcp, (unsigned long)args.clone_sources,
+ size, sources)) {
+ tprintf("}");
+ free(sources);
+ break;
+ }
+
+ tprints("[");
+ for (i = 0; i < args.clone_sources_count; i++) {
+ if (i)
+ tprints(", ");
+ btrfs_print_objectid(sources[i]);
+ }
+ tprints("]}");
+ free(sources);
+ break;
+ }
+
+ case BTRFS_IOC_SPACE_INFO: { /* RW */
+ struct btrfs_ioctl_space_args args;
+ struct btrfs_ioctl_space_info *spaces;
+ size_t size;
+ uint64_t i;
+
+ if (entering(tcp))
+ tprints(", ");
+ else if (syserror(tcp))
+ break;
+ else
+ tprints(" => ");
+
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprints("{");
+ if (entering(tcp)) {
+ tprintf("space_slots=%" PRI__u64,
+ args.space_slots);
+ return 0;
+ }
+
+ tprintf("total_spaces=%" PRI__u64, args.total_spaces);
+
+ if (args.space_slots == 0 && args.total_spaces) {
+ tprints("}");
+ break;
+ }
+
+ tprints(", spaces=");
+ if (abbrev(tcp)) {
+ tprints("...}");
+ break;
+ }
+
+ size = args.total_spaces * sizeof(args.spaces[0]);
+ spaces = malloc(size);
+ if (!spaces) {
+ tprintf("%#lx}", arg + sizeof(arg));
+ break;
+ }
+
+ if (umoven_or_printaddr(tcp, arg + sizeof(args),
+ size, spaces)) {
+ tprintf("%#lx}", arg + sizeof(arg));
+ free(spaces);
+ break;
+ }
+
+ tprints("[");
+
+ for (i = 0; i < args.total_spaces; i++) {
+ if (i)
+ tprints(", ");
+ tprints("{flags=");
+ printflags(btrfs_space_info_flags, spaces[i].flags,
+ "BTRFS_SPACE_INFO_???");
+ tprintf(", total_bytes=%" PRI__u64 ", "
+ "used_bytes=%" PRI__u64 "}",
+ spaces[i].total_bytes,
+ spaces[i].used_bytes);
+
+ }
+ tprints("]}");
+ free(spaces);
+ break;
+ }
+
+ case BTRFS_IOC_SNAP_CREATE:
+ case BTRFS_IOC_DEFRAG:
+ case BTRFS_IOC_RESIZE:
+ case BTRFS_IOC_SCAN_DEV:
+ case BTRFS_IOC_ADD_DEV:
+ case BTRFS_IOC_RM_DEV:
+ case BTRFS_IOC_BALANCE:
+ case BTRFS_IOC_SUBVOL_CREATE:
+ case BTRFS_IOC_SNAP_DESTROY:
+ case BTRFS_IOC_DEVICES_READY: { /* W */
+ struct btrfs_ioctl_vol_args args;
+
+ if (exiting(tcp))
+ return 0;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{fd=%" PRI__s64 ", name=\"%s\"}",
+ args.fd, args.name);
+ break;
+ }
+
+ case BTRFS_IOC_SNAP_CREATE_V2:
+ case BTRFS_IOC_SUBVOL_CREATE_V2: { /* W */
+ struct btrfs_ioctl_vol_args_v2 args;
+
+ if (syserror(tcp))
+ break;
+
+ if (exiting(tcp))
+ break;
+
+ tprints(", ");
+ if (umove_or_printaddr(tcp, arg, &args))
+ break;
+
+ tprintf("{fd=%" PRI__s64 ", flags=", args.fd);
+ printflags(btrfs_snap_flags_v2, args.flags, "BTRFS_SUBVOL_???");
+ if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
+ struct btrfs_qgroup_inherit *inherit;
+ uint64_t i;
+
+ tprintf(", size=%" PRI__u64 ", qgroup_inherit=",
+ args.size);
+
+ inherit = malloc(args.size);
+ if (!inherit) {
+ tprintf("%lx}",
+ (unsigned long)args.qgroup_inherit);
+ break;
+ }
+
+ if (umoven_or_printaddr(tcp,
+ (unsigned long)args.qgroup_inherit,
+ args.size, inherit) < 0) {
+ tprintf("%lx}",
+ (unsigned long)args.qgroup_inherit);
+ free(inherit);
+ break;
+ }
+
+ tprintf("{flags=");
+ printflags(btrfs_qgroup_inherit_flags,
+ inherit->flags, "BTRFS_QGROUP_INHERIT_???");
+ tprintf(", num_qgroups=%" PRI__u64
+ ", num_ref_copies=%" PRI__u64
+ ", num_excl_copies=%" PRI__u64
+ ", lim=",
+ inherit->num_qgroups,
+ inherit->num_ref_copies,
+ inherit->num_excl_copies);
+
+ btrfs_print_qgroup_limit(&inherit->lim);
+
+ tprints(", [");
+ for (i = 0; i < inherit->num_qgroups; i++) {
+ if (i)
+ tprints(", ");
+ tprintf("%" PRI__u64, inherit->qgroups[i]);
+ }
+ tprints("]}");
+ free(inherit);
+ }
+ tprints("}");
+ break;
+ }
+ case BTRFS_IOC_GET_FSLABEL: /* R */
+ case BTRFS_IOC_SET_FSLABEL: {/* W */
+ char label[BTRFS_LABEL_SIZE];
+ if ((code == BTRFS_IOC_GET_FSLABEL && entering(tcp)) ||
+ (code == BTRFS_IOC_SET_FSLABEL && exiting(tcp)))
+ return 0;
+
+ tprints(", ");
+ if (umoven_or_printaddr(tcp, arg, sizeof(label), label))
+ break;
+ tprintf("\"%s\"", label);
+ break;
+ }
+ default:
+ return RVAL_DECODED;
+ };
+ return ret | RVAL_DECODED | 1;
+}
diff --git a/configure.ac b/configure.ac
index 98907a0..20f37fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -433,6 +433,21 @@ AC_CHECK_HEADERS([linux/bpf.h], [
fi
])
+AC_CHECK_HEADERS([linux/btrfs.h], [
+ AC_CHECK_MEMBERS([struct btrfs_ioctl_feature_flags.compat_flags],
+ AC_DEFINE(HAVE_BTRFS_IOCTL_FEATURE_FLAGS, [1],
+ [Define 1 to if struct strfs_ioctl_feature_flags exists]),,
+ [#include <linux/btrfs.h>])
+ AC_CHECK_MEMBERS([struct btrfs_ioctl_fs_info_args.nodesize],
+ AC_DEFINE(HAVE_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE, [1],
+ [Define to 1 if struct btrfs_ioctl_fs_info_args.nodesize exists]),,
+ [#include <linux/btrfs.h>])
+ AC_CHECK_MEMBERS([struct btrfs_ioctl_defrag_range_args.start],
+ AC_DEFINE(HAVE_BTRFS_IOCTL_DEFRAG_RANGE_ARGS, [1],
+ [Define to 1 if struct btrfs_ioctl_defrag_range_args exists]),,
+ [#include <linux/btrfs.h>])
+])
+
AC_CHECK_DECLS([sys_errlist])
AC_CHECK_DECLS(m4_normalize([
PTRACE_PEEKUSER,
diff --git a/defs.h b/defs.h
index fe56de4..56e027c 100644
--- a/defs.h
+++ b/defs.h
@@ -639,6 +639,7 @@ extern const char *sprint_open_modes(int);
extern void print_seccomp_filter(struct tcb *tcp, unsigned long);
extern int block_ioctl(struct tcb *, const unsigned int, long);
+extern int btrfs_ioctl(struct tcb *, const unsigned int, long);
extern int evdev_ioctl(struct tcb *, const unsigned int, long);
extern int loop_ioctl(struct tcb *, const unsigned int, long);
extern int mtd_ioctl(struct tcb *, const unsigned int, long);
diff --git a/ioctl.c b/ioctl.c
index f70dc44..44df39d 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -263,6 +263,8 @@ ioctl_decode(struct tcb *tcp)
case 'E':
return evdev_ioctl(tcp, code, arg);
#endif
+ case 0x94:
+ return btrfs_ioctl(tcp, code, arg);
default:
break;
}
diff --git a/xlat/btrfs_balance_flags.in b/xlat/btrfs_balance_flags.in
new file mode 100644
index 0000000..6bd7549
--- /dev/null
+++ b/xlat/btrfs_balance_flags.in
@@ -0,0 +1,12 @@
+BTRFS_BALANCE_DATA (1ULL << 0)
+BTRFS_BALANCE_SYSTEM (1ULL << 1)
+BTRFS_BALANCE_METADATA (1ULL << 2)
+BTRFS_BALANCE_FORCE
+BTRFS_BALANCE_RESUME
+BTRFS_BALANCE_ARGS_PROFILES
+BTRFS_BALANCE_ARGS_USAGE
+BTRFS_BALANCE_ARGS_DEVID
+BTRFS_BALANCE_ARGS_DRANGE
+BTRFS_BALANCE_ARGS_VRANGE
+BTRFS_BALANCE_ARGS_CONVERT
+BTRFS_BALANCE_ARGS_SOFT
diff --git a/xlat/btrfs_defrag_flags.in b/xlat/btrfs_defrag_flags.in
new file mode 100644
index 0000000..33b490f
--- /dev/null
+++ b/xlat/btrfs_defrag_flags.in
@@ -0,0 +1,2 @@
+BTRFS_DEFRAG_RANGE_COMPRESS
+BTRFS_DEFRAG_RANGE_START_IO
diff --git a/xlat/btrfs_dev_replace_cmds.in b/xlat/btrfs_dev_replace_cmds.in
new file mode 100644
index 0000000..65bbf3b
--- /dev/null
+++ b/xlat/btrfs_dev_replace_cmds.in
@@ -0,0 +1,3 @@
+BTRFS_IOCTL_DEV_REPLACE_CMD_START
+BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS
+BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL
diff --git a/xlat/btrfs_dev_replace_results.in b/xlat/btrfs_dev_replace_results.in
new file mode 100644
index 0000000..4b75d09
--- /dev/null
+++ b/xlat/btrfs_dev_replace_results.in
@@ -0,0 +1,4 @@
+BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR
+BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED
+BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED
+BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS
diff --git a/xlat/btrfs_dev_replace_state.in b/xlat/btrfs_dev_replace_state.in
new file mode 100644
index 0000000..e89e5e6
--- /dev/null
+++ b/xlat/btrfs_dev_replace_state.in
@@ -0,0 +1,5 @@
+BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED
+BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED
+BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED
+BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED
+BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED
diff --git a/xlat/btrfs_dev_stats_flags.in b/xlat/btrfs_dev_stats_flags.in
new file mode 100644
index 0000000..0d62b14
--- /dev/null
+++ b/xlat/btrfs_dev_stats_flags.in
@@ -0,0 +1 @@
+BTRFS_DEV_STATS_RESET
diff --git a/xlat/btrfs_dev_stats_values.in b/xlat/btrfs_dev_stats_values.in
new file mode 100644
index 0000000..0b843db
--- /dev/null
+++ b/xlat/btrfs_dev_stats_values.in
@@ -0,0 +1,11 @@
+#define HAVE_DECL_BTRFS_DEV_STAT_WRITE_ERRS 1
+#define HAVE_DECL_BTRFS_DEV_STAT_READ_ERRS 1
+#define HAVE_DECL_BTRFS_DEV_STAT_FLUSH_ERRS 1
+#define HAVE_DECL_BTRFS_DEV_STAT_CORRUPTION_ERRS 1
+#define HAVE_DECL_BTRFS_DEV_STAT_GENERATION_ERRS 1
+
+BTRFS_DEV_STAT_WRITE_ERRS
+BTRFS_DEV_STAT_READ_ERRS
+BTRFS_DEV_STAT_FLUSH_ERRS
+BTRFS_DEV_STAT_CORRUPTION_ERRS
+BTRFS_DEV_STAT_GENERATION_ERRS
diff --git a/xlat/btrfs_features_compat.in b/xlat/btrfs_features_compat.in
new file mode 100644
index 0000000..e69de29
diff --git a/xlat/btrfs_features_compat_ro.in b/xlat/btrfs_features_compat_ro.in
new file mode 100644
index 0000000..13808c8
--- /dev/null
+++ b/xlat/btrfs_features_compat_ro.in
@@ -0,0 +1 @@
+BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0)
diff --git a/xlat/btrfs_features_incompat.in b/xlat/btrfs_features_incompat.in
new file mode 100644
index 0000000..edb21c2
--- /dev/null
+++ b/xlat/btrfs_features_incompat.in
@@ -0,0 +1,10 @@
+BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
+BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
+BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
+BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3)
+BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4)
+BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5)
+BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
+BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
+BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
+BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
diff --git a/xlat/btrfs_key_types.in b/xlat/btrfs_key_types.in
new file mode 100644
index 0000000..27f80e0
--- /dev/null
+++ b/xlat/btrfs_key_types.in
@@ -0,0 +1,40 @@
+BTRFS_INODE_ITEM_KEY 1
+BTRFS_INODE_REF_KEY 12
+BTRFS_INODE_EXTREF_KEY 13
+BTRFS_XATTR_ITEM_KEY 24
+BTRFS_ORPHAN_ITEM_KEY 48
+BTRFS_DIR_LOG_ITEM_KEY 60
+BTRFS_DIR_LOG_INDEX_KEY 72
+BTRFS_DIR_ITEM_KEY 84
+BTRFS_DIR_INDEX_KEY 96
+BTRFS_EXTENT_DATA_KEY 108
+BTRFS_EXTENT_CSUM_KEY 128
+BTRFS_ROOT_ITEM_KEY 132
+BTRFS_ROOT_BACKREF_KEY 144
+BTRFS_ROOT_REF_KEY 156
+BTRFS_EXTENT_ITEM_KEY 168
+BTRFS_METADATA_ITEM_KEY 169
+BTRFS_TREE_BLOCK_REF_KEY 176
+BTRFS_EXTENT_DATA_REF_KEY 178
+BTRFS_EXTENT_REF_V0_KEY 180
+BTRFS_SHARED_BLOCK_REF_KEY 182
+BTRFS_SHARED_DATA_REF_KEY 184
+BTRFS_BLOCK_GROUP_ITEM_KEY 192
+BTRFS_FREE_SPACE_INFO_KEY 198
+BTRFS_FREE_SPACE_EXTENT_KEY 199
+BTRFS_FREE_SPACE_BITMAP_KEY 200
+BTRFS_DEV_EXTENT_KEY 204
+BTRFS_DEV_ITEM_KEY 216
+BTRFS_CHUNK_ITEM_KEY 228
+BTRFS_QGROUP_STATUS_KEY 240
+BTRFS_QGROUP_INFO_KEY 242
+BTRFS_QGROUP_LIMIT_KEY 244
+BTRFS_QGROUP_RELATION_KEY 246
+BTRFS_BALANCE_ITEM_KEY 248
+BTRFS_TEMPORARY_ITEM_KEY 248
+BTRFS_DEV_STATS_KEY 249
+BTRFS_PERSISTENT_ITEM_KEY 249
+BTRFS_DEV_REPLACE_KEY 250
+BTRFS_UUID_KEY_SUBVOL 251
+BTRFS_UUID_KEY_RECEIVED_SUBVOL 252
+BTRFS_STRING_ITEM_KEY 253
diff --git a/xlat/btrfs_qgroup_ctl_cmds.in b/xlat/btrfs_qgroup_ctl_cmds.in
new file mode 100644
index 0000000..8e2aa5f
--- /dev/null
+++ b/xlat/btrfs_qgroup_ctl_cmds.in
@@ -0,0 +1,3 @@
+BTRFS_QUOTA_CTL_ENABLE
+BTRFS_QUOTA_CTL_DISABLE
+BTRFS_QUOTA_CTL_RESCAN__NOTUSED
diff --git a/xlat/btrfs_qgroup_inherit_flags.in b/xlat/btrfs_qgroup_inherit_flags.in
new file mode 100644
index 0000000..803c8c0
--- /dev/null
+++ b/xlat/btrfs_qgroup_inherit_flags.in
@@ -0,0 +1 @@
+BTRFS_QGROUP_INHERIT_SET_LIMITS
diff --git a/xlat/btrfs_qgroup_limit_flags.in b/xlat/btrfs_qgroup_limit_flags.in
new file mode 100644
index 0000000..3bf2f8f
--- /dev/null
+++ b/xlat/btrfs_qgroup_limit_flags.in
@@ -0,0 +1,6 @@
+BTRFS_QGROUP_LIMIT_MAX_RFER (1ULL << 0)
+BTRFS_QGROUP_LIMIT_MAX_EXCL (1ULL << 1)
+BTRFS_QGROUP_LIMIT_RSV_RFER (1ULL << 2)
+BTRFS_QGROUP_LIMIT_RSV_EXCL (1ULL << 3)
+BTRFS_QGROUP_LIMIT_RFER_CMPR (1ULL << 4)
+BTRFS_QGROUP_LIMIT_EXCL_CMPR (1ULL << 5)
diff --git a/xlat/btrfs_qgroup_status_flags.in b/xlat/btrfs_qgroup_status_flags.in
new file mode 100644
index 0000000..10236aa
--- /dev/null
+++ b/xlat/btrfs_qgroup_status_flags.in
@@ -0,0 +1,2 @@
+BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0)
+BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1)
diff --git a/xlat/btrfs_scrub_flags.in b/xlat/btrfs_scrub_flags.in
new file mode 100644
index 0000000..31e4f65
--- /dev/null
+++ b/xlat/btrfs_scrub_flags.in
@@ -0,0 +1 @@
+BTRFS_SCRUB_READONLY 1
diff --git a/xlat/btrfs_snap_flags_v2.in b/xlat/btrfs_snap_flags_v2.in
new file mode 100644
index 0000000..3fe3358
--- /dev/null
+++ b/xlat/btrfs_snap_flags_v2.in
@@ -0,0 +1,3 @@
+BTRFS_SUBVOL_CREATE_ASYNC
+BTRFS_SUBVOL_RDONLY
+BTRFS_SUBVOL_QGROUP_INHERIT
diff --git a/xlat/btrfs_space_info_flags.in b/xlat/btrfs_space_info_flags.in
new file mode 100644
index 0000000..9feaf74
--- /dev/null
+++ b/xlat/btrfs_space_info_flags.in
@@ -0,0 +1,11 @@
+BTRFS_BLOCK_GROUP_DATA (1ULL << 0)
+BTRFS_BLOCK_GROUP_SYSTEM (1ULL << 1)
+BTRFS_BLOCK_GROUP_METADATA (1ULL << 2)
+BTRFS_BLOCK_GROUP_RAID0 (1ULL << 3)
+BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4)
+BTRFS_BLOCK_GROUP_DUP (1ULL << 5)
+BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
+BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
+BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
+BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48)
+BTRFS_SPACE_INFO_GLOBAL_RSV (1ULL << 49)
diff --git a/xlat/btrfs_tree_objectids.in b/xlat/btrfs_tree_objectids.in
new file mode 100644
index 0000000..cc89c20
--- /dev/null
+++ b/xlat/btrfs_tree_objectids.in
@@ -0,0 +1,12 @@
+BTRFS_ROOT_TREE_OBJECTID 1ULL
+BTRFS_EXTENT_TREE_OBJECTID 2ULL
+BTRFS_CHUNK_TREE_OBJECTID 3ULL
+BTRFS_DEV_TREE_OBJECTID 4ULL
+BTRFS_FS_TREE_OBJECTID 5ULL
+BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
+BTRFS_CSUM_TREE_OBJECTID 7ULL
+BTRFS_QUOTA_TREE_OBJECTID 8ULL
+BTRFS_UUID_TREE_OBJECTID 9ULL
+BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
+BTRFS_FIRST_FREE_OBJECTID 256ULL
+BTRFS_LAST_FREE_OBJECTID -256ULL
--
2.7.1
More information about the Strace-devel
mailing list