Author: mav
Date: Tue Oct 11 16:48:12 2016
New Revision: 307054
URL: https://svnweb.freebsd.org/changeset/base/307054

Log:
  MFC r305197: 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 <p...@delphix.com>
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Approved by: Robert Mustacchi <r...@joyent.com>
  Author: Matthew Ahrens <mahr...@delphix.com>

Modified:
  stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
  stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c        
Tue Oct 11 16:47:21 2016        (r307053)
+++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c        
Tue Oct 11 16:48:12 2016        (r307054)
@@ -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: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h        
Tue Oct 11 16:47:21 2016        (r307053)
+++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h        
Tue Oct 11 16:48:12 2016        (r307054)
@@ -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: 
stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h    
Tue Oct 11 16:47:21 2016        (r307053)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h    
Tue Oct 11 16:48:12 2016        (r307054)
@@ -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: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Tue Oct 11 16:47:21 2016        (r307053)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Tue Oct 11 16:48:12 2016        (r307054)
@@ -6251,6 +6251,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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to