* btrfs.c: New file. * file_ioctl.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 | 2 + btrfs.c | 1298 ++++++++++++++++++++++++++++++++++++ configure.ac | 8 + defs.h | 2 + ioctl.c | 4 + xlat/btrfs_balance_flags.in | 16 + 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, 1446 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..9daccff 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 \ @@ -103,6 +104,7 @@ strace_SOURCES = \ fetch_struct_flock.c \ file.c \ file_handle.c \ + file_ioctl.c \ flock.c \ flock.h \ futex.c \ diff --git a/btrfs.c b/btrfs.c new file mode 100644 index 0000000..164fa6c --- /dev/null +++ b/btrfs.c @@ -0,0 +1,1298 @@ +/* + * Copyright (c) 2016 Jeff Mahoney <je...@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> +#ifdef HAVE_LINUX_BTRFS_H +/* + * Prior to Linux 3.12, the BTRFS_IOC_DEFAULT_SUBVOL used u64 in + * its definition, which isn't exported by the kernel. + */ +typedef __u64 u64; + +#include <linux/btrfs.h> + +#ifndef HAVE_STRUCT_BTRFS_IOCTL_FEATURE_FLAGS_COMPAT_FLAGS +struct btrfs_ioctl_feature_flags { + uint64_t compat_flags; + uint64_t compat_ro_flags; + uint64_t incompat_flags; +}; +#endif + +#ifndef HAVE_STRUCT_BTRFS_IOCTL_DEFRAG_RANGE_ARGS_START +struct btrfs_ioctl_defrag_range_args { + uint64_t start; + uint64_t len; + uint64_t flags; + uint32_t extent_thresh; + uint32_t compress_type; + uint32_t unused[4]; +}; +#endif + +#ifndef BTRFS_SUBVOL_NAME_MAX +#define BTRFS_SUBVOL_NAME_MAX 4039 +#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 + +#ifndef BTRFS_IOC_TREE_SEARCH_V2 +#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \ + struct btrfs_ioctl_search_args_v2) +struct btrfs_ioctl_search_args_v2 { + struct btrfs_ioctl_search_key key; /* in/out - search parameters */ + uint64_t buf_size; /* in - size of buffer + * out - on EOVERFLOW: needed size + * to store item */ + uint64_t buf[0]; /* out - found items */ +}; +#endif + +#include "xlat/btrfs_balance_flags.h" +#include "xlat/btrfs_defrag_flags.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; +} + +/* 8-4-4-4-12 = 36 characters */ +#define UUID_STRING_SIZE 36 + +/* 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[UUID_STRING_SIZE] = '\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); + tprints(", flags="); + printflags64(btrfs_balance_flags, bba->flags, "BTRFS_BALANCE_???"); + 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; + + tprints("{flags="); + printflags64(btrfs_balance_flags, balance_args.flags, + "BTRFS_BALANCE_???"); + if (out) + tprintf(", state=%" PRI__u64, balance_args.state); + + if (balance_args.flags & BTRFS_BALANCE_DATA) + btrfs_print_balance_args("data", &balance_args.data); + if (balance_args.flags & BTRFS_BALANCE_METADATA) + btrfs_print_balance_args("meta", &balance_args.meta); + if (balance_args.flags & BTRFS_BALANCE_SYSTEM) + btrfs_print_balance_args("sys", &balance_args.sys); + tprints("}"); +} + +static void +btrfs_print_features(struct btrfs_ioctl_feature_flags *flags) +{ + tprints("{compat_flags="); + printflags64(btrfs_features_compat, flags->compat_flags, + "BTRFS_FEATURE_COMPAT_???"); + + tprints(", compat_ro_flags="); + printflags64(btrfs_features_compat_ro, flags->compat_ro_flags, + "BTRFS_FEATURE_COMPAT_RO_???"); + + tprints(", incompat_flags="); + printflags64(btrfs_features_incompat, flags->incompat_flags, + "BTRFS_FEATURE_INCOMPAT_???"); + tprints("}"); +} + +static void +btrfs_print_qgroup_limit(struct btrfs_qgroup_limit *lim) +{ + tprints("{flags="); + printflags64(btrfs_qgroup_limit_flags, lim->flags, + "BTRFS_QGROUP_LIMIT_???"); + 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); +} + +static void +btrfs_print_data_container_header(struct btrfs_data_container *container) +{ + tprintf("{bytes_left=%u, bytes_missing=%u, " + "elem_cnt=%u, elem_missed=%u, val=", + container->bytes_left, container->bytes_missing, + container->elem_cnt, container->elem_missed); +} + +static void +btrfs_print_data_container_footer(void) +{ + tprints("}"); +} + +static void +btrfs_print_logical_ino_container(struct tcb *tcp, uint64_t inodes_addr) +{ + struct btrfs_data_container container; + uint64_t val_addr; + uint32_t i; + uint32_t printed = 0; + + if (umoven_or_printaddr(tcp, inodes_addr, + sizeof(container), &container)) + return; + + btrfs_print_data_container_header(&container); + if (abbrev(tcp)) { + tprints("..."); + btrfs_print_data_container_footer(); + return; + } + + tprints("["); + + val_addr = inodes_addr + offsetof(typeof(container), val); + for (i = 0; i < container.elem_cnt; i += 3, printed++) { + uint64_t addr = val_addr + sizeof(uint64_t) * i; + uint64_t record[3]; + + if (i) + tprints(", "); + + if (printed > max_strlen || + umoven(tcp, addr, sizeof(record), record)) { + tprints("..."); + break; + } + tprintf("{inum=%" PRIu64 ", offset=%" PRIu64 + ", root=%" PRIu64 "}", record[0], record[1], record[2]); + } + tprints("]"); + btrfs_print_data_container_footer(); +} + +static void +btrfs_print_ino_path_container(struct tcb *tcp, uint64_t fspath_addr) +{ + struct btrfs_data_container container; + uint32_t i; + uint64_t val_addr; + + if (umoven_or_printaddr(tcp, fspath_addr, + sizeof(container), &container)) + return; + + btrfs_print_data_container_header(&container); + if (abbrev(tcp)) { + tprints("..."); + btrfs_print_data_container_footer(); + return; + } + + tprints("["); + + val_addr = fspath_addr + offsetof(typeof(container), val); + for (i = 0; i < container.elem_cnt; i++) { + uint64_t addr = val_addr + sizeof(uint64_t) * i; + uint64_t ptr; + + if (i) + tprints(", "); + + if (i > max_strlen || umoven(tcp, addr, sizeof(ptr), &ptr)) { + tprints("..."); + break; + } + + printpath(tcp, val_addr + ptr); + } + tprints("]"); + btrfs_print_data_container_footer(); +} + +static void +btrfs_print_qgroup_inherit(struct tcb *tcp, uint64_t qgi_addr) +{ + struct btrfs_qgroup_inherit inherit; + + if (umoven_or_printaddr(tcp, qgi_addr, sizeof(inherit), &inherit) < 0) { + tprintf("%lx", (unsigned long)qgi_addr); + return; + } + + tprintf("{flags="); + printflags64(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(", qgroups="); + + if (abbrev(tcp)) { + tprints("..."); + } else { + uint64_t qgroups_addr = qgi_addr + + offsetof(typeof(inherit), qgroups); + uint32_t i; + + tprints("["); + for (i = 0; i < inherit.num_qgroups; i++) { + uint64_t record; + uint64_t addr = qgroups_addr + sizeof(record) * i; + if (i) + tprints(", "); + if (i > max_strlen || + umoven(tcp, addr, sizeof(record), &record)) { + tprints("..."); + break; + } + + tprintf("%" PRIu64, record); + } + tprints("]"); + } + tprints("}"); +} + +static void +__print_key_value(struct tcb *tcp, const char *name, uint64_t value) +{ + if (value == UINT64_MAX) + tprintf(", %s=UINT64_MAX", name); + else if (value || !abbrev(tcp)) + tprintf(", %s=%" PRIu64, name, value); +} +#define print_key_value(tcp, key, name) \ + __print_key_value((tcp), #name, (key)->name) + +static void +btrfs_print_tree_search(struct tcb *tcp, struct btrfs_ioctl_search_key *key, + uint64_t buf_addr, uint64_t buf_size) +{ + if (entering(tcp)) { + tprintf("{key={tree_id="); + btrfs_print_objectid(key->tree_id); + + if (key->min_objectid != BTRFS_FIRST_FREE_OBJECTID || + !abbrev(tcp)) { + tprints(", min_objectid="); + btrfs_print_objectid(key->min_objectid); + } + + if (key->max_objectid != BTRFS_LAST_FREE_OBJECTID || + !abbrev(tcp)) { + tprints(", max_objectid="); + btrfs_print_objectid(key->max_objectid); + } + + print_key_value(tcp, key, min_offset); + print_key_value(tcp, key, max_offset); + print_key_value(tcp, key, min_transid); + print_key_value(tcp, key, max_transid); + print_key_value(tcp, key, min_offset); + + tprints(", min_type="); + btrfs_print_key_type(key->min_type); + tprints(", max_type="); + btrfs_print_key_type(key->max_type); + tprintf(", nr_items=%u}}", key->nr_items); + return; + } + tprintf("{key={nr_items=%u}, buf=", key->nr_items); + if (abbrev(tcp)) + tprints("..."); + else { + uint64_t i; + uint64_t off = 0; + tprints("["); + for (i = 0; i < key->nr_items; i++) { + struct btrfs_ioctl_search_header sh; + uint64_t addr = buf_addr + off; + if (i) + tprints(", "); + if (i > max_strlen || + umoven(tcp, addr, sizeof(sh), &sh)) { + tprints("..."); + break; + } + 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("}"); +} + +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_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, "%" PRIu64); + 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; + + tprints(", "); + + if (umove_or_printaddr(tcp, arg, &flags)) + break; + + printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???"); + break; + } + case BTRFS_IOC_SUBVOL_SETFLAGS: { /* W */ + uint64_t flags; + + tprints(", "); + + if (umove_or_printaddr(tcp, arg, &flags)) + break; + + printflags64(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 (syserror(tcp)) + break; + + tprints(" => "); + btrfs_print_balance(tcp, arg, true); + break; + case BTRFS_IOC_BALANCE_PROGRESS: /* R */ + if (entering(tcp)) + return 0; + + tprints(", "); + btrfs_print_balance(tcp, arg, true); + break; + + case BTRFS_IOC_DEFRAG_RANGE: {/* W */ + struct btrfs_ioctl_defrag_range_args args; + + tprints(", "); + + if (umove_or_printaddr(tcp, arg, &args)) + break; + + tprintf("{start=%" PRIu64 ", len=%" PRIu64 ", flags=", + (uint64_t)args.start, (uint64_t)args.len); + printflags64(btrfs_defrag_flags, args.flags, + "BTRFS_DEFRAG_RANGE_???"); + 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[UUID_STRING_SIZE+1]; + 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=", + args.bytes_used, args.total_bytes); + print_quoted_string((const char *)args.path, sizeof(args.path), + QUOTE_0_TERMINATED); + tprints("}"); + break; + } + + case BTRFS_IOC_DEV_REPLACE: { /* RW */ + struct btrfs_ioctl_dev_replace_args args; + + if (entering(tcp)) + tprints(", "); + + 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) { + const char *str; + tprintf(", start={srcdevid=%" PRI__u64 ", " + "cont_reading_from_srcdev_mode=%" PRI__u64 + ", srcdev_name=", + args.start.srcdevid, + args.start.cont_reading_from_srcdev_mode); + + str = (const char*) args.start.srcdev_name; + print_quoted_string(str, + sizeof(args.start.srcdev_name), + QUOTE_0_TERMINATED); + tprints(", tgtdev_name="); + str = (const char*) args.start.tgtdev_name; + print_quoted_string(str, + sizeof(args.start.tgtdev_name), + QUOTE_0_TERMINATED); + tprints("}"); + + } + 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[sizeof("HH:MM:SS") + 1]; + time_t time; + tprints(", "); + printxvals(args.status.replace_state, + "BTRFS_IOCTL_DEV_REPLACE_STATE_???", + btrfs_dev_replace_state, NULL); + tprintf(", progress_1000=%" PRI__u64 " /* ", + args.status.progress_1000); + if (args.status.progress_1000 <= 1000) + tprintf("%" PRI__u64 ".%.2" PRI__u64 "%%", + args.status.progress_1000 / 10, + args.status.progress_1000 % 10); + else + tprints("???"); + tprints(" */ ,"); + + 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); + } + tprints("}"); + 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]; + + 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[UUID_STRING_SIZE+1]; + uint32_t nodesize, sectorsize, clone_alignment; +#ifndef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE + __u32 *reserved32; +#endif + + if (entering(tcp)) + return 0; + + tprints(", "); + if (umove_or_printaddr(tcp, arg, &args)) + break; + +#ifdef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE + nodesize = args.nodesize, + sectorsize = args.sectorsize, + clone_alignment = args.clone_alignment; +#else + reserved32 = (__u32 *)args.reserved; + nodesize = reserved32[0]; + sectorsize = reserved32[1]; + clone_alignment = reserved32[2]; +#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, + nodesize, sectorsize, clone_alignment); + 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); + printflags64(btrfs_dev_stats_flags, args.flags, + "BTRFS_DEV_STATS_???"); + + 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; + + tprints("name="); + print_quoted_string(args.name, sizeof(args.name), + QUOTE_0_TERMINATED); + tprints("}"); + break; + } + + case BTRFS_IOC_INO_PATHS: { /* RW */ + struct btrfs_ioctl_ino_path_args args; + + 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; + } + + tprints("fspath="); + btrfs_print_ino_path_container(tcp, args.fspath); + + tprints("}"); + break; + } + + case BTRFS_IOC_LOGICAL_INO: { /* RW */ + struct btrfs_ioctl_logical_ino_args args; + + 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="); + btrfs_print_logical_ino_container(tcp, args.inodes); + + tprints("}"); + break; + } + + case BTRFS_IOC_QGROUP_ASSIGN: { /* W */ + struct btrfs_ioctl_qgroup_assign_args args; + + 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; + + 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; + + 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; + + 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 == UINT64_MAX) + tprints("UINT64_MAX"); + else + btrfs_print_objectid(args.progress); + tprints("}"); + break; + } + case BTRFS_IOC_SET_RECEIVED_SUBVOL: { /* RW */ +#ifdef BTRFS_IOC_SET_RECEIVED_SUBVOL_32 + case BTRFS_IOC_SET_RECEIVED_SUBVOL_32: { /* RW */ + struct btrfs_ioctl_received_subvol_args_32 args32; +#endif + struct btrfs_ioctl_received_subvol_args args; + char uuid[UUID_STRING_SIZE+1]; + + if (entering(tcp)) + tprints(", "); + else if (syserror(tcp)) + break; + else + tprints(" => "); + +#ifdef BTRFS_IOC_SET_RECEIVED_SUBVOL_32 + /* + * This is a compat ioctl for 32 bit tools on + * 64 bit systems. + */ + if (code == BTRFS_IOC_SET_RECEIVED_SUBVOL_32) { + if (umove_or_printaddr(tcp, arg, &args32)) + break; + memcpy(args.uuid, args32.uuid, sizeof(uuid)); + args.stransid = args32.stransid; + args.rtransid = args32.rtransid; + args.stime.sec = args32.stime.sec; + args.stime.nsec = args32.stime.nsec; + args.rtime.sec = args32.rtime.sec; + args.rtime.nsec = args32.rtime.nsec; + args.flags = args32.flags; + } else +#endif + 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_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 == UINT64_MAX) + tprints("UINT64_MAX"); + else + tprintf("%" PRI__u64, args.end); + tprints(", flags="); + printflags64(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; + uint64_t buf_addr; + + if (entering(tcp)) + tprints(", "); + else if (syserror(tcp)) + break; + else + tprints(" => "); + + if (umove_or_printaddr(tcp, arg, &args)) + break; + + buf_addr = arg + offsetof(struct btrfs_ioctl_search_args, buf); + btrfs_print_tree_search(tcp, &args.key, buf_addr, + sizeof(args.buf)); + if (entering(tcp)) + return 0; + break; + } + + case BTRFS_IOC_TREE_SEARCH_V2: { /* RW */ + struct btrfs_ioctl_search_args_v2 args; + uint64_t buf_addr; + + if (entering(tcp)) + tprints(", "); + else if (syserror(tcp)) + break; + else + tprints(" => "); + + if (umove_or_printaddr(tcp, arg, &args)) + break; + + buf_addr = arg + offsetof(struct btrfs_ioctl_search_args, buf); + btrfs_print_tree_search(tcp, &args.key, buf_addr, + args.buf_size); + if (entering(tcp)) + return 0; + break; + } + + case BTRFS_IOC_SEND: { /* W */ + struct btrfs_ioctl_send_args args; + uint64_t base_addr; + uint64_t i; + + 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); + + if (abbrev(tcp)) { + tprints("...}"); + break; + } + + tprints("["); + base_addr = (unsigned long)args.clone_sources; + for (i = 0; i < args.clone_sources_count; i++) { + uint64_t addr = base_addr + sizeof(uint64_t) * i; + uint64_t record; + if (i) + tprints(", "); + if (i > max_strlen || + umoven(tcp, addr, sizeof(record), &record)) { + tprints("..."); + break; + } + btrfs_print_objectid(record); + } + tprints("]}"); + break; + } + + case BTRFS_IOC_SPACE_INFO: { /* RW */ + struct btrfs_ioctl_space_args args; + uint64_t spaces_addr; + 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; + } + + tprints("["); + + spaces_addr = arg + offsetof(typeof(args), spaces); + for (i = 0; i < args.total_spaces; i++) { + struct btrfs_ioctl_space_info info; + uint64_t addr = spaces_addr + sizeof(info) * i; + if (i) + tprints(", "); + + if (i > max_strlen || + umoven(tcp, addr, sizeof(info), &info)) { + tprints("..."); + break; + } + + tprints("{flags="); + printflags64(btrfs_space_info_flags, info.flags, + "BTRFS_SPACE_INFO_???"); + tprintf(", total_bytes=%" PRI__u64 ", " + "used_bytes=%" PRI__u64 "}", + info.total_bytes, info.used_bytes); + } + tprints("]}"); + 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; + + tprints(", "); + if (umove_or_printaddr(tcp, arg, &args)) + break; + + tprintf("{fd=%" PRI__s64 ", name=", args.fd); + print_quoted_string(args.name, sizeof(args.name), + QUOTE_0_TERMINATED); + tprints("}"); + break; + } + + case BTRFS_IOC_SNAP_CREATE_V2: + case BTRFS_IOC_SUBVOL_CREATE_V2: { /* W */ + struct btrfs_ioctl_vol_args_v2 args; + + tprints(", "); + if (umove_or_printaddr(tcp, arg, &args)) + break; + + tprintf("{fd=%" PRI__s64 ", flags=", args.fd); + printflags64(btrfs_snap_flags_v2, args.flags, + "BTRFS_SUBVOL_???"); + if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) { + tprintf(", size=%" PRI__u64 ", qgroup_inherit=", + args.size); + + btrfs_print_qgroup_inherit(tcp, + (unsigned long)args.qgroup_inherit); + + } + tprintf(", name="); + print_quoted_string(args.name, BTRFS_SUBVOL_NAME_MAX + 1, + QUOTE_0_TERMINATED); + 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)) + return 0; + + tprints(", "); + if (umoven_or_printaddr(tcp, arg, sizeof(label), label)) + break; + print_quoted_string(label, sizeof(label), QUOTE_0_TERMINATED); + break; + } + + case BTRFS_IOC_CLONE: /* FICLONE */ + case BTRFS_IOC_CLONE_RANGE: /* FICLONERANGE */ + case BTRFS_IOC_FILE_EXTENT_SAME: /* FIDEDUPERANGE */ + /* + * FICLONE, FICLONERANGE, and FIDEDUPERANGE started out as + * btrfs ioctls and the code was kept for the generic + * implementations. We use the BTRFS_* names here because + * they will be available on older systems. + */ + return file_ioctl(tcp, code, arg); + + default: + return RVAL_DECODED; + }; + return ret | RVAL_DECODED | 1; +} +#endif /* HAVE_LINUX_BTRFS_H */ diff --git a/configure.ac b/configure.ac index 98907a0..863b22c 100644 --- a/configure.ac +++ b/configure.ac @@ -433,6 +433,14 @@ AC_CHECK_HEADERS([linux/bpf.h], [ fi ]) +AC_CHECK_HEADERS([linux/btrfs.h], [ + AC_CHECK_MEMBERS(m4_normalize([ + struct btrfs_ioctl_feature_flags.compat_flags, + struct btrfs_ioctl_fs_info_args.nodesize, + struct btrfs_ioctl_defrag_range_args.start + ]),,, [ #include <stdio.h> +#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 cc2a0d4..d96dc4e 100644 --- a/defs.h +++ b/defs.h @@ -642,7 +642,9 @@ 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 file_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); extern int ptp_ioctl(struct tcb *, const unsigned int, long); diff --git a/ioctl.c b/ioctl.c index f70dc44..3f7eae1 100644 --- a/ioctl.c +++ b/ioctl.c @@ -263,6 +263,10 @@ ioctl_decode(struct tcb *tcp) case 'E': return evdev_ioctl(tcp, code, arg); #endif +#ifdef HAVE_LINUX_BTRFS_H + case 0x94: + return btrfs_ioctl(tcp, code, arg); +#endif default: break; } diff --git a/xlat/btrfs_balance_flags.in b/xlat/btrfs_balance_flags.in new file mode 100644 index 0000000..5745159 --- /dev/null +++ b/xlat/btrfs_balance_flags.in @@ -0,0 +1,16 @@ +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 (1ULL << 0) +BTRFS_BALANCE_ARGS_USAGE (1ULL << 1) +BTRFS_BALANCE_ARGS_DEVID (1ULL << 2) +BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3) +BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4) +BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) +BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) +BTRFS_BALANCE_ARGS_CONVERT (1ULL << 8) +BTRFS_BALANCE_ARGS_SOFT (1ULL << 9) +BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 10) 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 ------------------------------------------------------------------------------ Find and fix application performance issues faster with Applications Manager Applications Manager provides deep performance insights into multiple tiers of your business applications. It resolves application problems quickly and reduces your MTTR. Get your free trial! https://ad.doubleclick.net/ddm/clk/302982198;130105516;z _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel