summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorpetede <none@none>2005-10-28 02:26:45 -0700
committerpetede <none@none>2005-10-28 02:26:45 -0700
commit43d09bd41aaf70e71332e93df1cd47edf015749e (patch)
treec0bea0d7ac32a0e4d53037ed6ce763c91ec3c2c2 /usr/src
parent12b2e3e73495663d8524de577375cab2b57dedf1 (diff)
downloadillumos-joyent-43d09bd41aaf70e71332e93df1cd47edf015749e.tar.gz
6291662 running find may cause panic when wandering through /proc
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/proc/prvnops.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/usr/src/uts/common/fs/proc/prvnops.c b/usr/src/uts/common/fs/proc/prvnops.c
index ff04678858..dea54056c6 100644
--- a/usr/src/uts/common/fs/proc/prvnops.c
+++ b/usr/src/uts/common/fs/proc/prvnops.c
@@ -4936,22 +4936,31 @@ pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
as = NULL;
objdirsize = 0;
- } else {
- AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
- if (as->a_updatedir)
- rebuild_objdir(as);
- objdirsize = as->a_sizedir;
}
/*
* Loop until user's request is satisfied or until
- * all mapped objects have been examined.
+ * all mapped objects have been examined. Cannot hold
+ * the address space lock for the following call as
+ * gfs_readdir_pred() utimately causes a call to uiomove().
*/
while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
vattr_t vattr;
char str[64];
/*
+ * Set the correct size of the directory just
+ * in case the process has changed it's address
+ * space via mmap/munmap calls.
+ */
+ if (as != NULL) {
+ AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
+ if (as->a_updatedir)
+ rebuild_objdir(as);
+ objdirsize = as->a_sizedir;
+ }
+
+ /*
* Find next object.
*/
vattr.va_mask = AT_FSID | AT_NODEID;
@@ -4961,6 +4970,9 @@ pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
n++;
}
+ if (as != NULL)
+ AS_LOCK_EXIT(as, &as->a_lock);
+
/*
* Stop when all objects have been reported.
*/
@@ -4974,26 +4986,13 @@ pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
else
pr_object_name(str, vp, &vattr);
- /*
- * Drop the address space lock to do the uiomove().
- */
- if (as != NULL)
- AS_LOCK_EXIT(as, &as->a_lock);
error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
str);
- if (as != NULL) {
- AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
- if (as->a_updatedir) {
- rebuild_objdir(as);
- objdirsize = as->a_sizedir;
- }
- }
+
if (error)
break;
}
- if (as != NULL)
- AS_LOCK_EXIT(as, &as->a_lock);
mutex_enter(&p->p_lock);
prunlock(pnp);