Re: zfs related panic
- In reply to: Konstantin Belousov : "Re: zfs related panic"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 16 Aug 2025 01:13:32 UTC
On Aug 15, 2025, at 5:57 PM, Konstantin Belousov <kostikbel@gmail.com> wrote: > > Below is what I gathered so far. I haven't tried this patch as yet but a previous patch kib@ sent to me fixed the problem. Many thanks! Incidentally the breakpoint I set on zfsctl_root_readdir(struct vop_readdir_args *ap) was never triggered. Wrong thread? > > diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c > index 61d0bb26d1e5..c191b2abf6cc 100644 > --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c > +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c > @@ -674,6 +674,7 @@ zfsctl_root_readdir(struct vop_readdir_args *ap) > zfs_uio_t uio; > int *eofp = ap->a_eofflag; > off_t dots_offset; > + ssize_t orig_resid; > int error; > > zfs_uio_init(&uio, ap->a_uio); > @@ -688,14 +689,20 @@ zfsctl_root_readdir(struct vop_readdir_args *ap) > * count to return is 0. > */ > if (zfs_uio_offset(&uio) == 3 * sizeof (entry)) { > + if (eofp != NULL) > + *eofp = 1; > return (0); > } > > + orig_resid = zfs_uio_resid(&uio); > error = sfs_readdir_common(zfsvfs->z_root, ZFSCTL_INO_ROOT, ap, &uio, > &dots_offset); > if (error != 0) { > - if (error == ENAMETOOLONG) /* ran out of destination space */ > + if (error == ENAMETOOLONG) { /* ran out of destination space */ > error = 0; > + if (orig_resid == zfs_uio_resid(&uio) && eofp != NULL) > + *eofp = 1; > + } > return (error); > } > if (zfs_uio_offset(&uio) != dots_offset) > @@ -710,8 +717,11 @@ zfsctl_root_readdir(struct vop_readdir_args *ap) > entry.d_reclen = sizeof (entry); > error = vfs_read_dirent(ap, &entry, zfs_uio_offset(&uio)); > if (error != 0) { > - if (error == ENAMETOOLONG) > + if (error == ENAMETOOLONG) { > error = 0; > + if (orig_resid == zfs_uio_resid(&uio) && eofp != NULL) > + *eofp = 1; > + } > return (SET_ERROR(error)); > } > if (eofp != NULL) > @@ -1056,17 +1066,22 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap) > zfs_uio_t uio; > int *eofp = ap->a_eofflag; > off_t dots_offset; > + ssize_t orig_resid; > int error; > > zfs_uio_init(&uio, ap->a_uio); > + orig_resid = zfs_uio_resid(&uio); > > ASSERT3S(vp->v_type, ==, VDIR); > > error = sfs_readdir_common(ZFSCTL_INO_ROOT, ZFSCTL_INO_SNAPDIR, ap, > &uio, &dots_offset); > if (error != 0) { > - if (error == ENAMETOOLONG) /* ran out of destination space */ > + if (error == ENAMETOOLONG) { /* ran out of destination space */ > error = 0; > + if (orig_resid == zfs_uio_resid(&uio) && eofp != NULL) > + *eofp = 1; > + } > return (error); > } > > @@ -1084,7 +1099,8 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap) > dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG); > if (error != 0) { > if (error == ENOENT) { > - if (eofp != NULL) > + if (orig_resid == zfs_uio_resid(&uio) && > + eofp != NULL) > *eofp = 1; > error = 0; > } > @@ -1099,8 +1115,12 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap) > entry.d_reclen = sizeof (entry); > error = vfs_read_dirent(ap, &entry, zfs_uio_offset(&uio)); > if (error != 0) { > - if (error == ENAMETOOLONG) > + if (error == ENAMETOOLONG) { > error = 0; > + if (orig_resid == zfs_uio_resid(&uio) && > + eofp != NULL) > + *eofp = 1; > + } > zfs_exit(zfsvfs, FTAG); > return (SET_ERROR(error)); > } > diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c > index 1813c411b013..79e808a3ab3d 100644 > --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c > +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c > @@ -1695,6 +1695,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp, > objset_t *os; > caddr_t outbuf; > size_t bufsize; > + ssize_t orig_resid; > zap_cursor_t zc; > zap_attribute_t *zap; > uint_t bytes_wanted; > @@ -1735,7 +1736,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp, > /* > * Quit if directory has been removed (posix) > */ > - if ((*eofp = zp->z_unlinked) != 0) { > + if ((*eofp = (zp->z_unlinked != 0)) != 0) { > zfs_exit(zfsvfs, FTAG); > return (0); > } > @@ -1743,6 +1744,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp, > error = 0; > os = zfsvfs->z_os; > offset = zfs_uio_offset(uio); > + orig_resid = zfs_uio_resid(uio); > prefetch = zp->z_zn_prefetch; > zap = zap_attribute_long_alloc(); > > @@ -1933,6 +1935,8 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp, > *cookies = NULL; > *ncookies = 0; > } > + if (error == 0 && zfs_uio_resid(uio) != orig_resid) > + *eofp = 1; > return (error); > } >