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
This commit is contained in:
Konstantin Belousov 2006-08-08 12:29:26 +00:00
parent 7f557ac0a7
commit 1565bf54af

View File

@ -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;