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