summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2006-08-08 12:29:26 +0000
committerkib <kib@FreeBSD.org>2006-08-08 12:29:26 +0000
commitecc9acd26891da5892fc77bf0ed0df59cf810c1e (patch)
tree15d2fbed2dbc5571937620818025af1a243af9d6 /sys/compat
parent7c6c98a7255276df19be3353b070d8677f165cb6 (diff)
downloadFreeBSD-src-ecc9acd26891da5892fc77bf0ed0df59cf810c1e.zip
FreeBSD-src-ecc9acd26891da5892fc77bf0ed0df59cf810c1e.tar.gz
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
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linprocfs/linprocfs.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 2508023..6f32aaf 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;
OpenPOWER on IntegriCloud