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