Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2016 Jeff Mahoney <jeffm (at) suse.com>
      3  * Copyright (c) 2016-2018 The strace developers.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *    derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "defs.h"
     30 
     31 #ifdef HAVE_LINUX_BTRFS_H
     32 
     33 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_dev_replace_args)
     34 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_send_args)
     35 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_received_subvol_args)
     36 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_vol_args_v2)
     37 
     38 # include <linux/btrfs.h>
     39 
     40 typedef struct btrfs_ioctl_dev_replace_args
     41 	struct_btrfs_ioctl_dev_replace_args;
     42 typedef struct btrfs_ioctl_send_args
     43 	struct_btrfs_ioctl_send_args;
     44 typedef struct btrfs_ioctl_received_subvol_args
     45 	struct_btrfs_ioctl_received_subvol_args;
     46 typedef struct btrfs_ioctl_vol_args_v2
     47 	struct_btrfs_ioctl_vol_args_v2;
     48 
     49 #endif /* HAVE_LINUX_BTRFS_H */
     50 
     51 #include MPERS_DEFS
     52 
     53 #ifdef HAVE_LINUX_BTRFS_H
     54 
     55 #include "print_fields.h"
     56 #include <linux/fs.h>
     57 
     58 /*
     59  * Prior to Linux 3.12, the BTRFS_IOC_DEFAULT_SUBVOL used u64 in
     60  * its definition, which isn't exported by the kernel.
     61  */
     62 typedef __u64 u64;
     63 
     64 #ifndef HAVE_STRUCT_BTRFS_IOCTL_FEATURE_FLAGS_COMPAT_FLAGS
     65 struct btrfs_ioctl_feature_flags {
     66 	uint64_t compat_flags;
     67 	uint64_t compat_ro_flags;
     68 	uint64_t incompat_flags;
     69 };
     70 #endif
     71 
     72 #ifndef HAVE_STRUCT_BTRFS_IOCTL_DEFRAG_RANGE_ARGS_START
     73 struct btrfs_ioctl_defrag_range_args {
     74 	uint64_t start;
     75 	uint64_t len;
     76 	uint64_t flags;
     77 	uint32_t extent_thresh;
     78 	uint32_t compress_type;
     79 	uint32_t unused[4];
     80 };
     81 #endif
     82 
     83 #ifndef BTRFS_LABEL_SIZE
     84 # define BTRFS_LABEL_SIZE 256
     85 #endif
     86 
     87 #ifndef BTRFS_IOC_QUOTA_RESCAN
     88 struct btrfs_ioctl_quota_rescan_args {
     89 	uint64_t flags, progress, reserved[6];
     90 };
     91 # define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \
     92 					struct btrfs_ioctl_quota_rescan_args)
     93 # define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
     94 					struct btrfs_ioctl_quota_rescan_args)
     95 #endif
     96 
     97 #ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT
     98 # define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
     99 #endif
    100 
    101 #ifndef BTRFS_IOC_GET_FEATURES
    102 # define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
    103 					struct btrfs_ioctl_feature_flags)
    104 # define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
    105 					struct btrfs_ioctl_feature_flags[2])
    106 # define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
    107 					struct btrfs_ioctl_feature_flags[3])
    108 #endif
    109 
    110 #ifndef BTRFS_IOC_TREE_SEARCH_V2
    111 # define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
    112 					struct btrfs_ioctl_search_args_v2)
    113 struct btrfs_ioctl_search_args_v2 {
    114 	struct btrfs_ioctl_search_key key; /* in/out - search parameters */
    115 	uint64_t buf_size;		   /* in - size of buffer
    116 					    * out - on EOVERFLOW: needed size
    117 					    *       to store item */
    118 	uint64_t buf[0];		   /* out - found items */
    119 };
    120 #endif
    121 
    122 #include "xlat/btrfs_balance_args.h"
    123 #include "xlat/btrfs_balance_ctl_cmds.h"
    124 #include "xlat/btrfs_balance_flags.h"
    125 #include "xlat/btrfs_balance_state.h"
    126 #include "xlat/btrfs_compress_types.h"
    127 #include "xlat/btrfs_cont_reading_from_srcdev_mode.h"
    128 #include "xlat/btrfs_defrag_flags.h"
    129 #include "xlat/btrfs_dev_replace_cmds.h"
    130 #include "xlat/btrfs_dev_replace_results.h"
    131 #include "xlat/btrfs_dev_replace_state.h"
    132 #include "xlat/btrfs_dev_stats_flags.h"
    133 #include "xlat/btrfs_dev_stats_values.h"
    134 #include "xlat/btrfs_features_compat.h"
    135 #include "xlat/btrfs_features_compat_ro.h"
    136 #include "xlat/btrfs_features_incompat.h"
    137 #include "xlat/btrfs_key_types.h"
    138 #include "xlat/btrfs_logical_ino_args_flags.h"
    139 #include "xlat/btrfs_qgroup_ctl_cmds.h"
    140 #include "xlat/btrfs_qgroup_inherit_flags.h"
    141 #include "xlat/btrfs_qgroup_limit_flags.h"
    142 #include "xlat/btrfs_qgroup_status_flags.h"
    143 #include "xlat/btrfs_scrub_flags.h"
    144 #include "xlat/btrfs_send_flags.h"
    145 #include "xlat/btrfs_snap_flags_v2.h"
    146 #include "xlat/btrfs_space_info_flags.h"
    147 #include "xlat/btrfs_tree_objectids.h"
    148 
    149 static inline char
    150 prnibble(char v)
    151 {
    152 	if (v >= 10)
    153 		return 'a' + (v - 10);
    154 	return '0' + v;
    155 }
    156 
    157 /* 8-4-4-4-12 = 36 characters */
    158 #define UUID_STRING_SIZE 36
    159 
    160 /* Formats uuid, returns 0 if it's all zeroes */
    161 static int
    162 btrfs_unparse_uuid(unsigned char *uuid, char *out)
    163 {
    164 	int i;
    165 	int ret = 0;
    166 	for (i = 0; i < BTRFS_UUID_SIZE; i++) {
    167 		if (i == 4 || i == 6 || i == 8 || i == 10)
    168 			*out++ = '-';
    169 		*out++ = prnibble(uuid[i] >> 4);
    170 		*out++ = prnibble(uuid[i] & 0xf);
    171 		if (uuid[i])
    172 			ret = 1;
    173 	}
    174 	*out = '\0';
    175 	return ret;
    176 }
    177 
    178 static void
    179 btrfs_print_balance_args(const char *name, const struct btrfs_balance_args *bba)
    180 {
    181 	tprintf(", %s=", name);
    182 	PRINT_FIELD_FLAGS("{", *bba, profiles, btrfs_space_info_flags,
    183 			  "BTRFS_BLOCK_GROUP_???");
    184 	PRINT_FIELD_U64(", ", *bba, usage);
    185 	PRINT_FIELD_DEV(", ", *bba, devid);
    186 	PRINT_FIELD_U64(", ", *bba, pstart);
    187 	PRINT_FIELD_U64(", ", *bba, pend);
    188 	PRINT_FIELD_U64(", ", *bba, vstart);
    189 	PRINT_FIELD_U64(", ", *bba, vend);
    190 	PRINT_FIELD_U64(", ", *bba, target);
    191 	PRINT_FIELD_FLAGS(", ", *bba, flags, btrfs_balance_args,
    192 			  "BTRFS_BALANCE_ARGS_???");
    193 	tprints("}");
    194 }
    195 
    196 static void
    197 btrfs_print_balance(struct tcb *const tcp, const kernel_ulong_t arg, bool out)
    198 {
    199 	struct btrfs_ioctl_balance_args balance_args;
    200 
    201 	if (umove_or_printaddr(tcp, arg, &balance_args))
    202 		return;
    203 
    204 	PRINT_FIELD_FLAGS("{", balance_args, flags, btrfs_balance_flags,
    205 			  "BTRFS_BALANCE_???");
    206 	if (out)
    207 		PRINT_FIELD_FLAGS(", ", balance_args, state,
    208 				  btrfs_balance_state,
    209 				  "BTRFS_BALANCE_STATE_???");
    210 
    211 	if (balance_args.flags & BTRFS_BALANCE_DATA)
    212 		btrfs_print_balance_args("data", &balance_args.data);
    213 	if (balance_args.flags & BTRFS_BALANCE_METADATA)
    214 		btrfs_print_balance_args("meta", &balance_args.meta);
    215 	if (balance_args.flags & BTRFS_BALANCE_SYSTEM)
    216 		btrfs_print_balance_args("sys", &balance_args.sys);
    217 	tprints("}");
    218 }
    219 
    220 static void
    221 btrfs_print_features(const struct btrfs_ioctl_feature_flags *flags)
    222 {
    223 	PRINT_FIELD_FLAGS("{", *flags, compat_flags, btrfs_features_compat,
    224 			  "BTRFS_FEATURE_COMPAT_???");
    225 	PRINT_FIELD_FLAGS(", ", *flags, compat_ro_flags,
    226 			  btrfs_features_compat_ro,
    227 			  "BTRFS_FEATURE_COMPAT_RO_???");
    228 	PRINT_FIELD_FLAGS(", ", *flags, incompat_flags, btrfs_features_incompat,
    229 			  "BTRFS_FEATURE_INCOMPAT_???");
    230 	tprints("}");
    231 }
    232 
    233 static void
    234 btrfs_print_qgroup_limit(const struct btrfs_qgroup_limit *lim)
    235 {
    236 	PRINT_FIELD_FLAGS(", lim={", *lim, flags, btrfs_qgroup_limit_flags,
    237 			  "BTRFS_QGROUP_LIMIT_???");
    238 	PRINT_FIELD_U(", ", *lim, max_rfer);
    239 	PRINT_FIELD_U(", ", *lim, max_excl);
    240 	PRINT_FIELD_U(", ", *lim, rsv_rfer);
    241 	PRINT_FIELD_U(", ", *lim, rsv_excl);
    242 	tprints("}");
    243 }
    244 
    245 #define btrfs_print_key_type(prefix_, where_, field_) \
    246 	PRINT_FIELD_XVAL_U((prefix_), (where_), field_, btrfs_key_types, NULL)
    247 #define btrfs_print_objectid(prefix_, where_, field_) \
    248 	PRINT_FIELD_XVAL_U((prefix_), (where_), field_, btrfs_tree_objectids, \
    249 			   NULL)
    250 
    251 static void
    252 btrfs_print_data_container_header(const struct btrfs_data_container *container)
    253 {
    254 	PRINT_FIELD_U("{", *container, bytes_left);
    255 	PRINT_FIELD_U(", ", *container, bytes_missing);
    256 	PRINT_FIELD_U(", ", *container, elem_cnt);
    257 	PRINT_FIELD_U(", ", *container, elem_missed);
    258 }
    259 
    260 static void
    261 btrfs_print_data_container_footer(void)
    262 {
    263 	tprints("}");
    264 }
    265 
    266 static bool
    267 print_btrfs_data_container_logical_ino(struct tcb *tcp, void *elem_buf,
    268 				       size_t elem_size, void *data)
    269 {
    270 	const struct {
    271 		uint64_t inum;
    272 		uint64_t offset;
    273 		uint64_t root;
    274 	} *const record = elem_buf;
    275 
    276 	PRINT_FIELD_U("{", *record, inum);
    277 	PRINT_FIELD_U(", ", *record, offset);
    278 	PRINT_FIELD_U(", ", *record, root);
    279 	tprints("}");
    280 
    281 	return true;
    282 }
    283 
    284 static void
    285 btrfs_print_logical_ino_container(struct tcb *tcp,
    286 				  const uint64_t inodes_addr)
    287 {
    288 	struct btrfs_data_container container;
    289 
    290 	if (umove_or_printaddr(tcp, inodes_addr, &container))
    291 		return;
    292 
    293 	btrfs_print_data_container_header(&container);
    294 
    295 	if (abbrev(tcp)) {
    296 		tprints(", ...");
    297 	} else {
    298 		const uint64_t val_addr =
    299 			inodes_addr + offsetof(typeof(container), val);
    300 		uint64_t record[3];
    301 		tprints(", val=");
    302 		print_array(tcp, val_addr, container.elem_cnt / 3,
    303 			    record, sizeof(record),
    304 			    tfetch_mem,
    305 			    print_btrfs_data_container_logical_ino, 0);
    306 	}
    307 
    308 	btrfs_print_data_container_footer();
    309 }
    310 
    311 static bool
    312 print_btrfs_data_container_ino_path(struct tcb *tcp, void *elem_buf,
    313 				       size_t elem_size, void *data)
    314 {
    315 	const uint64_t *const offset = elem_buf;
    316 	const uint64_t *const val_addr = data;
    317 
    318 	printpath(tcp, *val_addr + *offset);
    319 
    320 	return true;
    321 }
    322 
    323 static void
    324 btrfs_print_ino_path_container(struct tcb *tcp,
    325 			       const uint64_t fspath_addr)
    326 {
    327 	struct btrfs_data_container container;
    328 
    329 	if (umove_or_printaddr(tcp, fspath_addr, &container))
    330 		return;
    331 
    332 	btrfs_print_data_container_header(&container);
    333 
    334 	if (abbrev(tcp)) {
    335 		tprints(", ...");
    336 	} else {
    337 		uint64_t val_addr =
    338 			fspath_addr + offsetof(typeof(container), val);
    339 		uint64_t offset;
    340 		tprints(", val=");
    341 		print_array(tcp, val_addr, container.elem_cnt,
    342 			    &offset, sizeof(offset),
    343 			    tfetch_mem,
    344 			    print_btrfs_data_container_ino_path, &val_addr);
    345 	}
    346 
    347 	btrfs_print_data_container_footer();
    348 }
    349 
    350 static void
    351 btrfs_print_qgroup_inherit(struct tcb *const tcp, const kernel_ulong_t qgi_addr)
    352 {
    353 	struct btrfs_qgroup_inherit inherit;
    354 
    355 	if (umove_or_printaddr(tcp, qgi_addr, &inherit))
    356 		return;
    357 
    358 	PRINT_FIELD_FLAGS("{", inherit, flags, btrfs_qgroup_inherit_flags,
    359 			  "BTRFS_QGROUP_INHERIT_???");
    360 	PRINT_FIELD_U(", ", inherit, num_qgroups);
    361 	PRINT_FIELD_U(", ", inherit, num_ref_copies);
    362 	PRINT_FIELD_U(", ", inherit, num_excl_copies);
    363 
    364 	btrfs_print_qgroup_limit(&inherit.lim);
    365 
    366 	if (abbrev(tcp)) {
    367 		tprints(", ...");
    368 	} else {
    369 		uint64_t record;
    370 		tprints(", qgroups=");
    371 		print_array(tcp, qgi_addr + offsetof(typeof(inherit), qgroups),
    372 			    inherit.num_qgroups, &record, sizeof(record),
    373 			    tfetch_mem, print_uint64_array_member, 0);
    374 	}
    375 	tprints("}");
    376 }
    377 
    378 static void
    379 btrfs_print_tree_search(struct tcb *tcp, struct btrfs_ioctl_search_key *key,
    380 			uint64_t buf_addr, uint64_t buf_size, bool print_size)
    381 {
    382 	if (entering(tcp)) {
    383 		btrfs_print_objectid("{key={", *key, tree_id);
    384 
    385 		if (key->min_objectid != BTRFS_FIRST_FREE_OBJECTID ||
    386 		    !abbrev(tcp))
    387 			btrfs_print_objectid(", ", *key, min_objectid);
    388 
    389 		if (key->max_objectid != BTRFS_LAST_FREE_OBJECTID ||
    390 		    !abbrev(tcp))
    391 			btrfs_print_objectid(", ", *key, max_objectid);
    392 
    393 		PRINT_FIELD_U64(", ", *key, min_offset);
    394 		PRINT_FIELD_U64(", ", *key, max_offset);
    395 		PRINT_FIELD_U64(", ", *key, min_transid);
    396 		PRINT_FIELD_U64(", ", *key, max_transid);
    397 
    398 		btrfs_print_key_type(", ", *key, min_type);
    399 		btrfs_print_key_type(", ", *key, max_type);
    400 		PRINT_FIELD_U(", ", *key, nr_items);
    401 		tprints("}");
    402 		if (print_size)
    403 			tprintf(", buf_size=%" PRIu64, buf_size);
    404 		tprints("}");
    405 	} else {
    406 		PRINT_FIELD_U("{key={", *key, nr_items);
    407 		tprints("}");
    408 		if (print_size)
    409 			tprintf(", buf_size=%" PRIu64, buf_size);
    410 		if (abbrev(tcp)) {
    411 			tprints(", ...");
    412 		} else {
    413 			uint64_t i;
    414 			uint64_t off = 0;
    415 			tprints(", buf=[");
    416 			for (i = 0; i < key->nr_items; i++) {
    417 				struct btrfs_ioctl_search_header sh;
    418 				uint64_t addr = buf_addr + off;
    419 				if (i)
    420 					tprints(", ");
    421 				if (i > max_strlen) {
    422 					tprints("...");
    423 					break;
    424 				}
    425 				if (umove(tcp, addr, &sh)) {
    426 					tprints("...");
    427 					printaddr_comment(addr);
    428 					break;
    429 				}
    430 				PRINT_FIELD_U("{", sh, transid);
    431 				btrfs_print_objectid(", ", sh, objectid);
    432 				PRINT_FIELD_U(", ", sh, offset);
    433 				btrfs_print_key_type(", ", sh, type);
    434 				PRINT_FIELD_U(", ", sh, len);
    435 				tprints("}");
    436 				off += sizeof(sh) + sh.len;
    437 
    438 			}
    439 			tprints("]");
    440 		}
    441 		tprints("}");
    442 	}
    443 }
    444 
    445 static bool
    446 print_objectid_callback(struct tcb *tcp, void *elem_buf,
    447 			size_t elem_size, void *data)
    448 {
    449 	printxvals_ex(*(uint64_t *) elem_buf, NULL, XLAT_STYLE_FMT_U,
    450 		      btrfs_tree_objectids, NULL);
    451 
    452 	return true;
    453 }
    454 
    455 static bool
    456 print_btrfs_ioctl_space_info(struct tcb *tcp, void *elem_buf,
    457 			     size_t elem_size, void *data)
    458 {
    459 	const struct btrfs_ioctl_space_info *info = elem_buf;
    460 
    461 	PRINT_FIELD_FLAGS("{", *info, flags, btrfs_space_info_flags,
    462 			  "BTRFS_SPACE_INFO_???");
    463 	PRINT_FIELD_U(", ", *info, total_bytes);
    464 	PRINT_FIELD_U(", ", *info, used_bytes);
    465 	tprints("}");
    466 
    467 	return true;
    468 }
    469 
    470 static void
    471 print_btrfs_timespec(const char *prefix, uint64_t sec, uint32_t nsec)
    472 {
    473 	tprintf("%s{sec=%" PRIu64 ", nsec=%u}", prefix, sec, nsec);
    474 	tprints_comment(sprinttime_nsec(sec, nsec));
    475 }
    476 
    477 MPERS_PRINTER_DECL(int, btrfs_ioctl,
    478 		   struct tcb *const tcp, const unsigned int code,
    479 		   const kernel_ulong_t arg)
    480 {
    481 	switch (code) {
    482 	/* Take no arguments; command only. */
    483 	case BTRFS_IOC_TRANS_START:
    484 	case BTRFS_IOC_TRANS_END:
    485 	case BTRFS_IOC_SYNC:
    486 	case BTRFS_IOC_SCRUB_CANCEL:
    487 	case BTRFS_IOC_QUOTA_RESCAN_WAIT:
    488 	/*
    489 	 * The codes for these ioctls are based on each accepting a
    490 	 * vol_args but none of them actually consume an argument.
    491 	 */
    492 	case BTRFS_IOC_DEFRAG:
    493 	case BTRFS_IOC_BALANCE:
    494 		break;
    495 
    496 	/* takes a signed int */
    497 	case BTRFS_IOC_BALANCE_CTL:
    498 		tprints(", ");
    499 		printxval(btrfs_balance_ctl_cmds, arg, "BTRFS_BALANCE_CTL_???");
    500 		break;
    501 
    502 	/* returns a 64 */
    503 	case BTRFS_IOC_START_SYNC: /* R */
    504 		if (entering(tcp))
    505 			return 0;
    506 	ATTRIBUTE_FALLTHROUGH;
    507 	/* takes a u64 */
    508 	case BTRFS_IOC_DEFAULT_SUBVOL: /* W */
    509 	case BTRFS_IOC_WAIT_SYNC: /* W */
    510 		tprints(", ");
    511 		printnum_int64(tcp, arg, "%" PRIu64);
    512 		break;
    513 
    514 	/* u64 but describe a flags bitfield; we can make that symbolic */
    515 	case BTRFS_IOC_SUBVOL_GETFLAGS: { /* R */
    516 		uint64_t flags;
    517 
    518 		if (entering(tcp))
    519 			return 0;
    520 
    521 		tprints(", ");
    522 
    523 		if (umove_or_printaddr(tcp, arg, &flags))
    524 			break;
    525 
    526 		printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
    527 		break;
    528 	}
    529 
    530 	case BTRFS_IOC_SUBVOL_SETFLAGS: { /* W */
    531 		uint64_t flags;
    532 
    533 		tprints(", ");
    534 
    535 		if (umove_or_printaddr(tcp, arg, &flags))
    536 			break;
    537 
    538 		printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
    539 		break;
    540 	}
    541 
    542 	/* More complex types */
    543 	case BTRFS_IOC_BALANCE_V2: /* RW */
    544 		if (entering(tcp)) {
    545 			tprints(", ");
    546 			btrfs_print_balance(tcp, arg, false);
    547 			return 0;
    548 		}
    549 
    550 		if (syserror(tcp))
    551 			break;
    552 
    553 		tprints(" => ");
    554 		btrfs_print_balance(tcp, arg, true);
    555 		break;
    556 	case BTRFS_IOC_BALANCE_PROGRESS: /* R */
    557 		if (entering(tcp))
    558 			return 0;
    559 
    560 		tprints(", ");
    561 		btrfs_print_balance(tcp, arg, true);
    562 		break;
    563 
    564 	case BTRFS_IOC_DEFRAG_RANGE: { /* W */
    565 		struct btrfs_ioctl_defrag_range_args args;
    566 
    567 		tprints(", ");
    568 
    569 		if (umove_or_printaddr(tcp, arg, &args))
    570 			break;
    571 
    572 		PRINT_FIELD_U("{", args, start);
    573 		PRINT_FIELD_U64(", ", args, len);
    574 
    575 		PRINT_FIELD_FLAGS(", ", args, flags, btrfs_defrag_flags,
    576 				  "BTRFS_DEFRAG_RANGE_???");
    577 		PRINT_FIELD_U(", ", args, extent_thresh);
    578 		PRINT_FIELD_XVAL(", ", args, compress_type,
    579 				 btrfs_compress_types, "BTRFS_COMPRESS_???");
    580 		tprints("}");
    581 		break;
    582 	}
    583 
    584 	case BTRFS_IOC_DEV_INFO: { /* RW */
    585 		struct btrfs_ioctl_dev_info_args args;
    586 		char uuid[UUID_STRING_SIZE+1];
    587 		int valid;
    588 
    589 		if (entering(tcp))
    590 			tprints(", ");
    591 		else if (syserror(tcp))
    592 			break;
    593 		else
    594 			tprints(" => ");
    595 		if (umove_or_printaddr(tcp, arg, &args))
    596 			break;
    597 
    598 		valid = btrfs_unparse_uuid(args.uuid, uuid);
    599 		if (entering(tcp)) {
    600 			PRINT_FIELD_DEV("{", args, devid);
    601 			if (valid)
    602 				tprintf(", uuid=%s", uuid);
    603 			tprints("}");
    604 			return 0;
    605 		}
    606 
    607 		tprints("{");
    608 		if (valid)
    609 			tprintf("uuid=%s, ", uuid);
    610 
    611 		PRINT_FIELD_U("", args, bytes_used);
    612 		PRINT_FIELD_U(", ", args, total_bytes);
    613 		PRINT_FIELD_CSTRING(", ", args, path);
    614 		tprints("}");
    615 
    616 		break;
    617 	}
    618 
    619 	case BTRFS_IOC_DEV_REPLACE: { /* RW */
    620 		struct_btrfs_ioctl_dev_replace_args args;
    621 
    622 		if (entering(tcp))
    623 			tprints(", ");
    624 		else if (syserror(tcp))
    625 			break;
    626 		else
    627 			tprints(" => ");
    628 
    629 		if (umove_or_printaddr(tcp, arg, &args))
    630 			break;
    631 
    632 		if (entering(tcp)) {
    633 			PRINT_FIELD_XVAL("{", args, cmd, btrfs_dev_replace_cmds,
    634 					 "BTRFS_IOCTL_DEV_REPLACE_CMD_???");
    635 			if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_START) {
    636 				PRINT_FIELD_DEV(", start={", args.start,
    637 					      srcdevid);
    638 				PRINT_FIELD_XVAL(", ", args.start,
    639 					cont_reading_from_srcdev_mode,
    640 					btrfs_cont_reading_from_srcdev_mode,
    641 					"BTRFS_IOCTL_DEV_REPLACE_CONT_READING"
    642 					"_FROM_SRCDEV_MODE_???");
    643 				PRINT_FIELD_CSTRING(", ", args.start,
    644 						    srcdev_name);
    645 				PRINT_FIELD_CSTRING(", ", args.start,
    646 						    tgtdev_name);
    647 				tprints("}");
    648 
    649 			}
    650 			tprints("}");
    651 			return 0;
    652 		}
    653 
    654 		PRINT_FIELD_XVAL("{", args, result, btrfs_dev_replace_results,
    655 				 "BTRFS_IOCTL_DEV_REPLACE_RESULT_???");
    656 		if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS) {
    657 			PRINT_FIELD_XVAL(", status={", args.status,
    658 					 replace_state, btrfs_dev_replace_state,
    659 					 "BTRFS_IOCTL_DEV_REPLACE_STATE_???");
    660 
    661 			PRINT_FIELD_U(", ", args.status, progress_1000);
    662 			if (args.status.progress_1000 <= 1000)
    663 				tprintf_comment("%u.%u%%",
    664 					(unsigned) args.status.progress_1000 / 10,
    665 					(unsigned) args.status.progress_1000 % 10);
    666 
    667 			PRINT_FIELD_U(", ", args.status, time_started);
    668 			tprints_comment(sprinttime(args.status.time_started));
    669 
    670 			PRINT_FIELD_U(", ", args.status, time_stopped);
    671 			tprints_comment(sprinttime(args.status.time_stopped));
    672 
    673 			PRINT_FIELD_U(", ", args.status, num_write_errors);
    674 			PRINT_FIELD_U(", ", args.status,
    675 				      num_uncorrectable_read_errors);
    676 		}
    677 		tprints("}");
    678 		break;
    679 	}
    680 
    681 	case BTRFS_IOC_GET_FEATURES: { /* R */
    682 		struct btrfs_ioctl_feature_flags flags;
    683 
    684 		if (entering(tcp))
    685 			return 0;
    686 
    687 		tprints(", ");
    688 		if (umove_or_printaddr(tcp, arg, &flags))
    689 			break;
    690 
    691 		btrfs_print_features(&flags);
    692 		break;
    693 	}
    694 
    695 	case BTRFS_IOC_SET_FEATURES: { /* W */
    696 		struct btrfs_ioctl_feature_flags flarg[2];
    697 
    698 		tprints(", ");
    699 
    700 		if (umove_or_printaddr(tcp, arg, &flarg))
    701 			break;
    702 
    703 		tprints("[");
    704 		btrfs_print_features(&flarg[0]);
    705 		tprints(", ");
    706 		btrfs_print_features(&flarg[1]);
    707 		tprints("]");
    708 		break;
    709 	}
    710 
    711 	case BTRFS_IOC_GET_SUPPORTED_FEATURES: { /* R */
    712 		struct btrfs_ioctl_feature_flags flarg[3];
    713 
    714 		if (entering(tcp))
    715 			return 0;
    716 
    717 		tprints(", ");
    718 		if (umove_or_printaddr(tcp, arg, &flarg))
    719 			break;
    720 
    721 		tprints("[");
    722 		btrfs_print_features(&flarg[0]);
    723 		tprints_comment("supported");
    724 
    725 		tprints(", ");
    726 		btrfs_print_features(&flarg[1]);
    727 		tprints_comment("safe to set");
    728 
    729 		tprints(", ");
    730 		btrfs_print_features(&flarg[2]);
    731 		tprints_comment("safe to clear");
    732 		tprints("]");
    733 
    734 		break;
    735 	}
    736 
    737 	case BTRFS_IOC_FS_INFO: { /* R */
    738 		struct btrfs_ioctl_fs_info_args args;
    739 		char uuid[UUID_STRING_SIZE+1];
    740 		uint32_t nodesize, sectorsize, clone_alignment;
    741 #ifndef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
    742 		uint32_t *reserved32;
    743 #endif
    744 
    745 		if (entering(tcp))
    746 			return 0;
    747 
    748 		tprints(", ");
    749 		if (umove_or_printaddr(tcp, arg, &args))
    750 			break;
    751 
    752 #ifdef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
    753 		nodesize = args.nodesize,
    754 		sectorsize = args.sectorsize,
    755 		clone_alignment = args.clone_alignment;
    756 #else
    757 		reserved32 = (void *) args.reserved;
    758 		nodesize = reserved32[0];
    759 		sectorsize = reserved32[1];
    760 		clone_alignment = reserved32[2];
    761 #endif
    762 		btrfs_unparse_uuid(args.fsid, uuid);
    763 
    764 		PRINT_FIELD_U("{", args, max_id);
    765 		PRINT_FIELD_U(", ", args, num_devices);
    766 		tprintf(", fsid=%s, nodesize=%u, sectorsize=%u"
    767 			", clone_alignment=%u",
    768 			uuid, nodesize, sectorsize, clone_alignment);
    769 		tprints("}");
    770 		break;
    771 	}
    772 
    773 	case BTRFS_IOC_GET_DEV_STATS: { /* RW */
    774 		struct btrfs_ioctl_get_dev_stats args;
    775 		uint64_t i;
    776 
    777 		if (entering(tcp))
    778 			tprints(", ");
    779 		else if (syserror(tcp))
    780 			break;
    781 		else
    782 			tprints(" => ");
    783 		if (umove_or_printaddr(tcp, arg, &args))
    784 			break;
    785 
    786 		tprints("{");
    787 
    788 		if (entering(tcp)) {
    789 			PRINT_FIELD_DEV("", args, devid);
    790 			tprints(", ");
    791 		}
    792 
    793 		PRINT_FIELD_U("", args, nr_items);
    794 		PRINT_FIELD_FLAGS(", ", args, flags, btrfs_dev_stats_flags,
    795 				  "BTRFS_DEV_STATS_???");
    796 
    797 		if (entering(tcp)) {
    798 			tprints("}");
    799 			return 0;
    800 		}
    801 
    802 		/*
    803 		 * The structure has a 1k limit; Let's make sure we don't
    804 		 * go off into the middle of nowhere with a bad nr_items
    805 		 * value.
    806 		 */
    807 		tprints(", [");
    808 		for (i = 0; i < args.nr_items; i++) {
    809 			if (i)
    810 				tprints(", ");
    811 			if (i >= ARRAY_SIZE(args.values)) {
    812 				tprints("...");
    813 				break;
    814 			}
    815 
    816 			tprints("[");
    817 			printxval_u(btrfs_dev_stats_values, i, NULL);
    818 			tprintf("] = %" PRI__u64, args.values[i]);
    819 		}
    820 		tprints("]}");
    821 		break;
    822 	}
    823 
    824 	case BTRFS_IOC_INO_LOOKUP: { /* RW */
    825 		struct btrfs_ioctl_ino_lookup_args args;
    826 
    827 		if (entering(tcp))
    828 			tprints(", ");
    829 		else if (syserror(tcp))
    830 			break;
    831 		else
    832 			tprints(" => ");
    833 
    834 		if (umove_or_printaddr(tcp, arg, &args))
    835 			break;
    836 
    837 		if (entering(tcp)) {
    838 			/* Use subvolume id of the containing root */
    839 			if (args.treeid == 0)
    840 				set_tcb_priv_ulong(tcp, 1);
    841 
    842 			btrfs_print_objectid("{", args, treeid);
    843 			btrfs_print_objectid(", ", args, objectid);
    844 			tprints("}");
    845 			return 0;
    846 		}
    847 
    848 		tprints("{");
    849 		if (get_tcb_priv_ulong(tcp)) {
    850 			btrfs_print_objectid("", args, treeid);
    851 			tprints(", ");
    852 		}
    853 
    854 		PRINT_FIELD_CSTRING("", args, name);
    855 		tprints("}");
    856 		break;
    857 	}
    858 
    859 	case BTRFS_IOC_INO_PATHS: { /* RW */
    860 		struct btrfs_ioctl_ino_path_args args;
    861 
    862 		if (entering(tcp))
    863 			tprints(", ");
    864 		else if (syserror(tcp))
    865 			break;
    866 		else
    867 			tprints(" => ");
    868 
    869 		if (umove_or_printaddr(tcp, arg, &args))
    870 			break;
    871 
    872 		if (entering(tcp)) {
    873 			PRINT_FIELD_U("{", args, inum);
    874 			PRINT_FIELD_U(", ", args, size);
    875 			PRINT_FIELD_ADDR64(", ", args, fspath);
    876 			tprints("}");
    877 			return 0;
    878 		}
    879 
    880 		tprints("{fspath=");
    881 		btrfs_print_ino_path_container(tcp, args.fspath);
    882 
    883 		tprints("}");
    884 		break;
    885 	}
    886 
    887 	case BTRFS_IOC_LOGICAL_INO: { /* RW */
    888 		struct btrfs_ioctl_logical_ino_args args;
    889 
    890 		if (entering(tcp))
    891 			tprints(", ");
    892 		else if (syserror(tcp))
    893 			break;
    894 		else
    895 			tprints(" => ");
    896 
    897 		if (umove_or_printaddr(tcp, arg, &args))
    898 			break;
    899 
    900 		if (entering(tcp)) {
    901 			PRINT_FIELD_U("{", args, logical);
    902 			PRINT_FIELD_U(", ", args, size);
    903 
    904 			if (!IS_ARRAY_ZERO(args.reserved)) {
    905 				tprints(", reserved=[");
    906 				for (size_t i = 0; i < 3; ++i)
    907 					tprintf("%s%#" PRI__x64,
    908 						i ? ", " : "",
    909 						args.reserved[i]);
    910 				tprints("]");
    911 			}
    912 
    913 			tprintf(", flags=");
    914 			printflags64(btrfs_logical_ino_args_flags,
    915 #ifdef HAVE_STRUCT_BTRFS_IOCTL_LOGICAL_INO_ARGS_FLAGS
    916 				     args.flags
    917 #else
    918 				     args.reserved[3]
    919 #endif
    920 				     , "BTRFS_LOGICAL_INO_ARGS_???");
    921 			PRINT_FIELD_ADDR64(", ", args, inodes);
    922 			tprints("}");
    923 			return 0;
    924 		}
    925 
    926 		tprints("{inodes=");
    927 		btrfs_print_logical_ino_container(tcp, args.inodes);
    928 
    929 		tprints("}");
    930 		break;
    931 	}
    932 
    933 	case BTRFS_IOC_QGROUP_ASSIGN: { /* W */
    934 		struct btrfs_ioctl_qgroup_assign_args args;
    935 
    936 		tprints(", ");
    937 		if (umove_or_printaddr(tcp, arg, &args))
    938 			break;
    939 
    940 		PRINT_FIELD_U("{", args, assign);
    941 		PRINT_FIELD_U(", ", args, src);
    942 		PRINT_FIELD_U(", ", args, dst);
    943 		tprints("}");
    944 		break;
    945 	}
    946 
    947 	case BTRFS_IOC_QGROUP_CREATE: { /* W */
    948 		struct btrfs_ioctl_qgroup_create_args args;
    949 
    950 		tprints(", ");
    951 		if (umove_or_printaddr(tcp, arg, &args))
    952 			break;
    953 
    954 		PRINT_FIELD_U("{", args, create);
    955 		PRINT_FIELD_U(", ", args, qgroupid);
    956 		tprints("}");
    957 		break;
    958 	}
    959 
    960 	case BTRFS_IOC_QGROUP_LIMIT: { /* R */
    961 		struct btrfs_ioctl_qgroup_limit_args args;
    962 
    963 		if (entering(tcp))
    964 			return 0;
    965 
    966 		tprints(", ");
    967 		if (umove_or_printaddr(tcp, arg, &args))
    968 			break;
    969 
    970 		PRINT_FIELD_U("{", args, qgroupid);
    971 		btrfs_print_qgroup_limit(&args.lim);
    972 		tprints("}");
    973 		break;
    974 	}
    975 
    976 	case BTRFS_IOC_QUOTA_CTL: { /* W */
    977 		struct btrfs_ioctl_quota_ctl_args args;
    978 
    979 		tprints(", ");
    980 		if (umove_or_printaddr(tcp, arg, &args))
    981 			break;
    982 
    983 		PRINT_FIELD_XVAL("{", args, cmd, btrfs_qgroup_ctl_cmds,
    984 				 "BTRFS_QUOTA_CTL_???");
    985 		tprints("}");
    986 
    987 		break;
    988 	}
    989 
    990 	case BTRFS_IOC_QUOTA_RESCAN: { /* W */
    991 		struct btrfs_ioctl_quota_rescan_args args;
    992 
    993 		tprints(", ");
    994 		if (umove_or_printaddr(tcp, arg, &args))
    995 			break;
    996 
    997 		PRINT_FIELD_U("{", args, flags);
    998 		tprints("}");
    999 		break;
   1000 	}
   1001 
   1002 	case BTRFS_IOC_QUOTA_RESCAN_STATUS: { /* R */
   1003 		struct btrfs_ioctl_quota_rescan_args args;
   1004 
   1005 		if (entering(tcp))
   1006 			return 0;
   1007 
   1008 		tprints(", ");
   1009 		if (umove_or_printaddr(tcp, arg, &args))
   1010 			break;
   1011 
   1012 		PRINT_FIELD_U("{", args, flags);
   1013 		btrfs_print_objectid(", ", args, progress);
   1014 		tprints("}");
   1015 		break;
   1016 	}
   1017 
   1018 	case BTRFS_IOC_SET_RECEIVED_SUBVOL: { /* RW */
   1019 		struct_btrfs_ioctl_received_subvol_args args;
   1020 		char uuid[UUID_STRING_SIZE+1];
   1021 
   1022 		if (entering(tcp))
   1023 			tprints(", ");
   1024 		else if (syserror(tcp))
   1025 			break;
   1026 		else
   1027 			tprints(" => ");
   1028 
   1029 		if (umove_or_printaddr(tcp, arg, &args))
   1030 			break;
   1031 
   1032 		if (entering(tcp)) {
   1033 			btrfs_unparse_uuid((unsigned char *)args.uuid, uuid);
   1034 			tprintf("{uuid=%s", uuid);
   1035 			PRINT_FIELD_U(", ", args, stransid);
   1036 			print_btrfs_timespec(", stime=",
   1037 					     args.stime.sec, args.stime.nsec);
   1038 			PRINT_FIELD_U(", ", args, flags);
   1039 			tprints("}");
   1040 			return 0;
   1041 		}
   1042 		PRINT_FIELD_U("{", args, rtransid);
   1043 		print_btrfs_timespec(", rtime=",
   1044 				     args.rtime.sec, args.rtime.nsec);
   1045 		tprints("}");
   1046 		break;
   1047 	}
   1048 
   1049 	case BTRFS_IOC_SCRUB: /* RW */
   1050 	case BTRFS_IOC_SCRUB_PROGRESS: { /* RW */
   1051 		struct btrfs_ioctl_scrub_args args;
   1052 
   1053 		if (entering(tcp))
   1054 			tprints(", ");
   1055 		else if (syserror(tcp))
   1056 			break;
   1057 		else
   1058 			tprints(" => ");
   1059 
   1060 		if (umove_or_printaddr(tcp, arg, &args))
   1061 			break;
   1062 
   1063 		if (entering(tcp)) {
   1064 			PRINT_FIELD_DEV("{", args, devid);
   1065 			if (code == BTRFS_IOC_SCRUB) {
   1066 				PRINT_FIELD_U(", ", args, start);
   1067 				PRINT_FIELD_U64(", ", args, end);
   1068 				PRINT_FIELD_FLAGS(", ", args, flags,
   1069 						  btrfs_scrub_flags,
   1070 						  "BTRFS_SCRUB_???");
   1071 			}
   1072 			tprints("}");
   1073 			return 0;
   1074 		}
   1075 		PRINT_FIELD_U("{progress={", args.progress,
   1076 			      data_extents_scrubbed);
   1077 		PRINT_FIELD_U(", ", args.progress, tree_extents_scrubbed);
   1078 		PRINT_FIELD_U(", ", args.progress, data_bytes_scrubbed);
   1079 		PRINT_FIELD_U(", ", args.progress, tree_bytes_scrubbed);
   1080 		PRINT_FIELD_U(", ", args.progress, read_errors);
   1081 		PRINT_FIELD_U(", ", args.progress, csum_errors);
   1082 		PRINT_FIELD_U(", ", args.progress, verify_errors);
   1083 		PRINT_FIELD_U(", ", args.progress, no_csum);
   1084 		PRINT_FIELD_U(", ", args.progress, csum_discards);
   1085 		PRINT_FIELD_U(", ", args.progress, super_errors);
   1086 		PRINT_FIELD_U(", ", args.progress, malloc_errors);
   1087 		PRINT_FIELD_U(", ", args.progress, uncorrectable_errors);
   1088 		PRINT_FIELD_U(", ", args.progress, corrected_errors);
   1089 		PRINT_FIELD_U(", ", args.progress, last_physical);
   1090 		PRINT_FIELD_U(", ", args.progress, unverified_errors);
   1091 		tprints("}}");
   1092 		break;
   1093 	}
   1094 
   1095 	case BTRFS_IOC_TREE_SEARCH: { /* RW */
   1096 		struct btrfs_ioctl_search_args args;
   1097 		uint64_t buf_offset;
   1098 
   1099 		if (entering(tcp))
   1100 			tprints(", ");
   1101 		else if (syserror(tcp))
   1102 			break;
   1103 		else
   1104 			tprints(" => ");
   1105 
   1106 		if (umove_or_printaddr(tcp, arg, &args))
   1107 			break;
   1108 
   1109 		buf_offset = offsetof(struct btrfs_ioctl_search_args, buf);
   1110 		btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
   1111 					sizeof(args.buf), false);
   1112 		if (entering(tcp))
   1113 			return 0;
   1114 		break;
   1115 	}
   1116 
   1117 	case BTRFS_IOC_TREE_SEARCH_V2: { /* RW */
   1118 		struct btrfs_ioctl_search_args_v2 args;
   1119 		uint64_t buf_offset;
   1120 
   1121 		if (entering(tcp))
   1122 			tprints(", ");
   1123 		else if (syserror(tcp)) {
   1124 			if (tcp->u_error == EOVERFLOW) {
   1125 				tprints(" => ");
   1126 				if (!umove_or_printaddr_ignore_syserror(tcp,
   1127 				    arg, &args)) {
   1128 					PRINT_FIELD_U("{", args, buf_size);
   1129 					tprints("}");
   1130 				}
   1131 			}
   1132 			break;
   1133 		} else
   1134 			tprints(" => ");
   1135 
   1136 		if (umove_or_printaddr(tcp, arg, &args))
   1137 			break;
   1138 
   1139 		buf_offset = offsetof(struct btrfs_ioctl_search_args_v2, buf);
   1140 		btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
   1141 					args.buf_size, true);
   1142 		if (entering(tcp))
   1143 			return 0;
   1144 		break;
   1145 	}
   1146 
   1147 	case BTRFS_IOC_SEND: { /* W */
   1148 		struct_btrfs_ioctl_send_args args;
   1149 
   1150 		tprints(", ");
   1151 		if (umove_or_printaddr(tcp, arg, &args))
   1152 			break;
   1153 
   1154 		PRINT_FIELD_FD("{", args, send_fd, tcp);
   1155 		PRINT_FIELD_U(", ", args, clone_sources_count);
   1156 
   1157 		tprints(", clone_sources=");
   1158 		if (abbrev(tcp))
   1159 			printaddr((uintptr_t) args.clone_sources);
   1160 		else {
   1161 			uint64_t record;
   1162 			print_array(tcp, ptr_to_kulong(args.clone_sources),
   1163 				    args.clone_sources_count,
   1164 				    &record, sizeof(record),
   1165 				    tfetch_mem,
   1166 				    print_objectid_callback, 0);
   1167 		}
   1168 		btrfs_print_objectid(", ", args, parent_root);
   1169 		PRINT_FIELD_FLAGS(", ", args, flags, btrfs_send_flags,
   1170 				  "BTRFS_SEND_FLAGS_???");
   1171 		tprints("}");
   1172 		break;
   1173 	}
   1174 
   1175 	case BTRFS_IOC_SPACE_INFO: { /* RW */
   1176 		struct btrfs_ioctl_space_args args;
   1177 
   1178 		if (entering(tcp))
   1179 			tprints(", ");
   1180 		else if (syserror(tcp))
   1181 			break;
   1182 		else
   1183 			tprints(" => ");
   1184 
   1185 		if (umove_or_printaddr(tcp, arg, &args))
   1186 			break;
   1187 
   1188 		if (entering(tcp)) {
   1189 			PRINT_FIELD_U("{", args, space_slots);
   1190 			tprints("}");
   1191 			return 0;
   1192 		}
   1193 
   1194 		PRINT_FIELD_U("{", args, total_spaces);
   1195 
   1196 		if (args.space_slots == 0 && args.total_spaces) {
   1197 			tprints("}");
   1198 			break;
   1199 		}
   1200 
   1201 		if (abbrev(tcp)) {
   1202 			tprints(", ...");
   1203 		} else {
   1204 			struct btrfs_ioctl_space_info info;
   1205 			tprints(", spaces=");
   1206 			print_array(tcp, arg + offsetof(typeof(args), spaces),
   1207 				    args.total_spaces,
   1208 				    &info, sizeof(info), tfetch_mem,
   1209 				    print_btrfs_ioctl_space_info, 0);
   1210 		}
   1211 		tprints("}");
   1212 		break;
   1213 	}
   1214 
   1215 	case BTRFS_IOC_SNAP_CREATE:
   1216 	case BTRFS_IOC_RESIZE:
   1217 	case BTRFS_IOC_SCAN_DEV:
   1218 	case BTRFS_IOC_ADD_DEV:
   1219 	case BTRFS_IOC_RM_DEV:
   1220 	case BTRFS_IOC_SUBVOL_CREATE:
   1221 	case BTRFS_IOC_SNAP_DESTROY:
   1222 	case BTRFS_IOC_DEVICES_READY: { /* W */
   1223 		struct btrfs_ioctl_vol_args args;
   1224 
   1225 		tprints(", ");
   1226 		if (umove_or_printaddr(tcp, arg, &args))
   1227 			break;
   1228 
   1229 		PRINT_FIELD_FD("{", args, fd, tcp);
   1230 		PRINT_FIELD_CSTRING(", ", args, name);
   1231 		tprints("}");
   1232 		break;
   1233 	}
   1234 
   1235 	case BTRFS_IOC_SNAP_CREATE_V2:
   1236 	case BTRFS_IOC_SUBVOL_CREATE_V2: { /* code is W, but is actually RW */
   1237 		struct_btrfs_ioctl_vol_args_v2 args;
   1238 
   1239 		if (entering(tcp))
   1240 			tprints(", ");
   1241 		else if (syserror(tcp))
   1242 			break;
   1243 		else
   1244 			tprints(" => ");
   1245 
   1246 		if (umove_or_printaddr(tcp, arg, &args))
   1247 			break;
   1248 
   1249 		if (entering(tcp)) {
   1250 			PRINT_FIELD_FD("{", args, fd, tcp);
   1251 			PRINT_FIELD_FLAGS(", ", args, flags,
   1252 					  btrfs_snap_flags_v2,
   1253 					  "BTRFS_SUBVOL_???");
   1254 			if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
   1255 				PRINT_FIELD_U(", ", args, size);
   1256 				tprints(", qgroup_inherit=");
   1257 				btrfs_print_qgroup_inherit(tcp,
   1258 					ptr_to_kulong(args.qgroup_inherit));
   1259 			}
   1260 			PRINT_FIELD_CSTRING(", ", args, name);
   1261 			tprints("}");
   1262 			return 0;
   1263 		}
   1264 		PRINT_FIELD_U("{", args, transid);
   1265 		tprints("}");
   1266 		break;
   1267 	}
   1268 
   1269 	case BTRFS_IOC_GET_FSLABEL: /* R */
   1270 		if (entering(tcp))
   1271 			return 0;
   1272 		ATTRIBUTE_FALLTHROUGH;
   1273 	case BTRFS_IOC_SET_FSLABEL: { /* W */
   1274 		char label[BTRFS_LABEL_SIZE];
   1275 
   1276 		tprints(", ");
   1277 		if (umove_or_printaddr(tcp, arg, &label))
   1278 			break;
   1279 		print_quoted_cstring(label, sizeof(label));
   1280 		break;
   1281 	}
   1282 
   1283 	case BTRFS_IOC_CLONE:			/* FICLONE */
   1284 	case BTRFS_IOC_CLONE_RANGE:		/* FICLONERANGE */
   1285 #ifdef BTRFS_IOC_FILE_EXTENT_SAME
   1286 	case BTRFS_IOC_FILE_EXTENT_SAME:	/* FIDEDUPERANGE */
   1287 #endif
   1288 		/*
   1289 		 * FICLONE, FICLONERANGE, and FIDEDUPERANGE started out as
   1290 		 * btrfs ioctls and the code was kept for the generic
   1291 		 * implementations.  We use the BTRFS_* names here because
   1292 		 * they will be available on older systems.
   1293 		 */
   1294 		return file_ioctl(tcp, code, arg);
   1295 
   1296 	default:
   1297 		return RVAL_DECODED;
   1298 	};
   1299 	return RVAL_IOCTL_DECODED;
   1300 }
   1301 #endif /* HAVE_LINUX_BTRFS_H */
   1302