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