NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/54541: kernel panic using "zfs diff"



The following reply was made to PR kern/54541; it has been noted by GNATS.

From: "J. Hannken-Illjes" <hannken%eis.cs.tu-bs.de@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: kern/54541: kernel panic using "zfs diff"
Date: Sat, 12 Oct 2019 13:57:07 +0200

 --Apple-Mail=_FC1C4FEB-E02A-47BF-8CBB-D3C164AF2FC6
 Content-Type: multipart/mixed;
 	boundary="Apple-Mail=_263A2ADB-9D83-4DF5-A153-C9D927E63EA4"
 
 
 --Apple-Mail=_263A2ADB-9D83-4DF5-A153-C9D927E63EA4
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain;
 	charset=us-ascii
 
 Ok, dmu_diff() gets called with a file of type "pipe" and
 treating it as "vnode" fails badly.
 
 Please try the attached diff.
 
 --
 J. Hannken-Illjes - hannken%eis.cs.tu-bs.de@localhost - TU Braunschweig
 
 --Apple-Mail=_263A2ADB-9D83-4DF5-A153-C9D927E63EA4
 Content-Disposition: attachment;
 	filename=54541.diff
 Content-Type: application/octet-stream;
 	x-unix-mode=0644;
 	name="54541.diff"
 Content-Transfer-Encoding: 7bit
 
 dmu_diff
 
 Change dmu_diff() back to use a "file" instead of a "vnode".
 Command "zfs diff" calls it with a pipe, not a plain file.
 
 Should fix PR kern/54541: kernel panic using "zfs diff"
 
 diff -r 78bb594e351e -r f95f69bb5abe external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c
 --- external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c
 +++ external/cddl/osnet/dist/uts/common/fs/zfs/dmu_diff.c
 @@ -43,16 +43,13 @@
  struct diffarg {
  #ifdef __FreeBSD__
  	kthread_t *da_td;
 +#endif
  	struct file *da_fp;		/* file to which we are reporting */
 -#else
 -	struct vnode *da_vp;		/* file to which we are reporting */
 -#endif
  	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;
 +#endif
  	da.da_fp = fp;
 -#else
 -	da.da_vp = vp;
 -#endif
  	da.da_offp = offp;
  	da.da_ddr.ddr_type = DDR_NONE;
  	da.da_ddr.ddr_first = da.da_ddr.ddr_last = 0;
 diff -r 78bb594e351e -r f95f69bb5abe external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h
 --- external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h
 +++ external/cddl/osnet/dist/uts/common/fs/zfs/sys/dmu.h
 @@ -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 */
 diff -r 78bb594e351e -r f95f69bb5abe external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
 --- external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
 +++ external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
 @@ -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;
 
 --Apple-Mail=_263A2ADB-9D83-4DF5-A153-C9D927E63EA4--
 
 --Apple-Mail=_FC1C4FEB-E02A-47BF-8CBB-D3C164AF2FC6
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 	filename=signature.asc
 Content-Type: application/pgp-signature;
 	name=signature.asc
 Content-Description: Message signed with OpenPGP
 
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAEBCAAdFiEE2BL3ha7Xao4WUZVYKoaVJdNr+uEFAl2hv5MACgkQKoaVJdNr
 +uET/Qf/fq7ruOcwDpKuv3BgNfH+EP7nkBaMXRAkNiMF+01q5hBLVXuS4mxGdHCP
 tx27pSSNRuY08LXyQeo/2T/JvJaLfR8u+ctrhWtIhe82M2wbPGEdh1Q0qX//TNXg
 6gs9DHpFl0FXT9Dgs93dX4L81VoqIctnkzsEXPWTASPGYJkZuu3/MwV6WXUm7F5X
 kM5QEpKalIJIMA2XoTVNv2F8raVzUzfzK0HwxwyeE1khP73i5n96dlov0mRFlgW+
 c2Ny/Nan+bTPZnlGxAcMQFPZqnsCpmB1HTxO7I1OUs1jxzGq4g/8R5HVBWHlVOte
 QYvEgmW0Bd7mMI3ozwrhHQ+Kmau4xA==
 =h6J2
 -----END PGP SIGNATURE-----
 
 --Apple-Mail=_FC1C4FEB-E02A-47BF-8CBB-D3C164AF2FC6--
 


Home | Main Index | Thread Index | Old Index