+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "kerncompat.h"
#include <stdio.h>
#include <stdlib.h>
-#include "kerncompat.h"
+
#include "ioctl.h"
+#include "ctree.h"
+
+#define LIST_32_COMPAT \
+ ONE(BTRFS_IOC_SET_RECEIVED_SUBVOL_32)
+
+#define LIST_64_COMPAT \
+ ONE(BTRFS_IOC_SEND_64)
+
+#define LIST_BASE \
+ ONE(BTRFS_IOC_SNAP_CREATE) \
+ ONE(BTRFS_IOC_DEFRAG) \
+ ONE(BTRFS_IOC_RESIZE) \
+ ONE(BTRFS_IOC_SCAN_DEV) \
+ ONE(BTRFS_IOC_TRANS_START) \
+ ONE(BTRFS_IOC_TRANS_END) \
+ ONE(BTRFS_IOC_SYNC) \
+ ONE(BTRFS_IOC_CLONE) \
+ ONE(BTRFS_IOC_ADD_DEV) \
+ ONE(BTRFS_IOC_RM_DEV) \
+ ONE(BTRFS_IOC_BALANCE) \
+ ONE(BTRFS_IOC_CLONE_RANGE) \
+ ONE(BTRFS_IOC_SUBVOL_CREATE) \
+ ONE(BTRFS_IOC_SNAP_DESTROY) \
+ ONE(BTRFS_IOC_DEFRAG_RANGE) \
+ ONE(BTRFS_IOC_TREE_SEARCH) \
+ ONE(BTRFS_IOC_TREE_SEARCH_V2) \
+ ONE(BTRFS_IOC_INO_LOOKUP) \
+ ONE(BTRFS_IOC_DEFAULT_SUBVOL) \
+ ONE(BTRFS_IOC_SPACE_INFO) \
+ ONE(BTRFS_IOC_START_SYNC) \
+ ONE(BTRFS_IOC_WAIT_SYNC) \
+ ONE(BTRFS_IOC_SNAP_CREATE_V2) \
+ ONE(BTRFS_IOC_SUBVOL_CREATE_V2) \
+ ONE(BTRFS_IOC_SUBVOL_GETFLAGS) \
+ ONE(BTRFS_IOC_SUBVOL_SETFLAGS) \
+ ONE(BTRFS_IOC_SCRUB) \
+ ONE(BTRFS_IOC_SCRUB_CANCEL) \
+ ONE(BTRFS_IOC_SCRUB_PROGRESS) \
+ ONE(BTRFS_IOC_DEV_INFO) \
+ ONE(BTRFS_IOC_FS_INFO) \
+ ONE(BTRFS_IOC_BALANCE_V2) \
+ ONE(BTRFS_IOC_BALANCE_CTL) \
+ ONE(BTRFS_IOC_BALANCE_PROGRESS) \
+ ONE(BTRFS_IOC_INO_PATHS) \
+ ONE(BTRFS_IOC_LOGICAL_INO) \
+ ONE(BTRFS_IOC_SET_RECEIVED_SUBVOL) \
+ ONE(BTRFS_IOC_SEND) \
+ ONE(BTRFS_IOC_DEVICES_READY) \
+ ONE(BTRFS_IOC_QUOTA_CTL) \
+ ONE(BTRFS_IOC_QGROUP_ASSIGN) \
+ ONE(BTRFS_IOC_QGROUP_CREATE) \
+ ONE(BTRFS_IOC_QGROUP_LIMIT) \
+ ONE(BTRFS_IOC_QUOTA_RESCAN) \
+ ONE(BTRFS_IOC_QUOTA_RESCAN_STATUS) \
+ ONE(BTRFS_IOC_QUOTA_RESCAN_WAIT) \
+ ONE(BTRFS_IOC_GET_FSLABEL) \
+ ONE(BTRFS_IOC_SET_FSLABEL) \
+ ONE(BTRFS_IOC_GET_DEV_STATS) \
+ ONE(BTRFS_IOC_DEV_REPLACE) \
+ ONE(BTRFS_IOC_FILE_EXTENT_SAME) \
+ ONE(BTRFS_IOC_GET_FEATURES) \
+ ONE(BTRFS_IOC_SET_FEATURES) \
+ ONE(BTRFS_IOC_GET_SUPPORTED_FEATURES) \
+ ONE(BTRFS_IOC_RM_DEV_V2)
-static unsigned long ioctls[] = {
- BTRFS_IOC_SNAP_CREATE,
- BTRFS_IOC_DEFRAG,
- BTRFS_IOC_RESIZE,
- BTRFS_IOC_SCAN_DEV,
- BTRFS_IOC_TRANS_START,
- BTRFS_IOC_TRANS_END,
- BTRFS_IOC_SYNC,
- BTRFS_IOC_CLONE,
- BTRFS_IOC_ADD_DEV,
- BTRFS_IOC_RM_DEV,
- BTRFS_IOC_BALANCE,
- BTRFS_IOC_SUBVOL_CREATE,
- BTRFS_IOC_SNAP_DESTROY,
- BTRFS_IOC_DEFRAG_RANGE,
- BTRFS_IOC_TREE_SEARCH,
- BTRFS_IOC_INO_LOOKUP,
- BTRFS_IOC_DEFAULT_SUBVOL,
- BTRFS_IOC_SPACE_INFO,
- BTRFS_IOC_SNAP_CREATE_V2,
- 0 };
+#define LIST \
+ LIST_BASE \
+ LIST_32_COMPAT \
+ LIST_64_COMPAT
+
+struct ioctl_number {
+ unsigned long defined;
+ unsigned long expected;
+};
+
+static struct ioctl_number expected_list[] = {
+ { BTRFS_IOC_SNAP_CREATE, 0x0050009401 },
+ { BTRFS_IOC_DEFRAG, 0x0050009402 },
+ { BTRFS_IOC_RESIZE, 0x0050009403 },
+ { BTRFS_IOC_SCAN_DEV, 0x0050009404 },
+ { BTRFS_IOC_TRANS_START, 0x0000009406 },
+ { BTRFS_IOC_TRANS_END, 0x0000009407 },
+ { BTRFS_IOC_SYNC, 0x0000009408 },
+ { BTRFS_IOC_CLONE, 0x0040049409 },
+ { BTRFS_IOC_ADD_DEV, 0x005000940a },
+ { BTRFS_IOC_RM_DEV, 0x005000940b },
+ { BTRFS_IOC_BALANCE, 0x005000940c },
+ { BTRFS_IOC_CLONE_RANGE, 0x004020940d },
+ { BTRFS_IOC_SUBVOL_CREATE, 0x005000940e },
+ { BTRFS_IOC_SNAP_DESTROY, 0x005000940f },
+ { BTRFS_IOC_DEFRAG_RANGE, 0x0040309410 },
+ { BTRFS_IOC_TREE_SEARCH, 0x00d0009411 },
+ { BTRFS_IOC_TREE_SEARCH_V2, 0x00c0709411 },
+ { BTRFS_IOC_INO_LOOKUP, 0x00d0009412 },
+ { BTRFS_IOC_DEFAULT_SUBVOL, 0x0040089413 },
+ { BTRFS_IOC_SPACE_INFO, 0x00c0109414 },
+ { BTRFS_IOC_START_SYNC, 0x0080089418 },
+ { BTRFS_IOC_WAIT_SYNC, 0x0040089416 },
+ { BTRFS_IOC_SNAP_CREATE_V2, 0x0050009417 },
+ { BTRFS_IOC_SUBVOL_CREATE_V2, 0x0050009418 },
+ { BTRFS_IOC_SUBVOL_GETFLAGS, 0x0080089419 },
+ { BTRFS_IOC_SUBVOL_SETFLAGS, 0x004008941a },
+ { BTRFS_IOC_SCRUB, 0x00c400941b },
+ { BTRFS_IOC_SCRUB_CANCEL, 0x000000941c },
+ { BTRFS_IOC_SCRUB_PROGRESS, 0x00c400941d },
+ { BTRFS_IOC_DEV_INFO, 0x00d000941e },
+ { BTRFS_IOC_FS_INFO, 0x008400941f },
+ { BTRFS_IOC_BALANCE_V2, 0x00c4009420 },
+ { BTRFS_IOC_BALANCE_CTL, 0x0040049421 },
+ { BTRFS_IOC_BALANCE_PROGRESS, 0x0084009422 },
+ { BTRFS_IOC_INO_PATHS, 0x00c0389423 },
+ { BTRFS_IOC_LOGICAL_INO, 0x00c0389424 },
+ { BTRFS_IOC_SET_RECEIVED_SUBVOL, 0x00c0c89425 },
+#ifdef BTRFS_IOC_SET_RECEIVED_SUBVOL_32_COMPAT_DEFINED
+ { BTRFS_IOC_SET_RECEIVED_SUBVOL_32, 0x00c0c09425 },
+#endif
+#if BITS_PER_LONG == 32
+ { BTRFS_IOC_SEND, 0x0040449426 },
+#elif BITS_PER_LONG == 64
+ { BTRFS_IOC_SEND, 0x0040489426 },
+#endif
+#ifdef BTRFS_IOC_SEND_64_COMPAT_DEFINED
+ { BTRFS_IOC_SEND_64, 0x0040489426 },
+#endif
+ { BTRFS_IOC_DEVICES_READY, 0x0090009427 },
+ { BTRFS_IOC_QUOTA_CTL, 0x00c0109428 },
+ { BTRFS_IOC_QGROUP_ASSIGN, 0x0040189429 },
+ { BTRFS_IOC_QGROUP_CREATE, 0x004010942a },
+ { BTRFS_IOC_QGROUP_LIMIT, 0x008030942b },
+ { BTRFS_IOC_QUOTA_RESCAN, 0x004040942c },
+ { BTRFS_IOC_QUOTA_RESCAN_STATUS, 0x008040942d },
+ { BTRFS_IOC_QUOTA_RESCAN_WAIT, 0x000000942e },
+ { BTRFS_IOC_GET_FSLABEL, 0x0081009431 },
+ { BTRFS_IOC_SET_FSLABEL, 0x0041009432 },
+ { BTRFS_IOC_GET_DEV_STATS, 0x00c4089434 },
+ { BTRFS_IOC_DEV_REPLACE, 0x00ca289435 },
+ { BTRFS_IOC_FILE_EXTENT_SAME, 0x00c0189436 },
+ { BTRFS_IOC_GET_FEATURES, 0x0080189439 },
+ { BTRFS_IOC_SET_FEATURES, 0x0040309439 },
+ { BTRFS_IOC_GET_SUPPORTED_FEATURES, 0x0080489439 },
+ { BTRFS_IOC_RM_DEV_V2, 0x005000943a },
+};
+
+static struct btrfs_ioctl_vol_args used_vol_args __attribute__((used));
+static struct btrfs_ioctl_vol_args_v2 used_vol_args2 __attribute__((used));
+static struct btrfs_ioctl_clone_range_args used_clone_args __attribute__((used));
+static struct btrfs_ioctl_defrag_range_args used_defrag_args __attribute__((used));
+static struct btrfs_ioctl_search_args used_search_args __attribute__((used));
+static struct btrfs_ioctl_search_args_v2 used_search_args2 __attribute__((used));
+static struct btrfs_ioctl_ino_lookup_args used_ino_lookup __attribute__((used));
+static struct btrfs_ioctl_space_args used_space_args __attribute__((used));
+static struct btrfs_ioctl_scrub_args used_scrub_args __attribute__((used));
+static struct btrfs_ioctl_dev_info_args used_dev_info_args __attribute__((used));
+static struct btrfs_ioctl_fs_info_args used_fs_info_args __attribute__((used));
+static struct btrfs_ioctl_balance_args used_balance_args __attribute__((used));
+static struct btrfs_ioctl_ino_path_args used_path_args __attribute__((used));
+static struct btrfs_ioctl_logical_ino_args used_logical_args __attribute__((used));
+static struct btrfs_ioctl_received_subvol_args used_received_args __attribute__((used));
+#ifdef BTRFS_IOC_SET_RECEIVED_SUBVOL_32_COMPAT_DEFINED
+static struct btrfs_ioctl_received_subvol_args_32 used_received_args32 __attribute__((used));
+#endif
+static struct btrfs_ioctl_send_args used_send_args __attribute__((used));
+#ifdef BTRFS_IOC_SEND_64_COMPAT_DEFINED
+static struct btrfs_ioctl_send_args_64 used_send_args64 __attribute__((used));
+#endif
+static struct btrfs_ioctl_quota_ctl_args used_qgctl_args __attribute__((used));
+static struct btrfs_ioctl_qgroup_assign_args used_qgassign_args __attribute__((used));
+static struct btrfs_ioctl_qgroup_create_args used_qgcreate_args __attribute__((used));
+static struct btrfs_ioctl_qgroup_limit_args used_qglimit_args __attribute__((used));
+static struct btrfs_ioctl_quota_rescan_args used_qgrescan_args __attribute__((used));
+static struct btrfs_ioctl_get_dev_stats used_dev_stats_args __attribute__((used));
+static struct btrfs_ioctl_dev_replace_args used_replace_args __attribute__((used));
+static struct btrfs_ioctl_same_args used_same_args __attribute__((used));
+static struct btrfs_ioctl_feature_flags used_feature_flags __attribute__((used));
+
+const char* value_to_string(unsigned long num)
+{
+#define ONE(x) case x: return #x;
+ switch (num) {
+ LIST_BASE
+ }
+
+ switch (num) {
+ LIST_32_COMPAT
+ }
+
+ switch (num) {
+ LIST_64_COMPAT
+ }
+#undef ONE
+ return "UNKNOWN";
+}
int main(int ac, char **av)
{
- int i = 0;
- while(ioctls[i]) {
- printf("%lu\n" ,ioctls[i]);
- i++;
+ int i;
+ int errors = 0;
+
+ value_to_string(random());
+
+ printf("Sizeof long long: %zu\n", sizeof(unsigned long long));
+ printf("Sizeof long: %zu\n", sizeof(unsigned long));
+ printf("Sizeof pointer: %zu\n", sizeof(void*));
+ printf("Alignof long long: %zu\n", __alignof__(unsigned long long));
+ printf("Alignof long: %zu\n", __alignof__(unsigned long));
+ printf("Alignof pointer: %zu\n", __alignof__(void*));
+ printf("Raw ioctl numbers:\n");
+
+#define ONE(n) printf("%-38s 0x%010lx\n", #n, (unsigned long)n);
+ LIST
+#undef ONE
+
+ for (i = 0; i < ARRAY_SIZE(expected_list); i++) {
+ if (expected_list[i].defined != expected_list[i].expected) {
+ printf("ERROR: wrong value for %s, defined=0x%lx expected=0x%lx\n",
+ value_to_string(expected_list[i].defined),
+ expected_list[i].defined,
+ expected_list[i].expected);
+ errors++;
+ }
}
- return 0;
+
+ if (!errors) {
+ printf("All ok\n");
+ } else {
+ printf("Found %d errors in definitions\n", errors);
+ }
+
+ return !!errors;
}