Print this page
patch as-lock-macro-simplification


 872 static int
 873 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
 874 {
 875         proc_t *p;
 876         struct as *as;
 877         list_t iolhead;
 878         int error;
 879 
 880 readmap_common:
 881         if ((error = prlock(pnp, ZNO)) != 0)
 882                 return (error);
 883 
 884         p = pnp->pr_common->prc_proc;
 885         as = p->p_as;
 886 
 887         if ((p->p_flag & SSYS) || as == &kas) {
 888                 prunlock(pnp);
 889                 return (0);
 890         }
 891 
 892         if (!AS_LOCK_TRYENTER(as, &as->a_lock, RW_WRITER)) {
 893                 prunlock(pnp);
 894                 delay(1);
 895                 goto readmap_common;
 896         }
 897         mutex_exit(&p->p_lock);
 898 
 899         switch (type) {
 900         case PR_XMAP:
 901                 error = prgetxmap(p, &iolhead);
 902                 break;
 903         case PR_RMAP:
 904                 error = prgetmap(p, 1, &iolhead);
 905                 break;
 906         case PR_MAP:
 907                 error = prgetmap(p, 0, &iolhead);
 908                 break;
 909         }
 910 
 911         AS_LOCK_EXIT(as, &as->a_lock);
 912         mutex_enter(&p->p_lock);
 913         prunlock(pnp);
 914 
 915         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
 916 
 917         return (error);
 918 }
 919 
 920 static int
 921 pr_read_map(prnode_t *pnp, uio_t *uiop)
 922 {
 923         ASSERT(pnp->pr_type == PR_MAP);
 924         return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 925 }
 926 
 927 static int
 928 pr_read_rmap(prnode_t *pnp, uio_t *uiop)
 929 {
 930         ASSERT(pnp->pr_type == PR_RMAP);
 931         return (pr_read_map_common(pnp, uiop, pnp->pr_type));


1988         list_t  iolhead;
1989         int error;
1990 
1991 readmap32_common:
1992         if ((error = prlock(pnp, ZNO)) != 0)
1993                 return (error);
1994 
1995         p = pnp->pr_common->prc_proc;
1996         as = p->p_as;
1997 
1998         if ((p->p_flag & SSYS) || as == &kas) {
1999                 prunlock(pnp);
2000                 return (0);
2001         }
2002 
2003         if (PROCESS_NOT_32BIT(p)) {
2004                 prunlock(pnp);
2005                 return (EOVERFLOW);
2006         }
2007 
2008         if (!AS_LOCK_TRYENTER(as, &as->a_lock, RW_WRITER)) {
2009                 prunlock(pnp);
2010                 delay(1);
2011                 goto readmap32_common;
2012         }
2013         mutex_exit(&p->p_lock);
2014 
2015         switch (type) {
2016         case PR_XMAP:
2017                 error = prgetxmap32(p, &iolhead);
2018                 break;
2019         case PR_RMAP:
2020                 error = prgetmap32(p, 1, &iolhead);
2021                 break;
2022         case PR_MAP:
2023                 error = prgetmap32(p, 0, &iolhead);
2024                 break;
2025         }
2026         AS_LOCK_EXIT(as, &as->a_lock);
2027         mutex_enter(&p->p_lock);
2028         prunlock(pnp);
2029 
2030         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2031 
2032         return (error);
2033 }
2034 
2035 static int
2036 pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2037 {
2038         ASSERT(pnp->pr_type == PR_MAP);
2039         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2040 }
2041 
2042 static int
2043 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2044 {
2045         ASSERT(pnp->pr_type == PR_RMAP);
2046         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));


2913                     vap->va_ctime.tv_nsec = 0;
2914         } else {
2915                 user_t *up = PTOU(p);
2916                 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2917                     vap->va_ctime.tv_sec = up->u_start.tv_sec;
2918                 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2919                     vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
2920         }
2921 
2922         switch (type) {
2923         case PR_PIDDIR:
2924                 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2925                 vap->va_nlink = 5;
2926                 vap->va_size = sizeof (piddir);
2927                 break;
2928         case PR_OBJECTDIR:
2929                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2930                         vap->va_size = 2 * PRSDSIZE;
2931                 else {
2932                         mutex_exit(&p->p_lock);
2933                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
2934                         if (as->a_updatedir)
2935                                 rebuild_objdir(as);
2936                         vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
2937                         AS_LOCK_EXIT(as, &as->a_lock);
2938                         mutex_enter(&p->p_lock);
2939                 }
2940                 vap->va_nlink = 2;
2941                 break;
2942         case PR_PATHDIR:
2943                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2944                         vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
2945                 else {
2946                         mutex_exit(&p->p_lock);
2947                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
2948                         if (as->a_updatedir)
2949                                 rebuild_objdir(as);
2950                         vap->va_size = (as->a_sizedir + 4 +
2951                             P_FINFO(p)->fi_nfiles) * PRSDSIZE;
2952                         AS_LOCK_EXIT(as, &as->a_lock);
2953                         mutex_enter(&p->p_lock);
2954                 }
2955                 vap->va_nlink = 2;
2956                 break;
2957         case PR_PATH:
2958         case PR_CURDIR:
2959         case PR_ROOTDIR:
2960         case PR_CT:
2961                 vap->va_type = VLNK;
2962                 vap->va_size = 0;
2963                 break;
2964         case PR_FDDIR:
2965                 vap->va_nlink = 2;
2966                 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
2967                 break;
2968         case PR_LWPDIR:
2969                 /*
2970                  * va_nlink: count each lwp as a directory link.
2971                  * va_size: size of p_lwpdir + 2
2972                  */


2998                 break;
2999         case PR_LSTATUS:
3000                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3001                     p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3002                 break;
3003         case PR_PSINFO:
3004                 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3005                 break;
3006         case PR_LPSINFO:
3007                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3008                     (p->p_lwpcnt + p->p_zombcnt) *
3009                     PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3010                 break;
3011         case PR_MAP:
3012         case PR_RMAP:
3013         case PR_XMAP:
3014                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3015                         vap->va_size = 0;
3016                 else {
3017                         mutex_exit(&p->p_lock);
3018                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3019                         if (type == PR_MAP)
3020                                 vap->va_mtime = as->a_updatetime;
3021                         if (type == PR_XMAP)
3022                                 vap->va_size = prnsegs(as, 0) *
3023                                     PR_OBJSIZE(prxmap32_t, prxmap_t);
3024                         else
3025                                 vap->va_size = prnsegs(as, type == PR_RMAP) *
3026                                     PR_OBJSIZE(prmap32_t, prmap_t);
3027                         AS_LOCK_EXIT(as, &as->a_lock);
3028                         mutex_enter(&p->p_lock);
3029                 }
3030                 break;
3031         case PR_CRED:
3032                 mutex_enter(&p->p_crlock);
3033                 vap->va_size = sizeof (prcred_t);
3034                 ngroups = crgetngroups(p->p_cred);
3035                 if (ngroups > 1)
3036                         vap->va_size += (ngroups - 1) * sizeof (gid_t);
3037                 mutex_exit(&p->p_crlock);
3038                 break;
3039         case PR_PRIV:
3040                 vap->va_size = prgetprivsize();
3041                 break;
3042         case PR_SIGACT:
3043                 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3044                 vap->va_size = (nsig-1) *
3045                     PR_OBJSIZE(struct sigaction32, struct sigaction);
3046                 break;
3047         case PR_AUXV:


3056                 mutex_enter(&p->p_lock);
3057                 break;
3058 #endif
3059         case PR_USAGE:
3060                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3061                 break;
3062         case PR_LUSAGE:
3063                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3064                     (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3065                 break;
3066         case PR_PAGEDATA:
3067                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3068                         vap->va_size = 0;
3069                 else {
3070                         /*
3071                          * We can drop p->p_lock before grabbing the
3072                          * address space lock because p->p_as will not
3073                          * change while the process is marked P_PR_LOCK.
3074                          */
3075                         mutex_exit(&p->p_lock);
3076                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3077 #ifdef _LP64
3078                         vap->va_size = iam32bit?
3079                             prpdsize32(as) : prpdsize(as);
3080 #else
3081                         vap->va_size = prpdsize(as);
3082 #endif
3083                         AS_LOCK_EXIT(as, &as->a_lock);
3084                         mutex_enter(&p->p_lock);
3085                 }
3086                 break;
3087         case PR_OPAGEDATA:
3088                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3089                         vap->va_size = 0;
3090                 else {
3091                         mutex_exit(&p->p_lock);
3092                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3093 #ifdef _LP64
3094                         vap->va_size = iam32bit?
3095                             oprpdsize32(as) : oprpdsize(as);
3096 #else
3097                         vap->va_size = oprpdsize(as);
3098 #endif
3099                         AS_LOCK_EXIT(as, &as->a_lock);
3100                         mutex_enter(&p->p_lock);
3101                 }
3102                 break;
3103         case PR_WATCH:
3104                 vap->va_size = avl_numnodes(&p->p_warea) *
3105                     PR_OBJSIZE(prwatch32_t, prwatch_t);
3106                 break;
3107         case PR_LWPSTATUS:
3108                 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3109                 break;
3110         case PR_LWPSINFO:
3111                 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3112                 break;
3113         case PR_LWPUSAGE:
3114                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3115                 break;
3116         case PR_XREGS:
3117                 if (prhasx(p))
3118                         vap->va_size = prgetprxregsize(p);
3119                 else


3676         pnp = prgetnode(dp, PR_OBJECT);
3677 
3678         if (prlock(dpnp, ZNO) != 0) {
3679                 prfreenode(pnp);
3680                 return (NULL);
3681         }
3682         p = dpnp->pr_common->prc_proc;
3683         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3684                 prunlock(dpnp);
3685                 prfreenode(pnp);
3686                 return (NULL);
3687         }
3688 
3689         /*
3690          * We drop p_lock before grabbing the address space lock
3691          * in order to avoid a deadlock with the clock thread.
3692          * The process will not disappear and its address space
3693          * will not change because it is marked P_PR_LOCK.
3694          */
3695         mutex_exit(&p->p_lock);
3696         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
3697         if ((seg = AS_SEGFIRST(as)) == NULL) {
3698                 vp = NULL;
3699                 goto out;
3700         }
3701         if (strcmp(comp, "a.out") == 0) {
3702                 vp = p->p_exec;
3703                 goto out;
3704         }
3705         do {
3706                 /*
3707                  * Manufacture a filename for the "object" directory.
3708                  */
3709                 vattr.va_mask = AT_FSID|AT_NODEID;
3710                 if (seg->s_ops == &segvn_ops &&
3711                     SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3712                     vp != NULL && vp->v_type == VREG &&
3713                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3714                         char name[64];
3715 
3716                         if (vp == p->p_exec) /* "a.out" */
3717                                 continue;
3718                         pr_object_name(name, vp, &vattr);
3719                         if (strcmp(name, comp) == 0)
3720                                 goto out;
3721                 }
3722         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3723 
3724         vp = NULL;
3725 out:
3726         if (vp != NULL) {
3727                 VN_HOLD(vp);
3728         }
3729         AS_LOCK_EXIT(as, &as->a_lock);
3730         mutex_enter(&p->p_lock);
3731         prunlock(dpnp);
3732 
3733         if (vp == NULL)
3734                 prfreenode(pnp);
3735         else {
3736                 /*
3737                  * Fill in the prnode so future references will
3738                  * be able to find the underlying object's vnode.
3739                  * Don't link this prnode into the list of all
3740                  * prnodes for the process; this is a one-use node.
3741                  * Its use is entirely to catch and fail opens for writing.
3742                  */
3743                 pnp->pr_realvp = vp;
3744                 vp = PTOV(pnp);
3745         }
3746 
3747         return (vp);
3748 }
3749 


4133                 /*
4134                  * Start with the inode index immediately after the number of
4135                  * files.
4136                  */
4137                 mutex_enter(&fip->fi_lock);
4138                 idx = fip->fi_nfiles + 4;
4139                 mutex_exit(&fip->fi_lock);
4140 
4141                 if (strcmp(comp, "a.out") == 0) {
4142                         if (p->p_execdir != NULL) {
4143                                 vp = p->p_execdir;
4144                                 VN_HOLD(vp);
4145                                 type = NAME_OBJECT;
4146                                 flags |= PR_AOUT;
4147                         } else {
4148                                 vp = p->p_exec;
4149                                 VN_HOLD(vp);
4150                                 type = NAME_OBJECT;
4151                         }
4152                 } else {
4153                         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
4154                         if ((seg = AS_SEGFIRST(as)) != NULL) {
4155                                 do {
4156                                         /*
4157                                          * Manufacture a filename for the
4158                                          * "object" directory.
4159                                          */
4160                                         vattr.va_mask = AT_FSID|AT_NODEID;
4161                                         if (seg->s_ops == &segvn_ops &&
4162                                             SEGOP_GETVP(seg, seg->s_base, &vp)
4163                                             == 0 &&
4164                                             vp != NULL && vp->v_type == VREG &&
4165                                             VOP_GETATTR(vp, &vattr, 0, CRED(),
4166                                             NULL) == 0) {
4167                                                 char name[64];
4168 
4169                                                 if (vp == p->p_exec)
4170                                                         continue;
4171                                                 idx++;
4172                                                 pr_object_name(name, vp,
4173                                                     &vattr);
4174                                                 if (strcmp(name, comp) == 0)
4175                                                         break;
4176                                         }
4177                                 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4178                         }
4179 
4180                         if (seg == NULL) {
4181                                 vp = NULL;
4182                         } else {
4183                                 VN_HOLD(vp);
4184                                 type = NAME_OBJECT;
4185                         }
4186 
4187                         AS_LOCK_EXIT(as, &as->a_lock);
4188                 }
4189         }
4190 
4191 
4192         switch (type) {
4193         case NAME_FD:
4194                 mutex_enter(&fip->fi_lock);
4195                 if (fd < fip->fi_nfiles) {
4196                         UF_ENTER(ufp, fip, fd);
4197                         if (ufp->uf_file != NULL) {
4198                                 vp = ufp->uf_file->f_vnode;
4199                                 VN_HOLD(vp);
4200                         }
4201                         UF_EXIT(ufp);
4202                 }
4203                 mutex_exit(&fip->fi_lock);
4204                 idx = fd + 4;
4205                 break;
4206         case NAME_ROOT:
4207                 idx = 2;


4821                         return (error);
4822         }
4823 out:
4824         if (eofp)
4825                 *eofp = (uiop->uio_offset >= sizeof (piddir));
4826         return (0);
4827 }
4828 
4829 static void
4830 rebuild_objdir(struct as *as)
4831 {
4832         struct seg *seg;
4833         vnode_t *vp;
4834         vattr_t vattr;
4835         vnode_t **dir;
4836         ulong_t nalloc;
4837         ulong_t nentries;
4838         int i, j;
4839         ulong_t nold, nnew;
4840 
4841         ASSERT(AS_WRITE_HELD(as, &as->a_lock));
4842 
4843         if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4844                 return;
4845         as->a_updatedir = 0;
4846 
4847         if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4848             (seg = AS_SEGFIRST(as)) == NULL)    /* can't happen? */
4849                 return;
4850 
4851         /*
4852          * Allocate space for the new object directory.
4853          * (This is usually about two times too many entries.)
4854          */
4855         nalloc = (nalloc + 0xf) & ~0xf;             /* multiple of 16 */
4856         dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4857 
4858         /* fill in the new directory with desired entries */
4859         nentries = 0;
4860         do {
4861                 vattr.va_mask = AT_FSID|AT_NODEID;


4926                                 continue;
4927                         for (; j < as->a_sizedir; j++) {
4928                                 if (as->a_objectdir[j] != NULL)
4929                                         continue;
4930                                 as->a_objectdir[j++] = vp;
4931                                 break;
4932                         }
4933                 }
4934         }
4935         kmem_free(dir, nalloc * sizeof (vnode_t *));
4936 }
4937 
4938 /*
4939  * Return the vnode from a slot in the process's object directory.
4940  * The caller must have locked the process's address space.
4941  * The only caller is below, in pr_readdir_objectdir().
4942  */
4943 static vnode_t *
4944 obj_entry(struct as *as, int slot)
4945 {
4946         ASSERT(AS_LOCK_HELD(as, &as->a_lock));
4947         if (as->a_objectdir == NULL)
4948                 return (NULL);
4949         ASSERT(slot < as->a_sizedir);
4950         return (as->a_objectdir[slot]);
4951 }
4952 
4953 /* ARGSUSED */
4954 static int
4955 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4956 {
4957         gfs_readdir_state_t gstate;
4958         int error, eof = 0;
4959         offset_t n;
4960         int pslot;
4961         size_t objdirsize;
4962         proc_t *p;
4963         struct as *as;
4964         vnode_t *vp;
4965 
4966         ASSERT(pnp->pr_type == PR_OBJECTDIR);


4990                 as = NULL;
4991                 objdirsize = 0;
4992         }
4993 
4994         /*
4995          * Loop until user's request is satisfied or until
4996          * all mapped objects have been examined. Cannot hold
4997          * the address space lock for the following call as
4998          * gfs_readdir_pred() utimately causes a call to uiomove().
4999          */
5000         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5001                 vattr_t vattr;
5002                 char str[64];
5003 
5004                 /*
5005                  * Set the correct size of the directory just
5006                  * in case the process has changed it's address
5007                  * space via mmap/munmap calls.
5008                  */
5009                 if (as != NULL) {
5010                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
5011                         if (as->a_updatedir)
5012                                 rebuild_objdir(as);
5013                         objdirsize = as->a_sizedir;
5014                 }
5015 
5016                 /*
5017                  * Find next object.
5018                  */
5019                 vattr.va_mask = AT_FSID | AT_NODEID;
5020                 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5021                     (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5022                     != 0))) {
5023                         vattr.va_mask = AT_FSID | AT_NODEID;
5024                         n++;
5025                 }
5026 
5027                 if (as != NULL)
5028                         AS_LOCK_EXIT(as, &as->a_lock);
5029 
5030                 /*
5031                  * Stop when all objects have been reported.
5032                  */
5033                 if (n >= objdirsize) {
5034                         eof = 1;
5035                         break;
5036                 }
5037 
5038                 if (vp == p->p_exec)
5039                         (void) strcpy(str, "a.out");
5040                 else
5041                         pr_object_name(str, vp, &vattr);
5042 
5043                 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5044                     str, 0);
5045 
5046                 if (error)
5047                         break;
5048         }


5282         ASSERT(pnp->pr_type == PR_PATHDIR);
5283 
5284         if (uiop->uio_offset < 0 ||
5285             uiop->uio_resid <= 0 ||
5286             (uiop->uio_offset % PRSDSIZE) != 0)
5287                 return (EINVAL);
5288         oresid = uiop->uio_resid;
5289         bzero(bp, sizeof (bp));
5290 
5291         if ((error = prlock(pnp, ZNO)) != 0)
5292                 return (error);
5293         p = pnp->pr_common->prc_proc;
5294         fip = P_FINFO(p);
5295         pslot = p->p_slot;
5296         mutex_exit(&p->p_lock);
5297 
5298         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5299                 as = NULL;
5300                 objdirsize = 0;
5301         } else {
5302                 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
5303                 if (as->a_updatedir)
5304                         rebuild_objdir(as);
5305                 objdirsize = as->a_sizedir;
5306                 AS_LOCK_EXIT(as, &as->a_lock);
5307                 as = NULL;
5308         }
5309 
5310         mutex_enter(&fip->fi_lock);
5311         if ((p->p_flag & SSYS) || p->p_as == &kas)
5312                 fddirsize = 0;
5313         else
5314                 fddirsize = fip->fi_nfiles;
5315 
5316         for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5317                 /*
5318                  * There are 4 special files in the path directory: ".", "..",
5319                  * "root", and "cwd".  We handle those specially here.
5320                  */
5321                 off = uiop->uio_offset;
5322                 idx = off / PRSDSIZE;
5323                 if (off == 0) {                         /* "." */
5324                         dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5325                         dirent->d_name[0] = '.';
5326                         dirent->d_name[1] = '\0';


5346                         fd = idx - 4;
5347                         if (fip->fi_list[fd].uf_file == NULL)
5348                                 continue;
5349                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5350                         (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5351                         reclen = DIRENT64_RECLEN(PLNSIZ);
5352                 } else if (idx < 4 + fddirsize + objdirsize) {
5353                         if (fip != NULL) {
5354                                 mutex_exit(&fip->fi_lock);
5355                                 fip = NULL;
5356                         }
5357 
5358                         /*
5359                          * We drop p_lock before grabbing the address space lock
5360                          * in order to avoid a deadlock with the clock thread.
5361                          * The process will not disappear and its address space
5362                          * will not change because it is marked P_PR_LOCK.
5363                          */
5364                         if (as == NULL) {
5365                                 as = p->p_as;
5366                                 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
5367                         }
5368 
5369                         if (as->a_updatedir) {
5370                                 rebuild_objdir(as);
5371                                 objdirsize = as->a_sizedir;
5372                         }
5373 
5374                         obj = idx - 4 - fddirsize;
5375                         if ((vp = obj_entry(as, obj)) == NULL)
5376                                 continue;
5377                         vattr.va_mask = AT_FSID|AT_NODEID;
5378                         if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5379                                 continue;
5380                         if (vp == p->p_exec)
5381                                 (void) strcpy(dirent->d_name, "a.out");
5382                         else
5383                                 pr_object_name(dirent->d_name, vp, &vattr);
5384                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5385                         reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5386                 } else {
5387                         break;
5388                 }
5389 
5390                 dirent->d_off = uiop->uio_offset + PRSDSIZE;
5391                 dirent->d_reclen = (ushort_t)reclen;
5392                 if (reclen > uiop->uio_resid) {
5393                         /*
5394                          * Error if no entries have been returned yet.
5395                          */
5396                         if (uiop->uio_resid == oresid)
5397                                 error = EINVAL;
5398                         break;
5399                 }
5400                 /*
5401                  * Drop the address space lock to do the uiomove().
5402                  */
5403                 if (as != NULL)
5404                         AS_LOCK_EXIT(as, &as->a_lock);
5405 
5406                 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5407                 if (as != NULL)
5408                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
5409 
5410                 if (error)
5411                         break;
5412         }
5413 
5414         if (error == 0 && eofp)
5415                 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5416 
5417         if (fip != NULL)
5418                 mutex_exit(&fip->fi_lock);
5419         if (as != NULL)
5420                 AS_LOCK_EXIT(as, &as->a_lock);
5421         mutex_enter(&p->p_lock);
5422         prunlock(pnp);
5423         return (error);
5424 }
5425 
5426 static int
5427 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5428 {
5429         proc_t *p;
5430         int pslot, tslot;
5431         gfs_readdir_state_t gstate;
5432         int error, eof = 0;
5433         offset_t n;
5434 
5435         ASSERT(pnp->pr_type == PR_TMPLDIR);
5436 
5437         if ((error = prlock(pnp, ZNO)) != 0)
5438                 return (error);
5439         p = pnp->pr_common->prc_proc;
5440         pslot = pnp->pr_common->prc_slot;




 872 static int
 873 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
 874 {
 875         proc_t *p;
 876         struct as *as;
 877         list_t iolhead;
 878         int error;
 879 
 880 readmap_common:
 881         if ((error = prlock(pnp, ZNO)) != 0)
 882                 return (error);
 883 
 884         p = pnp->pr_common->prc_proc;
 885         as = p->p_as;
 886 
 887         if ((p->p_flag & SSYS) || as == &kas) {
 888                 prunlock(pnp);
 889                 return (0);
 890         }
 891 
 892         if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
 893                 prunlock(pnp);
 894                 delay(1);
 895                 goto readmap_common;
 896         }
 897         mutex_exit(&p->p_lock);
 898 
 899         switch (type) {
 900         case PR_XMAP:
 901                 error = prgetxmap(p, &iolhead);
 902                 break;
 903         case PR_RMAP:
 904                 error = prgetmap(p, 1, &iolhead);
 905                 break;
 906         case PR_MAP:
 907                 error = prgetmap(p, 0, &iolhead);
 908                 break;
 909         }
 910 
 911         AS_LOCK_EXIT(as);
 912         mutex_enter(&p->p_lock);
 913         prunlock(pnp);
 914 
 915         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
 916 
 917         return (error);
 918 }
 919 
 920 static int
 921 pr_read_map(prnode_t *pnp, uio_t *uiop)
 922 {
 923         ASSERT(pnp->pr_type == PR_MAP);
 924         return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 925 }
 926 
 927 static int
 928 pr_read_rmap(prnode_t *pnp, uio_t *uiop)
 929 {
 930         ASSERT(pnp->pr_type == PR_RMAP);
 931         return (pr_read_map_common(pnp, uiop, pnp->pr_type));


1988         list_t  iolhead;
1989         int error;
1990 
1991 readmap32_common:
1992         if ((error = prlock(pnp, ZNO)) != 0)
1993                 return (error);
1994 
1995         p = pnp->pr_common->prc_proc;
1996         as = p->p_as;
1997 
1998         if ((p->p_flag & SSYS) || as == &kas) {
1999                 prunlock(pnp);
2000                 return (0);
2001         }
2002 
2003         if (PROCESS_NOT_32BIT(p)) {
2004                 prunlock(pnp);
2005                 return (EOVERFLOW);
2006         }
2007 
2008         if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2009                 prunlock(pnp);
2010                 delay(1);
2011                 goto readmap32_common;
2012         }
2013         mutex_exit(&p->p_lock);
2014 
2015         switch (type) {
2016         case PR_XMAP:
2017                 error = prgetxmap32(p, &iolhead);
2018                 break;
2019         case PR_RMAP:
2020                 error = prgetmap32(p, 1, &iolhead);
2021                 break;
2022         case PR_MAP:
2023                 error = prgetmap32(p, 0, &iolhead);
2024                 break;
2025         }
2026         AS_LOCK_EXIT(as);
2027         mutex_enter(&p->p_lock);
2028         prunlock(pnp);
2029 
2030         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2031 
2032         return (error);
2033 }
2034 
2035 static int
2036 pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2037 {
2038         ASSERT(pnp->pr_type == PR_MAP);
2039         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2040 }
2041 
2042 static int
2043 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2044 {
2045         ASSERT(pnp->pr_type == PR_RMAP);
2046         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));


2913                     vap->va_ctime.tv_nsec = 0;
2914         } else {
2915                 user_t *up = PTOU(p);
2916                 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2917                     vap->va_ctime.tv_sec = up->u_start.tv_sec;
2918                 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2919                     vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
2920         }
2921 
2922         switch (type) {
2923         case PR_PIDDIR:
2924                 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2925                 vap->va_nlink = 5;
2926                 vap->va_size = sizeof (piddir);
2927                 break;
2928         case PR_OBJECTDIR:
2929                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2930                         vap->va_size = 2 * PRSDSIZE;
2931                 else {
2932                         mutex_exit(&p->p_lock);
2933                         AS_LOCK_ENTER(as, RW_WRITER);
2934                         if (as->a_updatedir)
2935                                 rebuild_objdir(as);
2936                         vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
2937                         AS_LOCK_EXIT(as);
2938                         mutex_enter(&p->p_lock);
2939                 }
2940                 vap->va_nlink = 2;
2941                 break;
2942         case PR_PATHDIR:
2943                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2944                         vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
2945                 else {
2946                         mutex_exit(&p->p_lock);
2947                         AS_LOCK_ENTER(as, RW_WRITER);
2948                         if (as->a_updatedir)
2949                                 rebuild_objdir(as);
2950                         vap->va_size = (as->a_sizedir + 4 +
2951                             P_FINFO(p)->fi_nfiles) * PRSDSIZE;
2952                         AS_LOCK_EXIT(as);
2953                         mutex_enter(&p->p_lock);
2954                 }
2955                 vap->va_nlink = 2;
2956                 break;
2957         case PR_PATH:
2958         case PR_CURDIR:
2959         case PR_ROOTDIR:
2960         case PR_CT:
2961                 vap->va_type = VLNK;
2962                 vap->va_size = 0;
2963                 break;
2964         case PR_FDDIR:
2965                 vap->va_nlink = 2;
2966                 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
2967                 break;
2968         case PR_LWPDIR:
2969                 /*
2970                  * va_nlink: count each lwp as a directory link.
2971                  * va_size: size of p_lwpdir + 2
2972                  */


2998                 break;
2999         case PR_LSTATUS:
3000                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3001                     p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3002                 break;
3003         case PR_PSINFO:
3004                 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3005                 break;
3006         case PR_LPSINFO:
3007                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3008                     (p->p_lwpcnt + p->p_zombcnt) *
3009                     PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3010                 break;
3011         case PR_MAP:
3012         case PR_RMAP:
3013         case PR_XMAP:
3014                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3015                         vap->va_size = 0;
3016                 else {
3017                         mutex_exit(&p->p_lock);
3018                         AS_LOCK_ENTER(as, RW_WRITER);
3019                         if (type == PR_MAP)
3020                                 vap->va_mtime = as->a_updatetime;
3021                         if (type == PR_XMAP)
3022                                 vap->va_size = prnsegs(as, 0) *
3023                                     PR_OBJSIZE(prxmap32_t, prxmap_t);
3024                         else
3025                                 vap->va_size = prnsegs(as, type == PR_RMAP) *
3026                                     PR_OBJSIZE(prmap32_t, prmap_t);
3027                         AS_LOCK_EXIT(as);
3028                         mutex_enter(&p->p_lock);
3029                 }
3030                 break;
3031         case PR_CRED:
3032                 mutex_enter(&p->p_crlock);
3033                 vap->va_size = sizeof (prcred_t);
3034                 ngroups = crgetngroups(p->p_cred);
3035                 if (ngroups > 1)
3036                         vap->va_size += (ngroups - 1) * sizeof (gid_t);
3037                 mutex_exit(&p->p_crlock);
3038                 break;
3039         case PR_PRIV:
3040                 vap->va_size = prgetprivsize();
3041                 break;
3042         case PR_SIGACT:
3043                 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3044                 vap->va_size = (nsig-1) *
3045                     PR_OBJSIZE(struct sigaction32, struct sigaction);
3046                 break;
3047         case PR_AUXV:


3056                 mutex_enter(&p->p_lock);
3057                 break;
3058 #endif
3059         case PR_USAGE:
3060                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3061                 break;
3062         case PR_LUSAGE:
3063                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3064                     (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3065                 break;
3066         case PR_PAGEDATA:
3067                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3068                         vap->va_size = 0;
3069                 else {
3070                         /*
3071                          * We can drop p->p_lock before grabbing the
3072                          * address space lock because p->p_as will not
3073                          * change while the process is marked P_PR_LOCK.
3074                          */
3075                         mutex_exit(&p->p_lock);
3076                         AS_LOCK_ENTER(as, RW_WRITER);
3077 #ifdef _LP64
3078                         vap->va_size = iam32bit?
3079                             prpdsize32(as) : prpdsize(as);
3080 #else
3081                         vap->va_size = prpdsize(as);
3082 #endif
3083                         AS_LOCK_EXIT(as);
3084                         mutex_enter(&p->p_lock);
3085                 }
3086                 break;
3087         case PR_OPAGEDATA:
3088                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3089                         vap->va_size = 0;
3090                 else {
3091                         mutex_exit(&p->p_lock);
3092                         AS_LOCK_ENTER(as, RW_WRITER);
3093 #ifdef _LP64
3094                         vap->va_size = iam32bit?
3095                             oprpdsize32(as) : oprpdsize(as);
3096 #else
3097                         vap->va_size = oprpdsize(as);
3098 #endif
3099                         AS_LOCK_EXIT(as);
3100                         mutex_enter(&p->p_lock);
3101                 }
3102                 break;
3103         case PR_WATCH:
3104                 vap->va_size = avl_numnodes(&p->p_warea) *
3105                     PR_OBJSIZE(prwatch32_t, prwatch_t);
3106                 break;
3107         case PR_LWPSTATUS:
3108                 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3109                 break;
3110         case PR_LWPSINFO:
3111                 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3112                 break;
3113         case PR_LWPUSAGE:
3114                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3115                 break;
3116         case PR_XREGS:
3117                 if (prhasx(p))
3118                         vap->va_size = prgetprxregsize(p);
3119                 else


3676         pnp = prgetnode(dp, PR_OBJECT);
3677 
3678         if (prlock(dpnp, ZNO) != 0) {
3679                 prfreenode(pnp);
3680                 return (NULL);
3681         }
3682         p = dpnp->pr_common->prc_proc;
3683         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3684                 prunlock(dpnp);
3685                 prfreenode(pnp);
3686                 return (NULL);
3687         }
3688 
3689         /*
3690          * We drop p_lock before grabbing the address space lock
3691          * in order to avoid a deadlock with the clock thread.
3692          * The process will not disappear and its address space
3693          * will not change because it is marked P_PR_LOCK.
3694          */
3695         mutex_exit(&p->p_lock);
3696         AS_LOCK_ENTER(as, RW_READER);
3697         if ((seg = AS_SEGFIRST(as)) == NULL) {
3698                 vp = NULL;
3699                 goto out;
3700         }
3701         if (strcmp(comp, "a.out") == 0) {
3702                 vp = p->p_exec;
3703                 goto out;
3704         }
3705         do {
3706                 /*
3707                  * Manufacture a filename for the "object" directory.
3708                  */
3709                 vattr.va_mask = AT_FSID|AT_NODEID;
3710                 if (seg->s_ops == &segvn_ops &&
3711                     SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3712                     vp != NULL && vp->v_type == VREG &&
3713                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3714                         char name[64];
3715 
3716                         if (vp == p->p_exec) /* "a.out" */
3717                                 continue;
3718                         pr_object_name(name, vp, &vattr);
3719                         if (strcmp(name, comp) == 0)
3720                                 goto out;
3721                 }
3722         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3723 
3724         vp = NULL;
3725 out:
3726         if (vp != NULL) {
3727                 VN_HOLD(vp);
3728         }
3729         AS_LOCK_EXIT(as);
3730         mutex_enter(&p->p_lock);
3731         prunlock(dpnp);
3732 
3733         if (vp == NULL)
3734                 prfreenode(pnp);
3735         else {
3736                 /*
3737                  * Fill in the prnode so future references will
3738                  * be able to find the underlying object's vnode.
3739                  * Don't link this prnode into the list of all
3740                  * prnodes for the process; this is a one-use node.
3741                  * Its use is entirely to catch and fail opens for writing.
3742                  */
3743                 pnp->pr_realvp = vp;
3744                 vp = PTOV(pnp);
3745         }
3746 
3747         return (vp);
3748 }
3749 


4133                 /*
4134                  * Start with the inode index immediately after the number of
4135                  * files.
4136                  */
4137                 mutex_enter(&fip->fi_lock);
4138                 idx = fip->fi_nfiles + 4;
4139                 mutex_exit(&fip->fi_lock);
4140 
4141                 if (strcmp(comp, "a.out") == 0) {
4142                         if (p->p_execdir != NULL) {
4143                                 vp = p->p_execdir;
4144                                 VN_HOLD(vp);
4145                                 type = NAME_OBJECT;
4146                                 flags |= PR_AOUT;
4147                         } else {
4148                                 vp = p->p_exec;
4149                                 VN_HOLD(vp);
4150                                 type = NAME_OBJECT;
4151                         }
4152                 } else {
4153                         AS_LOCK_ENTER(as, RW_READER);
4154                         if ((seg = AS_SEGFIRST(as)) != NULL) {
4155                                 do {
4156                                         /*
4157                                          * Manufacture a filename for the
4158                                          * "object" directory.
4159                                          */
4160                                         vattr.va_mask = AT_FSID|AT_NODEID;
4161                                         if (seg->s_ops == &segvn_ops &&
4162                                             SEGOP_GETVP(seg, seg->s_base, &vp)
4163                                             == 0 &&
4164                                             vp != NULL && vp->v_type == VREG &&
4165                                             VOP_GETATTR(vp, &vattr, 0, CRED(),
4166                                             NULL) == 0) {
4167                                                 char name[64];
4168 
4169                                                 if (vp == p->p_exec)
4170                                                         continue;
4171                                                 idx++;
4172                                                 pr_object_name(name, vp,
4173                                                     &vattr);
4174                                                 if (strcmp(name, comp) == 0)
4175                                                         break;
4176                                         }
4177                                 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4178                         }
4179 
4180                         if (seg == NULL) {
4181                                 vp = NULL;
4182                         } else {
4183                                 VN_HOLD(vp);
4184                                 type = NAME_OBJECT;
4185                         }
4186 
4187                         AS_LOCK_EXIT(as);
4188                 }
4189         }
4190 
4191 
4192         switch (type) {
4193         case NAME_FD:
4194                 mutex_enter(&fip->fi_lock);
4195                 if (fd < fip->fi_nfiles) {
4196                         UF_ENTER(ufp, fip, fd);
4197                         if (ufp->uf_file != NULL) {
4198                                 vp = ufp->uf_file->f_vnode;
4199                                 VN_HOLD(vp);
4200                         }
4201                         UF_EXIT(ufp);
4202                 }
4203                 mutex_exit(&fip->fi_lock);
4204                 idx = fd + 4;
4205                 break;
4206         case NAME_ROOT:
4207                 idx = 2;


4821                         return (error);
4822         }
4823 out:
4824         if (eofp)
4825                 *eofp = (uiop->uio_offset >= sizeof (piddir));
4826         return (0);
4827 }
4828 
4829 static void
4830 rebuild_objdir(struct as *as)
4831 {
4832         struct seg *seg;
4833         vnode_t *vp;
4834         vattr_t vattr;
4835         vnode_t **dir;
4836         ulong_t nalloc;
4837         ulong_t nentries;
4838         int i, j;
4839         ulong_t nold, nnew;
4840 
4841         ASSERT(AS_WRITE_HELD(as));
4842 
4843         if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4844                 return;
4845         as->a_updatedir = 0;
4846 
4847         if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4848             (seg = AS_SEGFIRST(as)) == NULL)    /* can't happen? */
4849                 return;
4850 
4851         /*
4852          * Allocate space for the new object directory.
4853          * (This is usually about two times too many entries.)
4854          */
4855         nalloc = (nalloc + 0xf) & ~0xf;             /* multiple of 16 */
4856         dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4857 
4858         /* fill in the new directory with desired entries */
4859         nentries = 0;
4860         do {
4861                 vattr.va_mask = AT_FSID|AT_NODEID;


4926                                 continue;
4927                         for (; j < as->a_sizedir; j++) {
4928                                 if (as->a_objectdir[j] != NULL)
4929                                         continue;
4930                                 as->a_objectdir[j++] = vp;
4931                                 break;
4932                         }
4933                 }
4934         }
4935         kmem_free(dir, nalloc * sizeof (vnode_t *));
4936 }
4937 
4938 /*
4939  * Return the vnode from a slot in the process's object directory.
4940  * The caller must have locked the process's address space.
4941  * The only caller is below, in pr_readdir_objectdir().
4942  */
4943 static vnode_t *
4944 obj_entry(struct as *as, int slot)
4945 {
4946         ASSERT(AS_LOCK_HELD(as));
4947         if (as->a_objectdir == NULL)
4948                 return (NULL);
4949         ASSERT(slot < as->a_sizedir);
4950         return (as->a_objectdir[slot]);
4951 }
4952 
4953 /* ARGSUSED */
4954 static int
4955 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4956 {
4957         gfs_readdir_state_t gstate;
4958         int error, eof = 0;
4959         offset_t n;
4960         int pslot;
4961         size_t objdirsize;
4962         proc_t *p;
4963         struct as *as;
4964         vnode_t *vp;
4965 
4966         ASSERT(pnp->pr_type == PR_OBJECTDIR);


4990                 as = NULL;
4991                 objdirsize = 0;
4992         }
4993 
4994         /*
4995          * Loop until user's request is satisfied or until
4996          * all mapped objects have been examined. Cannot hold
4997          * the address space lock for the following call as
4998          * gfs_readdir_pred() utimately causes a call to uiomove().
4999          */
5000         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5001                 vattr_t vattr;
5002                 char str[64];
5003 
5004                 /*
5005                  * Set the correct size of the directory just
5006                  * in case the process has changed it's address
5007                  * space via mmap/munmap calls.
5008                  */
5009                 if (as != NULL) {
5010                         AS_LOCK_ENTER(as, RW_WRITER);
5011                         if (as->a_updatedir)
5012                                 rebuild_objdir(as);
5013                         objdirsize = as->a_sizedir;
5014                 }
5015 
5016                 /*
5017                  * Find next object.
5018                  */
5019                 vattr.va_mask = AT_FSID | AT_NODEID;
5020                 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5021                     (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5022                     != 0))) {
5023                         vattr.va_mask = AT_FSID | AT_NODEID;
5024                         n++;
5025                 }
5026 
5027                 if (as != NULL)
5028                         AS_LOCK_EXIT(as);
5029 
5030                 /*
5031                  * Stop when all objects have been reported.
5032                  */
5033                 if (n >= objdirsize) {
5034                         eof = 1;
5035                         break;
5036                 }
5037 
5038                 if (vp == p->p_exec)
5039                         (void) strcpy(str, "a.out");
5040                 else
5041                         pr_object_name(str, vp, &vattr);
5042 
5043                 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5044                     str, 0);
5045 
5046                 if (error)
5047                         break;
5048         }


5282         ASSERT(pnp->pr_type == PR_PATHDIR);
5283 
5284         if (uiop->uio_offset < 0 ||
5285             uiop->uio_resid <= 0 ||
5286             (uiop->uio_offset % PRSDSIZE) != 0)
5287                 return (EINVAL);
5288         oresid = uiop->uio_resid;
5289         bzero(bp, sizeof (bp));
5290 
5291         if ((error = prlock(pnp, ZNO)) != 0)
5292                 return (error);
5293         p = pnp->pr_common->prc_proc;
5294         fip = P_FINFO(p);
5295         pslot = p->p_slot;
5296         mutex_exit(&p->p_lock);
5297 
5298         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5299                 as = NULL;
5300                 objdirsize = 0;
5301         } else {
5302                 AS_LOCK_ENTER(as, RW_WRITER);
5303                 if (as->a_updatedir)
5304                         rebuild_objdir(as);
5305                 objdirsize = as->a_sizedir;
5306                 AS_LOCK_EXIT(as);
5307                 as = NULL;
5308         }
5309 
5310         mutex_enter(&fip->fi_lock);
5311         if ((p->p_flag & SSYS) || p->p_as == &kas)
5312                 fddirsize = 0;
5313         else
5314                 fddirsize = fip->fi_nfiles;
5315 
5316         for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5317                 /*
5318                  * There are 4 special files in the path directory: ".", "..",
5319                  * "root", and "cwd".  We handle those specially here.
5320                  */
5321                 off = uiop->uio_offset;
5322                 idx = off / PRSDSIZE;
5323                 if (off == 0) {                         /* "." */
5324                         dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5325                         dirent->d_name[0] = '.';
5326                         dirent->d_name[1] = '\0';


5346                         fd = idx - 4;
5347                         if (fip->fi_list[fd].uf_file == NULL)
5348                                 continue;
5349                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5350                         (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5351                         reclen = DIRENT64_RECLEN(PLNSIZ);
5352                 } else if (idx < 4 + fddirsize + objdirsize) {
5353                         if (fip != NULL) {
5354                                 mutex_exit(&fip->fi_lock);
5355                                 fip = NULL;
5356                         }
5357 
5358                         /*
5359                          * We drop p_lock before grabbing the address space lock
5360                          * in order to avoid a deadlock with the clock thread.
5361                          * The process will not disappear and its address space
5362                          * will not change because it is marked P_PR_LOCK.
5363                          */
5364                         if (as == NULL) {
5365                                 as = p->p_as;
5366                                 AS_LOCK_ENTER(as, RW_WRITER);
5367                         }
5368 
5369                         if (as->a_updatedir) {
5370                                 rebuild_objdir(as);
5371                                 objdirsize = as->a_sizedir;
5372                         }
5373 
5374                         obj = idx - 4 - fddirsize;
5375                         if ((vp = obj_entry(as, obj)) == NULL)
5376                                 continue;
5377                         vattr.va_mask = AT_FSID|AT_NODEID;
5378                         if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5379                                 continue;
5380                         if (vp == p->p_exec)
5381                                 (void) strcpy(dirent->d_name, "a.out");
5382                         else
5383                                 pr_object_name(dirent->d_name, vp, &vattr);
5384                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5385                         reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5386                 } else {
5387                         break;
5388                 }
5389 
5390                 dirent->d_off = uiop->uio_offset + PRSDSIZE;
5391                 dirent->d_reclen = (ushort_t)reclen;
5392                 if (reclen > uiop->uio_resid) {
5393                         /*
5394                          * Error if no entries have been returned yet.
5395                          */
5396                         if (uiop->uio_resid == oresid)
5397                                 error = EINVAL;
5398                         break;
5399                 }
5400                 /*
5401                  * Drop the address space lock to do the uiomove().
5402                  */
5403                 if (as != NULL)
5404                         AS_LOCK_EXIT(as);
5405 
5406                 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5407                 if (as != NULL)
5408                         AS_LOCK_ENTER(as, RW_WRITER);
5409 
5410                 if (error)
5411                         break;
5412         }
5413 
5414         if (error == 0 && eofp)
5415                 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5416 
5417         if (fip != NULL)
5418                 mutex_exit(&fip->fi_lock);
5419         if (as != NULL)
5420                 AS_LOCK_EXIT(as);
5421         mutex_enter(&p->p_lock);
5422         prunlock(pnp);
5423         return (error);
5424 }
5425 
5426 static int
5427 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5428 {
5429         proc_t *p;
5430         int pslot, tslot;
5431         gfs_readdir_state_t gstate;
5432         int error, eof = 0;
5433         offset_t n;
5434 
5435         ASSERT(pnp->pr_type == PR_TMPLDIR);
5436 
5437         if ((error = prlock(pnp, ZNO)) != 0)
5438                 return (error);
5439         p = pnp->pr_common->prc_proc;
5440         pslot = pnp->pr_common->prc_slot;