Index: src/sys/kern/vfs_subr.c =================================================================== --- src/sys/kern/vfs_subr.c (revision 179) +++ src/sys/kern/vfs_subr.c (working copy) @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include #include #include @@ -3695,7 +3697,14 @@ { struct vnode *vp = (struct vnode *)kn->kn_hook; struct vattr va; + int kllocked, kqlocked; + if (kn->kn_knlist != NULL) + kllocked = mtx_owned(kn->kn_knlist->kl_lock); + else + kllocked = 0; + kqlocked = mtx_owned(&kn->kn_kq->kq_lock); + /* * filesystem is gone, so set the EOF flag and schedule * the knote for deletion. @@ -3705,12 +3714,26 @@ return (1); } + /* + * We can unlock here and reacquire later, since we don't touch + * any of the protected fields. + */ + if (kllocked) + mtx_unlock(kn->kn_knlist->kl_lock); + if (kqlocked) + mtx_unlock(&kn->kn_kq->kq_lock); + vn_lock(vp, LK_SHARED | LK_RETRY, curthread); if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread)) return (0); if (VOP_UNLOCK(vp, 0, curthread)) return (0); + if (kllocked) + mtx_lock(kn->kn_knlist->kl_lock); + if (kqlocked) + mtx_lock(&kn->kn_kq->kq_lock); + kn->kn_data = va.va_size - kn->kn_fp->f_offset; return (kn->kn_data != 0); }