Skip to contentSkip to conversation

32/64-bit structure alignment problem in receive

DISCUSSION Hugo Mills 1 participant 1 message Jan 4, 2014 Btrfs file system

lore
Share & tools
lore

Hugo Mills

author
#0 lore raw

Sending the exact same send stream to two different machines, on
one of them I am getting:

ERROR: BTRFS_IOC_SET_RECEIVED_SUBVOL failed. Inappropriate ioctl for device

The other machine is fine. Investigating, I find that the working
machine is 64-bit userspace and kernel. The failing machine is 32-bit userspace and 64-bit kernel.

struct btrfs_ioctl_received_subvol_args {

        char    uuid[BTRFS_UUID_SIZE];  /* in */
        __u64   stransid;               /* in */
        __u64   rtransid;               /* out */

struct btrfs_ioctl_timespec stime; /* in */ struct btrfs_ioctl_timespec rtime; /* out */
__u64 flags; /* in */
__u64 reserved[16]; /* in */
};

struct btrfs_ioctl_timespec {
        __u64 sec;
        __u32 nsec;
};

This latter struct is 16 bytes in a 64-bit environment (with 4
bytes wasted) and 12 bytes in a 32-bit environment. This means that on my broken machine, the kernel is expecting ioctl(5, 0xc0c89425, ...) and is being called with ioctl(5, 0xc0c09425, ...).

As far as I can see, the best (only?) solution is to teach the
kernel to accept both

_IOWR(BTRFS_IOCTL_MAGIC, 37, struct btrfs_ioctl_received_subvol_args)

and

_IOWR(BTRFS_IOCTL_MAGIC, 37, struct btrfs_ioctl_received_subvol_args_32)

if it's compiled on a 64-bit architecture, where the _32 version of the struct is otherwise identical to the struct(s) above, but declared as __packed__.

Patch to follow.

Hugo.

Signature · 3 lines
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
  PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
      --- "Big data" doesn't just mean increasing the font size ---