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