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