Date: Thu, 1 Sep 2016 14:06:31 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305197 - in head/sys/cddl/contrib/opensolaris: common/zfs uts/common/fs/zfs uts/common/fs/zfs/sys Message-ID: <201609011406.u81E6VTh097431@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Thu Sep 1 14:06:30 2016 New Revision: 305197 URL: https://svnweb.freebsd.org/changeset/base/305197 Log: MFV r302646: 6980 6902 causes zfs send to break due to 32-bit/64-bit struct mismatch illumos/illumos-gate@ea4a67f462de0a39a9adea8197bcdef849de5371 https://github.com/illumos/illumos-gate/commit/ea4a67f462de0a39a9adea8197bcdef84 9de5371 https://www.illumos.org/issues/6980 doing zfs send -i snap1 snap2 >testfile results in internal error: Invalid argument Abort (core dumped) Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: Matthew Ahrens <mahrens@delphix.com> Modified: head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Directory Properties: head/sys/cddl/contrib/opensolaris/ (props changed) Modified: head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Thu Sep 1 13:38:46 2016 (r305196) +++ head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Thu Sep 1 14:06:30 2016 (r305197) @@ -55,8 +55,52 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_ zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; zfs_cmd_resume_t *resume_c; + zfs_cmd_inlanes_t *inlanes_c; switch (cflag) { + case ZFS_CMD_COMPAT_INLANES: + inlanes_c = (void *)addr; + /* zc */ + strlcpy(zc->zc_name, inlanes_c->zc_name, MAXPATHLEN); + strlcpy(zc->zc_value, inlanes_c->zc_value, MAXPATHLEN * 2); + strlcpy(zc->zc_string, inlanes_c->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) zc->field = inlanes_c->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_resumable); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_RESUME: resume_c = (void *)addr; /* zc */ @@ -434,8 +478,50 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_ zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; zfs_cmd_resume_t *resume_c; + zfs_cmd_inlanes_t *inlanes_c; switch (cflag) { + case ZFS_CMD_COMPAT_INLANES: + inlanes_c = (void *)addr; + strlcpy(inlanes_c->zc_name, zc->zc_name, MAXPATHLEN); + strlcpy(inlanes_c->zc_value, zc->zc_value, MAXPATHLEN * 2); + strlcpy(inlanes_c->zc_string, zc->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) inlanes_c->field = zc->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_RESUME: resume_c = (void *)addr; strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN); @@ -987,6 +1073,12 @@ zcmd_ioctl_compat(int fd, int request, z zp.zfs_cmd_size = sizeof(zfs_cmd_t); zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT; return (ioctl(fd, ncmd, &zp)); + case ZFS_CMD_COMPAT_INLANES: + ncmd = _IOWR('Z', request, struct zfs_iocparm); + zp.zfs_cmd = (uint64_t)zc; + zp.zfs_cmd_size = sizeof(zfs_cmd_inlanes_t); + zp.zfs_ioctl_version = ZFS_IOCVER_INLANES; + return (ioctl(fd, ncmd, &zp)); case ZFS_CMD_COMPAT_RESUME: ncmd = _IOWR('Z', request, struct zfs_iocparm); zp.zfs_cmd = (uint64_t)zc; @@ -1104,7 +1196,7 @@ zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nv if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || - cflag == ZFS_CMD_COMPAT_RESUME) + cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES) goto out; switch (vec) { @@ -1257,7 +1349,7 @@ zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, n if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || - cflag == ZFS_CMD_COMPAT_RESUME) + cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES) return (outnvl); switch (vec) { Modified: head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h ============================================================================== --- head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Thu Sep 1 13:38:46 2016 (r305196) +++ head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Thu Sep 1 14:06:30 2016 (r305197) @@ -54,7 +54,8 @@ extern "C" { #define ZFS_IOCVER_EDBP 4 #define ZFS_IOCVER_RESUME 5 #define ZFS_IOCVER_INLANES 6 -#define ZFS_IOCVER_CURRENT ZFS_IOCVER_INLANES +#define ZFS_IOCVER_PAD 7 +#define ZFS_IOCVER_CURRENT ZFS_IOCVER_PAD /* compatibility conversion flag */ #define ZFS_CMD_COMPAT_NONE 0 @@ -65,6 +66,7 @@ extern "C" { #define ZFS_CMD_COMPAT_ZCMD 5 #define ZFS_CMD_COMPAT_EDBP 6 #define ZFS_CMD_COMPAT_RESUME 7 +#define ZFS_CMD_COMPAT_INLANES 8 #define ZFS_IOC_COMPAT_PASS 254 #define ZFS_IOC_COMPAT_FAIL 255 @@ -355,6 +357,49 @@ typedef struct zfs_cmd_resume { zfs_stat_t zc_stat; } zfs_cmd_resume_t; +typedef struct zfs_cmd_inlanes { + char zc_name[MAXPATHLEN]; /* name of pool or dataset */ + uint64_t zc_nvlist_src; /* really (char *) */ + uint64_t zc_nvlist_src_size; + uint64_t zc_nvlist_dst; /* really (char *) */ + uint64_t zc_nvlist_dst_size; + boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ + int zc_pad2; + + /* + * The following members are for legacy ioctls which haven't been + * converted to the new method. + */ + uint64_t zc_history; /* really (char *) */ + char zc_value[MAXPATHLEN * 2]; + char zc_string[MAXNAMELEN]; + uint64_t zc_guid; + uint64_t zc_nvlist_conf; /* really (char *) */ + uint64_t zc_nvlist_conf_size; + uint64_t zc_cookie; + uint64_t zc_objset_type; + uint64_t zc_perm_action; + uint64_t zc_history_len; + uint64_t zc_history_offset; + uint64_t zc_obj; + uint64_t zc_iflags; /* internal to zfs(7fs) */ + zfs_share_t zc_share; + uint64_t zc_jailid; + dmu_objset_stats_t zc_objset_stats; + dmu_replay_record_t zc_begin_record; + zinject_record_t zc_inject_record; + uint32_t zc_defer_destroy; + uint32_t zc_flags; + uint64_t zc_action_handle; + int zc_cleanup_fd; + uint8_t zc_simple; + boolean_t zc_resumable; + uint64_t zc_sendobj; + uint64_t zc_fromobj; + uint64_t zc_createtxg; + zfs_stat_t zc_stat; +} zfs_cmd_inlanes_t; + #ifdef _KERNEL unsigned static long zfs_ioctl_v15_to_v28[] = { 0, /* 0 ZFS_IOC_POOL_CREATE */ Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Thu Sep 1 13:38:46 2016 (r305196) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Thu Sep 1 14:06:30 2016 (r305197) @@ -353,6 +353,12 @@ typedef enum zfs_case { ZFS_CASE_MIXED } zfs_case_t; +/* + * Note: this struct must have the same layout in 32-bit and 64-bit, so + * that 32-bit processes (like /sbin/zfs) can pass it to the 64-bit + * kernel. Therefore, we add padding to it so that no "hidden" padding + * is automatically added on 64-bit (but not on 32-bit). + */ typedef struct zfs_cmd { char zc_name[MAXPATHLEN]; /* name of pool or dataset */ uint64_t zc_nvlist_src; /* really (char *) */ @@ -389,7 +395,9 @@ typedef struct zfs_cmd { uint64_t zc_action_handle; int zc_cleanup_fd; uint8_t zc_simple; + uint8_t zc_pad3[3]; boolean_t zc_resumable; + uint32_t zc_pad4; uint64_t zc_sendobj; uint64_t zc_fromobj; uint64_t zc_createtxg; Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Thu Sep 1 13:38:46 2016 (r305196) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Thu Sep 1 14:06:30 2016 (r305197) @@ -6252,6 +6252,14 @@ zfsdev_ioctl(struct cdev *dev, u_long zc goto out; } break; + case ZFS_IOCVER_INLANES: + if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_inlanes_t)) { + error = SET_ERROR(EFAULT); + goto out; + } + compat = B_TRUE; + cflag = ZFS_CMD_COMPAT_INLANES; + break; case ZFS_IOCVER_RESUME: if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_resume_t)) { error = SET_ERROR(EFAULT);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609011406.u81E6VTh097431>