diff options
author | petede <none@none> | 2005-10-28 02:26:45 -0700 |
---|---|---|
committer | petede <none@none> | 2005-10-28 02:26:45 -0700 |
commit | 43d09bd41aaf70e71332e93df1cd47edf015749e (patch) | |
tree | c0bea0d7ac32a0e4d53037ed6ce763c91ec3c2c2 /usr/src | |
parent | 12b2e3e73495663d8524de577375cab2b57dedf1 (diff) | |
download | illumos-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.c | 39 |
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); |