blob: b44bc872939837bc010513fe520196a3afe99693 [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>
Dmitry V. Levin28a5f662016-05-24 01:32:41 +00009#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
Dmitry V. Levin28a5f662016-05-24 01:32:41 +000014#include <sys/ioctl.h>
15#include <sys/stat.h>
Elliott Hughes03a418e2018-06-15 13:11:40 -070016#include <sys/sysmacros.h>
Dmitry V. Levin28a5f662016-05-24 01:32:41 +000017#include <sys/vfs.h>
Jeff Mahoney35866792016-05-18 18:09:42 -040018#include <linux/fs.h>
19#include <linux/btrfs.h>
20#include <linux/magic.h>
Jeff Mahoney35866792016-05-18 18:09:42 -040021#include "xlat.h"
22
23#include "xlat/btrfs_balance_args.h"
24#include "xlat/btrfs_balance_flags.h"
25#include "xlat/btrfs_balance_state.h"
26#include "xlat/btrfs_compress_types.h"
Elliott Hughes03a418e2018-06-15 13:11:40 -070027#include "xlat/btrfs_cont_reading_from_srcdev_mode.h"
Jeff Mahoney35866792016-05-18 18:09:42 -040028#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
Dmitry V. Levin2447de42016-05-24 01:32:55 +000050# define BTRFS_LABEL_SIZE 256
Jeff Mahoney35866792016-05-18 18:09:42 -040051#endif
52
53#ifndef BTRFS_NAME_LEN
Dmitry V. Levin2447de42016-05-24 01:32:55 +000054# define BTRFS_NAME_LEN 255
Jeff Mahoney35866792016-05-18 18:09:42 -040055#endif
56
Dmitry V. Levin6697d152016-05-24 02:56:39 +000057/*
58 * Prior to Linux 3.12, the BTRFS_IOC_DEFAULT_SUBVOL used u64 in
59 * its definition, which isn't exported by the kernel.
60 */
61typedef __u64 u64;
62
Jeff Mahoney35866792016-05-18 18:09:42 -040063static const char *btrfs_test_root;
64static int btrfs_test_dir_fd;
Elliott Hughesdc75b012017-07-05 13:54:44 -070065static bool verbose;
66static bool write_ok;
Elliott Hughes03a418e2018-06-15 13:11:40 -070067static bool verbose_xlat;
68
69static const char *path;
70static const char dir_name_fmt[] = "strace-test-%d";
71static char dir_name[sizeof(dir_name_fmt) + sizeof(int) * 3];
Jeff Mahoney35866792016-05-18 18:09:42 -040072
73const unsigned char uuid_reference[BTRFS_UUID_SIZE] = {
74 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
75 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
76};
77
78const char uuid_reference_string[] = "01234567-89ab-cdef-fedc-ba9876543210";
79
Dmitry V. Levinfe7a4512016-06-17 03:02:46 +030080#ifndef BTRFS_IOC_QUOTA_RESCAN
81struct btrfs_ioctl_quota_rescan_args {
82 uint64_t flags, progress, reserved[6];
83};
Elliott Hughesdc75b012017-07-05 13:54:44 -070084# define BTRFS_IOC_QUOTA_RESCAN \
85 _IOW(BTRFS_IOCTL_MAGIC, 44, struct btrfs_ioctl_quota_rescan_args)
86# define BTRFS_IOC_QUOTA_RESCAN_STATUS \
87 _IOR(BTRFS_IOCTL_MAGIC, 45, struct btrfs_ioctl_quota_rescan_args)
Dmitry V. Levinfe7a4512016-06-17 03:02:46 +030088#endif
89
90#ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT
91# define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
92#endif
93
Jeff Mahoney35866792016-05-18 18:09:42 -040094#ifndef BTRFS_IOC_GET_FEATURES
Elliott Hughesdc75b012017-07-05 13:54:44 -070095# define BTRFS_IOC_GET_FEATURES \
96 _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags)
97# define BTRFS_IOC_SET_FEATURES \
98 _IOW(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[2])
99# define BTRFS_IOC_GET_SUPPORTED_FEATURES \
100 _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[3])
Jeff Mahoney35866792016-05-18 18:09:42 -0400101#endif
102
103#ifndef HAVE_STRUCT_BTRFS_IOCTL_FEATURE_FLAGS_COMPAT_FLAGS
104struct btrfs_ioctl_feature_flags {
Elliott Hughesdc75b012017-07-05 13:54:44 -0700105 uint64_t compat_flags;
106 uint64_t compat_ro_flags;
107 uint64_t incompat_flags;
Jeff Mahoney35866792016-05-18 18:09:42 -0400108};
109#endif
110
111#ifndef HAVE_STRUCT_BTRFS_IOCTL_DEFRAG_RANGE_ARGS_START
112struct btrfs_ioctl_defrag_range_args {
Elliott Hughesdc75b012017-07-05 13:54:44 -0700113 uint64_t start;
114 uint64_t len;
115 uint64_t flags;
116 uint32_t extent_thresh;
117 uint32_t compress_type;
118 uint32_t unused[4];
Jeff Mahoney35866792016-05-18 18:09:42 -0400119};
120#endif
121
122#ifndef FIDEDUPERANGE
Dmitry V. Levin2447de42016-05-24 01:32:55 +0000123# define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range)
Jeff Mahoney35866792016-05-18 18:09:42 -0400124struct file_dedupe_range_info {
125 int64_t dest_fd; /* in - destination file */
126 uint64_t dest_offset; /* in - start of extent in destination */
127 uint64_t bytes_deduped; /* out - total # of bytes we were able
128 * to dedupe from this file. */
129 /* status of this dedupe operation:
130 * < 0 for error
131 * == FILE_DEDUPE_RANGE_SAME if dedupe succeeds
132 * == FILE_DEDUPE_RANGE_DIFFERS if data differs
133 */
134 int32_t status; /* out - see above description */
135 uint32_t reserved; /* must be zero */
136};
137
138struct file_dedupe_range {
139 uint64_t src_offset; /* in - start of extent in source */
140 uint64_t src_length; /* in - length of extent */
141 uint16_t dest_count; /* in - total elements in info array */
142 uint16_t reserved1; /* must be zero */
143 uint32_t reserved2; /* must be zero */
144 struct file_dedupe_range_info info[0];
145};
146#endif
147
148#ifndef BTRFS_IOC_TREE_SEARCH_V2
Elliott Hughesdc75b012017-07-05 13:54:44 -0700149# define BTRFS_IOC_TREE_SEARCH_V2 \
150 _IOWR(BTRFS_IOCTL_MAGIC, 17, struct btrfs_ioctl_search_args_v2)
Jeff Mahoney35866792016-05-18 18:09:42 -0400151struct btrfs_ioctl_search_args_v2 {
152 struct btrfs_ioctl_search_key key; /* in/out - search parameters */
153 uint64_t buf_size; /* in - size of buffer
154 * out - on EOVERFLOW: needed size
155 * to store item */
Elliott Hughesdc75b012017-07-05 13:54:44 -0700156 uint64_t buf[0]; /* out - found items */
Jeff Mahoney35866792016-05-18 18:09:42 -0400157};
158#endif
159
160
Dmitry V. Levin2447de42016-05-24 01:32:55 +0000161static const char *
Elliott Hughes03a418e2018-06-15 13:11:40 -0700162sprint_xlat_(uint32_t val, const char *xlat)
Jeff Mahoney35866792016-05-18 18:09:42 -0400163{
Elliott Hughes03a418e2018-06-15 13:11:40 -0700164 static char str[256];
165 int ret;
166
167 if (verbose_xlat) {
168 ret = snprintf(str, sizeof(str), "%#x /* %s */", val, xlat);
169
170 if (ret < 0)
171 perror_msg_and_fail("sprint_ioc(%#x, %s)", val, xlat);
172 if ((unsigned) ret >= sizeof(str))
173 error_msg_and_fail("sprint_ioc(%#x, %s): buffer "
174 "overflow", val, xlat);
175
176 return str;
177 }
178
179 return xlat;
180}
181
182#define ioc(x_) sprint_xlat_(x_, #x_)
183
184void
185prfl_btrfs(const struct xlat *xlat, const unsigned long long val,
186 const char *str)
187{
188 if (verbose_xlat && val)
189 printf("%#llx /* ", val);
190 printflags(xlat, val, str);
191 if (verbose_xlat && val)
192 printf(" */");
193}
194
195void
196prxval_btrfs(const struct xlat *xlat, const unsigned long long val,
197 const char *str, bool known)
198{
199 if (verbose_xlat && known)
200 printf("%#llx /* ", val);
201 printxval(xlat, val, str);
202 if (verbose_xlat && known)
203 printf(" */");
204}
205
206static void
207print_uint64(const char *prefix, uint64_t val)
208{
209 if (val == UINT64_MAX) {
210 if (verbose_xlat)
211 printf("%s%" PRIu64 " /* UINT64_MAX */", prefix, val);
212 else
213 printf("%sUINT64_MAX", prefix);
214 } else {
215 printf("%s%" PRIu64, prefix, val);
216 }
Jeff Mahoney35866792016-05-18 18:09:42 -0400217}
218
219/* takes highest valid flag bit */
Dmitry V. Levin2447de42016-05-24 01:32:55 +0000220static uint64_t
221max_flags_plus_one(int bit)
Jeff Mahoney35866792016-05-18 18:09:42 -0400222{
223 int i;
224 uint64_t val = 0;
225 if (bit == -1)
226 return 1;
227 for (i = 0; i <= bit + 1 && i < 64; i++)
228 val |= (1ULL << i);
229 return val;
230}
231
232/*
233 * Consumes no arguments, returns nothing:
234 *
235 * - BTRFS_IOC_TRANS_START
236 * - BTRFS_IOC_TRANS_END
237 */
238static void
239btrfs_test_trans_ioctls(void)
240{
241 ioctl(-1, BTRFS_IOC_TRANS_START, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700242 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_TRANS_START));
Jeff Mahoney35866792016-05-18 18:09:42 -0400243
244 ioctl(-1, BTRFS_IOC_TRANS_END, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700245 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_TRANS_END));
Jeff Mahoney35866792016-05-18 18:09:42 -0400246}
247
248/*
249 * Consumes no arguments, returns nothing:
250 * - BTRFS_IOC_SYNC
251 *
252 * Consumes argument, returns nothing
253 * - BTRFS_IOC_WAIT_SYNC
254 */
255static void
256btrfs_test_sync_ioctls(void)
257{
Elliott Hughesd35df492017-02-15 15:19:05 -0800258 uint64_t u64val = 0xdeadbeefbadc0dedULL;
Jeff Mahoney35866792016-05-18 18:09:42 -0400259
260 ioctl(-1, BTRFS_IOC_SYNC, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700261 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_SYNC));
Jeff Mahoney35866792016-05-18 18:09:42 -0400262
263 ioctl(-1, BTRFS_IOC_WAIT_SYNC, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700264 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
265 ioc(BTRFS_IOC_WAIT_SYNC));
Jeff Mahoney35866792016-05-18 18:09:42 -0400266
267 ioctl(-1, BTRFS_IOC_WAIT_SYNC, &u64val);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700268 printf("ioctl(-1, %s, [%" PRIu64 "]) = -1 EBADF (%m)\n",
269 ioc(BTRFS_IOC_WAIT_SYNC), u64val);
Jeff Mahoney35866792016-05-18 18:09:42 -0400270
271 /*
272 * The live test of BTRFS_IOC_SYNC happens as a part of the test
273 * for BTRFS_IOC_LOGICAL_INO
274 */
275}
276
277static void
278btrfs_print_qgroup_inherit(struct btrfs_qgroup_inherit *inherit)
279{
280 printf("{flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -0700281 prfl_btrfs(btrfs_qgroup_inherit_flags, inherit->flags,
Jeff Mahoney35866792016-05-18 18:09:42 -0400282 "BTRFS_QGROUP_INHERIT_???");
283 printf(", num_qgroups=%" PRI__u64
284 ", num_ref_copies=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700285 ", num_excl_copies=%" PRI__u64 ", lim={flags=",
Jeff Mahoney35866792016-05-18 18:09:42 -0400286 inherit->num_qgroups, inherit->num_ref_copies,
287 inherit->num_excl_copies);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700288 prfl_btrfs(btrfs_qgroup_limit_flags,
Jeff Mahoney35866792016-05-18 18:09:42 -0400289 inherit->lim.flags,
290 "BTRFS_QGROUP_LIMIT_???");
291 printf(", max_rfer=%" PRI__u64 ", max_excl=%" PRI__u64
292 ", rsv_rfer=%" PRI__u64 ", rsv_excl=%" PRI__u64
Elliott Hughes03a418e2018-06-15 13:11:40 -0700293 "}, ",
Jeff Mahoney35866792016-05-18 18:09:42 -0400294 inherit->lim.max_rfer, inherit->lim.max_excl,
295 inherit->lim.rsv_rfer, inherit->lim.rsv_excl);
296 if (verbose) {
297 unsigned int i;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700298 printf("qgroups=[");
Jeff Mahoney35866792016-05-18 18:09:42 -0400299 for (i = 0; i < inherit->num_qgroups; i++) {
300 if (i > 0)
301 printf(", ");
302 printf("%" PRI__u64, inherit->qgroups[i]);
303 }
304 printf("]");
305 } else
306 printf("...");
307 printf("}");
308}
309
310
311static void
312btrfs_print_vol_args_v2(struct btrfs_ioctl_vol_args_v2 *args, int print_qgroups)
313{
Dmitry V. Levin6ce6d3b2016-05-24 01:53:02 +0000314 printf("{fd=%d, flags=", (int) args->fd);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700315 prfl_btrfs(btrfs_snap_flags_v2, args->flags, "BTRFS_SUBVOL_???");
Jeff Mahoney35866792016-05-18 18:09:42 -0400316
317 if (args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
318 printf(", size=%" PRI__u64 ", qgroup_inherit=", args->size);
319 if (args->qgroup_inherit && print_qgroups)
320 btrfs_print_qgroup_inherit(args->qgroup_inherit);
321 else if (args->qgroup_inherit)
322 printf("%p", args->qgroup_inherit);
323 else
324 printf("NULL");
325 }
326 printf(", name=\"%s\"}", args->name);
327}
328
329/*
330 * Consumes argument, returns nothing:
331 * - BTRFS_IOC_SNAP_CREATE
332 * - BTRFS_IOC_SUBVOL_CREATE
333 * - BTRFS_IOC_SNAP_DESTROY
334 * - BTRFS_IOC_DEFAULT_SUBVOL
335 *
336 * Consumes argument, returns u64:
337 * - BTRFS_IOC_SNAP_CREATE_V2
338 * - BTRFS_IOC_SUBVOL_CREATE_V2
339 */
340
341static void
342btrfs_test_subvol_ioctls(void)
343{
344 const char *subvol_name = "subvol-name";
345 char *long_subvol_name;
Elliott Hughesd35df492017-02-15 15:19:05 -0800346 void *bad_pointer = (void *) (unsigned long) 0xdeadbeeffffffeedULL;
347 uint64_t u64val = 0xdeadbeefbadc0dedULL;
Jeff Mahoney35866792016-05-18 18:09:42 -0400348 struct btrfs_ioctl_vol_args vol_args = {};
349 struct btrfs_ioctl_vol_args_v2 vol_args_v2 = {
350 .fd = 2,
351 .flags = max_flags_plus_one(2),
352 };
Jeff Mahoney35866792016-05-18 18:09:42 -0400353
354 long_subvol_name = malloc(BTRFS_PATH_NAME_MAX);
355 if (!long_subvol_name)
356 perror_msg_and_fail("malloc failed");
357 memset(long_subvol_name, 'f', BTRFS_PATH_NAME_MAX);
358 long_subvol_name[BTRFS_PATH_NAME_MAX - 1] = '\0';
359
360 strcpy(vol_args.name, subvol_name);
361
362 ioctl(-1, BTRFS_IOC_SNAP_CREATE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700363 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
364 ioc(BTRFS_IOC_SNAP_CREATE));
Jeff Mahoney35866792016-05-18 18:09:42 -0400365
366 ioctl(-1, BTRFS_IOC_SNAP_CREATE, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700367 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
368 ioc(BTRFS_IOC_SNAP_CREATE), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400369
370 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700371 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
372 ioc(BTRFS_IOC_SUBVOL_CREATE), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400373
374 ioctl(-1, BTRFS_IOC_SNAP_DESTROY, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700375 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
376 ioc(BTRFS_IOC_SNAP_DESTROY), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400377
378 strncpy(vol_args.name, long_subvol_name, BTRFS_PATH_NAME_MAX);
379 ioctl(-1, BTRFS_IOC_SNAP_CREATE, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700380 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
381 ioc(BTRFS_IOC_SNAP_CREATE), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400382
383 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700384 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
385 ioc(BTRFS_IOC_SUBVOL_CREATE), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400386
387 ioctl(-1, BTRFS_IOC_SNAP_DESTROY, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700388 printf("ioctl(-1, %s, {fd=0, name=\"%s\"}) = -1 EBADF (%m)\n",
389 ioc(BTRFS_IOC_SNAP_DESTROY), vol_args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400390
391 long_subvol_name = realloc(long_subvol_name, BTRFS_SUBVOL_NAME_MAX);
392 if (!long_subvol_name)
393 perror_msg_and_fail("realloc failed");
394
395 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700396 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
397 ioc(BTRFS_IOC_SNAP_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400398
399 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700400 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
401 ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400402
403 strcpy(vol_args_v2.name, subvol_name);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700404 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SNAP_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400405 btrfs_print_vol_args_v2(&vol_args_v2, 1);
406 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
407 printf(") = -1 EBADF (%m)\n");
408
Elliott Hughes03a418e2018-06-15 13:11:40 -0700409 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400410 btrfs_print_vol_args_v2(&vol_args_v2, 1);
411 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
412 printf(") = -1 EBADF (%m)\n");
413
414 strncpy(vol_args_v2.name, long_subvol_name, BTRFS_SUBVOL_NAME_MAX);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700415 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SNAP_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400416 btrfs_print_vol_args_v2(&vol_args_v2, 1);
417 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
418 printf(") = -1 EBADF (%m)\n");
419
Elliott Hughes03a418e2018-06-15 13:11:40 -0700420 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400421 btrfs_print_vol_args_v2(&vol_args_v2, 1);
422 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
423 printf(") = -1 EBADF (%m)\n");
424
425 strcpy(vol_args_v2.name, subvol_name);
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000426 vol_args_v2.qgroup_inherit = bad_pointer;
Jeff Mahoney35866792016-05-18 18:09:42 -0400427
Elliott Hughes03a418e2018-06-15 13:11:40 -0700428 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SNAP_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400429 btrfs_print_vol_args_v2(&vol_args_v2, 0);
430 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
431 printf(") = -1 EBADF (%m)\n");
432
Elliott Hughes03a418e2018-06-15 13:11:40 -0700433 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400434 btrfs_print_vol_args_v2(&vol_args_v2, 0);
435 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
436 printf(") = -1 EBADF (%m)\n");
437
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000438 const unsigned int n_qgroups = 8;
439 unsigned int i;
440 struct btrfs_qgroup_inherit *inherit;
441 vol_args_v2.size =
442 sizeof(*inherit) + n_qgroups * sizeof(inherit->qgroups[0]);
443 inherit = tail_alloc(vol_args_v2.size);
Jeff Mahoney35866792016-05-18 18:09:42 -0400444
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000445 inherit->flags = 0x3;
446 inherit->num_ref_copies = 0;
447 inherit->num_excl_copies = 0;
448 inherit->num_qgroups = n_qgroups;
449 for (i = 0; i < n_qgroups; i++)
450 inherit->qgroups[i] = 1ULL << i;
451 inherit->lim.flags = 0x7f;
452 inherit->lim.max_rfer = u64val;
453 inherit->lim.max_excl = u64val;
454 inherit->lim.rsv_rfer = u64val;
455 inherit->lim.rsv_excl = u64val;
456 vol_args_v2.qgroup_inherit = inherit;
Jeff Mahoney35866792016-05-18 18:09:42 -0400457
Elliott Hughes03a418e2018-06-15 13:11:40 -0700458 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SNAP_CREATE_V2));
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000459 btrfs_print_vol_args_v2(&vol_args_v2, 1);
460 ioctl(-1, BTRFS_IOC_SNAP_CREATE_V2, &vol_args_v2);
461 printf(") = -1 EBADF (%m)\n");
Jeff Mahoney35866792016-05-18 18:09:42 -0400462
Elliott Hughes03a418e2018-06-15 13:11:40 -0700463 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Dmitry V. Levin45fcc0c2016-05-24 01:32:27 +0000464 btrfs_print_vol_args_v2(&vol_args_v2, 1);
465 ioctl(-1, BTRFS_IOC_SUBVOL_CREATE_V2, &vol_args_v2);
466 printf(") = -1 EBADF (%m)\n");
Jeff Mahoney35866792016-05-18 18:09:42 -0400467
468 ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700469 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
470 ioc(BTRFS_IOC_DEFAULT_SUBVOL));
Jeff Mahoney35866792016-05-18 18:09:42 -0400471
472 ioctl(-1, BTRFS_IOC_DEFAULT_SUBVOL, &u64val);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700473 printf("ioctl(-1, %s, [%" PRIu64 "]) = -1 EBADF (%m)\n",
474 ioc(BTRFS_IOC_DEFAULT_SUBVOL), u64val);
Jeff Mahoney35866792016-05-18 18:09:42 -0400475
Elliott Hughes03a418e2018-06-15 13:11:40 -0700476 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_SUBVOL_SETFLAGS));
477 prfl_btrfs(btrfs_snap_flags_v2, vol_args_v2.flags,
Jeff Mahoney35866792016-05-18 18:09:42 -0400478 "BTRFS_SUBVOL_???");
479 ioctl(-1, BTRFS_IOC_SUBVOL_SETFLAGS, &vol_args_v2.flags);
480 printf(") = -1 EBADF (%m)\n");
481
482 if (write_ok) {
483 struct btrfs_ioctl_vol_args_v2 args_passed;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700484 long ret;
Jeff Mahoney35866792016-05-18 18:09:42 -0400485 /*
486 * Returns transid if flags & BTRFS_SUBVOL_CREATE_ASYNC
487 * - BTRFS_IOC_SNAP_CREATE_V2
488 * - BTRFS_IOC_SUBVOL_CREATE_V2
489 */
490 int subvolfd;
491
492 strncpy(vol_args_v2.name, subvol_name,
493 sizeof(vol_args_v2.name));
494 vol_args_v2.flags = BTRFS_SUBVOL_CREATE_ASYNC;
495 vol_args_v2.size = 0;
496 vol_args_v2.qgroup_inherit = NULL;
497 args_passed = vol_args_v2;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700498 printf("ioctl(%d, %s, ",
499 btrfs_test_dir_fd, ioc(BTRFS_IOC_SUBVOL_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400500 btrfs_print_vol_args_v2(&vol_args_v2, 1);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700501 ret = ioctl(btrfs_test_dir_fd, BTRFS_IOC_SUBVOL_CREATE_V2,
Jeff Mahoney35866792016-05-18 18:09:42 -0400502 &args_passed);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700503 if (ret < 0)
504 perror_msg_and_fail("ioctl(BTRFS_IOC_SUBVOL_CREATE_V2) "
505 "failed");
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700506 printf(" => {transid=%" PRI__u64 "}) = 0\n",
Jeff Mahoney35866792016-05-18 18:09:42 -0400507 args_passed.transid);
508
509 subvolfd = openat(btrfs_test_dir_fd, subvol_name,
510 O_RDONLY|O_DIRECTORY);
511 if (subvolfd < 0)
512 perror_msg_and_fail("openat(%s) failed", subvol_name);
513
514 strncpy(vol_args_v2.name, long_subvol_name, BTRFS_NAME_LEN);
515 vol_args_v2.fd = subvolfd;
516 args_passed = vol_args_v2;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700517 printf("ioctl(%d, %s, ",
518 btrfs_test_dir_fd, ioc(BTRFS_IOC_SNAP_CREATE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400519 btrfs_print_vol_args_v2(&args_passed, 1);
520 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_CREATE_V2,
521 &args_passed);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700522 printf(" => {transid=%" PRI__u64 "}) = 0\n",
Jeff Mahoney35866792016-05-18 18:09:42 -0400523 args_passed.transid);
524
525 /* This only works when mounted w/ -ouser_subvol_rm_allowed */
526 strncpy(vol_args.name, long_subvol_name, 255);
527 vol_args.name[255] = 0;
528 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_DESTROY, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700529 printf("ioctl(%d, %s, {fd=%d, name=\"%.*s\"}) = 0\n",
530 btrfs_test_dir_fd, ioc(BTRFS_IOC_SNAP_DESTROY),
531 (int) vol_args.fd, 255, long_subvol_name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400532
533 strcpy(vol_args.name, subvol_name);
534 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SNAP_DESTROY, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700535 printf("ioctl(%d, %s, {fd=%d, name=\"%s\"}) = 0\n",
536 btrfs_test_dir_fd, ioc(BTRFS_IOC_SNAP_DESTROY),
537 (int) vol_args.fd, subvol_name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400538
539 close(subvolfd);
540 }
541 free(long_subvol_name);
542}
543
544static void
545btrfs_print_balance_args(struct btrfs_balance_args *args)
546{
547 printf("{profiles=");
Elliott Hughes03a418e2018-06-15 13:11:40 -0700548 prfl_btrfs(btrfs_space_info_flags, args->profiles,
Jeff Mahoney35866792016-05-18 18:09:42 -0400549 "BTRFS_BLOCK_GROUP_???");
Elliott Hughes03a418e2018-06-15 13:11:40 -0700550 print_uint64(", usage=", args->usage);
551 printf(", devid=makedev(%u, %u)",
552 major(args->devid), minor(args->devid));
553 print_uint64(", pstart=", args->pstart);
554 print_uint64(", pend=", args->pend);
555 print_uint64(", vstart=", args->vstart);
556 print_uint64(", vend=", args->vend);
557 print_uint64(", target=", args->target);
558 printf(", flags=");
559 prfl_btrfs(btrfs_balance_args, args->flags, "BTRFS_BALANCE_ARGS_???");
Jeff Mahoney35866792016-05-18 18:09:42 -0400560 printf("}");
561}
562
563/*
564 * Accepts argument, returns nothing
565 * - BTRFS_IOC_BALANCE
566 * - BTRFS_IOC_BALANCE_CTL
567 *
568 * Accepts argument, returns argument
569 * - BTRFS_IOC_BALANCE_V2
570 */
571static void
572btrfs_test_balance_ioctls(void)
573{
574 struct btrfs_ioctl_balance_args args = {
575 .flags = 0x3f,
576 .data = {
577 .profiles = 0x7,
578 .flags = 0x7,
579 .devid = 1,
580 .pend = -1ULL,
581 .vend = -1ULL,
582 },
583
584 .meta = {
585 .profiles = 0x38,
586 .flags = 0x38,
587 .devid = 1,
588 },
589
590 .sys = {
591 .profiles = 0x1c0 | (1ULL << 48),
592 .flags = 0x4c0,
593 .devid = 1,
594 },
595 };
596 struct btrfs_ioctl_vol_args vol_args = {};
597
598 ioctl(-1, BTRFS_IOC_BALANCE_CTL, 1);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700599 printf("ioctl(-1, %s, %sBTRFS_BALANCE_CTL_PAUSE%s) = -1 EBADF (%m)\n",
600 ioc(BTRFS_IOC_BALANCE_CTL),
601 verbose_xlat ? "0x1 /* " : "",
602 verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -0400603
604 ioctl(-1, BTRFS_IOC_BALANCE_CTL, 2);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700605 printf("ioctl(-1, %s, "
606 "%sBTRFS_BALANCE_CTL_CANCEL%s) = -1 EBADF (%m)\n",
607 ioc(BTRFS_IOC_BALANCE_CTL),
608 verbose_xlat ? "0x2 /* " : "",
609 verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -0400610
611 ioctl(-1, BTRFS_IOC_BALANCE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700612 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_BALANCE));
Jeff Mahoney35866792016-05-18 18:09:42 -0400613
614 ioctl(-1, BTRFS_IOC_BALANCE, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700615 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_BALANCE));
Jeff Mahoney35866792016-05-18 18:09:42 -0400616
617 /* struct btrfs_ioctl_balance_args */
618 ioctl(-1, BTRFS_IOC_BALANCE_V2, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700619 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
620 ioc(BTRFS_IOC_BALANCE_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400621
Elliott Hughes03a418e2018-06-15 13:11:40 -0700622 printf("ioctl(-1, %s, {flags=", ioc(BTRFS_IOC_BALANCE_V2));
623 prfl_btrfs(btrfs_balance_flags, args.flags, "BTRFS_BALANCE_???");
Jeff Mahoney35866792016-05-18 18:09:42 -0400624 printf(", data=");
625 btrfs_print_balance_args(&args.data);
626 printf(", meta=");
627 btrfs_print_balance_args(&args.meta);
628 printf(", sys=");
629 btrfs_print_balance_args(&args.sys);
630 ioctl(-1, BTRFS_IOC_BALANCE_V2, &args);
631 printf("}) = -1 EBADF (%m)\n");
632
633 if (write_ok) {
Elliott Hughes03a418e2018-06-15 13:11:40 -0700634 long ret;
635
Jeff Mahoney35866792016-05-18 18:09:42 -0400636 args.flags = BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA |
637 BTRFS_BALANCE_SYSTEM;
638 args.data.flags = 0;
639 args.data.profiles = 0;
640 args.meta.flags = 0;
641 args.meta.profiles = 0;
642 args.sys.flags = 0;
643 args.sys.profiles = 0;
Jeff Mahoney35866792016-05-18 18:09:42 -0400644
Elliott Hughes03a418e2018-06-15 13:11:40 -0700645 /*
646 * We should keep args the same for data in meta in case
647 * volume-under-tests uses mixed groups data and metadata.
648 */
649 args.meta.pend = -1ULL;
650 args.meta.vend = -1ULL;
651
652 printf("ioctl(%d, %s, {flags=",
653 btrfs_test_dir_fd, ioc(BTRFS_IOC_BALANCE_V2));
654
655 prfl_btrfs(btrfs_balance_flags, args.flags,
Jeff Mahoney35866792016-05-18 18:09:42 -0400656 "BTRFS_BALANCE_???");
657 printf(", data=");
658 btrfs_print_balance_args(&args.data);
659 printf(", meta=");
660 btrfs_print_balance_args(&args.meta);
661 printf(", sys=");
662 btrfs_print_balance_args(&args.sys);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700663 ret = ioctl(btrfs_test_dir_fd, BTRFS_IOC_BALANCE_V2, &args);
664 if (ret < 0) {
665 printf("}) = %s\n", sprintrc(ret));
666 } else {
667 printf("} => {flags=");
668 prfl_btrfs(btrfs_balance_flags, args.flags,
669 "BTRFS_BALANCE_???");
670 printf(", state=");
671 prfl_btrfs(btrfs_balance_state, args.state,
672 "BTRFS_BALANCE_STATE_???");
673 printf(", data=");
674 btrfs_print_balance_args(&args.data);
675 printf(", meta=");
676 btrfs_print_balance_args(&args.meta);
677 printf(", sys=");
678 btrfs_print_balance_args(&args.sys);
679 printf("}) = %ld\n", ret);
680 }
Jeff Mahoney35866792016-05-18 18:09:42 -0400681 }
682}
683
684/*
685 * Consumes argument, returns nothing:
686 * - BTRFS_IOC_RESIZE
687 *
688 * Requires /dev/btrfs-control, consumes argument, returns nothing:
689 * - BTRFS_IOC_SCAN_DEV
690 * - BTRFS_IOC_DEVICES_READY
691 *
692 */
693static void
694btrfs_test_device_ioctls(void)
695{
696 const char *devid = "1";
697 const char *devname = "/dev/sda1";
698 struct btrfs_ioctl_vol_args args = {
699 .fd = 2,
700 };
701
702 ioctl(-1, BTRFS_IOC_RESIZE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700703 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_RESIZE));
Jeff Mahoney35866792016-05-18 18:09:42 -0400704
705 strcpy(args.name, devid);
706 ioctl(-1, BTRFS_IOC_RESIZE, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700707 printf("ioctl(-1, %s, {fd=%d, name=\"%s\"}) = -1 EBADF (%m)\n",
708 ioc(BTRFS_IOC_RESIZE), (int) args.fd, args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400709
710 ioctl(-1, BTRFS_IOC_SCAN_DEV, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700711 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
712 ioc(BTRFS_IOC_SCAN_DEV));
Jeff Mahoney35866792016-05-18 18:09:42 -0400713
714 strcpy(args.name, devname);
715 ioctl(-1, BTRFS_IOC_SCAN_DEV, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700716 printf("ioctl(-1, %s, {fd=%d, name=\"%s\"}) = -1 EBADF (%m)\n",
717 ioc(BTRFS_IOC_SCAN_DEV), (int) args.fd, args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400718
719 ioctl(-1, BTRFS_IOC_ADD_DEV, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700720 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_ADD_DEV));
Jeff Mahoney35866792016-05-18 18:09:42 -0400721
722 ioctl(-1, BTRFS_IOC_ADD_DEV, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700723 printf("ioctl(-1, %s, {fd=%d, name=\"%s\"}) = -1 EBADF (%m)\n",
724 ioc(BTRFS_IOC_ADD_DEV), (int) args.fd, args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400725
726 ioctl(-1, BTRFS_IOC_RM_DEV, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700727 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_RM_DEV));
Jeff Mahoney35866792016-05-18 18:09:42 -0400728
729 ioctl(-1, BTRFS_IOC_RM_DEV, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700730 printf("ioctl(-1, %s, {fd=%d, name=\"%s\"}) = -1 EBADF (%m)\n",
731 ioc(BTRFS_IOC_RM_DEV), (int) args.fd, args.name);
Jeff Mahoney35866792016-05-18 18:09:42 -0400732
733}
734
735/*
736 * Consumes argument, returns nothing:
737 * - BTRFS_IOC_CLONE
738 * - BTRFS_IOC_CLONE_RANGE
739 */
740static void
741btrfs_test_clone_ioctls(void)
742{
743 int clone_fd = 4;
744 struct btrfs_ioctl_clone_range_args args = {
745 .src_fd = clone_fd,
746 .src_offset = 4096,
747 .src_length = 16384,
748 .dest_offset = 128 * 1024,
749 };
750
751 ioctl(-1, BTRFS_IOC_CLONE, clone_fd);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700752 printf("ioctl(-1, %s, %x) = -1 EBADF (%m)\n",
753 sprint_xlat_(BTRFS_IOC_CLONE, "BTRFS_IOC_CLONE or FICLONE"),
754 clone_fd);
Jeff Mahoney35866792016-05-18 18:09:42 -0400755
756 ioctl(-1, BTRFS_IOC_CLONE_RANGE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700757 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
758 sprint_xlat_(BTRFS_IOC_CLONE_RANGE,
759 "BTRFS_IOC_CLONE_RANGE or FICLONERANGE"));
Jeff Mahoney35866792016-05-18 18:09:42 -0400760
761 ioctl(-1, BTRFS_IOC_CLONE_RANGE, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700762 printf("ioctl(-1, %s, "
Dmitry V. Levin3f366112016-05-24 02:17:49 +0000763 "{src_fd=%d, src_offset=%" PRI__u64 ", src_length=%" PRI__u64
764 ", dest_offset=%" PRI__u64 "}) = -1 EBADF (%m)\n",
Elliott Hughes03a418e2018-06-15 13:11:40 -0700765 sprint_xlat_(BTRFS_IOC_CLONE_RANGE,
766 "BTRFS_IOC_CLONE_RANGE or FICLONERANGE"),
Dmitry V. Levin6ce6d3b2016-05-24 01:53:02 +0000767 (int) args.src_fd, args.src_offset, args.src_length,
Jeff Mahoney35866792016-05-18 18:09:42 -0400768 args.dest_offset);
769}
770
771#define BTRFS_COMPRESS_TYPES 2
772#define BTRFS_INVALID_COMPRESS (BTRFS_COMPRESS_TYPES + 1)
773
774static void
Elliott Hughes03a418e2018-06-15 13:11:40 -0700775btrfs_print_defrag_range_args(struct btrfs_ioctl_defrag_range_args *args,
776 bool compress_type_known)
Jeff Mahoney35866792016-05-18 18:09:42 -0400777{
Elliott Hughes03a418e2018-06-15 13:11:40 -0700778 printf("{start=%" PRIu64, (uint64_t) args->start);
779 print_uint64(", len=", args->len);
Jeff Mahoney35866792016-05-18 18:09:42 -0400780
Elliott Hughes03a418e2018-06-15 13:11:40 -0700781 printf(", flags=");
782 prfl_btrfs(btrfs_defrag_flags, args->flags, "BTRFS_DEFRAG_RANGE_???");
Jeff Mahoney35866792016-05-18 18:09:42 -0400783 printf(", extent_thresh=%u, compress_type=", args->extent_thresh);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700784 prxval_btrfs(btrfs_compress_types, args->compress_type,
785 "BTRFS_COMPRESS_???", compress_type_known);
Jeff Mahoney35866792016-05-18 18:09:42 -0400786 printf("}");
787}
788
789/*
790 * Consumes argument, returns nothing:
791 * - BTRFS_IOC_DEFRAG
792 * - BTRFS_DEFRAG_RANGE
793 */
794static void
795btrfs_test_defrag_ioctls(void)
796{
797 struct btrfs_ioctl_vol_args vol_args = {};
798 struct btrfs_ioctl_defrag_range_args args = {
799 .start = 0,
800 .len = -1ULL,
801 .flags = max_flags_plus_one(1),
802 .extent_thresh = 128 * 1024,
803 .compress_type = 2, /* BTRFS_COMPRESS_LZO */
804 };
805
806 /*
807 * These are documented as using vol_args but don't
808 * actually consume it.
809 */
810 ioctl(-1, BTRFS_IOC_DEFRAG, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700811 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_DEFRAG));
Jeff Mahoney35866792016-05-18 18:09:42 -0400812
813 ioctl(-1, BTRFS_IOC_DEFRAG, &vol_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700814 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_DEFRAG));
Jeff Mahoney35866792016-05-18 18:09:42 -0400815
816 /* struct btrfs_ioctl_defrag_range_args */
817 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700818 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
819 ioc(BTRFS_IOC_DEFRAG_RANGE));
Jeff Mahoney35866792016-05-18 18:09:42 -0400820
Elliott Hughes03a418e2018-06-15 13:11:40 -0700821 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_DEFRAG_RANGE));
822 btrfs_print_defrag_range_args(&args, true);
Jeff Mahoney35866792016-05-18 18:09:42 -0400823 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
824 printf(") = -1 EBADF (%m)\n");
825
826 args.compress_type = BTRFS_INVALID_COMPRESS;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700827 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_DEFRAG_RANGE));
828 btrfs_print_defrag_range_args(&args, false);
Jeff Mahoney35866792016-05-18 18:09:42 -0400829 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
830 printf(") = -1 EBADF (%m)\n");
831
832 args.len--;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700833 printf("ioctl(-1, %s, ", ioc(BTRFS_IOC_DEFRAG_RANGE));
834 btrfs_print_defrag_range_args(&args, false);
Jeff Mahoney35866792016-05-18 18:09:42 -0400835 ioctl(-1, BTRFS_IOC_DEFRAG_RANGE, &args);
836 printf(") = -1 EBADF (%m)\n");
837}
838
839static const char *
840xlookup(const struct xlat *xlat, const uint64_t val)
841{
842 for (; xlat->str != NULL; xlat++)
843 if (xlat->val == val)
844 return xlat->str;
845 return NULL;
846}
847
848static void
849btrfs_print_objectid(uint64_t objectid)
850{
851 const char *str = xlookup(btrfs_tree_objectids, objectid);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700852 if (str) {
853 if (verbose_xlat)
854 printf("%" PRIu64 " /* %s */", objectid, str);
855 else
856 printf("%s", str);
857 } else {
858 printf("%" PRIu64, objectid);
859 }
Jeff Mahoney35866792016-05-18 18:09:42 -0400860}
861
862static void
863btrfs_print_key_type(uint32_t type)
864{
865 const char *str = xlookup(btrfs_key_types, type);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700866 if (str) {
867 if (verbose_xlat)
868 printf("%u /* %s */", type, str);
869 else
870 printf("%s", str);
871 } else {
872 printf("%u", type);
873 }
Jeff Mahoney35866792016-05-18 18:09:42 -0400874}
875
876static void
877btrfs_print_search_key(struct btrfs_ioctl_search_key *key)
878{
879 printf("key={tree_id=");
880 btrfs_print_objectid(key->tree_id);
881 if (verbose || key->min_objectid != 256) {
882 printf(", min_objectid=");
883 btrfs_print_objectid(key->min_objectid);
884 }
885 if (verbose || key->max_objectid != -256ULL) {
886 printf(", max_objectid=");
887 btrfs_print_objectid(key->max_objectid);
888 }
Elliott Hughes03a418e2018-06-15 13:11:40 -0700889 print_uint64(", min_offset=", key->min_offset);
890 print_uint64(", max_offset=", key->max_offset);
891 print_uint64(", min_transid=", key->min_transid);
892 print_uint64(", max_transid=", key->max_transid);
Jeff Mahoney35866792016-05-18 18:09:42 -0400893 printf(", min_type=");
894 btrfs_print_key_type(key->min_type);
895 printf(", max_type=");
896 btrfs_print_key_type(key->max_type);
897 printf(", nr_items=%u}", key->nr_items);
898}
899
900static void
901btrfs_print_tree_search_buf(struct btrfs_ioctl_search_key *key,
902 void *buf, uint64_t buf_size)
903{
904 if (verbose) {
905 uint64_t i;
906 uint64_t off = 0;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700907 printf("buf=[");
Jeff Mahoney35866792016-05-18 18:09:42 -0400908 for (i = 0; i < key->nr_items; i++) {
909 struct btrfs_ioctl_search_header *sh;
910 sh = (typeof(sh))(buf + off);
911 if (i)
912 printf(", ");
913 printf("{transid=%" PRI__u64 ", objectid=",
914 sh->transid);
915 btrfs_print_objectid(sh->objectid);
916 printf(", offset=%" PRI__u64 ", type=", sh->offset);
917 btrfs_print_key_type(sh->type);
918 printf(", len=%u}", sh->len);
919 off += sizeof(*sh) + sh->len;
920 }
921 printf("]");
922 } else
923 printf("...");
924}
925
926/*
927 * Consumes argument, returns argument:
928 * - BTRFS_IOC_TREE_SEARCH
929 * - BTRFS_IOC_TREE_SEARCH_V2
930 */
931static void
932btrfs_test_search_ioctls(void)
933{
934 struct btrfs_ioctl_search_key key_reference = {
935 .tree_id = 5,
936 .min_objectid = 256,
937 .max_objectid = -1ULL,
938 .min_offset = 0,
939 .max_offset = -1ULL,
940 .min_transid = 0,
941 .max_transid = -1ULL,
942 .min_type = 0,
943 .max_type = -1U,
944 .nr_items = 10,
945 };
946 struct btrfs_ioctl_search_args search_args;
947 struct btrfs_ioctl_search_args_v2 search_args_v2 = {
948 .buf_size = 4096,
949 };
950
951 ioctl(-1, BTRFS_IOC_TREE_SEARCH, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700952 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
953 ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -0400954
955 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -0700956 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
957 ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400958
Jeff Mahoney563a7582016-05-26 16:09:28 -0400959 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700960 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -0400961 btrfs_print_search_key(&search_args.key);
962 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
963 printf("}) = -1 EBADF (%m)\n");
964
965 search_args_v2.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700966 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400967 btrfs_print_search_key(&search_args_v2.key);
968 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
969 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
970 (uint64_t)search_args_v2.buf_size);
971
972 key_reference.min_objectid = 6;
973 key_reference.max_objectid = 7;
Jeff Mahoney563a7582016-05-26 16:09:28 -0400974 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700975 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -0400976 btrfs_print_search_key(&search_args.key);
977 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
978 printf("}) = -1 EBADF (%m)\n");
979
980 search_args_v2.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700981 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400982 btrfs_print_search_key(&search_args_v2.key);
983 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
984 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
985 (uint64_t)search_args_v2.buf_size);
986
987 key_reference.min_offset++;
988 key_reference.max_offset--;
Jeff Mahoney563a7582016-05-26 16:09:28 -0400989 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700990 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -0400991 btrfs_print_search_key(&search_args.key);
992 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
993 printf("}) = -1 EBADF (%m)\n");
994
995 search_args_v2.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700996 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -0400997 btrfs_print_search_key(&search_args_v2.key);
998 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
999 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
1000 (uint64_t)search_args_v2.buf_size);
1001
1002 key_reference.min_transid++;
1003 key_reference.max_transid--;
Jeff Mahoney563a7582016-05-26 16:09:28 -04001004 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001005 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -04001006 btrfs_print_search_key(&search_args.key);
1007 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
1008 printf("}) = -1 EBADF (%m)\n");
1009
1010 search_args_v2.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001011 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -04001012 btrfs_print_search_key(&search_args_v2.key);
1013 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
1014 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
1015 (uint64_t)search_args_v2.buf_size);
1016
1017 key_reference.min_type = 1;
1018 key_reference.max_type = 12;
Jeff Mahoney563a7582016-05-26 16:09:28 -04001019 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001020 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -04001021 btrfs_print_search_key(&search_args.key);
1022 ioctl(-1, BTRFS_IOC_TREE_SEARCH, &search_args);
1023 printf("}) = -1 EBADF (%m)\n");
1024
1025 search_args_v2.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001026 printf("ioctl(-1, %s, {", ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -04001027 btrfs_print_search_key(&search_args_v2.key);
1028 ioctl(-1, BTRFS_IOC_TREE_SEARCH_V2, &search_args_v2);
1029 printf(", buf_size=%" PRIu64 "}) = -1 EBADF (%m)\n",
1030 (uint64_t)search_args_v2.buf_size);
1031
1032 if (btrfs_test_root) {
1033 struct btrfs_ioctl_search_args_v2 *args;
1034 int bufsize = 4096;
1035
1036 key_reference.tree_id = 5;
1037 key_reference.min_type = 1;
1038 key_reference.max_type = 1;
1039 key_reference.min_objectid = 256;
1040 key_reference.max_objectid = 357;
1041 key_reference.min_offset = 0;
1042 key_reference.max_offset = -1ULL;
1043
1044 search_args.key = key_reference;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001045 printf("ioctl(%d, %s, {",
1046 btrfs_test_dir_fd, ioc(BTRFS_IOC_TREE_SEARCH));
Jeff Mahoney35866792016-05-18 18:09:42 -04001047 btrfs_print_search_key(&search_args.key);
1048 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH, &search_args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001049 printf("} => {key={nr_items=%u}, ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001050 search_args.key.nr_items);
Jeff Mahoneyfd70b502016-05-26 23:33:05 -04001051 btrfs_print_tree_search_buf(&search_args.key, search_args.buf,
1052 sizeof(search_args.buf));
1053 printf("}) = 0\n");
Jeff Mahoney35866792016-05-18 18:09:42 -04001054
1055 args = malloc(sizeof(*args) + bufsize);
1056 if (!args)
1057 perror_msg_and_fail("malloc failed");
1058
1059 args->key = key_reference;
1060 args->buf_size = bufsize;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001061 printf("ioctl(%d, %s, {",
1062 btrfs_test_dir_fd, ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -04001063 btrfs_print_search_key(&key_reference);
1064 printf(", buf_size=%" PRIu64 "}", (uint64_t) args->buf_size);
1065 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH_V2, args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001066 printf(" => {key={nr_items=%u}, buf_size=%" PRIu64 ", ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001067 args->key.nr_items, (uint64_t)args->buf_size);
1068 btrfs_print_tree_search_buf(&args->key, args->buf,
1069 args->buf_size);
1070 printf("}) = 0\n");
1071
1072 args->key = key_reference;
1073 args->buf_size = sizeof(struct btrfs_ioctl_search_header);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001074 printf("ioctl(%d, %s, {",
1075 btrfs_test_dir_fd, ioc(BTRFS_IOC_TREE_SEARCH_V2));
Jeff Mahoney35866792016-05-18 18:09:42 -04001076 btrfs_print_search_key(&args->key);
1077 printf(", buf_size=%" PRIu64 "}", (uint64_t)args->buf_size);
1078 ioctl(btrfs_test_dir_fd, BTRFS_IOC_TREE_SEARCH_V2, args);
Jeff Mahoneyfd70b502016-05-26 23:33:05 -04001079 printf(" => {buf_size=%" PRIu64 "}) = -1 EOVERFLOW (%m)\n",
Jeff Mahoney35866792016-05-18 18:09:42 -04001080 (uint64_t)args->buf_size);
1081 free(args);
1082 }
1083}
1084
1085/*
1086 * Consumes argument, returns argument:
1087 * - BTRFS_IOC_INO_LOOKUP
1088 */
1089static void
1090btrfs_test_ino_lookup_ioctl(void)
1091{
1092 struct btrfs_ioctl_ino_lookup_args args = {
1093 .treeid = 5,
1094 .objectid = 256,
1095 };
1096
1097 ioctl(-1, BTRFS_IOC_INO_LOOKUP, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001098 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1099 ioc(BTRFS_IOC_INO_LOOKUP));
Jeff Mahoney35866792016-05-18 18:09:42 -04001100
Elliott Hughes03a418e2018-06-15 13:11:40 -07001101 printf("ioctl(-1, %s, {treeid=", ioc(BTRFS_IOC_INO_LOOKUP));
Jeff Mahoney35866792016-05-18 18:09:42 -04001102 btrfs_print_objectid(args.treeid);
1103 printf(", objectid=");
1104 btrfs_print_objectid(args.objectid);
1105 ioctl(-1, BTRFS_IOC_INO_LOOKUP, &args);
1106 printf("}) = -1 EBADF (%m)\n");
1107
1108 if (btrfs_test_root) {
Elliott Hughes03a418e2018-06-15 13:11:40 -07001109 printf("ioctl(%d, %s, {treeid=",
1110 btrfs_test_dir_fd, ioc(BTRFS_IOC_INO_LOOKUP));
Jeff Mahoney35866792016-05-18 18:09:42 -04001111 btrfs_print_objectid(args.treeid);
1112 printf(", objectid=");
1113 btrfs_print_objectid(args.objectid);
1114 ioctl(btrfs_test_dir_fd, BTRFS_IOC_INO_LOOKUP, &args);
1115 printf("} => {name=\"%s\"}) = 0\n", args.name);
1116 }
1117}
1118
1119/*
1120 * Consumes argument, returns argument:
1121 * - BTRFS_IOC_SPACE_INFO
1122 */
1123static void
1124btrfs_test_space_info_ioctl(void)
1125{
1126 struct btrfs_ioctl_space_args args = {};
1127
1128 ioctl(-1, BTRFS_IOC_SPACE_INFO, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001129 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1130 ioc(BTRFS_IOC_SPACE_INFO));
Jeff Mahoney35866792016-05-18 18:09:42 -04001131
1132 ioctl(-1, BTRFS_IOC_SPACE_INFO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001133 printf("ioctl(-1, %s, {space_slots=%" PRI__u64 "}) = -1 EBADF (%m)\n",
1134 ioc(BTRFS_IOC_SPACE_INFO), args.space_slots);
Jeff Mahoney35866792016-05-18 18:09:42 -04001135
1136 if (btrfs_test_root) {
1137 struct btrfs_ioctl_space_args args_passed;
1138 struct btrfs_ioctl_space_args *argsp;
1139 args_passed = args;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001140 printf("ioctl(%d, %s, {space_slots=%" PRI__u64 "}",
1141 btrfs_test_dir_fd, ioc(BTRFS_IOC_SPACE_INFO),
1142 args_passed.space_slots);
Jeff Mahoney35866792016-05-18 18:09:42 -04001143 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SPACE_INFO, &args_passed);
1144 printf(" => {total_spaces=%" PRI__u64 "}) = 0\n",
1145 args_passed.total_spaces);
1146
1147 argsp = malloc(sizeof(args) +
1148 args_passed.total_spaces * sizeof(args.spaces[0]));
1149 if (!argsp)
1150 perror_msg_and_fail("malloc failed");
1151
1152 *argsp = args;
1153 argsp->space_slots = args_passed.total_spaces;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001154 printf("ioctl(%d, %s, {space_slots=%" PRI__u64 "}",
1155 btrfs_test_dir_fd, ioc(BTRFS_IOC_SPACE_INFO),
1156 argsp->space_slots);
Jeff Mahoney35866792016-05-18 18:09:42 -04001157 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SPACE_INFO, argsp);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001158 printf(" => {total_spaces=%" PRI__u64 ", ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001159 argsp->total_spaces);
1160 if (verbose) {
1161 unsigned int i;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001162 printf("spaces=[");
Jeff Mahoney35866792016-05-18 18:09:42 -04001163 for (i = 0; i < argsp->total_spaces; i++) {
1164 struct btrfs_ioctl_space_info *info;
1165 info = &argsp->spaces[i];
1166 if (i)
1167 printf(", ");
1168 printf("{flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001169 prfl_btrfs(btrfs_space_info_flags, info->flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001170 "BTRFS_SPACE_INFO_???");
1171 printf(", total_bytes=%" PRI__u64
1172 ", used_bytes=%" PRI__u64 "}",
1173 info->total_bytes, info->used_bytes);
1174 }
1175
1176 printf("]");
1177 } else
1178 printf("...");
1179 printf("}) = 0\n");
1180 free(argsp);
1181 }
1182}
1183
1184/*
1185 * Consumes no arguments, returns nothing:
1186 * - BTRFS_IOC_SCRUB_CANCEL
1187 * Consumes argument, returns argument:
1188 - * BTRFS_IOC_SCRUB
1189 - * BTRFS_IOC_SCRUB_PROGRESS
1190 */
1191static void
1192btrfs_test_scrub_ioctls(void)
1193{
1194 struct btrfs_ioctl_scrub_args args = {
1195 .devid = 1,
1196 .start = 0,
1197 .end = -1ULL,
1198 .flags = max_flags_plus_one(0),
1199 };
1200
1201 ioctl(-1, BTRFS_IOC_SCRUB, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001202 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_SCRUB));
Jeff Mahoney35866792016-05-18 18:09:42 -04001203
1204 ioctl(-1, BTRFS_IOC_SCRUB_CANCEL, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001205 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_SCRUB_CANCEL));
Jeff Mahoney35866792016-05-18 18:09:42 -04001206
Elliott Hughes03a418e2018-06-15 13:11:40 -07001207 printf("ioctl(-1, %s, {devid=makedev(%u, %u)",
1208 ioc(BTRFS_IOC_SCRUB), major(args.devid), minor(args.devid));
1209 print_uint64(", start=", args.start);
1210 print_uint64(", end=", args.end);
1211 printf(", flags=");
1212 prfl_btrfs(btrfs_scrub_flags, args.flags, "BTRFS_SCRUB_???");
Jeff Mahoney35866792016-05-18 18:09:42 -04001213 ioctl(-1, BTRFS_IOC_SCRUB, &args);
1214 printf("}) = -1 EBADF (%m)\n");
1215
1216 ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001217 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1218 ioc(BTRFS_IOC_SCRUB_PROGRESS));
Jeff Mahoney35866792016-05-18 18:09:42 -04001219
1220 ioctl(-1, BTRFS_IOC_SCRUB_PROGRESS, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001221 printf("ioctl(-1, %s, {devid=makedev(%u, %u)}) = -1 EBADF (%m)\n",
1222 ioc(BTRFS_IOC_SCRUB_PROGRESS),
1223 major(args.devid), minor(args.devid));
Jeff Mahoney35866792016-05-18 18:09:42 -04001224}
1225
1226/*
1227 * Consumes argument, returns argument:
1228 * - BTRFS_IOC_DEV_INFO
1229 */
1230static void
1231btrfs_test_dev_info_ioctl(void)
1232{
1233 struct btrfs_ioctl_dev_info_args args = {
1234 .devid = 1,
1235 };
1236 memcpy(&args.uuid, uuid_reference, BTRFS_UUID_SIZE);
1237
1238 ioctl(-1, BTRFS_IOC_DEV_INFO, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001239 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1240 ioc(BTRFS_IOC_DEV_INFO));
Jeff Mahoney35866792016-05-18 18:09:42 -04001241
1242 ioctl(-1, BTRFS_IOC_DEV_INFO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001243 printf("ioctl(-1, %s, "
1244 "{devid=makedev(%u, %u), uuid=%s}) = -1 EBADF (%m)\n",
1245 ioc(BTRFS_IOC_DEV_INFO), major(args.devid), minor(args.devid),
1246 uuid_reference_string);
Jeff Mahoney35866792016-05-18 18:09:42 -04001247}
1248
1249/*
1250 * Consumes argument, returns argument:
1251 * - BTRFS_IOC_INO_PATHS
1252 * - BTRFS_IOC_LOGICAL_INO
1253 */
1254static void
1255btrfs_test_ino_path_ioctls(void)
1256{
1257 char buf[16384];
1258 struct btrfs_ioctl_ino_path_args args = {
1259 .inum = 256,
1260 .size = sizeof(buf),
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001261 .reserved = {
1262 0xdeadc0defacefeebULL,
1263 0xdeadc0defacefeecULL,
1264 0xdeadc0defacefeedULL,
1265 },
1266 .fspath = 0,
Jeff Mahoney35866792016-05-18 18:09:42 -04001267 };
1268
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001269#ifdef HAVE_BTRFS_IOCTL_LOGICAL_INO_ARGS
1270 args.flags =
1271#else
1272 args.reserved[3] =
1273#endif
1274 0xdeadc0defacefeeeULL;
1275
1276
Jeff Mahoney35866792016-05-18 18:09:42 -04001277 ioctl(-1, BTRFS_IOC_INO_PATHS, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001278 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1279 ioc(BTRFS_IOC_INO_PATHS));
Jeff Mahoney35866792016-05-18 18:09:42 -04001280
1281 ioctl(-1, BTRFS_IOC_LOGICAL_INO, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001282 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1283 ioc(BTRFS_IOC_LOGICAL_INO));
Jeff Mahoney35866792016-05-18 18:09:42 -04001284
1285 ioctl(-1, BTRFS_IOC_INO_PATHS, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001286 printf("ioctl(-1, %s, {inum=%" PRI__u64 ", size=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001287 ", fspath=NULL}) = -1 EBADF (%m)\n",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001288 ioc(BTRFS_IOC_INO_PATHS), args.inum, args.size);
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001289
1290 args.fspath = (uintptr_t) buf;
1291 ioctl(-1, BTRFS_IOC_INO_PATHS, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001292 printf("ioctl(-1, %s, {inum=%" PRI__u64 ", size=%" PRI__u64
Jeff Mahoney35866792016-05-18 18:09:42 -04001293 ", fspath=0x%" PRI__x64 "}) = -1 EBADF (%m)\n",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001294 ioc(BTRFS_IOC_INO_PATHS), args.inum, args.size, args.fspath);
Jeff Mahoney35866792016-05-18 18:09:42 -04001295
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001296 args.fspath = 0;
Jeff Mahoney35866792016-05-18 18:09:42 -04001297 ioctl(-1, BTRFS_IOC_LOGICAL_INO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001298 printf("ioctl(-1, %s, {logical=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001299 ", size=%" PRI__u64 ", reserved=[0xdeadc0defacefeeb"
1300 ", 0xdeadc0defacefeec, 0xdeadc0defacefeed]"
1301 ", flags=0xdeadc0defacefeee /* BTRFS_LOGICAL_INO_ARGS_??? */"
1302 ", inodes=NULL}) = -1 EBADF (%m)\n",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001303 ioc(BTRFS_IOC_LOGICAL_INO), args.inum, args.size);
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001304
1305 args.fspath = (uintptr_t) buf;
1306 args.reserved[0] = 0;
1307 args.reserved[2] = 0;
1308#ifdef HAVE_BTRFS_IOCTL_LOGICAL_INO_ARGS
1309 args.flags =
1310#else
1311 args.reserved[3] =
1312#endif
1313 1;
1314
1315 ioctl(-1, BTRFS_IOC_LOGICAL_INO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001316 printf("ioctl(-1, %s, {logical=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001317 ", size=%" PRI__u64 ", reserved=[0, 0xdeadc0defacefeec, 0]"
Elliott Hughes03a418e2018-06-15 13:11:40 -07001318 ", flags=%sBTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET%s"
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001319 ", inodes=0x%" PRI__x64 "}) = -1 EBADF (%m)\n",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001320 ioc(BTRFS_IOC_LOGICAL_INO), args.inum, args.size,
1321 verbose_xlat ? "0x1 /* " : "", verbose_xlat ? " */" : "",
1322 args.fspath);
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001323
1324 args.reserved[1] = 0;
1325#ifdef HAVE_BTRFS_IOCTL_LOGICAL_INO_ARGS
1326 args.flags =
1327#else
1328 args.reserved[3] =
1329#endif
1330 0;
1331
1332 ioctl(-1, BTRFS_IOC_LOGICAL_INO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001333 printf("ioctl(-1, %s, {logical=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001334 ", size=%" PRI__u64 ", flags=0, inodes=0x%" PRI__x64
Elliott Hughes03a418e2018-06-15 13:11:40 -07001335 "}) = -1 EBADF (%m)\n",
1336 ioc(BTRFS_IOC_LOGICAL_INO), args.inum, args.size, args.fspath);
Jeff Mahoney35866792016-05-18 18:09:42 -04001337
Dmitry V. Levin22129182016-05-24 01:32:09 +00001338#ifdef HAVE_LINUX_FIEMAP_H
Jeff Mahoney35866792016-05-18 18:09:42 -04001339 if (btrfs_test_root) {
1340 int size;
1341 struct stat si;
1342 int ret;
1343 struct btrfs_data_container *data = (void *)buf;
1344 struct fiemap *fiemap;
1345 int fd;
1346
1347 ret = fstat(btrfs_test_dir_fd, &si);
1348 if (ret)
1349 perror_msg_and_fail("fstat failed");
1350
1351 args.inum = si.st_ino;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001352 printf("ioctl(%d, %s, {inum=%" PRI__u64 ", size=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001353 ", fspath=0x%" PRI__x64 "}",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001354 btrfs_test_dir_fd, ioc(BTRFS_IOC_INO_PATHS),
1355 args.inum, args.size, args.fspath);
Jeff Mahoney35866792016-05-18 18:09:42 -04001356 ioctl(btrfs_test_dir_fd, BTRFS_IOC_INO_PATHS, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001357 printf(" => {fspath={bytes_left=%u, bytes_missing=%u, elem_cnt=%u, elem_missed=%u, ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001358 data->bytes_left, data->bytes_missing, data->elem_cnt,
1359 data->elem_missed);
1360 if (verbose) {
Elliott Hughes03a418e2018-06-15 13:11:40 -07001361 printf("val=[\"%s\"]", dir_name);
Jeff Mahoney35866792016-05-18 18:09:42 -04001362 } else
1363 printf("...");
1364 printf("}}) = 0\n");
1365
1366 fd = openat(btrfs_test_dir_fd, "file1", O_RDWR|O_CREAT, 0600);
1367 if (fd < 0)
1368 perror_msg_and_fail("openat(file1) failed");
1369
1370 ret = fstat(fd, &si);
1371 if (ret)
1372 perror_msg_and_fail("fstat failed");
1373
1374 if (write(fd, buf, sizeof(buf)) < 0)
1375 perror_msg_and_fail("write: fd");
1376
1377 /*
1378 * Force delalloc so we can actually
1379 * search for the extent.
1380 */
1381 fsync(fd);
1382 ioctl(fd, BTRFS_IOC_SYNC, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001383 printf("ioctl(%d, %s) = 0\n", fd, ioc(BTRFS_IOC_SYNC));
Jeff Mahoney35866792016-05-18 18:09:42 -04001384
1385 size = sizeof(*fiemap) + 2 * sizeof(fiemap->fm_extents[0]);
1386 fiemap = malloc(size);
1387 if (!fiemap)
1388 perror_msg_and_fail("malloc failed");
1389 memset(fiemap, 0, size);
1390
1391 fiemap->fm_length = sizeof(buf);
1392 fiemap->fm_extent_count = 2;
1393
1394 /* This is also a live test for FIEMAP */
Elliott Hughes03a418e2018-06-15 13:11:40 -07001395 printf("ioctl(%d, %s, {fm_start=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001396 ", fm_length=%" PRI__u64 ", fm_flags=",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001397 fd, ioc(FS_IOC_FIEMAP),
1398 fiemap->fm_start, fiemap->fm_length);
1399 prfl_btrfs(fiemap_flags, fiemap->fm_flags, "FIEMAP_FLAG_???");
Jeff Mahoney35866792016-05-18 18:09:42 -04001400 printf(", fm_extent_count=%u}", fiemap->fm_extent_count);
1401 ioctl(fd, FS_IOC_FIEMAP, fiemap);
1402 printf(" => {fm_flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001403 prfl_btrfs(fiemap_flags, fiemap->fm_flags, "FIEMAP_FLAG_???");
1404 printf(", fm_mapped_extents=%u, ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001405 fiemap->fm_mapped_extents);
1406 if (verbose) {
Elliott Hughes03a418e2018-06-15 13:11:40 -07001407 printf("fm_extents=[");
Jeff Mahoney35866792016-05-18 18:09:42 -04001408 unsigned int i;
1409 for (i = 0; i < fiemap->fm_mapped_extents; i++) {
1410 struct fiemap_extent *fe;
1411 fe = &fiemap->fm_extents[i];
1412 if (i)
1413 printf(", ");
1414 printf("{fe_logical=%" PRI__u64
1415 ", fe_physical=%" PRI__u64
1416 ", fe_length=%" PRI__u64
1417 ", ",
1418 fe->fe_logical, fe->fe_physical,
1419 fe->fe_length);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001420 prfl_btrfs(fiemap_extent_flags, fe->fe_flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001421 "FIEMAP_EXTENT_???");
1422 printf("}");
1423 }
1424 printf("]");
1425 } else
1426 printf("...");
1427 printf("}) = 0\n");
1428
1429 args.inum = fiemap->fm_extents[0].fe_physical;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001430 printf("ioctl(%d, %s, {logical=%" PRI__u64
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001431 ", size=%" PRI__u64 ", flags=0, inodes=0x%" PRI__x64 "}",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001432 fd, ioc(BTRFS_IOC_LOGICAL_INO),
1433 args.inum, args.size, args.fspath);
Jeff Mahoney35866792016-05-18 18:09:42 -04001434 ioctl(fd, BTRFS_IOC_LOGICAL_INO, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001435 printf(" => {inodes={bytes_left=%u, bytes_missing=%u, elem_cnt=%u, elem_missed=%u, ",
Jeff Mahoney35866792016-05-18 18:09:42 -04001436 data->bytes_left, data->bytes_missing, data->elem_cnt,
1437 data->elem_missed);
1438 if (verbose) {
Elliott Hughes03a418e2018-06-15 13:11:40 -07001439 printf("val=[{inum=%llu, offset=0, root=5}]",
Gleb Fotengauer-Malinovskiye79f0382016-05-24 18:09:46 +03001440 (unsigned long long) si.st_ino);
Jeff Mahoney35866792016-05-18 18:09:42 -04001441 } else
1442 printf("...");
1443 printf("}}) = 0\n");
1444 close(fd);
1445 free(fiemap);
1446 }
Dmitry V. Levin22129182016-05-24 01:32:09 +00001447#endif /* HAVE_LINUX_FIEMAP_H */
Jeff Mahoney35866792016-05-18 18:09:42 -04001448}
1449
1450/*
1451 * Consumes argument, returns argument:
1452 * - BTRFS_IOC_SET_RECEIVED_SUBVOL
1453 */
1454static void
1455btrfs_test_set_received_subvol_ioctl(void)
1456{
1457 struct btrfs_ioctl_received_subvol_args args = {
1458 .stransid = 0x12345,
1459 .stime = {
1460 .sec = 1463193386,
1461 .nsec = 12345,
1462 },
1463 };
Elliott Hughes03a418e2018-06-15 13:11:40 -07001464 int saved_errno;
1465
Jeff Mahoney35866792016-05-18 18:09:42 -04001466 memcpy(&args.uuid, uuid_reference, BTRFS_UUID_SIZE);
1467
1468 ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001469 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1470 ioc(BTRFS_IOC_SET_RECEIVED_SUBVOL));
Jeff Mahoney35866792016-05-18 18:09:42 -04001471
1472 ioctl(-1, BTRFS_IOC_SET_RECEIVED_SUBVOL, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001473 saved_errno = errno;
1474 printf("ioctl(-1, %s, {uuid=%s, stransid=%" PRI__u64
1475 ", stime={sec=%" PRI__u64 ", nsec=%u}",
1476 ioc(BTRFS_IOC_SET_RECEIVED_SUBVOL), uuid_reference_string,
1477 args.stransid, args.stime.sec, args.stime.nsec);
1478 print_time_t_nsec(args.stime.sec, args.stime.nsec, true);
1479 errno = saved_errno;
1480 printf(", flags=0}) = -1 EBADF (%m)\n");
Jeff Mahoney35866792016-05-18 18:09:42 -04001481}
1482
1483/*
1484 * Consumes argument, returns nothing (output is via send_fd)
1485 * - BTRFS_IOC_SEND
1486 */
1487static void
1488btrfs_test_send_ioctl(void)
1489{
1490 uint64_t u64_array[2] = { 256, 257 };
1491 struct btrfs_ioctl_send_args args = {
1492 .send_fd = 4,
1493 .parent_root = 257,
1494 .flags = max_flags_plus_one(2),
1495 };
1496
1497 ioctl(-1, BTRFS_IOC_SEND, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001498 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_SEND));
Jeff Mahoney35866792016-05-18 18:09:42 -04001499
Elliott Hughes03a418e2018-06-15 13:11:40 -07001500 printf("ioctl(-1, %s, {send_fd=%d, clone_sources_count=%" PRI__u64
1501 ", clone_sources=NULL",
1502 ioc(BTRFS_IOC_SEND),
Dmitry V. Levin6ce6d3b2016-05-24 01:53:02 +00001503 (int) args.send_fd, args.clone_sources_count);
Jeff Mahoney35866792016-05-18 18:09:42 -04001504 printf(", parent_root=");
1505 btrfs_print_objectid(args.parent_root);
1506 printf(", flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001507 prfl_btrfs(btrfs_send_flags, args.flags, "BTRFS_SEND_FLAGS_???");
Jeff Mahoney35866792016-05-18 18:09:42 -04001508 ioctl(-1, BTRFS_IOC_SEND, &args);
1509 printf("}) = -1 EBADF (%m)\n");
1510
1511 args.clone_sources_count = 2;
Dmitry V. Levinde5b0092016-07-26 15:59:28 +00001512 args.clone_sources = (__u64 *) (void *) u64_array;
Jeff Mahoney35866792016-05-18 18:09:42 -04001513
Elliott Hughes03a418e2018-06-15 13:11:40 -07001514 printf("ioctl(-1, %s, {send_fd=%d, clone_sources_count=%" PRI__u64
Dmitry V. Levin6ce6d3b2016-05-24 01:53:02 +00001515 ", clone_sources=",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001516 ioc(BTRFS_IOC_SEND),
Dmitry V. Levin6ce6d3b2016-05-24 01:53:02 +00001517 (int) args.send_fd, args.clone_sources_count);
Jeff Mahoney35866792016-05-18 18:09:42 -04001518 if (verbose) {
1519 printf("[");
1520 btrfs_print_objectid(u64_array[0]);
1521 printf(", ");
1522 btrfs_print_objectid(u64_array[1]);
1523 printf("]");
1524 } else
Elliott Hughes03a418e2018-06-15 13:11:40 -07001525 printf("%p", args.clone_sources);
Jeff Mahoney35866792016-05-18 18:09:42 -04001526 printf(", parent_root=");
1527 btrfs_print_objectid(args.parent_root);
1528 printf(", flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001529 prfl_btrfs(btrfs_send_flags, args.flags, "BTRFS_SEND_FLAGS_???");
Jeff Mahoney35866792016-05-18 18:09:42 -04001530 ioctl(-1, BTRFS_IOC_SEND, &args);
1531 printf("}) = -1 EBADF (%m)\n");
1532}
1533
1534/*
1535 * Consumes argument, returns nothing:
1536 * - BTRFS_IOC_QUOTA_CTL
1537 */
1538static void
1539btrfs_test_quota_ctl_ioctl(void)
1540{
1541 struct btrfs_ioctl_quota_ctl_args args = {
1542 .cmd = 1,
1543 };
1544
1545 ioctl(-1, BTRFS_IOC_QUOTA_CTL, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001546 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1547 ioc(BTRFS_IOC_QUOTA_CTL));
Jeff Mahoney35866792016-05-18 18:09:42 -04001548
1549 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001550 printf("ioctl(-1, %s, {cmd=%sBTRFS_QUOTA_CTL_ENABLE%s}) "
1551 "= -1 EBADF (%m)\n",
1552 ioc(BTRFS_IOC_QUOTA_CTL),
1553 verbose_xlat ? "0x1 /* " : "",
1554 verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -04001555
1556 args.cmd = 2;
1557 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001558 printf("ioctl(-1, %s, {cmd=%sBTRFS_QUOTA_CTL_DISABLE%s}) "
1559 "= -1 EBADF (%m)\n",
1560 ioc(BTRFS_IOC_QUOTA_CTL),
1561 verbose_xlat ? "0x2 /* " : "",
1562 verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -04001563
1564 args.cmd = 3;
1565 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001566 printf("ioctl(-1, %s, "
1567 "{cmd=%sBTRFS_QUOTA_CTL_RESCAN__NOTUSED%s}) = -1 EBADF (%m)\n",
1568 ioc(BTRFS_IOC_QUOTA_CTL),
1569 verbose_xlat ? "0x3 /* " : "",
1570 verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -04001571
1572 args.cmd = 4;
1573 ioctl(-1, BTRFS_IOC_QUOTA_CTL, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001574 printf("ioctl(-1, %s, "
1575 "{cmd=0x4 /* BTRFS_QUOTA_CTL_??? */}) = -1 EBADF (%m)\n",
1576 ioc(BTRFS_IOC_QUOTA_CTL));
Jeff Mahoney35866792016-05-18 18:09:42 -04001577}
1578
1579/*
1580 * Consumes argument, returns nothing:
1581 * - BTRFS_IOC_QGROUP_ASSIGN
1582 */
1583static void
1584btrfs_test_qgroup_assign_ioctl(void)
1585{
1586 struct btrfs_ioctl_qgroup_assign_args args = {
1587 .assign = 1,
1588 .src = 257,
1589 .dst = 258,
1590 };
1591
1592 ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001593 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1594 ioc(BTRFS_IOC_QGROUP_ASSIGN));
Jeff Mahoney35866792016-05-18 18:09:42 -04001595
1596 ioctl(-1, BTRFS_IOC_QGROUP_ASSIGN, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001597 printf("ioctl(-1, %s, "
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001598 "{assign=%" PRI__u64 ", src=%" PRI__u64 ", dst=%" PRI__u64
Elliott Hughes03a418e2018-06-15 13:11:40 -07001599 "}) = -1 EBADF (%m)\n",
1600 ioc(BTRFS_IOC_QGROUP_ASSIGN), args.assign, args.src, args.dst);
Jeff Mahoney35866792016-05-18 18:09:42 -04001601}
1602
1603/*
1604 * Consumes argument, returns nothing:
1605 * - BTRFS_IOC_QGROUP_CREATE
1606 */
1607static void
1608btrfs_test_qgroup_create_ioctl(void)
1609{
1610 struct btrfs_ioctl_qgroup_create_args args = {
1611 .create = 1,
1612 .qgroupid = 257,
1613 };
1614
1615 ioctl(-1, BTRFS_IOC_QGROUP_CREATE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001616 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_QGROUP_CREATE));
Jeff Mahoney35866792016-05-18 18:09:42 -04001617
1618 ioctl(-1, BTRFS_IOC_QGROUP_CREATE, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001619 printf("ioctl(-1, %s, "
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001620 "{create=%" PRI__u64 ", qgroupid=%" PRI__u64
Elliott Hughes03a418e2018-06-15 13:11:40 -07001621 "}) = -1 EBADF (%m)\n",
1622 ioc(BTRFS_IOC_QGROUP_CREATE), args.create, args.qgroupid);
Jeff Mahoney35866792016-05-18 18:09:42 -04001623}
1624
1625/*
1626 * Consumes nothing, returns nothing:
1627 * - BTRFS_IOC_QUOTA_RESCAN_WAIT
1628 * Consumes argument, returns nothing:
1629 * - BTRFS_IOC_QUOTA_RESCAN
1630 */
1631static void
1632btrfs_test_quota_rescan_ioctl(void)
1633{
1634 struct btrfs_ioctl_quota_rescan_args args = {
1635 .progress = 1,
1636 };
1637
1638 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001639 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1640 ioc(BTRFS_IOC_QUOTA_RESCAN));
Jeff Mahoney35866792016-05-18 18:09:42 -04001641
1642 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001643 printf("ioctl(-1, %s, {flags=0}) = -1 EBADF (%m)\n",
1644 ioc(BTRFS_IOC_QUOTA_RESCAN));
Jeff Mahoney35866792016-05-18 18:09:42 -04001645 ioctl(-1, BTRFS_IOC_QUOTA_RESCAN_WAIT, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001646 printf("ioctl(-1, %s) = -1 EBADF (%m)\n",
1647 ioc(BTRFS_IOC_QUOTA_RESCAN_WAIT));
Jeff Mahoney35866792016-05-18 18:09:42 -04001648
1649}
1650
1651/*
1652 * Consumes argument, returns nothing:
1653 * - BTRFS_IOC_SET_FSLABEL
1654 *
1655 * Consumes no argument, returns argument:
1656 * - BTRFS_IOC_GET_FS_LABEL
1657 */
1658static void
1659btrfs_test_label_ioctls(void)
1660{
1661 char label[BTRFS_LABEL_SIZE] = "btrfs-label";
1662
1663 ioctl(-1, BTRFS_IOC_SET_FSLABEL, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001664 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1665 ioc(BTRFS_IOC_SET_FSLABEL));
Jeff Mahoney35866792016-05-18 18:09:42 -04001666
1667 ioctl(-1, BTRFS_IOC_SET_FSLABEL, label);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001668 printf("ioctl(-1, %s, \"%s\") = -1 EBADF (%m)\n",
1669 ioc(BTRFS_IOC_SET_FSLABEL), label);
Jeff Mahoney35866792016-05-18 18:09:42 -04001670
1671 if (write_ok) {
1672 ioctl(btrfs_test_dir_fd, BTRFS_IOC_SET_FSLABEL, label);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001673 printf("ioctl(%d, %s, \"%s\") = 0\n",
1674 btrfs_test_dir_fd, ioc(BTRFS_IOC_SET_FSLABEL), label);
Jeff Mahoney35866792016-05-18 18:09:42 -04001675
1676 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_FSLABEL, label);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001677 printf("ioctl(%d, %s, \"%s\") = 0\n",
1678 btrfs_test_dir_fd, ioc(BTRFS_IOC_GET_FSLABEL), label);
Jeff Mahoney35866792016-05-18 18:09:42 -04001679 }
1680}
1681
1682/*
1683 * Consumes argument, returns argument:
1684 * - BTRFS_IOC_GET_DEV_STATS
1685 */
1686static void
1687btrfs_test_get_dev_stats_ioctl(void)
1688{
1689 struct btrfs_ioctl_get_dev_stats args = {
1690 .devid = 1,
1691 .nr_items = 5,
1692 .flags = max_flags_plus_one(0),
1693 };
1694
1695 ioctl(-1, BTRFS_IOC_GET_DEV_STATS, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001696 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_GET_DEV_STATS));
Jeff Mahoney35866792016-05-18 18:09:42 -04001697
Elliott Hughes03a418e2018-06-15 13:11:40 -07001698 printf("ioctl(-1, %s, {devid=makedev(%u, %u)"
1699 ", nr_items=%" PRI__u64 ", flags=",
1700 ioc(BTRFS_IOC_GET_DEV_STATS),
1701 major(args.devid), minor(args.devid), args.nr_items);
1702 prfl_btrfs(btrfs_dev_stats_flags, args.flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001703 "BTRFS_DEV_STATS_???");
1704 ioctl(-1, BTRFS_IOC_GET_DEV_STATS, &args);
1705 printf("}) = -1 EBADF (%m)\n");
1706
1707 if (write_ok) {
1708 unsigned int i;
1709 args.flags = BTRFS_DEV_STATS_RESET;
Elliott Hughes03a418e2018-06-15 13:11:40 -07001710 printf("ioctl(%d, %s, {devid=makedev(%u, %u)"
Elliott Hughes28e98bc2018-06-14 16:59:04 -07001711 ", nr_items=%" PRI__u64 ", flags=",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001712 btrfs_test_dir_fd, ioc(BTRFS_IOC_GET_DEV_STATS),
1713 major(args.devid), minor(args.devid), args.nr_items);
1714 prfl_btrfs(btrfs_dev_stats_flags, args.flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001715 "BTRFS_DEV_STATS_???");
1716 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_DEV_STATS, &args);
1717 printf("} => {nr_items=%" PRI__u64 ", flags=",
1718 args.nr_items);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001719 prfl_btrfs(btrfs_dev_stats_flags, args.flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001720 "BTRFS_DEV_STATS_???");
1721 printf(", [");
1722 for (i = 0; i < args.nr_items; i++) {
1723 const char *name = xlookup(btrfs_dev_stats_values, i);
1724 if (i)
1725 printf(", ");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001726
1727 if (name) {
1728 if (verbose_xlat)
1729 printf("[%u /* %s */] = ", i, name);
1730 else
1731 printf("[%s] = ", name);
1732 } else {
1733 printf("[%u] = ", i);
1734 }
1735
Jeff Mahoney35866792016-05-18 18:09:42 -04001736 printf("%" PRI__u64, args.values[i]);
1737 }
1738 printf("]}) = 0\n");
1739 }
1740}
1741
1742/*
1743 * Consumes argument, returns argument:
1744 * - BTRFS_IOC_DEV_REPLACE
1745 *
1746 * Test environment for this is more difficult; It's better to do it by hand.
1747 */
1748static void
1749btrfs_test_dev_replace_ioctl(void)
1750{
1751 struct btrfs_ioctl_dev_replace_args args = {
1752 .cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_START,
Jeff Mahoney35866792016-05-18 18:09:42 -04001753 };
Elliott Hughesd35df492017-02-15 15:19:05 -08001754 args.start.srcdevid = 1;
Jeff Mahoney35866792016-05-18 18:09:42 -04001755 strcpy((char *)args.start.srcdev_name, "/dev/sda1");
1756 strcpy((char *)args.start.tgtdev_name, "/dev/sdb1");
1757
1758 /* struct btrfs_ioctl_dev_replace_args */
1759 ioctl(-1, BTRFS_IOC_DEV_REPLACE, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001760 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", ioc(BTRFS_IOC_DEV_REPLACE));
Jeff Mahoney35866792016-05-18 18:09:42 -04001761
Elliott Hughes03a418e2018-06-15 13:11:40 -07001762 for (unsigned long i = 0; i < 3; i++) {
1763 int saved_errno;
1764
1765 args.start.cont_reading_from_srcdev_mode = i;
1766 ioctl(-1, BTRFS_IOC_DEV_REPLACE, &args);
1767 saved_errno = errno;
1768 printf("ioctl(-1, %s, "
1769 "{cmd=%sBTRFS_IOCTL_DEV_REPLACE_CMD_START%s"
1770 ", start={srcdevid=makedev(%u, %u)"
1771 ", cont_reading_from_srcdev_mode=",
1772 ioc(BTRFS_IOC_DEV_REPLACE),
1773 verbose_xlat ? "0 /* " : "", verbose_xlat ? " */" : "",
1774 major(args.start.srcdevid), minor(args.start.srcdevid));
1775 prxval_btrfs(btrfs_cont_reading_from_srcdev_mode,
1776 args.start.cont_reading_from_srcdev_mode,
1777 "BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV"
1778 "_MODE_???", i < 2);
1779 errno = saved_errno;
1780 printf(", srcdev_name=\"%s\", tgtdev_name=\"%s\"}}) "
1781 "= -1 EBADF (%m)\n",
1782 (char *)args.start.srcdev_name,
1783 (char *)args.start.tgtdev_name);
1784 }
Jeff Mahoney35866792016-05-18 18:09:42 -04001785
1786 args.cmd = 1;
1787 ioctl(-1, BTRFS_IOC_DEV_REPLACE, &args);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001788 printf("ioctl(-1, %s, {cmd=%sBTRFS_IOCTL_DEV_REPLACE_CMD_STATUS%s}) "
1789 "= -1 EBADF (%m)\n",
1790 ioc(BTRFS_IOC_DEV_REPLACE),
1791 verbose_xlat ? "0x1 /* " : "", verbose_xlat ? " */" : "");
Jeff Mahoney35866792016-05-18 18:09:42 -04001792}
1793
1794static void
1795btrfs_test_extent_same_ioctl(void)
1796{
Dmitry V. Levinea516df2016-05-24 02:40:13 +00001797#ifdef BTRFS_IOC_FILE_EXTENT_SAME
Jeff Mahoney35866792016-05-18 18:09:42 -04001798 struct file_dedupe_range args = {
1799 .src_offset = 1024,
1800 .src_length = 10240,
1801 };
1802 struct file_dedupe_range *argsp;
1803
1804 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001805 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1806 sprint_xlat_(BTRFS_IOC_FILE_EXTENT_SAME,
1807 "BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE"));
Jeff Mahoney35866792016-05-18 18:09:42 -04001808
Elliott Hughes03a418e2018-06-15 13:11:40 -07001809 printf("ioctl(-1, %s, "
Jeff Mahoney35866792016-05-18 18:09:42 -04001810 "{src_offset=%" PRIu64
1811 ", src_length=%" PRIu64
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001812 ", dest_count=%hu, info=[]",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001813 sprint_xlat_(BTRFS_IOC_FILE_EXTENT_SAME,
1814 "BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE"),
Jeff Mahoney35866792016-05-18 18:09:42 -04001815 (uint64_t)args.src_offset,
1816 (uint64_t)args.src_length, args.dest_count);
Jeff Mahoney35866792016-05-18 18:09:42 -04001817 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, &args);
1818 printf("}) = -1 EBADF (%m)\n");
1819
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001820 argsp = malloc(sizeof(*argsp) + sizeof(argsp->info[0]) * 3);
Jeff Mahoney35866792016-05-18 18:09:42 -04001821 if (!argsp)
1822 perror_msg_and_fail("malloc failed");
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001823 memset(argsp, 0, sizeof(*argsp) + sizeof(argsp->info[0]) * 3);
Jeff Mahoney35866792016-05-18 18:09:42 -04001824
1825 *argsp = args;
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001826 argsp->dest_count = 3;
Jeff Mahoney35866792016-05-18 18:09:42 -04001827 argsp->info[0].dest_fd = 2;
1828 argsp->info[0].dest_offset = 0;
1829 argsp->info[1].dest_fd = 2;
1830 argsp->info[1].dest_offset = 10240;
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001831 argsp->info[2].dest_fd = 2;
1832 argsp->info[2].dest_offset = 20480;
Jeff Mahoney35866792016-05-18 18:09:42 -04001833
Elliott Hughes03a418e2018-06-15 13:11:40 -07001834 printf("ioctl(-1, %s, "
Jeff Mahoney35866792016-05-18 18:09:42 -04001835 "{src_offset=%" PRIu64
1836 ", src_length=%" PRIu64
1837 ", dest_count=%hu, info=",
Elliott Hughes03a418e2018-06-15 13:11:40 -07001838 sprint_xlat_(BTRFS_IOC_FILE_EXTENT_SAME,
1839 "BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE"),
Jeff Mahoney35866792016-05-18 18:09:42 -04001840 (int64_t)argsp->src_offset,
1841 (uint64_t)argsp->src_length, argsp->dest_count);
Jeff Mahoney35866792016-05-18 18:09:42 -04001842 printf("[{dest_fd=%" PRId64 ", dest_offset=%" PRIu64
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001843 "}, {dest_fd=%" PRId64 ", dest_offset=%"PRIu64 "}",
Jeff Mahoney35866792016-05-18 18:09:42 -04001844 (int64_t)argsp->info[0].dest_fd,
1845 (uint64_t)argsp->info[0].dest_offset,
1846 (int64_t)argsp->info[1].dest_fd,
1847 (uint64_t)argsp->info[1].dest_offset);
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001848 if (verbose)
1849 printf(", {dest_fd=%" PRId64 ", dest_offset=%" PRIu64 "}",
1850 (int64_t)argsp->info[2].dest_fd,
1851 (uint64_t)argsp->info[2].dest_offset);
Jeff Mahoney35866792016-05-18 18:09:42 -04001852 else
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001853 printf(", ...");
1854 printf("]");
Jeff Mahoney35866792016-05-18 18:09:42 -04001855 ioctl(-1, BTRFS_IOC_FILE_EXTENT_SAME, argsp);
1856 printf("}) = -1 EBADF (%m)\n");
1857
1858 if (write_ok) {
1859 int fd1, fd2;
1860 char buf[16384];
Jeff Mahoney35866792016-05-18 18:09:42 -04001861
1862 memset(buf, 0, sizeof(buf));
1863
1864 fd1 = openat(btrfs_test_dir_fd, "file1", O_RDWR|O_CREAT, 0600);
1865 if (fd1 < 0)
1866 perror_msg_and_fail("open file1 failed");
1867
1868 fd2 = openat(btrfs_test_dir_fd, "file2", O_RDWR|O_CREAT, 0600);
1869 if (fd2 < 0)
1870 perror_msg_and_fail("open file2 failed");
1871
1872 if (write(fd1, buf, sizeof(buf)) < 0)
1873 perror_msg_and_fail("write: fd1");
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001874 if (write(fd1, buf, sizeof(buf)) < 0)
1875 perror_msg_and_fail("write: fd1");
1876 if (write(fd2, buf, sizeof(buf)) < 0)
1877 perror_msg_and_fail("write: fd2");
Jeff Mahoney35866792016-05-18 18:09:42 -04001878 if (write(fd2, buf, sizeof(buf)) < 0)
1879 perror_msg_and_fail("write: fd2");
1880
1881 close(fd2);
1882 fd2 = openat(btrfs_test_dir_fd, "file2", O_RDONLY);
1883 if (fd2 < 0)
1884 perror_msg_and_fail("open file2 failed");
1885
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001886 memset(argsp, 0, sizeof(*argsp) + sizeof(argsp->info[0]) * 3);
Jeff Mahoney35866792016-05-18 18:09:42 -04001887
1888 argsp->src_offset = 0;
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001889 argsp->src_length = 4096;
1890 argsp->dest_count = 3;
Jeff Mahoney35866792016-05-18 18:09:42 -04001891 argsp->info[0].dest_fd = fd2;
1892 argsp->info[0].dest_offset = 0;
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001893 argsp->info[1].dest_fd = fd2;
1894 argsp->info[1].dest_offset = 10240;
1895 argsp->info[2].dest_fd = fd2;
1896 argsp->info[2].dest_offset = 20480;
Jeff Mahoney35866792016-05-18 18:09:42 -04001897
Elliott Hughes03a418e2018-06-15 13:11:40 -07001898 printf("ioctl(%d, %s, "
Jeff Mahoney35866792016-05-18 18:09:42 -04001899 "{src_offset=%" PRIu64 ", src_length=%" PRIu64
1900 ", dest_count=%hu, info=", fd1,
Elliott Hughes03a418e2018-06-15 13:11:40 -07001901 sprint_xlat_(BTRFS_IOC_FILE_EXTENT_SAME,
1902 "BTRFS_IOC_FILE_EXTENT_SAME"
1903 " or FIDEDUPERANGE"),
Jeff Mahoney35866792016-05-18 18:09:42 -04001904 (uint64_t)argsp->src_offset,
1905 (uint64_t)argsp->src_length, argsp->dest_count);
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001906 printf("[{dest_fd=%" PRId64 ", dest_offset=%" PRIu64
1907 "}, {dest_fd=%" PRId64 ", dest_offset=%"PRIu64 "}",
1908 (int64_t)argsp->info[0].dest_fd,
1909 (uint64_t)argsp->info[0].dest_offset,
1910 (int64_t)argsp->info[1].dest_fd,
1911 (uint64_t)argsp->info[1].dest_offset);
Jeff Mahoney35866792016-05-18 18:09:42 -04001912 if (verbose)
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001913 printf(", {dest_fd=%" PRId64
1914 ", dest_offset=%" PRIu64 "}",
1915 (int64_t)argsp->info[2].dest_fd,
1916 (uint64_t)argsp->info[2].dest_offset);
Jeff Mahoney35866792016-05-18 18:09:42 -04001917 else
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001918 printf(", ...");
1919
Jeff Mahoney35866792016-05-18 18:09:42 -04001920 ioctl(fd1, BTRFS_IOC_FILE_EXTENT_SAME, argsp);
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001921 printf("]} => {info=");
1922 printf("[{bytes_deduped=%" PRIu64 ", status=%d}, "
1923 "{bytes_deduped=%" PRIu64 ", status=%d}",
1924 (uint64_t)argsp->info[0].bytes_deduped,
1925 argsp->info[0].status,
1926 (uint64_t)argsp->info[1].bytes_deduped,
1927 argsp->info[1].status);
Jeff Mahoney35866792016-05-18 18:09:42 -04001928 if (verbose)
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001929 printf(", {bytes_deduped=%" PRIu64 ", status=%d}",
1930 (uint64_t)argsp->info[2].bytes_deduped,
1931 argsp->info[2].status);
Jeff Mahoney35866792016-05-18 18:09:42 -04001932 else
Jeff Mahoneyeb36e382016-05-27 16:07:22 -04001933 printf(", ...");
1934 printf("]}) = 0\n");
Jeff Mahoney35866792016-05-18 18:09:42 -04001935 close(fd1);
1936 close(fd2);
1937 unlinkat(btrfs_test_dir_fd, "file1", 0);
1938 unlinkat(btrfs_test_dir_fd, "file2", 0);
1939 close(fd1);
1940 close(fd2);
1941 }
1942 free(argsp);
Dmitry V. Levinea516df2016-05-24 02:40:13 +00001943#endif /* BTRFS_IOC_FILE_EXTENT_SAME */
Jeff Mahoney35866792016-05-18 18:09:42 -04001944}
1945
1946static void
1947btrfs_print_features(struct btrfs_ioctl_feature_flags *flags)
1948{
1949 printf("{compat_flags=");
1950 printflags(btrfs_features_compat, flags->compat_flags,
1951 "BTRFS_FEATURE_COMPAT_???");
1952
1953 printf(", compat_ro_flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001954 prfl_btrfs(btrfs_features_compat_ro, flags->compat_ro_flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001955 "BTRFS_FEATURE_COMPAT_RO_???");
1956
1957 printf(", incompat_flags=");
Elliott Hughes03a418e2018-06-15 13:11:40 -07001958 prfl_btrfs(btrfs_features_incompat, flags->incompat_flags,
Jeff Mahoney35866792016-05-18 18:09:42 -04001959 "BTRFS_FEATURE_INCOMPAT_???");
1960 printf("}");
1961}
1962
1963/*
1964 * Consumes argument, returns nothing:
1965 * - BTRFS_IOC_SET_FEATURES
1966 *
1967 * Consumes nothing, returns argument:
1968 * - BTRFS_IOC_GET_FEATURES
1969 * - BTRFS_IOC_GET_SUPPORTED_FEATURES
1970 */
1971static void
1972btrfs_test_features_ioctls(void)
1973{
1974 struct btrfs_ioctl_feature_flags args[2] = {
1975 {
1976 .compat_flags = max_flags_plus_one(-1),
1977 .incompat_flags = max_flags_plus_one(9),
1978 .compat_ro_flags = max_flags_plus_one(0),
1979 }, {
1980 .compat_flags = max_flags_plus_one(-1),
1981 .incompat_flags = max_flags_plus_one(9),
1982 .compat_ro_flags = max_flags_plus_one(0),
1983 },
1984 };
1985 struct btrfs_ioctl_feature_flags supported_features[3];
1986
1987 ioctl(-1, BTRFS_IOC_SET_FEATURES, NULL);
Elliott Hughes03a418e2018-06-15 13:11:40 -07001988 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
1989 ioc(BTRFS_IOC_SET_FEATURES));
Jeff Mahoney35866792016-05-18 18:09:42 -04001990
Elliott Hughes03a418e2018-06-15 13:11:40 -07001991 printf("ioctl(-1, %s, [", ioc(BTRFS_IOC_SET_FEATURES));
Jeff Mahoney35866792016-05-18 18:09:42 -04001992 btrfs_print_features(&args[0]);
1993 printf(", ");
1994 btrfs_print_features(&args[1]);
1995 ioctl(-1, BTRFS_IOC_SET_FEATURES, &args);
1996 printf("]) = -1 EBADF (%m)\n");
1997
1998 if (btrfs_test_root) {
Elliott Hughes03a418e2018-06-15 13:11:40 -07001999 printf("ioctl(%d, %s, ",
2000 btrfs_test_dir_fd, ioc(BTRFS_IOC_GET_FEATURES));
Jeff Mahoney35866792016-05-18 18:09:42 -04002001 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_FEATURES,
2002 &supported_features);
2003 btrfs_print_features(&supported_features[0]);
2004 printf(") = 0\n");
2005
2006 ioctl(btrfs_test_dir_fd, BTRFS_IOC_GET_SUPPORTED_FEATURES,
2007 &supported_features);
Elliott Hughes03a418e2018-06-15 13:11:40 -07002008 printf("ioctl(%d, %s, ",
2009 btrfs_test_dir_fd,
2010 ioc(BTRFS_IOC_GET_SUPPORTED_FEATURES));
Elliott Hughes39bac052017-05-25 16:56:11 -07002011 printf("[");
Jeff Mahoney35866792016-05-18 18:09:42 -04002012 btrfs_print_features(&supported_features[0]);
Elliott Hughes39bac052017-05-25 16:56:11 -07002013 printf(" /* supported */, ");
Jeff Mahoney35866792016-05-18 18:09:42 -04002014 btrfs_print_features(&supported_features[1]);
Elliott Hughes39bac052017-05-25 16:56:11 -07002015 printf(" /* safe to set */, ");
Jeff Mahoney35866792016-05-18 18:09:42 -04002016 btrfs_print_features(&supported_features[2]);
Elliott Hughes39bac052017-05-25 16:56:11 -07002017 printf(" /* safe to clear */]) = 0\n");
Jeff Mahoney35866792016-05-18 18:09:42 -04002018 }
2019}
2020
Dmitry V. Levinb356ad82016-05-26 14:26:15 +00002021static void
2022btrfs_test_read_ioctls(void)
2023{
2024 static const struct xlat btrfs_read_cmd[] = {
2025 XLAT(BTRFS_IOC_BALANCE_PROGRESS),
2026 XLAT(BTRFS_IOC_FS_INFO),
2027 XLAT(BTRFS_IOC_GET_FEATURES),
2028 XLAT(BTRFS_IOC_GET_FSLABEL),
2029 XLAT(BTRFS_IOC_GET_SUPPORTED_FEATURES),
2030 XLAT(BTRFS_IOC_QGROUP_LIMIT),
2031 XLAT(BTRFS_IOC_QUOTA_RESCAN_STATUS),
2032 XLAT(BTRFS_IOC_START_SYNC),
2033 XLAT(BTRFS_IOC_SUBVOL_GETFLAGS),
2034 };
2035
2036 unsigned int i;
2037 for (i = 0; i < ARRAY_SIZE(btrfs_read_cmd); ++i) {
2038 ioctl(-1, (unsigned long) btrfs_read_cmd[i].val, 0);
Elliott Hughes03a418e2018-06-15 13:11:40 -07002039 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
2040 sprint_xlat_(btrfs_read_cmd[i].val,
2041 btrfs_read_cmd[i].str));
Dmitry V. Levinb356ad82016-05-26 14:26:15 +00002042 }
2043}
2044
Elliott Hughes03a418e2018-06-15 13:11:40 -07002045static void
2046rm_test_dir(void)
2047{
2048 int rootfd = open(path, O_RDONLY|O_DIRECTORY);
2049
2050 unlinkat(rootfd, dir_name, AT_REMOVEDIR);
2051}
2052
Jeff Mahoney35866792016-05-18 18:09:42 -04002053int
2054main(int argc, char *argv[])
2055{
2056
2057 int opt;
2058 int ret;
Jeff Mahoney35866792016-05-18 18:09:42 -04002059
Elliott Hughes03a418e2018-06-15 13:11:40 -07002060 while ((opt = getopt(argc, argv, "wvX")) != -1) {
Jeff Mahoney35866792016-05-18 18:09:42 -04002061 switch (opt) {
2062 case 'v':
2063 /*
2064 * These tests are incomplete, especially when
2065 * printing arrays of objects are involved.
2066 */
2067 verbose = true;
2068 break;
2069 case 'w':
2070 write_ok = true;
2071 break;
Elliott Hughes03a418e2018-06-15 13:11:40 -07002072 case 'X':
2073 verbose_xlat = true;
2074 break;
Jeff Mahoney35866792016-05-18 18:09:42 -04002075 default:
Elliott Hughes03a418e2018-06-15 13:11:40 -07002076 error_msg_and_fail("usage: btrfs [-vwX] [path]");
Jeff Mahoney35866792016-05-18 18:09:42 -04002077 }
2078 }
2079
Elliott Hughes03a418e2018-06-15 13:11:40 -07002080 ret = snprintf(dir_name, sizeof(dir_name), dir_name_fmt, getpid());
2081 if (ret < 0)
2082 perror_msg_and_fail("snprintf(dir_name)");
2083
Jeff Mahoney35866792016-05-18 18:09:42 -04002084 /*
2085 * This will enable optional tests that require a valid file descriptor
2086 */
2087 if (optind < argc) {
2088 int rootfd;
2089 struct statfs sfi;
2090 path = argv[optind];
2091
2092 ret = statfs(path, &sfi);
2093 if (ret)
2094 perror_msg_and_fail("statfs(%s) failed", path);
2095
2096 if ((unsigned) sfi.f_type != BTRFS_SUPER_MAGIC)
Dmitry V. Levin9298c662016-05-24 01:33:08 +00002097 error_msg_and_fail("%s is not a btrfs file system",
2098 path);
Jeff Mahoney35866792016-05-18 18:09:42 -04002099
2100 btrfs_test_root = path;
2101 rootfd = open(path, O_RDONLY|O_DIRECTORY);
2102 if (rootfd < 0)
2103 perror_msg_and_fail("open(%s) failed", path);
2104
Elliott Hughes03a418e2018-06-15 13:11:40 -07002105 ret = mkdirat(rootfd, dir_name, 0755);
Jeff Mahoney35866792016-05-18 18:09:42 -04002106 if (ret < 0 && errno != EEXIST)
Elliott Hughes03a418e2018-06-15 13:11:40 -07002107 perror_msg_and_fail("mkdirat(%s) failed", dir_name);
Jeff Mahoney35866792016-05-18 18:09:42 -04002108
Elliott Hughes03a418e2018-06-15 13:11:40 -07002109 /* Register removal of the created directory. */
2110 if (ret == 0)
2111 atexit(rm_test_dir);
2112
2113 btrfs_test_dir_fd = openat(rootfd, dir_name,
Jeff Mahoney35866792016-05-18 18:09:42 -04002114 O_RDONLY|O_DIRECTORY);
2115 if (btrfs_test_dir_fd < 0)
Elliott Hughes03a418e2018-06-15 13:11:40 -07002116 perror_msg_and_fail("openat(%s) failed", dir_name);
Jeff Mahoney35866792016-05-18 18:09:42 -04002117 close(rootfd);
2118 } else
2119 write_ok = false;
2120
2121 if (btrfs_test_root) {
2122 fprintf(stderr, "Testing live ioctls on %s (%s)\n",
2123 btrfs_test_root, write_ok ? "read/write" : "read only");
2124 }
2125
Dmitry V. Levinb356ad82016-05-26 14:26:15 +00002126 btrfs_test_read_ioctls();
Jeff Mahoney35866792016-05-18 18:09:42 -04002127 btrfs_test_trans_ioctls();
2128 btrfs_test_sync_ioctls();
2129 btrfs_test_subvol_ioctls();
2130 btrfs_test_balance_ioctls();
2131 btrfs_test_device_ioctls();
2132 btrfs_test_clone_ioctls();
2133 btrfs_test_defrag_ioctls();
2134 btrfs_test_search_ioctls();
2135 btrfs_test_ino_lookup_ioctl();
2136 btrfs_test_space_info_ioctl();
2137 btrfs_test_scrub_ioctls();
2138 btrfs_test_dev_info_ioctl();
2139 btrfs_test_ino_path_ioctls();
2140 btrfs_test_set_received_subvol_ioctl();
2141 btrfs_test_send_ioctl();
2142 btrfs_test_quota_ctl_ioctl();
2143 btrfs_test_qgroup_assign_ioctl();
2144 btrfs_test_qgroup_create_ioctl();
2145 btrfs_test_quota_rescan_ioctl();
2146 btrfs_test_label_ioctls();
2147 btrfs_test_get_dev_stats_ioctl();
2148 btrfs_test_dev_replace_ioctl();
2149 btrfs_test_extent_same_ioctl();
2150 btrfs_test_features_ioctls();
2151
2152 puts("+++ exited with 0 +++");
2153
2154 return 0;
2155}
Dmitry V. Levin22129182016-05-24 01:32:09 +00002156
2157#else
2158
2159SKIP_MAIN_UNDEFINED("HAVE_LINUX_BTRFS_H")
2160
2161#endif