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