macos-rollup-20051013
[openafs.git] / src / afs / DARWIN / osi_misc.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 RCSID
14     ("$Header$");
15
16 #include "afs/sysincludes.h"
17 #include "afsincludes.h"
18 #include <sys/namei.h>
19
20 #ifndef PATHBUFLEN
21 #define PATHBUFLEN 256
22 #endif
23
24 #ifdef AFS_DARWIN80_ENV
25 int
26 osi_lookupname(char *aname, enum uio_seg seg, int followlink,
27                struct vnode **vpp) {
28     vfs_context_t ctx;
29     char tname[PATHBUFLEN];
30     int code, flags;
31     size_t len;
32     
33     if (seg == AFS_UIOUSER) { /* XXX 64bit */
34         AFS_COPYINSTR(aname, tname, sizeof(tname), &len, code);
35         if (code)
36             return code;
37         aname=tname;
38     }
39     flags = 0;
40     if (!followlink)
41         flags |= VNODE_LOOKUP_NOFOLLOW;
42     ctx=vfs_context_create(NULL);
43     code = vnode_lookup(aname, flags, vpp, ctx);
44     if (!code) { /* get a usecount */
45         vnode_ref(*vpp);
46         vnode_put(*vpp);
47     }
48     vfs_context_rele(ctx);
49     return code;
50 }
51 #else
52 int
53 osi_lookupname(char *aname, enum uio_seg seg, int followlink,
54                struct vnode **vpp)
55 {
56     struct nameidata n;
57     int flags, error;
58     flags = 0;
59     flags = LOCKLEAF;
60     if (followlink)
61         flags |= FOLLOW;
62     else
63         flags |= NOFOLLOW;
64     NDINIT(&n, LOOKUP, flags, seg, aname, current_proc());
65     if (error = namei(&n))
66         return error;
67     *vpp = n.ni_vp;
68    /* should we do this? */
69     VOP_UNLOCK(n.ni_vp, 0, current_proc());
70     return 0;
71 }
72 #endif
73
74 /*
75  * afs_suser() returns true if the caller is superuser, false otherwise.
76  *
77  * Note that it must NOT set errno.
78  */
79 int
80 afs_suser(void *credp)
81 {
82     int error;
83     struct proc *p = current_proc();
84
85 #ifdef AFS_DARWIN80_ENV
86     if ((error = proc_suser(p)) == 0) {
87         return (1);
88     }
89     return (0);
90 #else
91     if ((error = suser(p->p_ucred, &p->p_acflag)) == 0) {
92         return (1);
93     }
94     return (0);
95 #endif
96 }
97
98 #ifdef AFS_DARWIN80_ENV
99 uio_t afsio_darwin_partialcopy(uio_t auio, int size) {
100    uio_t res;
101    int i;
102    user_addr_t iovaddr;
103    user_size_t iovsize;
104
105    /* XXX 64 bit userspaace? */
106    res = uio_create(uio_iovcnt(auio), uio_offset(auio),
107                     uio_isuserspace(auio) ? UIO_USERSPACE32 : UIO_SYSSPACE32,
108                     uio_rw(auio));
109
110    for (i = 0;i < uio_iovcnt(auio) && size > 0;i++) {
111        if (uio_getiov(auio, i, &iovaddr, &iovsize))
112            break;
113        if (iovsize > size)
114           iovsize = size;
115        if (uio_addiov(res, iovaddr, iovsize))
116           break;
117        size -= iovsize;
118    }
119    return res;
120 }
121
122 vfs_context_t afs_osi_ctxtp;
123 int afs_osi_ctxtp_initialized;
124 static thread_t vfs_context_owner;
125 #define RECURSIVE_VFS_CONTEXT 1
126 #if RECURSIVE_VFS_CONTEXT
127 static proc_t vfs_context_curproc;
128 int vfs_context_ref;
129 #else 
130 #define vfs_context_ref 1
131 #endif
132 void get_vfs_context(void) {
133   int isglock = ISAFS_GLOCK();
134
135   if (!isglock)
136      AFS_GLOCK();
137   if (afs_osi_ctxtp_initialized) {
138      if (!isglock)
139         AFS_GUNLOCK();
140       return;
141   }
142   osi_Assert(vfs_context_owner != current_thread());
143 #if RECURSIVE_VFS_CONTEXT
144   if (afs_osi_ctxtp && current_proc() == vfs_context_curproc) {
145      vfs_context_ref++;
146      vfs_context_owner = current_thread();
147      if (!isglock)
148         AFS_GUNLOCK();
149      return;
150   }
151 #endif
152   while (afs_osi_ctxtp && vfs_context_ref) {
153      printf("[%d] waiting for afs_osi_ctxtp\n", proc_selfpid());
154      afs_osi_Sleep(&afs_osi_ctxtp);
155      if (afs_osi_ctxtp_initialized) {
156        printf("[%d] ok\n", proc_selfpid());
157        if (!isglock)
158           AFS_GUNLOCK();
159        return;
160      }
161      if (!afs_osi_ctxtp || !vfs_context_ref)
162         printf("[%d] ok\n", proc_selfpid());
163   }
164 #if RECURSIVE_VFS_CONTEXT
165   vfs_context_rele(afs_osi_ctxtp);
166   vfs_context_ref=1;
167 #else
168   osi_Assert(vfs_context_owner == (thread_t)0);
169 #endif
170   afs_osi_ctxtp = vfs_context_create(NULL);
171   vfs_context_owner = current_thread();
172   vfs_context_curproc = current_proc();
173   if (!isglock)
174      AFS_GUNLOCK();
175 }
176
177 void put_vfs_context(void) {
178   int isglock = ISAFS_GLOCK();
179
180   if (!isglock)
181      AFS_GLOCK();
182   if (afs_osi_ctxtp_initialized) {
183      if (!isglock)
184         AFS_GUNLOCK();
185       return;
186   }
187 #if RECURSIVE_VFS_CONTEXT
188   if (vfs_context_owner == current_thread())
189       vfs_context_owner = (thread_t)0;
190   vfs_context_ref--;
191 #else
192   osi_Assert(vfs_context_owner == current_thread());
193   vfs_context_rele(afs_osi_ctxtp);
194   afs_osi_ctxtp = NULL;
195   vfs_context_owner = (thread_t)0;
196 #endif
197   afs_osi_Wakeup(&afs_osi_ctxtp);
198      if (!isglock)
199         AFS_GUNLOCK();
200 }
201
202 extern int afs3_syscall();
203
204 int afs_cdev_nop_openclose(dev_t dev, int flags, int devtype,struct proc *p) {
205   return 0;
206 }
207 extern int afs3_syscall(struct proc *p, void *data, unsigned long *retval);
208
209 int
210 afs_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) {
211    unsigned long retval=0;
212    int code;
213    struct afssysargs *a = (struct afssysargs *)data;
214    if (proc_is64bit(p))
215      return EINVAL;
216
217   if (cmd != VIOC_SYSCALL) {
218      return EINVAL;
219   }
220
221  code=afs3_syscall(p, data, &retval);
222  if (code)
223     return code;
224  if (retval && a->syscall != AFSCALL_CALL && a->param1 != AFSOP_CACHEINODE) { printf("SSCall(%d,%d) is returning non-error value %d\n", a->syscall, a->param1, retval); }
225  a->retval = retval;
226  return 0; 
227 }
228
229 #endif