Module Name:    src
Committed By:   hannken
Date:           Mon Oct 14 13:18:00 UTC 2019

Modified Files:
        src/external/cddl/osnet/dist/uts/common/fs/zfs: dmu_diff.c zfs_ioctl.c
        src/external/cddl/osnet/dist/uts/common/fs/zfs/sys: dmu.h

Log Message:
Change dmu_diff() back to use a "file" instead of a "vnode".
Command "zfs diff" calls it with a pipe, not a plain file.

Fixes PR kern/54541: kernel panic using "zfs diff"


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 \
    src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c
cvs rdiff -u -r1.20 -r1.21 \
    src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
cvs rdiff -u -r1.3 -r1.4 \
    src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c:1.2 src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c:1.3
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c:1.2	Mon May 28 21:05:07 2018
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c	Mon Oct 14 13:18:00 2019
@@ -43,16 +43,13 @@
 struct diffarg {
 #ifdef __FreeBSD__
 	kthread_t *da_td;
-	struct file *da_fp;		/* file to which we are reporting */
-#else
-	struct vnode *da_vp;		/* file to which we are reporting */
 #endif
+	struct file *da_fp;		/* file to which we are reporting */
 	offset_t *da_offp;
 	int da_err;			/* error that stopped diff search */
 	dmu_diff_record_t da_ddr;
 };
 
-#ifdef __FreeBSD__
 static int
 write_bytes(struct diffarg *da)
 {
@@ -66,18 +63,30 @@ write_bytes(struct diffarg *da)
 	auio.uio_resid = aiov.iov_len;
 	auio.uio_rw = UIO_WRITE;
 	auio.uio_offset = (off_t)-1;
+#ifdef __FreeBSD__
 	auio.uio_segflg = UIO_SYSSPACE;
 	auio.uio_td = da->da_td;
+#else
+	auio.uio_vmspace = vmspace_kernel();
+#endif /* __FreeBSD__ */
 #ifdef _KERNEL
+#ifdef __FreeBSD__
 	if (da->da_fp->f_type == DTYPE_VNODE)
 		bwillwrite();
 	return (fo_write(da->da_fp, &auio, da->da_td->td_ucred, 0, da->da_td));
 #else
+	int flags = 0;
+
+	if (da->da_fp->f_type == DTYPE_VNODE)
+		flags |= FOF_UPDATE_OFFSET;
+	return (*da->da_fp->f_ops->fo_write)(da->da_fp, &da->da_fp->f_offset,
+	    &auio, da->da_fp->f_cred, flags);
+#endif /* __FreeBSD__ */
+#else
 	fprintf(stderr, "%s: returning EOPNOTSUPP\n", __func__);
 	return (EOPNOTSUPP);
 #endif
 }
-#endif /* __FreeBSD__ */
 
 static int
 write_record(struct diffarg *da)
@@ -89,13 +98,7 @@ write_record(struct diffarg *da)
 		return (0);
 	}
 
-#ifdef __FreeBSD__
 	da->da_err = write_bytes(da);
-#else
-	da->da_err = vn_rdwr(UIO_WRITE, da->da_vp, (caddr_t)&da->da_ddr,
-	    sizeof (da->da_ddr), 0, UIO_SYSSPACE, FAPPEND,
-	    RLIM64_INFINITY, CRED(), &resid);
-#endif
 	*da->da_offp += sizeof (da->da_ddr);
 	return (da->da_err);
 }
@@ -193,11 +196,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, cons
 
 int
 dmu_diff(const char *tosnap_name, const char *fromsnap_name,
-#ifdef __FreeBSD__
     struct file *fp, offset_t *offp)
-#else
-    struct vnode *vp, offset_t *offp)
-#endif
 {
 	struct diffarg da;
 	dsl_dataset_t *fromsnap;
@@ -242,10 +241,8 @@ dmu_diff(const char *tosnap_name, const 
 
 #ifdef __FreeBSD__
 	da.da_td = curthread;
-	da.da_fp = fp;
-#else
-	da.da_vp = vp;
 #endif
+	da.da_fp = fp;
 	da.da_offp = offp;
 	da.da_ddr.ddr_type = DDR_NONE;
 	da.da_ddr.ddr_first = da.da_ddr.ddr_last = 0;

Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.20 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.21
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.20	Wed May 22 08:46:27 2019
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c	Mon Oct 14 13:18:00 2019
@@ -5296,11 +5296,7 @@ zfs_ioc_diff(zfs_cmd_t *zc)
 
 	off = fp->f_offset;
 
-#ifdef __FreeBSD__
 	error = dmu_diff(zc->zc_name, zc->zc_value, fp, &off);
-#else
-	error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off);
-#endif
 
 	if (off >= 0 && off <= MAXOFFSET_T)
 		fp->f_offset = off;

Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h:1.3 src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h:1.4
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h:1.3	Mon May 28 21:05:07 2018
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h	Mon Oct 14 13:18:00 2019
@@ -957,13 +957,8 @@ typedef void (*dmu_traverse_cb_t)(objset
 void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
     dmu_traverse_cb_t cb, void *arg);
 
-#ifdef __FreeBSD__
 int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
     struct file *fp, offset_t *offp);
-#else
-int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
-    struct vnode *vp, offset_t *offp);
-#endif
 
 /* CRC64 table */
 #define	ZFS_CRC64_POLY	0xC96C5795D7870F42ULL	/* ECMA-182, reflected form */

Reply via email to