• Arnd Bergmann's avatar
    xfs: avoid time_t in user api · e8777b27
    Arnd Bergmann authored
    The ioctl definitions for XFS_IOC_SWAPEXT, XFS_IOC_FSBULKSTAT and
    XFS_IOC_FSBULKSTAT_SINGLE are part of libxfs and based on time_t.
    
    The definition for time_t differs between current kernels and coming
    32-bit libc variants that define it as 64-bit. For most ioctls, that
    means the kernel has to be able to handle two different command codes
    based on the different structure sizes.
    
    The same solution could be applied for XFS_IOC_SWAPEXT, but it would
    not work for XFS_IOC_FSBULKSTAT and XFS_IOC_FSBULKSTAT_SINGLE because
    the structure with the time_t is passed through an indirect pointer,
    and the command number itself is based on struct xfs_fsop_bulkreq,
    which does not differ based on time_t.
    
    This means any solution that can be applied requires a change of the
    ABI definition in the xfs_fs.h header file, as well as doing the same
    change in any user application that contains a copy of this header.
    
    The usual solution would be to define a replacement structure and
    use conditional compilation for the ioctl command codes to use
    one or the other, such as
    
     #define XFS_IOC_FSBULKSTAT_OLD _IOWR('X', 101, struct xfs_fsop_bulkreq)
     #define XFS_IOC_FSBULKSTAT_NEW _IOWR('X', 129, struct xfs_fsop_bulkreq)
     #define XFS_IOC_FSBULKSTAT ((sizeof(time_t) == sizeof(__kernel_long_t)) ? \
    			     XFS_IOC_FSBULKSTAT_OLD : XFS_IOC_FSBULKSTAT_NEW)
    
    After this, the kernel would be able to implement both
    XFS_IOC_FSBULKSTAT_OLD and XFS_IOC_FSBULKSTAT_NEW handlers on
    32-bit architectures with the correct ABI for either definition
    of time_t.
    
    However, as long as two observations are true, a much simpler solution
    can be used:
    
    1. xfsprogs is the only user space project that has a copy of this header
    2. xfsprogs already has a replacement for all three affected ioctl commands,
       based on the xfs_bulkstat structure to pass 64-bit timestamps
       regardless of the architecture
    
    Based on those assumptions, changing xfs_bstime to use __kernel_long_t
    instead of time_t in both the kernel and in xfsprogs preserves the current
    ABI for any libc definition of time_t and solves the problem of passing
    64-bit timestamps to 32-bit user space.
    
    If either of the two assumptions is invalid, more discussion is needed
    for coming up with a way to fix as much of the affected user space
    code as possible.
    Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    e8777b27
xfs_fs.h 30.3 KB