btrfs-progs: add build-time checks for size of ioctl structures
authorDavid Sterba <dsterba@suse.com>
Tue, 4 Oct 2016 22:01:31 +0000 (00:01 +0200)
committerDavid Sterba <dsterba@suse.com>
Wed, 5 Oct 2016 10:39:01 +0000 (12:39 +0200)
All structures that become part of ioctl definition must never change
size. Add the build time checks for that.

Signed-off-by: David Sterba <dsterba@suse.com>
ioctl.h

diff --git a/ioctl.h b/ioctl.h
index 620dd3d..a7235c0 100644 (file)
--- a/ioctl.h
+++ b/ioctl.h
@@ -39,6 +39,7 @@ struct btrfs_ioctl_vol_args {
        __s64 fd;
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_vol_args) == 4096);
 
 #define BTRFS_DEVICE_PATH_NAME_MAX 1024
 
@@ -65,6 +66,7 @@ struct btrfs_qgroup_limit {
        __u64   rsv_referenced;
        __u64   rsv_exclusive;
 };
+BUILD_ASSERT(sizeof(struct btrfs_qgroup_limit) == 40);
 
 struct btrfs_qgroup_inherit {
        __u64   flags;
@@ -74,11 +76,13 @@ struct btrfs_qgroup_inherit {
        struct btrfs_qgroup_limit lim;
        __u64   qgroups[0];
 };
+BUILD_ASSERT(sizeof(struct btrfs_qgroup_inherit) == 72);
 
 struct btrfs_ioctl_qgroup_limit_args {
        __u64   qgroupid;
        struct btrfs_qgroup_limit lim;
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_qgroup_limit_args) == 48);
 
 #define BTRFS_SUBVOL_NAME_MAX 4039
 struct btrfs_ioctl_vol_args_v2 {
@@ -97,6 +101,7 @@ struct btrfs_ioctl_vol_args_v2 {
                __u64 devid;
        };
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_vol_args_v2) == 4096);
 
 /*
  * structure to report errors and progress to userspace, either as a
@@ -145,6 +150,7 @@ struct btrfs_ioctl_scrub_args {
        /* pad to 1k */
        __u64 unused[(1024-32-sizeof(struct btrfs_scrub_progress))/8];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_scrub_args) == 1024);
 
 #define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS   0
 #define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID    1
@@ -155,6 +161,7 @@ struct btrfs_ioctl_dev_replace_start_params {
        __u8 srcdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];       /* in */
        __u8 tgtdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];       /* in */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_start_params) == 2072);
 
 #define BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED    0
 #define BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED          1
@@ -169,6 +176,7 @@ struct btrfs_ioctl_dev_replace_status_params {
        __u64 num_write_errors; /* out */
        __u64 num_uncorrectable_read_errors;    /* out */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_status_params) == 48);
 
 #define BTRFS_IOCTL_DEV_REPLACE_CMD_START                      0
 #define BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS                     1
@@ -189,6 +197,7 @@ struct btrfs_ioctl_dev_replace_args {
 
        __u64 spare[64];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_args) == 2600);
 
 struct btrfs_ioctl_dev_info_args {
        __u64 devid;                            /* in/out */
@@ -198,6 +207,7 @@ struct btrfs_ioctl_dev_info_args {
        __u64 unused[379];                      /* pad to 4k */
        __u8 path[BTRFS_DEVICE_PATH_NAME_MAX];  /* out */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_info_args) == 4096);
 
 struct btrfs_ioctl_fs_info_args {
        __u64 max_id;                           /* out */
@@ -209,12 +219,14 @@ struct btrfs_ioctl_fs_info_args {
        __u32 reserved32;
        __u64 reserved[122];                    /* pad to 1k */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_fs_info_args) == 1024);
 
 struct btrfs_ioctl_feature_flags {
        __u64 compat_flags;
        __u64 compat_ro_flags;
        __u64 incompat_flags;
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_feature_flags) == 24);
 
 /* balance control ioctl modes */
 #define BTRFS_BALANCE_CTL_PAUSE                1
@@ -292,6 +304,7 @@ struct btrfs_ioctl_balance_args {
 
        __u64 unused[72];                       /* pad to 1k */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_balance_args) == 1024);
 
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
 struct btrfs_ioctl_ino_lookup_args {
@@ -299,6 +312,7 @@ struct btrfs_ioctl_ino_lookup_args {
        __u64 objectid;
        char name[BTRFS_INO_LOOKUP_PATH_MAX];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_ino_lookup_args) == 4096);
 
 struct btrfs_ioctl_search_key {
        /* which root are we searching.  0 is the tree of tree roots */
@@ -366,6 +380,7 @@ struct btrfs_ioctl_search_args_v2 {
                                             *       to store item */
         __u64 buf[0];                      /* out - found items */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_search_args_v2) == 112);
 
 /* With a @src_length of zero, the range from @src_offset->EOF is cloned! */
 struct btrfs_ioctl_clone_range_args {
@@ -373,6 +388,7 @@ struct btrfs_ioctl_clone_range_args {
        __u64 src_offset, src_length;
        __u64 dest_offset;
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_clone_range_args) == 32);
 
 /* flags for the defrag range ioctl */
 #define BTRFS_DEFRAG_RANGE_COMPRESS 1
@@ -402,6 +418,7 @@ struct btrfs_ioctl_same_args {
        __u32 reserved2;
        struct btrfs_ioctl_same_extent_info info[0];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_same_args) == 24);
 
 struct btrfs_ioctl_defrag_range_args {
        /* start of the defrag operation */
@@ -433,6 +450,7 @@ struct btrfs_ioctl_defrag_range_args {
        /* spare for later */
        __u32 unused[4];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_defrag_range_args) == 48);
 
 struct btrfs_ioctl_space_info {
        __u64 flags;
@@ -445,6 +463,7 @@ struct btrfs_ioctl_space_args {
        __u64 total_spaces;
        struct btrfs_ioctl_space_info spaces[0];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_space_args) == 16);
 
 struct btrfs_data_container {
        __u32   bytes_left;     /* out -- bytes not needed to deliver output */
@@ -461,6 +480,7 @@ struct btrfs_ioctl_ino_path_args {
        /* struct btrfs_data_container  *fspath;           out */
        __u64                           fspath;         /* out */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_ino_path_args) == 56);
 
 struct btrfs_ioctl_logical_ino_args {
        __u64                           logical;        /* in */
@@ -500,8 +520,9 @@ struct btrfs_ioctl_get_dev_stats {
        /* out values: */
        __u64 values[BTRFS_DEV_STAT_VALUES_MAX];
 
-       __u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */
+       __u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k + 8B */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_get_dev_stats) == 1032);
 
 /* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
 #define BTRFS_QUOTA_CTL_ENABLE 1
@@ -511,12 +532,14 @@ struct btrfs_ioctl_quota_ctl_args {
        __u64 cmd;
        __u64 status;
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_quota_ctl_args) == 16);
 
 struct btrfs_ioctl_quota_rescan_args {
        __u64   flags;
        __u64   progress;
        __u64   reserved[6];
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_quota_rescan_args) == 64);
 
 struct btrfs_ioctl_qgroup_assign_args {
        __u64 assign;
@@ -528,6 +551,8 @@ struct btrfs_ioctl_qgroup_create_args {
        __u64 create;
        __u64 qgroupid;
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_qgroup_create_args) == 16);
+
 struct btrfs_ioctl_timespec {
        __u64 sec;
        __u32 nsec;
@@ -542,6 +567,7 @@ struct btrfs_ioctl_received_subvol_args {
        __u64   flags;                  /* in */
        __u64   reserved[16];           /* in */
 };
+BUILD_ASSERT(sizeof(struct btrfs_ioctl_received_subvol_args) == 200);
 
 /*
  * Caller doesn't want file data in the send stream, even if the
@@ -576,6 +602,15 @@ struct btrfs_ioctl_send_args {
        __u64 flags;                    /* in */
        __u64 reserved[4];              /* in */
 };
+/*
+ * Size of structure depends on pointer width, was not caught.  Kernel handles
+ * pointer width differences transparently
+ */
+BUILD_ASSERT(sizeof(__u64 *) == 8
+            ? sizeof(struct btrfs_ioctl_send_args) == 72
+            : (sizeof(void *) == 4
+               ? sizeof(struct btrfs_ioctl_send_args) == 68
+               : 0));
 
 /* Error codes as returned by the kernel */
 enum btrfs_err_code {