blob: 8286325ef4cbd644559c2e732a1b2e7844fde151 [file] [log] [blame]
Dmitry V. Levin22129182016-05-24 01:32:09 +00001#include "tests.h"
2
3#ifdef HAVE_LINUX_BTRFS_H
4
Jeff Mahoney35866792016-05-18 18:09:42 -04005#include <errno.h>
Jeff Mahoney35866792016-05-18 18:09:42 -04006#include <fcntl.h>
Dmitry V. Levin28a5f662016-05-24 01:32:41 +00007#include <inttypes.h>
8#include <limits.h>
9#include <stdbool.h>
10#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15#include <sys/fcntl.h>
16#include <sys/ioctl.h>
17#include <sys/stat.h>
18#include <sys/vfs.h>
Jeff Mahoney35866792016-05-18 18:09:42 -040019#include <linux/fs.h>
20#include <linux/btrfs.h>
21#include <linux/magic.h>
Jeff Mahoney35866792016-05-18 18:09:42 -040022#include "xlat.h"
23
24#include "xlat/btrfs_balance_args.h"
25#include "xlat/btrfs_balance_flags.h"
26#include "xlat/btrfs_balance_state.h"
27#include "xlat/btrfs_compress_types.h"
28#include "xlat/btrfs_defrag_flags.h"
29#include "xlat/btrfs_dev_stats_values.h"
30#include "xlat/btrfs_dev_stats_flags.h"
31#include "xlat/btrfs_qgroup_inherit_flags.h"
32#include "xlat/btrfs_qgroup_limit_flags.h"
33#include "xlat/btrfs_scrub_flags.h"
34#include "xlat/btrfs_send_flags.h"
35#include "xlat/btrfs_space_info_flags.h"
36#include "xlat/btrfs_snap_flags_v2.h"
37#include "xlat/btrfs_tree_objectids.h"
38#include "xlat/btrfs_features_compat.h"
39#include "xlat/btrfs_features_compat_ro.h"
40#include "xlat/btrfs_features_incompat.h"
41#include "xlat/btrfs_key_types.h"
42
Dmitry V. Levin22129182016-05-24 01:32:09 +000043#ifdef HAVE_LINUX_FIEMAP_H
44# include <linux/fiemap.h>
45# include "xlat/fiemap_flags.h"
46# include "xlat/fiemap_extent_flags.h"
47#endif
Jeff Mahoney35866792016-05-18 18:09:42 -040048
49#ifndef BTRFS_LABEL_SIZE
50#define BTRFS_LABEL_SIZE 256
51#endif
52
53#ifndef BTRFS_NAME_LEN
54#define BTRFS_NAME_LEN 255
55#endif
56
57static const char *btrfs_test_root;
58static int btrfs_test_dir_fd;
59static bool verbose = false;
60static bool write_ok = false;
61
62const unsigned char uuid_reference[BTRFS_UUID_SIZE] = {
63 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
64 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
65};
66
67const char uuid_reference_string[] = "01234567-89ab-cdef-fedc-ba9876543210";
68
69#ifndef BTRFS_IOC_GET_FEATURES
70#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
71 struct btrfs_ioctl_feature_flags)
72#define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
73 struct btrfs_ioctl_feature_flags[2])
74#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
75 struct btrfs_ioctl_feature_flags[3])
76#endif
77
78#ifndef HAVE_STRUCT_BTRFS_IOCTL_FEATURE_FLAGS_COMPAT_FLAGS
79struct btrfs_ioctl_feature_flags {
80 uint64_t compat_flags;
81 uint64_t compat_ro_flags;
82 uint64_t incompat_flags;
83};
84#endif
85
86#ifndef HAVE_STRUCT_BTRFS_IOCTL_DEFRAG_RANGE_ARGS_START
87struct btrfs_ioctl_defrag_range_args {
88 uint64_t start;
89 uint64_t len;
90 uint64_t flags;
91 uint32_t extent_thresh;
92 uint32_t compress_type;
93 uint32_t unused[4];
94};
95#endif
96
97#ifndef FIDEDUPERANGE
98#define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range)
99struct file_dedupe_range_info {
100 int64_t dest_fd; /* in - destination file */
101 uint64_t dest_offset; /* in - start of extent in destination */
102 uint64_t bytes_deduped; /* out - total # of bytes we were able
103 * to dedupe from this file. */
104 /* status of this dedupe operation:
105 * < 0 for error
106 * == FILE_DEDUPE_RANGE_SAME if dedupe succeeds
107 * == FILE_DEDUPE_RANGE_DIFFERS if data differs
108 */
109 int32_t status; /* out - see above description */
110 uint32_t reserved; /* must be zero */
111};
112
113struct file_dedupe_range {
114 uint64_t src_offset; /* in - start of extent in source */
115 uint64_t src_length; /* in - length of extent */
116 uint16_t dest_count; /* in - total elements in info array */
117 uint16_t reserved1; /* must be zero */
118 uint32_t reserved2; /* must be zero */
119 struct file_dedupe_range_info info[0];
120};
121#endif
122
123#ifndef BTRFS_IOC_TREE_SEARCH_V2
124#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
125 struct btrfs_ioctl_search_args_v2)
126struct btrfs_ioctl_search_args_v2 {
127 struct btrfs_ioctl_search_key key; /* in/out - search parameters */
128 uint64_t buf_size; /* in - size of buffer
129 * out - on EOVERFLOW: needed size
130 * to store item */
131 uint64_t buf[0]; /* out - found items */
132};
133#endif
134
135
136static const char *maybe_print_uint64max(uint64_t val)
137{
138 if (val == UINT64_MAX)
139 return " /* UINT64_MAX */";
140 return "";
141}
142
143/* takes highest valid flag bit */
144static uint64_t max_flags_plus_one(int bit)
145{
146 int i;
147 uint64_t val = 0;
148 if (bit == -1)
149 return 1;
150 for (i = 0; i <= bit + 1 && i < 64; i++)
151 val |= (1ULL << i);
152 return val;
153}
154
155/*
156 * Consumes no arguments, returns nothing:
157 *
158 * - BTRFS_IOC_TRANS_START
159 * - BTRFS_IOC_TRANS_END
160 */
161static void
162btrfs_test_trans_ioctls(void)
163{
164 ioctl(-1, BTRFS_IOC_TRANS_START, NULL);
165 printf("ioctl(-1, BTRFS_IOC_TRANS_START) = -1 EBADF (%m)\n");
166
167 ioctl(-1, BTRFS_IOC_TRANS_END, NULL);
168 printf("ioctl(-1, BTRFS_IOC_TRANS_END) = -1 EBADF (%m)\n");
169}
170
171/*
172 * Consumes no arguments, returns nothing:
173 * - BTRFS_IOC_SYNC
174 *
175 * Consumes argument, returns nothing
176 * - BTRFS_IOC_WAIT_SYNC
177 */
178static void
179btrfs_test_sync_ioctls(void)
180{
181 uint64_t u64val = 257;
182
183 ioctl(-1, BTRFS_IOC_SYNC, NULL);
184 printf("ioctl(-1, BTRFS_IOC_SYNC) = -1 EBADF (%m)\n");
185
186 ioctl(-1, BTRFS_IOC_WAIT_SYNC, NULL);
187 printf("ioctl(-1, BTRFS_IOC_WAIT_SYNC, NULL) = -1 EBADF (%m)\n");
188
189 ioctl(-1, BTRFS_IOC_WAIT_SYNC, &u64val);
190 printf("ioctl(-1, BTRFS_IOC_WAIT_SYNC, [%" PRIu64
191 "]) = -1 EBADF (%m)\n", u64val);
192
193 /*
194 * The live test of BTRFS_IOC_SYNC happens as a part of the test
195 * for BTRFS_IOC_LOGICAL_INO
196 */
197}
198
199static void
200btrfs_print_qgroup_inherit(struct btrfs_qgroup_inherit *inherit)
201{
202 printf("{flags=");
203 printflags(btrfs_qgroup_inherit_flags, inherit->flags,
204 "BTRFS_QGROUP_INHERIT_???");
205 printf(", num_qgroups=%" PRI__u64
206 ", num_ref_copies=%" PRI__u64
207 ", num_excl_copies=%" PRI__u64", lim={flags=",
208 inherit->num_qgroups, inherit->num_ref_copies,
209 inherit->num_excl_copies);
210 printflags(btrfs_qgroup_limit_flags,
211 inherit->lim.flags,
212 "BTRFS_QGROUP_LIMIT_???");
213 printf(", max_rfer=%" PRI__u64 ", max_excl=%" PRI__u64
214 ", rsv_rfer=%" PRI__u64 ", rsv_excl=%" PRI__u64
215 "}, qgroups=",
216 inherit->lim.max_rfer, inherit->lim.max_excl,
217 inherit->lim.rsv_rfer, inherit->lim.rsv_excl);
218 if (verbose) {
219 unsigned int i;
220 printf("[");
221 for (i = 0; i < inherit->num_qgroups; i++) {
222 if (i > 0)
223 printf(", ");
224 printf("%" PRI__u64, inherit->qgroups[i]);
225 }
226 printf("]");
227 } else
228 printf("...");
229 printf("}");
230}
231
232
233static void
234btrfs_print_vol_args_v2(struct btrfs_ioctl_vol_args_v2 *args, int print_qgroups)
235{
236 printf("{fd=%lld, flags=", args->fd);
237 printflags(btrfs_snap_flags_v2, args->flags, "BTRFS_SUBVOL_???");
238
239 if (args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
240 printf(", size=%" PRI__u64 ", qgroup_inherit=", args->size);
241 if (args->qgroup_inherit && print_qgroups)
242 btrfs_print_qgroup_inherit(args->qgroup_inherit);
243 else if (args->qgroup_inherit)
244 printf("%p", args->qgroup_inherit);
245 else
246 printf("NULL");
247 }
248 printf(", name=\"%s\"}", args->name);
249}
250
251/*
252 * Consumes argument, returns nothing:
253 * - BTRFS_IOC_SNAP_CREATE
254 * - BTRFS_IOC_SUBVOL_CREATE
255 * - BTRFS_IOC_SNAP_DESTROY
256 * - BTRFS_IOC_DEFAULT_SUBVOL
257 *
258 * Consumes argument, returns u64:
259 * - BTRFS_IOC_SNAP_CREATE_V2
260 * - BTRFS_IOC_SUBVOL_CREATE_V2
261 */
262
263static void
264btrfs_test_subvol_ioctls(void)
265{
266 const char *subvol_name = "subvol-name";
267 char *long_subvol_name;
268 void *bad_pointer = (void *)0xdeadbeef;
269 uint64_t u64val = 0xdeadbeef;
270 struct btrfs_ioctl_vol_args vol_args = {};
271 struct btrfs_ioctl_vol_args_v2 vol_args_v2 = {
272 .fd = 2,
273 .flags = max_flags_plus_one(2),
274 };
Jeff Mahoney35866792016-05-18 18:09:42 -0400275
276 long_subvol_name = malloc(BTRFS_PATH_NAME_MAX);
277 if (!long_subvol_name)
278 perror_msg_and_fail("malloc failed");
279 memset(long_subvol_name, 'f', BTRFS_PATH_NAME_MAX);
280 long_subvol_name[BTRFS_PATH_NAME_MAX - 1] = '\0';
281
282 strcpy(vol_args.name, subvol_name);
283
284 ioctl(-1, BTRFS_IOC_SNAP_CREATE, NULL);
285 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE, NULL) = -1 EBADF (%m)\n");
286
287 ioctl(-1, BTRFS_IOC_SNAP_CREATE, &vol_args);
288 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE, "
289 "{fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
290
291 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE, &vol_args);
292 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE, "
293 "{fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
294
295 ioctl(-1, BTRFS_IOC_SNAP_DESTROY, &vol_args);
296 printf("ioctl(-1, BTRFS_IOC_SNAP_DESTROY,"
297 " {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
298
299 strncpy(vol_args.name, long_subvol_name, BTRFS_PATH_NAME_MAX);
300 ioctl(-1, BTRFS_IOC_SNAP_CREATE, &vol_args);
301 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE,"
302 " {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
303
304 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE, &vol_args);
305 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE,"
306 " {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
307
308 ioctl(-1, BTRFS_IOC_SNAP_DESTROY, &vol_args);
309 printf("ioctl(-1, BTRFS_IOC_SNAP_DESTROY,"
310 " {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n", vol_args.name);
311
312 long_subvol_name = realloc(long_subvol_name, BTRFS_SUBVOL_NAME_MAX);
313 if (!long_subvol_name)
314 perror_msg_and_fail("realloc failed");
315
316 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, NULL);
317 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, NULL) = -1 EBADF (%m)\n");
318
319 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, NULL);
320 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, NULL) = -1 EBADF (%m)\n");
321
322 strcpy(vol_args_v2.name, subvol_name);
323 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, ");
324 btrfs_print_vol_args_v2(&vol_args_v2, 1);
325 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
326 printf(") = -1 EBADF (%m)\n");
327
328 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, ");
329 btrfs_print_vol_args_v2(&vol_args_v2, 1);
330 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
331 printf(") = -1 EBADF (%m)\n");
332
333 strncpy(vol_args_v2.name, long_subvol_name, BTRFS_SUBVOL_NAME_MAX);
334 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, ");
335 btrfs_print_vol_args_v2(&vol_args_v2, 1);
336 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
337 printf(") = -1 EBADF (%m)\n");
338
Jeff Mahoney35866792016-05-18 18:09:42 -0400339 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, ");
340 btrfs_print_vol_args_v2(&vol_args_v2, 1);
341 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
342 printf(") = -1 EBADF (%m)\n");
343
344 strcpy(vol_args_v2.name, subvol_name);
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000345 vol_args_v2.qgroup_inherit = bad_pointer;
Jeff Mahoney35866792016-05-18 18:09:42 -0400346
Jeff Mahoney35866792016-05-18 18:09:42 -0400347 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, ");
348 btrfs_print_vol_args_v2(&vol_args_v2, 0);
349 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
350 printf(") = -1 EBADF (%m)\n");
351
Jeff Mahoney35866792016-05-18 18:09:42 -0400352 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, ");
353 btrfs_print_vol_args_v2(&vol_args_v2, 0);
354 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
355 printf(") = -1 EBADF (%m)\n");
356
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000357 const unsigned int n_qgroups = 8;
358 unsigned int i;
359 struct btrfs_qgroup_inherit *inherit;
360 vol_args_v2.size =
361 sizeof(*inherit) + n_qgroups * sizeof(inherit->qgroups[0]);
362 inherit = tail_alloc(vol_args_v2.size);
Jeff Mahoney35866792016-05-18 18:09:42 -0400363
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000364 inherit->flags = 0x3;
365 inherit->num_ref_copies = 0;
366 inherit->num_excl_copies = 0;
367 inherit->num_qgroups = n_qgroups;
368 for (i = 0; i < n_qgroups; i++)
369 inherit->qgroups[i] = 1ULL << i;
370 inherit->lim.flags = 0x7f;
371 inherit->lim.max_rfer = u64val;
372 inherit->lim.max_excl = u64val;
373 inherit->lim.rsv_rfer = u64val;
374 inherit->lim.rsv_excl = u64val;
375 vol_args_v2.qgroup_inherit = inherit;
Jeff Mahoney35866792016-05-18 18:09:42 -0400376
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000377 printf("ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, ");
378 btrfs_print_vol_args_v2(&vol_args_v2, 1);
379 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
380 printf(") = -1 EBADF (%m)\n");
Jeff Mahoney35866792016-05-18 18:09:42 -0400381
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000382 printf("ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, ");
383 btrfs_print_vol_args_v2(&vol_args_v2, 1);
384 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
385 printf(") = -1 EBADF (%m)\n");
Jeff Mahoney35866792016-05-18 18:09:42 -0400386
387 ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, NULL);
388 printf("ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, NULL) = -1 EBADF (%m)\n");
389
390 ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, &u64val);
391 printf("ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, [%"
392 PRIu64 "]) = -1 EBADF (%m)\n", u64val);
393
394 printf("ioctl(-1, BTRFS_IOC_SUBVOL_SETFLAGS, ");
395 printflags(btrfs_snap_flags_v2, vol_args_v2.flags,
396 "BTRFS_SUBVOL_???");
397 ioctl(-1, BTRFS_IOC_SUBVOL_SETFLAGS, &vol_args_v2.flags);
398 printf(") = -1 EBADF (%m)\n");
399
400 if (write_ok) {
401 struct btrfs_ioctl_vol_args_v2 args_passed;
402 /*
403 * Returns transid if flags & BTRFS_SUBVOL_CREATE_ASYNC
404 * - BTRFS_IOC_SNAP_CREATE_V2
405 * - BTRFS_IOC_SUBVOL_CREATE_V2
406 */
407 int subvolfd;
408
409 strncpy(vol_args_v2.name, subvol_name,
410 sizeof(vol_args_v2.name));
411 vol_args_v2.flags = BTRFS_SUBVOL_CREATE_ASYNC;
412 vol_args_v2.size = 0;
413 vol_args_v2.qgroup_inherit = NULL;
414 args_passed = vol_args_v2;
415 printf("ioctl(%d, BTRFS_IOC_SUBVOL_CREATE_V2, ",
416 btrfs_test_dir_fd);
417 btrfs_print_vol_args_v2(&vol_args_v2, 1);
418 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SUBVOL_CREATE_V2,
419 &args_passed);
420 printf(" => {transid=%" PRI__u64"}) = 0\n",
421 args_passed.transid);
422
423 subvolfd = openat(btrfs_test_dir_fd, subvol_name,
424 O_RDONLY|O_DIRECTORY);
425 if (subvolfd < 0)
426 perror_msg_and_fail("openat(%s) failed", subvol_name);
427
428 strncpy(vol_args_v2.name, long_subvol_name, BTRFS_NAME_LEN);
429 vol_args_v2.fd = subvolfd;
430 args_passed = vol_args_v2;
431 printf("ioctl(%d, BTRFS_IOC_SNAP_CREATE_V2, ",
432 btrfs_test_dir_fd);
433 btrfs_print_vol_args_v2(&args_passed, 1);
434 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_CREATE_V2,
435 &args_passed);
436 printf(" => {transid=%" PRI__u64"}) = 0\n",
437 args_passed.transid);
438
439 /* This only works when mounted w/ -ouser_subvol_rm_allowed */
440 strncpy(vol_args.name, long_subvol_name, 255);
441 vol_args.name[255] = 0;
442 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_DESTROY, &vol_args);
443 printf("ioctl(%d, BTRFS_IOC_SNAP_DESTROY, "
444 "{fd=%lld, name=\"%.*s\"}) = 0\n",
445 btrfs_test_dir_fd, vol_args.fd, 255, long_subvol_name);
446
447 strcpy(vol_args.name, subvol_name);
448 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_DESTROY, &vol_args);
449 printf("ioctl(%d, BTRFS_IOC_SNAP_DESTROY, "
450 "{fd=%lld, name=\"%s\"}) = 0\n",
451 btrfs_test_dir_fd, vol_args.fd, subvol_name);
452
453 close(subvolfd);
454 }
455 free(long_subvol_name);
456}
457
458static void
459btrfs_print_balance_args(struct btrfs_balance_args *args)
460{
461 printf("{profiles=");
462 printflags(btrfs_space_info_flags, args->profiles,
463 "BTRFS_BLOCK_GROUP_???");
464 printf(", usage=%"PRI__u64 "%s, devid=%"PRI__u64 "%s, pstart=%"PRI__u64
465 "%s, pend=%"PRI__u64 "%s, vstart=%"PRI__u64 "%s, vend=%"PRI__u64
466 "%s, target=%"PRI__u64 "%s, flags=",
467 args->usage, maybe_print_uint64max(args->usage),
468 args->devid, maybe_print_uint64max(args->devid),
469 args->pstart, maybe_print_uint64max(args->pstart),
470 args->pend, maybe_print_uint64max(args->pend),
471 args->vstart, maybe_print_uint64max(args->vstart),
472 args->vend, maybe_print_uint64max(args->vend),
473 args->target, maybe_print_uint64max(args->target));
474 printflags(btrfs_balance_args, args->flags, "BTRFS_BALANCE_ARGS_???");
475 printf("}");
476}
477
478/*
479 * Accepts argument, returns nothing
480 * - BTRFS_IOC_BALANCE
481 * - BTRFS_IOC_BALANCE_CTL
482 *
483 * Accepts argument, returns argument
484 * - BTRFS_IOC_BALANCE_V2
485 */
486static void
487btrfs_test_balance_ioctls(void)
488{
489 struct btrfs_ioctl_balance_args args = {
490 .flags = 0x3f,
491 .data = {
492 .profiles = 0x7,
493 .flags = 0x7,
494 .devid = 1,
495 .pend = -1ULL,
496 .vend = -1ULL,
497 },
498
499 .meta = {
500 .profiles = 0x38,
501 .flags = 0x38,
502 .devid = 1,
503 },
504
505 .sys = {
506 .profiles = 0x1c0 | (1ULL << 48),
507 .flags = 0x4c0,
508 .devid = 1,
509 },
510 };
511 struct btrfs_ioctl_vol_args vol_args = {};
512
513 ioctl(-1, BTRFS_IOC_BALANCE_CTL, 1);
514 printf("ioctl(-1, BTRFS_IOC_BALANCE_CTL, "
515 "BTRFS_BALANCE_CTL_PAUSE) = -1 EBADF (%m)\n");
516
517 ioctl(-1, BTRFS_IOC_BALANCE_CTL, 2);
518 printf("ioctl(-1, BTRFS_IOC_BALANCE_CTL, "
519 "BTRFS_BALANCE_CTL_CANCEL) = -1 EBADF (%m)\n");
520
521 ioctl(-1, BTRFS_IOC_BALANCE, NULL);
522 printf("ioctl(-1, BTRFS_IOC_BALANCE) = -1 EBADF (%m)\n");
523
524 ioctl(-1, BTRFS_IOC_BALANCE, &vol_args);
525 printf("ioctl(-1, BTRFS_IOC_BALANCE) = -1 EBADF (%m)\n");
526
527 /* struct btrfs_ioctl_balance_args */
528 ioctl(-1, BTRFS_IOC_BALANCE_V2, NULL);
529 printf("ioctl(-1, BTRFS_IOC_BALANCE_V2, NULL) = -1 EBADF (%m)\n");
530
531 printf("ioctl(-1, BTRFS_IOC_BALANCE_V2, {flags=");
532 printflags(btrfs_balance_flags, args.flags, "BTRFS_BALANCE_???");
533 printf(", data=");
534 btrfs_print_balance_args(&args.data);
535 printf(", meta=");
536 btrfs_print_balance_args(&args.meta);
537 printf(", sys=");
538 btrfs_print_balance_args(&args.sys);
539 ioctl(-1, BTRFS_IOC_BALANCE_V2, &args);
540 printf("}) = -1 EBADF (%m)\n");
541
542 if (write_ok) {
543 args.flags = BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA |
544 BTRFS_BALANCE_SYSTEM;
545 args.data.flags = 0;
546 args.data.profiles = 0;
547 args.meta.flags = 0;
548 args.meta.profiles = 0;
549 args.sys.flags = 0;
550 args.sys.profiles = 0;
551 printf("ioctl(%d, BTRFS_IOC_BALANCE_V2, {flags=",
552 btrfs_test_dir_fd);
553
554 printflags(btrfs_balance_flags, args.flags,
555 "BTRFS_BALANCE_???");
556 printf(", data=");
557 btrfs_print_balance_args(&args.data);
558 printf(", meta=");
559 btrfs_print_balance_args(&args.meta);
560 printf(", sys=");
561 btrfs_print_balance_args(&args.sys);
562 ioctl(btrfs_test_dir_fd, BTRFS_IOC_BALANCE_V2, &args);
563 printf("} => {flags=");
564 printflags(btrfs_balance_flags, args.flags,
565 "BTRFS_BALANCE_???");
566 printf(", state=");
567 printflags(btrfs_balance_state, args.state,
568 "BTRFS_BALANCE_STATE_???");
569 printf(", data=");
570 btrfs_print_balance_args(&args.data);
571 printf(", meta=");
572 btrfs_print_balance_args(&args.meta);
573 printf(", sys=");
574 btrfs_print_balance_args(&args.sys);
575 printf("}) = 0\n");
576 }
577}
578
579/*
580 * Consumes argument, returns nothing:
581 * - BTRFS_IOC_RESIZE
582 *
583 * Requires /dev/btrfs-control, consumes argument, returns nothing:
584 * - BTRFS_IOC_SCAN_DEV
585 * - BTRFS_IOC_DEVICES_READY
586 *
587 */
588static void
589btrfs_test_device_ioctls(void)
590{
591 const char *devid = "1";
592 const char *devname = "/dev/sda1";
593 struct btrfs_ioctl_vol_args args = {
594 .fd = 2,
595 };
596
597 ioctl(-1, BTRFS_IOC_RESIZE, NULL);
598 printf("ioctl(-1, BTRFS_IOC_RESIZE, NULL) = -1 EBADF (%m)\n");
599
600 strcpy(args.name, devid);
601 ioctl(-1, BTRFS_IOC_RESIZE, &args);
602 printf("ioctl(-1, BTRFS_IOC_RESIZE, "
603 "{fd=%lld, name=\"%s\"}) = -1 EBADF (%m)\n",
604 args.fd, args.name);
605
606 ioctl(-1, BTRFS_IOC_SCAN_DEV, NULL);
607 printf("ioctl(-1, BTRFS_IOC_SCAN_DEV, NULL) = -1 EBADF (%m)\n");
608
609 strcpy(args.name, devname);
610 ioctl(-1, BTRFS_IOC_SCAN_DEV, &args);
611 printf("ioctl(-1, BTRFS_IOC_SCAN_DEV, "
612 "{fd=%lld, name=\"%s\"}) = -1 EBADF (%m)\n",
613 args.fd, args.name);
614
615 ioctl(-1, BTRFS_IOC_ADD_DEV, NULL);
616 printf("ioctl(-1, BTRFS_IOC_ADD_DEV, NULL) = -1 EBADF (%m)\n");
617
618 ioctl(-1, BTRFS_IOC_ADD_DEV, &args);
619 printf("ioctl(-1, BTRFS_IOC_ADD_DEV, "
620 "{fd=%lld, name=\"%s\"}) = -1 EBADF (%m)\n",
621 args.fd, args.name);
622
623 ioctl(-1, BTRFS_IOC_RM_DEV, NULL);
624 printf("ioctl(-1, BTRFS_IOC_RM_DEV, NULL) = -1 EBADF (%m)\n");
625
626 ioctl(-1, BTRFS_IOC_RM_DEV, &args);
627 printf("ioctl(-1, BTRFS_IOC_RM_DEV, "
628 "{fd=%lld, name=\"%s\"}) = -1 EBADF (%m)\n",
629 args.fd, args.name);
630
631}
632
633/*
634 * Consumes argument, returns nothing:
635 * - BTRFS_IOC_CLONE
636 * - BTRFS_IOC_CLONE_RANGE
637 */
638static void
639btrfs_test_clone_ioctls(void)
640{
641 int clone_fd = 4;
642 struct btrfs_ioctl_clone_range_args args = {
643 .src_fd = clone_fd,
644 .src_offset = 4096,
645 .src_length = 16384,
646 .dest_offset = 128 * 1024,
647 };
648
649 ioctl(-1, BTRFS_IOC_CLONE, clone_fd);
650 printf("ioctl(-1, BTRFS_IOC_CLONE or FICLONE, %x) = -1 EBADF (%m)\n",
651 clone_fd);
652
653 ioctl(-1, BTRFS_IOC_CLONE_RANGE, NULL);
654 printf("ioctl(-1, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, "
655 "NULL) = -1 EBADF (%m)\n");
656
657 ioctl(-1, BTRFS_IOC_CLONE_RANGE, &args);
658 printf("ioctl(-1, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, "
659 "{src_fd=%lld, src_offset=%llu, src_length=%llu, dest_offset=%llu}) = -1 EBADF (%m)\n",
660 args.src_fd, args.src_offset, args.src_length,
661 args.dest_offset);
662}
663
664#define BTRFS_COMPRESS_TYPES 2
665#define BTRFS_INVALID_COMPRESS (BTRFS_COMPRESS_TYPES + 1)
666
667static void
668btrfs_print_defrag_range_args(struct btrfs_ioctl_defrag_range_args *args)
669{
670 printf("{start=%" PRIu64", len=%" PRIu64 "%s, flags=",
671 args->start, args->len, maybe_print_uint64max(args->len));
672
673 printflags(btrfs_defrag_flags, args->flags, "BTRFS_DEFRAG_RANGE_???");
674 printf(", extent_thresh=%u, compress_type=", args->extent_thresh);
675 printxval(btrfs_compress_types, args->compress_type,
676 "BTRFS_COMPRESS_???");
677 printf("}");
678}
679
680/*
681 * Consumes argument, returns nothing:
682 * - BTRFS_IOC_DEFRAG
683 * - BTRFS_DEFRAG_RANGE
684 */
685static void
686btrfs_test_defrag_ioctls(void)
687{
688 struct btrfs_ioctl_vol_args vol_args = {};
689 struct btrfs_ioctl_defrag_range_args args = {
690 .start = 0,
691 .len = -1ULL,
692 .flags = max_flags_plus_one(1),
693 .extent_thresh = 128 * 1024,
694 .compress_type = 2, /* BTRFS_COMPRESS_LZO */
695 };
696
697 /*
698 * These are documented as using vol_args but don't
699 * actually consume it.
700 */
701 ioctl(-1, BTRFS_IOC_DEFRAG, NULL);
702 printf("ioctl(-1, BTRFS_IOC_DEFRAG) = -1 EBADF (%m)\n");
703
704 ioctl(-1, BTRFS_IOC_DEFRAG, &vol_args);
705 printf("ioctl(-1, BTRFS_IOC_DEFRAG) = -1 EBADF (%m)\n");
706
707 /* struct btrfs_ioctl_defrag_range_args */
708 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, NULL);
709 printf("ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, NULL) = -1 EBADF (%m)\n");
710
711 printf("ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, ");
712 btrfs_print_defrag_range_args(&args);
713 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
714 printf(") = -1 EBADF (%m)\n");
715
716 args.compress_type = BTRFS_INVALID_COMPRESS;
717 printf("ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, ");
718 btrfs_print_defrag_range_args(&args);
719 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
720 printf(") = -1 EBADF (%m)\n");
721
722 args.len--;
723 printf("ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, ");
724 btrfs_print_defrag_range_args(&args);
725 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
726 printf(") = -1 EBADF (%m)\n");
727}
728
729static const char *
730xlookup(const struct xlat *xlat, const uint64_t val)
731{
732 for (; xlat->str != NULL; xlat++)
733 if (xlat->val == val)
734 return xlat->str;
735 return NULL;
736}
737
738static void
739btrfs_print_objectid(uint64_t objectid)
740{
741 const char *str = xlookup(btrfs_tree_objectids, objectid);
742 printf("%" PRIu64, objectid);
743 if (str)
744 printf(" /* %s */", str);
745}
746
747static void
748btrfs_print_key_type(uint32_t type)
749{
750 const char *str = xlookup(btrfs_key_types, type);
751 printf("%u", type);
752 if (str)
753 printf(" /* %s */", str);
754}
755
756static void
757btrfs_print_search_key(struct btrfs_ioctl_search_key *key)
758{
759 printf("key={tree_id=");
760 btrfs_print_objectid(key->tree_id);
761 if (verbose || key->min_objectid != 256) {
762 printf(", min_objectid=");
763 btrfs_print_objectid(key->min_objectid);
764 }
765 if (verbose || key->max_objectid != -256ULL) {
766 printf(", max_objectid=");
767 btrfs_print_objectid(key->max_objectid);
768 }
769 if (key->min_offset)
770 printf(", min_offset=%" PRI__u64 "%s",
771 key->min_offset, maybe_print_uint64max(key->min_offset));
772 if (key->max_offset)
773 printf(", max_offset=%" PRI__u64 "%s",
774 key->max_offset, maybe_print_uint64max(key->max_offset));
775 if (key->min_transid)
776 printf(", min_transid=%" PRI__u64"%s", key->min_transid,
777 maybe_print_uint64max(key->min_transid));
778 if (key->max_transid)
779 printf(", max_transid=%" PRI__u64"%s", key->max_transid,
780 maybe_print_uint64max(key->max_transid));
781 printf(", min_type=");
782 btrfs_print_key_type(key->min_type);
783 printf(", max_type=");
784 btrfs_print_key_type(key->max_type);
785 printf(", nr_items=%u}", key->nr_items);
786}
787
788static void
789btrfs_print_tree_search_buf(struct btrfs_ioctl_search_key *key,
790 void *buf, uint64_t buf_size)
791{
792 if (verbose) {
793 uint64_t i;
794 uint64_t off = 0;
795 printf("[");
796 for (i = 0; i < key->nr_items; i++) {
797 struct btrfs_ioctl_search_header *sh;
798 sh = (typeof(sh))(buf + off);
799 if (i)
800 printf(", ");
801 printf("{transid=%" PRI__u64 ", objectid=",
802 sh->transid);
803 btrfs_print_objectid(sh->objectid);
804 printf(", offset=%" PRI__u64 ", type=", sh->offset);
805 btrfs_print_key_type(sh->type);
806 printf(", len=%u}", sh->len);
807 off += sizeof(*sh) + sh->len;
808 }
809 printf("]");
810 } else
811 printf("...");
812}
813
814/*
815 * Consumes argument, returns argument:
816 * - BTRFS_IOC_TREE_SEARCH
817 * - BTRFS_IOC_TREE_SEARCH_V2
818 */
819static void
820btrfs_test_search_ioctls(void)
821{
822 struct btrfs_ioctl_search_key key_reference = {
823 .tree_id = 5,
824 .min_objectid = 256,
825 .max_objectid = -1ULL,
826 .min_offset = 0,
827 .max_offset = -1ULL,
828 .min_transid = 0,
829 .max_transid = -1ULL,
830 .min_type = 0,
831 .max_type = -1U,
832 .nr_items = 10,
833 };
834 struct btrfs_ioctl_search_args search_args;
835 struct btrfs_ioctl_search_args_v2 search_args_v2 = {
836 .buf_size = 4096,
837 };
838
839 ioctl(-1, BTRFS_IOC_TREE_SEARCH, NULL);
840 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, NULL) = -1 EBADF (%m)\n");
841
842 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, NULL);
843 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, NULL) = -1 EBADF (%m)\n");
844
845 search_args_v2.key = key_reference;
846 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, {");
847 btrfs_print_search_key(&search_args.key);
848 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
849 printf("}) = -1 EBADF (%m)\n");
850
851 search_args_v2.key = key_reference;
852 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, {");
853 btrfs_print_search_key(&search_args_v2.key);
854 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
855 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
856 (uint64_t)search_args_v2.buf_size);
857
858 key_reference.min_objectid = 6;
859 key_reference.max_objectid = 7;
860 search_args_v2.key = key_reference;
861 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, {");
862 btrfs_print_search_key(&search_args.key);
863 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
864 printf("}) = -1 EBADF (%m)\n");
865
866 search_args_v2.key = key_reference;
867 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, {");
868 btrfs_print_search_key(&search_args_v2.key);
869 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
870 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
871 (uint64_t)search_args_v2.buf_size);
872
873 key_reference.min_offset++;
874 key_reference.max_offset--;
875 search_args_v2.key = key_reference;
876 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, {");
877 btrfs_print_search_key(&search_args.key);
878 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
879 printf("}) = -1 EBADF (%m)\n");
880
881 search_args_v2.key = key_reference;
882 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, {");
883 btrfs_print_search_key(&search_args_v2.key);
884 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
885 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
886 (uint64_t)search_args_v2.buf_size);
887
888 key_reference.min_transid++;
889 key_reference.max_transid--;
890 search_args_v2.key = key_reference;
891 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, {");
892 btrfs_print_search_key(&search_args.key);
893 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
894 printf("}) = -1 EBADF (%m)\n");
895
896 search_args_v2.key = key_reference;
897 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, {");
898 btrfs_print_search_key(&search_args_v2.key);
899 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
900 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
901 (uint64_t)search_args_v2.buf_size);
902
903 key_reference.min_type = 1;
904 key_reference.max_type = 12;
905 search_args_v2.key = key_reference;
906 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH, {");
907 btrfs_print_search_key(&search_args.key);
908 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
909 printf("}) = -1 EBADF (%m)\n");
910
911 search_args_v2.key = key_reference;
912 printf("ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, {");
913 btrfs_print_search_key(&search_args_v2.key);
914 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
915 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
916 (uint64_t)search_args_v2.buf_size);
917
918 if (btrfs_test_root) {
919 struct btrfs_ioctl_search_args_v2 *args;
920 int bufsize = 4096;
921
922 key_reference.tree_id = 5;
923 key_reference.min_type = 1;
924 key_reference.max_type = 1;
925 key_reference.min_objectid = 256;
926 key_reference.max_objectid = 357;
927 key_reference.min_offset = 0;
928 key_reference.max_offset = -1ULL;
929
930 search_args.key = key_reference;
931 printf("ioctl(%d, BTRFS_IOC_TREE_SEARCH, {",
932 btrfs_test_dir_fd);
933 btrfs_print_search_key(&search_args.key);
934 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH, &search_args);
935 printf("} => {key={nr_items=%u}, buf=...}) = 0\n",
936 search_args.key.nr_items);
937
938 args = malloc(sizeof(*args) + bufsize);
939 if (!args)
940 perror_msg_and_fail("malloc failed");
941
942 args->key = key_reference;
943 args->buf_size = bufsize;
944 printf("ioctl(%d, BTRFS_IOC_TREE_SEARCH_V2, {",
945 btrfs_test_dir_fd);
946 btrfs_print_search_key(&key_reference);
947 printf(", buf_size=%" PRIu64 "}", (uint64_t) args->buf_size);
948 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH_V2, args);
949 printf(" => {key={nr_items=%u}, buf_size=%" PRIu64 ", buf=",
950 args->key.nr_items, (uint64_t)args->buf_size);
951 btrfs_print_tree_search_buf(&args->key, args->buf,
952 args->buf_size);
953 printf("}) = 0\n");
954
955 args->key = key_reference;
956 args->buf_size = sizeof(struct btrfs_ioctl_search_header);
957 printf("ioctl(%d, BTRFS_IOC_TREE_SEARCH_V2, {",
958 btrfs_test_dir_fd);
959 btrfs_print_search_key(&args->key);
960 printf(", buf_size=%" PRIu64 "}", (uint64_t)args->buf_size);
961 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH_V2, args);
962 printf("=> {buf_size=%" PRIu64 "}) = -1 EOVERFLOW (%m)\n",
963 (uint64_t)args->buf_size);
964 free(args);
965 }
966}
967
968/*
969 * Consumes argument, returns argument:
970 * - BTRFS_IOC_INO_LOOKUP
971 */
972static void
973btrfs_test_ino_lookup_ioctl(void)
974{
975 struct btrfs_ioctl_ino_lookup_args args = {
976 .treeid = 5,
977 .objectid = 256,
978 };
979
980 ioctl(-1, BTRFS_IOC_INO_LOOKUP, NULL);
981 printf("ioctl(-1, BTRFS_IOC_INO_LOOKUP, NULL) = -1 EBADF (%m)\n");
982
983 printf("ioctl(-1, BTRFS_IOC_INO_LOOKUP, {treeid=");
984 btrfs_print_objectid(args.treeid);
985 printf(", objectid=");
986 btrfs_print_objectid(args.objectid);
987 ioctl(-1, BTRFS_IOC_INO_LOOKUP, &args);
988 printf("}) = -1 EBADF (%m)\n");
989
990 if (btrfs_test_root) {
991 printf("ioctl(%d, BTRFS_IOC_INO_LOOKUP, {treeid=",
992 btrfs_test_dir_fd);
993 btrfs_print_objectid(args.treeid);
994 printf(", objectid=");
995 btrfs_print_objectid(args.objectid);
996 ioctl(btrfs_test_dir_fd, BTRFS_IOC_INO_LOOKUP, &args);
997 printf("} => {name=\"%s\"}) = 0\n", args.name);
998 }
999}
1000
1001/*
1002 * Consumes argument, returns argument:
1003 * - BTRFS_IOC_SPACE_INFO
1004 */
1005static void
1006btrfs_test_space_info_ioctl(void)
1007{
1008 struct btrfs_ioctl_space_args args = {};
1009
1010 ioctl(-1, BTRFS_IOC_SPACE_INFO, NULL);
1011 printf("ioctl(-1, BTRFS_IOC_SPACE_INFO, NULL) = -1 EBADF (%m)\n");
1012
1013 ioctl(-1, BTRFS_IOC_SPACE_INFO, &args);
1014 printf("ioctl(-1, BTRFS_IOC_SPACE_INFO, "
1015 "{space_slots=%" PRI__u64 "}) = -1 EBADF (%m)\n",
1016 args.space_slots);
1017
1018 if (btrfs_test_root) {
1019 struct btrfs_ioctl_space_args args_passed;
1020 struct btrfs_ioctl_space_args *argsp;
1021 args_passed = args;
1022 printf("ioctl(%d, BTRFS_IOC_SPACE_INFO, "
1023 "{space_slots=%" PRI__u64 "}",
1024 btrfs_test_dir_fd, args_passed.space_slots);
1025 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SPACE_INFO, &args_passed);
1026 printf(" => {total_spaces=%" PRI__u64 "}) = 0\n",
1027 args_passed.total_spaces);
1028
1029 argsp = malloc(sizeof(args) +
1030 args_passed.total_spaces * sizeof(args.spaces[0]));
1031 if (!argsp)
1032 perror_msg_and_fail("malloc failed");
1033
1034 *argsp = args;
1035 argsp->space_slots = args_passed.total_spaces;
1036 printf("ioctl(%d, BTRFS_IOC_SPACE_INFO, "
1037 "{space_slots=%" PRI__u64 "}",
1038 btrfs_test_dir_fd, argsp->space_slots);
1039 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SPACE_INFO, argsp);
1040 printf(" => {total_spaces=%" PRI__u64 ", spaces=",
1041 argsp->total_spaces);
1042 if (verbose) {
1043 unsigned int i;
1044 printf("[");
1045 for (i = 0; i < argsp->total_spaces; i++) {
1046 struct btrfs_ioctl_space_info *info;
1047 info = &argsp->spaces[i];
1048 if (i)
1049 printf(", ");
1050 printf("{flags=");
1051 printflags(btrfs_space_info_flags, info->flags,
1052 "BTRFS_SPACE_INFO_???");
1053 printf(", total_bytes=%" PRI__u64
1054 ", used_bytes=%" PRI__u64 "}",
1055 info->total_bytes, info->used_bytes);
1056 }
1057
1058 printf("]");
1059 } else
1060 printf("...");
1061 printf("}) = 0\n");
1062 free(argsp);
1063 }
1064}
1065
1066/*
1067 * Consumes no arguments, returns nothing:
1068 * - BTRFS_IOC_SCRUB_CANCEL
1069 * Consumes argument, returns argument:
1070 - * BTRFS_IOC_SCRUB
1071 - * BTRFS_IOC_SCRUB_PROGRESS
1072 */
1073static void
1074btrfs_test_scrub_ioctls(void)
1075{
1076 struct btrfs_ioctl_scrub_args args = {
1077 .devid = 1,
1078 .start = 0,
1079 .end = -1ULL,
1080 .flags = max_flags_plus_one(0),
1081 };
1082
1083 ioctl(-1, BTRFS_IOC_SCRUB, NULL);
1084 printf("ioctl(-1, BTRFS_IOC_SCRUB, NULL) = -1 EBADF (%m)\n");
1085
1086 ioctl(-1, BTRFS_IOC_SCRUB_CANCEL, NULL);
1087 printf("ioctl(-1, BTRFS_IOC_SCRUB_CANCEL) = -1 EBADF (%m)\n");
1088
1089 printf("ioctl(-1, BTRFS_IOC_SCRUB, {devid=%" PRI__u64 ", start=%"
1090 PRI__u64 "%s, end=%" PRI__u64"%s, flags=",
1091 args.devid, args.start, maybe_print_uint64max(args.start),
1092 args.end, maybe_print_uint64max(args.end));
1093 printflags(btrfs_scrub_flags, args.flags, "BTRFS_SCRUB_???");
1094 ioctl(-1, BTRFS_IOC_SCRUB, &args);
1095 printf("}) = -1 EBADF (%m)\n");
1096
1097 ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, NULL);
1098 printf("ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, NULL) = -1 EBADF (%m)\n");
1099
1100 ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, &args);
1101 printf("ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, "
1102 "{devid=%" PRI__u64 "}) = -1 EBADF (%m)\n", args.devid);
1103}
1104
1105/*
1106 * Consumes argument, returns argument:
1107 * - BTRFS_IOC_DEV_INFO
1108 */
1109static void
1110btrfs_test_dev_info_ioctl(void)
1111{
1112 struct btrfs_ioctl_dev_info_args args = {
1113 .devid = 1,
1114 };
1115 memcpy(&args.uuid, uuid_reference, BTRFS_UUID_SIZE);
1116
1117 ioctl(-1, BTRFS_IOC_DEV_INFO, NULL);
1118 printf("ioctl(-1, BTRFS_IOC_DEV_INFO, NULL) = -1 EBADF (%m)\n");
1119
1120 ioctl(-1, BTRFS_IOC_DEV_INFO, &args);
1121 printf("ioctl(-1, BTRFS_IOC_DEV_INFO, "
1122 "{devid=%" PRI__u64", uuid=%s}) = -1 EBADF (%m)\n",
1123 args.devid, uuid_reference_string);
1124}
1125
1126/*
1127 * Consumes argument, returns argument:
1128 * - BTRFS_IOC_INO_PATHS
1129 * - BTRFS_IOC_LOGICAL_INO
1130 */
1131static void
1132btrfs_test_ino_path_ioctls(void)
1133{
1134 char buf[16384];
1135 struct btrfs_ioctl_ino_path_args args = {
1136 .inum = 256,
1137 .size = sizeof(buf),
1138 .fspath = (unsigned long)buf,
1139 };
1140
1141 ioctl(-1, BTRFS_IOC_INO_PATHS, NULL);
1142 printf("ioctl(-1, BTRFS_IOC_INO_PATHS, NULL) = -1 EBADF (%m)\n");
1143
1144 ioctl(-1, BTRFS_IOC_LOGICAL_INO, NULL);
1145 printf("ioctl(-1, BTRFS_IOC_LOGICAL_INO, NULL) = -1 EBADF (%m)\n");
1146
1147 ioctl(-1, BTRFS_IOC_INO_PATHS, &args);
1148 printf("ioctl(-1, BTRFS_IOC_INO_PATHS, "
1149 "{inum=%" PRI__u64", size=%" PRI__u64
1150 ", fspath=0x%" PRI__x64 "}) = -1 EBADF (%m)\n",
1151 args.inum, args.size, args.fspath);
1152
1153 ioctl(-1, BTRFS_IOC_LOGICAL_INO, &args);
1154 printf("ioctl(-1, BTRFS_IOC_LOGICAL_INO, {logical=%" PRI__u64
1155 ", size=%" PRI__u64", inodes=0x%" PRI__x64
1156 "}) = -1 EBADF (%m)\n", args.inum, args.size, args.fspath);
1157
Dmitry V. Levin22129182016-05-24 01:32:09 +00001158#ifdef HAVE_LINUX_FIEMAP_H
Jeff Mahoney35866792016-05-18 18:09:42 -04001159 if (btrfs_test_root) {
1160 int size;
1161 struct stat si;
1162 int ret;
1163 struct btrfs_data_container *data = (void *)buf;
1164 struct fiemap *fiemap;
1165 int fd;
1166
1167 ret = fstat(btrfs_test_dir_fd, &si);
1168 if (ret)
1169 perror_msg_and_fail("fstat failed");
1170
1171 args.inum = si.st_ino;
1172 printf("ioctl(%d, BTRFS_IOC_INO_PATHS, "
1173 "{inum=%" PRI__u64", size=%" PRI__u64
1174 ", fspath=0x%" PRI__x64"}",
1175 btrfs_test_dir_fd, args.inum, args.size,
1176 args.fspath);
1177 ioctl(btrfs_test_dir_fd, BTRFS_IOC_INO_PATHS, &args);
1178 printf(" => {fspath={bytes_left=%u, bytes_missing=%u, elem_cnt=%u, elem_missed=%u, val=",
1179 data->bytes_left, data->bytes_missing, data->elem_cnt,
1180 data->elem_missed);
1181 if (verbose) {
1182 printf("[\"strace-test\"]");
1183 } else
1184 printf("...");
1185 printf("}}) = 0\n");
1186
1187 fd = openat(btrfs_test_dir_fd, "file1", O_RDWR|O_CREAT, 0600);
1188 if (fd < 0)
1189 perror_msg_and_fail("openat(file1) failed");
1190
1191 ret = fstat(fd, &si);
1192 if (ret)
1193 perror_msg_and_fail("fstat failed");
1194
1195 if (write(fd, buf, sizeof(buf)) < 0)
1196 perror_msg_and_fail("write: fd");
1197
1198 /*
1199 * Force delalloc so we can actually
1200 * search for the extent.
1201 */
1202 fsync(fd);
1203 ioctl(fd, BTRFS_IOC_SYNC, NULL);
1204 printf("ioctl(%d, BTRFS_IOC_SYNC) = 0\n", fd);
1205
1206 size = sizeof(*fiemap) + 2 * sizeof(fiemap->fm_extents[0]);
1207 fiemap = malloc(size);
1208 if (!fiemap)
1209 perror_msg_and_fail("malloc failed");
1210 memset(fiemap, 0, size);
1211
1212 fiemap->fm_length = sizeof(buf);
1213 fiemap->fm_extent_count = 2;
1214
1215 /* This is also a live test for FIEMAP */
1216 printf("ioctl(%d, FS_IOC_FIEMAP, {fm_start=%" PRI__u64
1217 ", fm_length=%" PRI__u64", fm_flags=",
1218 fd, fiemap->fm_start, fiemap->fm_length);
1219 printflags(fiemap_flags, fiemap->fm_flags, "FIEMAP_FLAG_???");
1220 printf(", fm_extent_count=%u}", fiemap->fm_extent_count);
1221 ioctl(fd, FS_IOC_FIEMAP, fiemap);
1222 printf(" => {fm_flags=");
1223 printflags(fiemap_flags, fiemap->fm_flags, "FIEMAP_FLAG_???");
1224 printf(", fm_mapped_extents=%u, fm_extents=",
1225 fiemap->fm_mapped_extents);
1226 if (verbose) {
1227 printf("[");
1228 unsigned int i;
1229 for (i = 0; i < fiemap->fm_mapped_extents; i++) {
1230 struct fiemap_extent *fe;
1231 fe = &fiemap->fm_extents[i];
1232 if (i)
1233 printf(", ");
1234 printf("{fe_logical=%" PRI__u64
1235 ", fe_physical=%" PRI__u64
1236 ", fe_length=%" PRI__u64
1237 ", ",
1238 fe->fe_logical, fe->fe_physical,
1239 fe->fe_length);
1240 printflags(fiemap_extent_flags, fe->fe_flags,
1241 "FIEMAP_EXTENT_???");
1242 printf("}");
1243 }
1244 printf("]");
1245 } else
1246 printf("...");
1247 printf("}) = 0\n");
1248
1249 args.inum = fiemap->fm_extents[0].fe_physical;
1250 printf("ioctl(%d, BTRFS_IOC_LOGICAL_INO, {logical=%" PRI__u64
1251 ", size=%" PRI__u64", inodes=0x%" PRI__x64"}",
1252 fd, args.inum, args.size, args.fspath);
1253 ioctl(fd, BTRFS_IOC_LOGICAL_INO, &args);
1254 printf(" => {inodes={bytes_left=%u, bytes_missing=%u, elem_cnt=%u, elem_missed=%u, val=",
1255 data->bytes_left, data->bytes_missing, data->elem_cnt,
1256 data->elem_missed);
1257 if (verbose) {
1258 printf("[{inum=%lu, offset=0, root=5}]",
1259 si.st_ino);
1260 } else
1261 printf("...");
1262 printf("}}) = 0\n");
1263 close(fd);
1264 free(fiemap);
1265 }
Dmitry V. Levin22129182016-05-24 01:32:09 +00001266#endif /* HAVE_LINUX_FIEMAP_H */
Jeff Mahoney35866792016-05-18 18:09:42 -04001267}
1268
1269/*
1270 * Consumes argument, returns argument:
1271 * - BTRFS_IOC_SET_RECEIVED_SUBVOL
1272 */
1273static void
1274btrfs_test_set_received_subvol_ioctl(void)
1275{
1276 struct btrfs_ioctl_received_subvol_args args = {
1277 .stransid = 0x12345,
1278 .stime = {
1279 .sec = 1463193386,
1280 .nsec = 12345,
1281 },
1282 };
1283 memcpy(&args.uuid, uuid_reference, BTRFS_UUID_SIZE);
1284
1285 ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, NULL);
1286 printf("ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, "
1287 "NULL) = -1 EBADF (%m)\n");
1288
1289 ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, &args);
1290 printf("ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, "
1291 "{uuid=%s, stransid=%" PRI__u64", stime=%" PRI__u64
1292 ".%u, flags=0}) = -1 EBADF (%m)\n",
1293 uuid_reference_string, args.stransid, args.stime.sec,
1294 args.stime.nsec);
1295}
1296
1297/*
1298 * Consumes argument, returns nothing (output is via send_fd)
1299 * - BTRFS_IOC_SEND
1300 */
1301static void
1302btrfs_test_send_ioctl(void)
1303{
1304 uint64_t u64_array[2] = { 256, 257 };
1305 struct btrfs_ioctl_send_args args = {
1306 .send_fd = 4,
1307 .parent_root = 257,
1308 .flags = max_flags_plus_one(2),
1309 };
1310
1311 ioctl(-1, BTRFS_IOC_SEND, NULL);
1312 printf("ioctl(-1, BTRFS_IOC_SEND, NULL) = -1 EBADF (%m)\n");
1313
1314 printf("ioctl(-1, BTRFS_IOC_SEND, "
1315 "{send_fd=%lld, clone_sources_count=%" PRI__u64
1316 ", clone_sources=", args.send_fd, args.clone_sources_count);
1317 if (verbose)
1318 printf("NULL");
1319 else
1320 printf("...");
1321 printf(", parent_root=");
1322 btrfs_print_objectid(args.parent_root);
1323 printf(", flags=");
1324 printflags(btrfs_send_flags, args.flags, "BTRFS_SEND_FLAGS_???");
1325 ioctl(-1, BTRFS_IOC_SEND, &args);
1326 printf("}) = -1 EBADF (%m)\n");
1327
1328 args.clone_sources_count = 2;
1329 args.clone_sources = (__u64 *)u64_array;
1330
1331 printf("ioctl(-1, BTRFS_IOC_SEND, "
1332 "{send_fd=%lld, clone_sources_count=%" PRI__u64
1333 ", clone_sources=", args.send_fd, args.clone_sources_count);
1334 if (verbose) {
1335 printf("[");
1336 btrfs_print_objectid(u64_array[0]);
1337 printf(", ");
1338 btrfs_print_objectid(u64_array[1]);
1339 printf("]");
1340 } else
1341 printf("...");
1342 printf(", parent_root=");
1343 btrfs_print_objectid(args.parent_root);
1344 printf(", flags=");
1345 printflags(btrfs_send_flags, args.flags, "BTRFS_SEND_FLAGS_???");
1346 ioctl(-1, BTRFS_IOC_SEND, &args);
1347 printf("}) = -1 EBADF (%m)\n");
1348}
1349
1350/*
1351 * Consumes argument, returns nothing:
1352 * - BTRFS_IOC_QUOTA_CTL
1353 */
1354static void
1355btrfs_test_quota_ctl_ioctl(void)
1356{
1357 struct btrfs_ioctl_quota_ctl_args args = {
1358 .cmd = 1,
1359 };
1360
1361 ioctl(-1, BTRFS_IOC_QUOTA_CTL, NULL);
1362 printf("ioctl(-1, BTRFS_IOC_QUOTA_CTL, NULL) = -1 EBADF (%m)\n");
1363
1364 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
1365 printf("ioctl(-1, BTRFS_IOC_QUOTA_CTL, "
1366 "BTRFS_QUOTA_CTL_ENABLE}) = -1 EBADF (%m)\n");
1367
1368 args.cmd = 2;
1369 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
1370 printf("ioctl(-1, BTRFS_IOC_QUOTA_CTL, "
1371 "BTRFS_QUOTA_CTL_DISABLE}) = -1 EBADF (%m)\n");
1372
1373 args.cmd = 3;
1374 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
1375 printf("ioctl(-1, BTRFS_IOC_QUOTA_CTL, "
1376 "BTRFS_QUOTA_CTL_RESCAN__NOTUSED}) = -1 EBADF (%m)\n");
1377
1378 args.cmd = 4;
1379 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
1380 printf("ioctl(-1, BTRFS_IOC_QUOTA_CTL, "
1381 "0x4 /* BTRFS_QUOTA_CTL_??? */}) = -1 EBADF (%m)\n");
1382}
1383
1384/*
1385 * Consumes argument, returns nothing:
1386 * - BTRFS_IOC_QGROUP_ASSIGN
1387 */
1388static void
1389btrfs_test_qgroup_assign_ioctl(void)
1390{
1391 struct btrfs_ioctl_qgroup_assign_args args = {
1392 .assign = 1,
1393 .src = 257,
1394 .dst = 258,
1395 };
1396
1397 ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, NULL);
1398 printf("ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, NULL) = -1 EBADF (%m)\n");
1399
1400 ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, &args);
1401 printf("ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, "
1402 "{assign=%" PRI__u64", src=%" PRI__u64", dst=%" PRI__u64
1403 "}) = -1 EBADF (%m)\n", args.assign, args.src, args.dst);
1404}
1405
1406/*
1407 * Consumes argument, returns nothing:
1408 * - BTRFS_IOC_QGROUP_CREATE
1409 */
1410static void
1411btrfs_test_qgroup_create_ioctl(void)
1412{
1413 struct btrfs_ioctl_qgroup_create_args args = {
1414 .create = 1,
1415 .qgroupid = 257,
1416 };
1417
1418 ioctl(-1, BTRFS_IOC_QGROUP_CREATE, NULL);
1419 printf("ioctl(-1, BTRFS_IOC_QGROUP_CREATE, NULL) = -1 EBADF (%m)\n");
1420
1421 ioctl(-1, BTRFS_IOC_QGROUP_CREATE, &args);
1422 printf("ioctl(-1, BTRFS_IOC_QGROUP_CREATE, "
1423 "{create=%" PRI__u64", qgroupid=%" PRI__u64
1424 "}) = -1 EBADF (%m)\n", args.create, args.qgroupid);
1425}
1426
1427/*
1428 * Consumes nothing, returns nothing:
1429 * - BTRFS_IOC_QUOTA_RESCAN_WAIT
1430 * Consumes argument, returns nothing:
1431 * - BTRFS_IOC_QUOTA_RESCAN
1432 */
1433static void
1434btrfs_test_quota_rescan_ioctl(void)
1435{
1436 struct btrfs_ioctl_quota_rescan_args args = {
1437 .progress = 1,
1438 };
1439
1440 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, NULL);
1441 printf("ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, NULL) = -1 EBADF (%m)\n");
1442
1443 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, &args);
1444 printf("ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, "
1445 "{flags=0}) = -1 EBADF (%m)\n");
1446 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN_WAIT, NULL);
1447 printf("ioctl(-1, BTRFS_IOC_QUOTA_RESCAN_WAIT) = -1 EBADF (%m)\n");
1448
1449}
1450
1451/*
1452 * Consumes argument, returns nothing:
1453 * - BTRFS_IOC_SET_FSLABEL
1454 *
1455 * Consumes no argument, returns argument:
1456 * - BTRFS_IOC_GET_FS_LABEL
1457 */
1458static void
1459btrfs_test_label_ioctls(void)
1460{
1461 char label[BTRFS_LABEL_SIZE] = "btrfs-label";
1462
1463 ioctl(-1, BTRFS_IOC_SET_FSLABEL, NULL);
1464 printf("ioctl(-1, BTRFS_IOC_SET_FSLABEL, NULL) = -1 EBADF (%m)\n");
1465
1466 ioctl(-1, BTRFS_IOC_SET_FSLABEL, label);
1467 printf("ioctl(-1, BTRFS_IOC_SET_FSLABEL, \"%s\") = -1 EBADF (%m)\n",
1468 label);
1469
1470 if (write_ok) {
1471 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SET_FSLABEL, label);
1472 printf("ioctl(%d, BTRFS_IOC_SET_FSLABEL, \"%s\") = 0\n",
1473 btrfs_test_dir_fd, label);
1474
1475 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_FSLABEL, label);
1476 printf("ioctl(%d, BTRFS_IOC_GET_FSLABEL, \"%s\") = 0\n",
1477 btrfs_test_dir_fd, label);
1478 }
1479}
1480
1481/*
1482 * Consumes argument, returns argument:
1483 * - BTRFS_IOC_GET_DEV_STATS
1484 */
1485static void
1486btrfs_test_get_dev_stats_ioctl(void)
1487{
1488 struct btrfs_ioctl_get_dev_stats args = {
1489 .devid = 1,
1490 .nr_items = 5,
1491 .flags = max_flags_plus_one(0),
1492 };
1493
1494 ioctl(-1, BTRFS_IOC_GET_DEV_STATS, NULL);
1495 printf("ioctl(-1, BTRFS_IOC_GET_DEV_STATS, NULL) = -1 EBADF (%m)\n");
1496
1497 printf("ioctl(-1, BTRFS_IOC_GET_DEV_STATS, {devid=%" PRI__u64
1498 ", nr_items=%" PRI__u64", flags=",
1499 args.devid, args.nr_items);
1500 printflags(btrfs_dev_stats_flags, args.flags,
1501 "BTRFS_DEV_STATS_???");
1502 ioctl(-1, BTRFS_IOC_GET_DEV_STATS, &args);
1503 printf("}) = -1 EBADF (%m)\n");
1504
1505 if (write_ok) {
1506 unsigned int i;
1507 args.flags = BTRFS_DEV_STATS_RESET;
1508 printf("ioctl(%d, BTRFS_IOC_GET_DEV_STATS, {devid=%" PRI__u64
1509 ", nr_items=%" PRI__u64", flags=",
1510 btrfs_test_dir_fd, args.devid, args.nr_items);
1511 printflags(btrfs_dev_stats_flags, args.flags,
1512 "BTRFS_DEV_STATS_???");
1513 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_DEV_STATS, &args);
1514 printf("} => {nr_items=%" PRI__u64 ", flags=",
1515 args.nr_items);
1516 printflags(btrfs_dev_stats_flags, args.flags,
1517 "BTRFS_DEV_STATS_???");
1518 printf(", [");
1519 for (i = 0; i < args.nr_items; i++) {
1520 const char *name = xlookup(btrfs_dev_stats_values, i);
1521 if (i)
1522 printf(", ");
1523 if (name)
1524 printf("/* %s */ ", name);
1525 printf("%" PRI__u64, args.values[i]);
1526 }
1527 printf("]}) = 0\n");
1528 }
1529}
1530
1531/*
1532 * Consumes argument, returns argument:
1533 * - BTRFS_IOC_DEV_REPLACE
1534 *
1535 * Test environment for this is more difficult; It's better to do it by hand.
1536 */
1537static void
1538btrfs_test_dev_replace_ioctl(void)
1539{
1540 struct btrfs_ioctl_dev_replace_args args = {
1541 .cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_START,
1542 .start = {
1543 .srcdevid = 1,
1544 },
1545 };
1546 strcpy((char *)args.start.srcdev_name, "/dev/sda1");
1547 strcpy((char *)args.start.tgtdev_name, "/dev/sdb1");
1548
1549 /* struct btrfs_ioctl_dev_replace_args */
1550 ioctl(-1, BTRFS_IOC_DEV_REPLACE, NULL);
1551 printf("ioctl(-1, BTRFS_IOC_DEV_REPLACE, NULL) = -1 EBADF (%m)\n");
1552
1553 ioctl(-1, BTRFS_IOC_DEV_REPLACE, &args);
1554 printf("ioctl(-1, BTRFS_IOC_DEV_REPLACE, "
1555 "{cmd=BTRFS_IOCTL_DEV_REPLACE_CMD_START, start={srcdevid=%"
1556 PRI__u64", cont_reading_from_srcdev_mode=%" PRI__u64
1557 ", srcdev_name=\"%s\", tgtdev_name=\"%s\"}}) = -1 EBADF (%m)\n",
1558 args.start.srcdevid,
1559 args.start.cont_reading_from_srcdev_mode,
1560 (char *)args.start.srcdev_name,
1561 (char *)args.start.tgtdev_name);
1562
1563 args.cmd = 1;
1564 ioctl(-1, BTRFS_IOC_DEV_REPLACE, &args);
1565 printf("ioctl(-1, BTRFS_IOC_DEV_REPLACE, "
1566 "{cmd=BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS}) = -1 EBADF (%m)\n");
1567}
1568
1569static void
1570btrfs_test_extent_same_ioctl(void)
1571{
1572 struct file_dedupe_range args = {
1573 .src_offset = 1024,
1574 .src_length = 10240,
1575 };
1576 struct file_dedupe_range *argsp;
1577
1578 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, NULL);
1579 printf("ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, "
1580 "NULL) = -1 EBADF (%m)\n");
1581
1582 printf("ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, "
1583 "{src_offset=%" PRIu64
1584 ", src_length=%" PRIu64
1585 ", dest_count=%hu, info=",
1586 (uint64_t)args.src_offset,
1587 (uint64_t)args.src_length, args.dest_count);
1588 if (verbose)
1589 printf("[]");
1590 else
1591 printf("...");
1592 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, &args);
1593 printf("}) = -1 EBADF (%m)\n");
1594
1595 argsp = malloc(sizeof(*argsp) + sizeof(argsp->info[0]) * 2);
1596 if (!argsp)
1597 perror_msg_and_fail("malloc failed");
1598 memset(argsp, 0, sizeof(*argsp) + sizeof(argsp->info[0]) * 2);
1599
1600 *argsp = args;
1601 argsp->dest_count = 2;
1602 argsp->info[0].dest_fd = 2;
1603 argsp->info[0].dest_offset = 0;
1604 argsp->info[1].dest_fd = 2;
1605 argsp->info[1].dest_offset = 10240;
1606
1607 printf("ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, "
1608 "{src_offset=%" PRIu64
1609 ", src_length=%" PRIu64
1610 ", dest_count=%hu, info=",
1611 (int64_t)argsp->src_offset,
1612 (uint64_t)argsp->src_length, argsp->dest_count);
1613 if (verbose)
1614 printf("[{dest_fd=%" PRId64 ", dest_offset=%" PRIu64
1615 "}, {dest_fd=%" PRId64 ", dest_offset=%"PRIu64
1616 "}]",
1617 (int64_t)argsp->info[0].dest_fd,
1618 (uint64_t)argsp->info[0].dest_offset,
1619 (int64_t)argsp->info[1].dest_fd,
1620 (uint64_t)argsp->info[1].dest_offset);
1621 else
1622 printf("...");
1623 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, argsp);
1624 printf("}) = -1 EBADF (%m)\n");
1625
1626 if (write_ok) {
1627 int fd1, fd2;
1628 char buf[16384];
1629 int size = sizeof(*argsp) + sizeof(argsp->info[0]);
1630
1631 memset(buf, 0, sizeof(buf));
1632
1633 fd1 = openat(btrfs_test_dir_fd, "file1", O_RDWR|O_CREAT, 0600);
1634 if (fd1 < 0)
1635 perror_msg_and_fail("open file1 failed");
1636
1637 fd2 = openat(btrfs_test_dir_fd, "file2", O_RDWR|O_CREAT, 0600);
1638 if (fd2 < 0)
1639 perror_msg_and_fail("open file2 failed");
1640
1641 if (write(fd1, buf, sizeof(buf)) < 0)
1642 perror_msg_and_fail("write: fd1");
1643 if (write(fd2, buf, sizeof(buf)) < 0)
1644 perror_msg_and_fail("write: fd2");
1645
1646 close(fd2);
1647 fd2 = openat(btrfs_test_dir_fd, "file2", O_RDONLY);
1648 if (fd2 < 0)
1649 perror_msg_and_fail("open file2 failed");
1650
1651 argsp = realloc(argsp, size);
1652 if (!argsp)
1653 perror_msg_and_fail("realloc failed");
1654 memset(argsp, 0, size);
1655
1656 argsp->src_offset = 0;
1657 argsp->src_length = sizeof(buf);
1658 argsp->dest_count = 1;
1659 argsp->info[0].dest_fd = fd2;
1660 argsp->info[0].dest_offset = 0;
1661
1662 printf("ioctl(%d, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, "
1663 "{src_offset=%" PRIu64 ", src_length=%" PRIu64
1664 ", dest_count=%hu, info=", fd1,
1665 (uint64_t)argsp->src_offset,
1666 (uint64_t)argsp->src_length, argsp->dest_count);
1667 if (verbose)
1668 printf("[{dest_fd=%d, dest_offset=0}]", fd2);
1669 else
1670 printf("...");
1671 ioctl(fd1, BTRFS_IOC_FILE_EXTENT_SAME, argsp);
1672 printf("} => {info=");
1673 if (verbose)
1674 printf("[{bytes_deduped=%u, status=0}]",
1675 (unsigned) sizeof(buf));
1676 else
1677 printf("...");
1678 printf("}) = 0\n");
1679 close(fd1);
1680 close(fd2);
1681 unlinkat(btrfs_test_dir_fd, "file1", 0);
1682 unlinkat(btrfs_test_dir_fd, "file2", 0);
1683 close(fd1);
1684 close(fd2);
1685 }
1686 free(argsp);
1687}
1688
1689static void
1690btrfs_print_features(struct btrfs_ioctl_feature_flags *flags)
1691{
1692 printf("{compat_flags=");
1693 printflags(btrfs_features_compat, flags->compat_flags,
1694 "BTRFS_FEATURE_COMPAT_???");
1695
1696 printf(", compat_ro_flags=");
1697 printflags(btrfs_features_compat_ro, flags->compat_ro_flags,
1698 "BTRFS_FEATURE_COMPAT_RO_???");
1699
1700 printf(", incompat_flags=");
1701 printflags(btrfs_features_incompat, flags->incompat_flags,
1702 "BTRFS_FEATURE_INCOMPAT_???");
1703 printf("}");
1704}
1705
1706/*
1707 * Consumes argument, returns nothing:
1708 * - BTRFS_IOC_SET_FEATURES
1709 *
1710 * Consumes nothing, returns argument:
1711 * - BTRFS_IOC_GET_FEATURES
1712 * - BTRFS_IOC_GET_SUPPORTED_FEATURES
1713 */
1714static void
1715btrfs_test_features_ioctls(void)
1716{
1717 struct btrfs_ioctl_feature_flags args[2] = {
1718 {
1719 .compat_flags = max_flags_plus_one(-1),
1720 .incompat_flags = max_flags_plus_one(9),
1721 .compat_ro_flags = max_flags_plus_one(0),
1722 }, {
1723 .compat_flags = max_flags_plus_one(-1),
1724 .incompat_flags = max_flags_plus_one(9),
1725 .compat_ro_flags = max_flags_plus_one(0),
1726 },
1727 };
1728 struct btrfs_ioctl_feature_flags supported_features[3];
1729
1730 ioctl(-1, BTRFS_IOC_SET_FEATURES, NULL);
1731 printf("ioctl(-1, BTRFS_IOC_SET_FEATURES, NULL) = -1 EBADF (%m)\n");
1732
1733 printf("ioctl(-1, BTRFS_IOC_SET_FEATURES, [");
1734 btrfs_print_features(&args[0]);
1735 printf(", ");
1736 btrfs_print_features(&args[1]);
1737 ioctl(-1, BTRFS_IOC_SET_FEATURES, &args);
1738 printf("]) = -1 EBADF (%m)\n");
1739
1740 if (btrfs_test_root) {
1741 printf("ioctl(%d, BTRFS_IOC_GET_FEATURES, ",
1742 btrfs_test_dir_fd);
1743 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_FEATURES,
1744 &supported_features);
1745 btrfs_print_features(&supported_features[0]);
1746 printf(") = 0\n");
1747
1748 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_SUPPORTED_FEATURES,
1749 &supported_features);
1750 printf("ioctl(%d, BTRFS_IOC_GET_SUPPORTED_FEATURES, ",
1751 btrfs_test_dir_fd);
1752 printf("[ /* supported */ ");
1753 btrfs_print_features(&supported_features[0]);
1754 printf(", /* safe to set */ ");
1755 btrfs_print_features(&supported_features[1]);
1756 printf(", /* safe to clear */ ");
1757 btrfs_print_features(&supported_features[2]);
1758 printf("]) = 0\n");
1759 }
1760}
1761
1762int
1763main(int argc, char *argv[])
1764{
1765
1766 int opt;
1767 int ret;
1768 const char *path;
1769
1770 while ((opt = getopt(argc, argv, "wv")) != -1) {
1771 switch (opt) {
1772 case 'v':
1773 /*
1774 * These tests are incomplete, especially when
1775 * printing arrays of objects are involved.
1776 */
1777 verbose = true;
1778 break;
1779 case 'w':
1780 write_ok = true;
1781 break;
1782 default:
1783 error_msg_and_fail("usage: btrfs [-v] [-w] [path]");
1784 }
1785 }
1786
1787 /*
1788 * This will enable optional tests that require a valid file descriptor
1789 */
1790 if (optind < argc) {
1791 int rootfd;
1792 struct statfs sfi;
1793 path = argv[optind];
1794
1795 ret = statfs(path, &sfi);
1796 if (ret)
1797 perror_msg_and_fail("statfs(%s) failed", path);
1798
1799 if ((unsigned) sfi.f_type != BTRFS_SUPER_MAGIC)
1800 perror_msg_and_fail("%s is not a btrfs file system",
1801 path);
1802
1803 btrfs_test_root = path;
1804 rootfd = open(path, O_RDONLY|O_DIRECTORY);
1805 if (rootfd < 0)
1806 perror_msg_and_fail("open(%s) failed", path);
1807
1808 ret = mkdirat(rootfd, "strace-test", 0755);
1809 if (ret < 0 && errno != EEXIST)
1810 perror_msg_and_fail("mkdirat(strace-test) failed");
1811
1812 btrfs_test_dir_fd = openat(rootfd, "strace-test",
1813 O_RDONLY|O_DIRECTORY);
1814 if (btrfs_test_dir_fd < 0)
1815 perror_msg_and_fail("openat(strace-test) failed");
1816 close(rootfd);
1817 } else
1818 write_ok = false;
1819
1820 if (btrfs_test_root) {
1821 fprintf(stderr, "Testing live ioctls on %s (%s)\n",
1822 btrfs_test_root, write_ok ? "read/write" : "read only");
1823 }
1824
1825 btrfs_test_trans_ioctls();
1826 btrfs_test_sync_ioctls();
1827 btrfs_test_subvol_ioctls();
1828 btrfs_test_balance_ioctls();
1829 btrfs_test_device_ioctls();
1830 btrfs_test_clone_ioctls();
1831 btrfs_test_defrag_ioctls();
1832 btrfs_test_search_ioctls();
1833 btrfs_test_ino_lookup_ioctl();
1834 btrfs_test_space_info_ioctl();
1835 btrfs_test_scrub_ioctls();
1836 btrfs_test_dev_info_ioctl();
1837 btrfs_test_ino_path_ioctls();
1838 btrfs_test_set_received_subvol_ioctl();
1839 btrfs_test_send_ioctl();
1840 btrfs_test_quota_ctl_ioctl();
1841 btrfs_test_qgroup_assign_ioctl();
1842 btrfs_test_qgroup_create_ioctl();
1843 btrfs_test_quota_rescan_ioctl();
1844 btrfs_test_label_ioctls();
1845 btrfs_test_get_dev_stats_ioctl();
1846 btrfs_test_dev_replace_ioctl();
1847 btrfs_test_extent_same_ioctl();
1848 btrfs_test_features_ioctls();
1849
1850 puts("+++ exited with 0 +++");
1851
1852 return 0;
1853}
Dmitry V. Levin22129182016-05-24 01:32:09 +00001854
1855#else
1856
1857SKIP_MAIN_UNDEFINED("HAVE_LINUX_BTRFS_H")
1858
1859#endif