From 1565bf54af20e272c3c45a49e8c67348d32f2cf6 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 8 Aug 2006 12:29:26 +0000 Subject: [PATCH] Lock the vnode around the call to VOP_GETATTR. Move the locked code and vn_fullpath (that call malloc(..., M_WAITOK)) from under the vm object lock, since sleep is not allowed while holding the mutex. Being there, wrap VOP_GETATTR call with conditional Giant aquire. Currently this is (almost) noop because pseudofs is Giant-locked. Tested by: kris Approved by: pjd (mentor) MFC after: 2 weeks --- sys/compat/linprocfs/linprocfs.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 2508023b5b25..6f32aafa4e0b 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -803,6 +803,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) int error; struct vnode *vp; struct vattr vat; + int locked; PROC_LOCK(p); error = p_candebug(td, p); @@ -831,18 +832,28 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) lobj = tobj; ino = 0; if (lobj) { - vp = lobj->handle; VM_OBJECT_LOCK(lobj); off = IDX_TO_OFF(lobj->size); - if (lobj->type == OBJT_VNODE && lobj->handle) { - vn_fullpath(td, vp, &name, &freename); - VOP_GETATTR(vp, &vat, td->td_ucred, td); - ino = vat.va_fileid; + if (lobj->type == OBJT_VNODE) { + vp = lobj->handle; + if (vp) + vref(vp); } + else + vp = NULL; flags = obj->flags; ref_count = obj->ref_count; shadow_count = obj->shadow_count; VM_OBJECT_UNLOCK(lobj); + if (vp) { + vn_fullpath(td, vp, &name, &freename); + locked = VFS_LOCK_GIANT(vp->v_mount); + vn_lock(vp, LK_SHARED | LK_RETRY, td); + VOP_GETATTR(vp, &vat, td->td_ucred, td); + ino = vat.va_fileid; + vput(vp); + VFS_UNLOCK_GIANT(locked); + } } else { flags = 0; ref_count = 0;