2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h"
15 #include "afsincludes.h"
16 #include <sys/namei.h>
19 #define PATHBUFLEN 256
22 #ifdef AFS_DARWIN80_ENV
23 static thread_t vfs_context_owner;
25 /* works like PFlushVolumeData */
27 darwin_notify_perms(struct unixuser *auser, int event)
30 struct afs_q *tq, *uq = NULL;
31 struct vcache *tvc, *hnext;
32 int isglock = ISAFS_GLOCK();
37 if (!afs_darwin_fsevents)
41 VATTR_SET(&va, va_mode, 0777);
42 if (event & UTokensObtained)
43 VATTR_SET(&va, va_uid, auser->uid);
45 VATTR_SET(&va, va_uid, -2); /* nobody */
49 if (!(vfs_context_owner == current_thread())) {
54 ObtainReadLock(&afs_xvcache);
55 for (i = 0; i < VCSIZE; i++) {
56 for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
59 if (tvc->f.states & CDeadVnode) {
60 /* we can afford to be best-effort */
63 /* no per-file acls, so only notify on directories */
64 if (!(vp = AFSTOV(tvc)) || !vnode_isdir(AFSTOV(tvc)))
66 /* dynroot object. no callbacks. anonymous ACL. just no. */
67 if (afs_IsDynrootFid(&tvc->f.fid))
69 /* no fake fsevents on mount point sources. leaks refs */
72 /* if it's being reclaimed, just pass */
81 ReleaseReadLock(&afs_xvcache);
82 /* Avoid potentially re-entering on this lock */
83 if (0 == NBObtainWriteLock(&tvc->lock, 234)) {
84 tvc->f.states |= CEvent;
86 vnode_setattr(vp, &va, afs_osi_ctxtp);
87 tvc->f.states &= ~CEvent;
90 ReleaseWriteLock(&tvc->lock);
92 ObtainReadLock(&afs_xvcache);
93 /* our tvc ptr is still good until now */
97 ReleaseReadLock(&afs_xvcache);
105 osi_lookupname_user(user_addr_t aname, enum uio_seg seg, int followlink,
106 struct vnode **vpp) {
107 char tname[PATHBUFLEN];
111 if (seg == AFS_UIOUSER) { /* XXX 64bit */
112 AFS_COPYINSTR(aname, tname, sizeof(tname), &len, code);
115 return osi_lookupname(tname, seg, followlink, vpp);
117 return osi_lookupname(CAST_DOWN(char *, aname), seg, followlink, vpp);
122 osi_lookupname(char *aname, enum uio_seg seg, int followlink,
123 struct vnode **vpp) {
129 flags |= VNODE_LOOKUP_NOFOLLOW;
130 ctx=vfs_context_create(NULL);
131 code = vnode_lookup(aname, flags, vpp, ctx);
132 if (!code) { /* get a usecount */
136 vfs_context_rele(ctx);
141 osi_lookupname(char *aname, enum uio_seg seg, int followlink,
152 NDINIT(&n, LOOKUP, flags, seg, aname, current_proc());
153 if (error = namei(&n))
156 /* should we do this? */
157 VOP_UNLOCK(n.ni_vp, 0, current_proc());
163 * afs_suser() returns true if the caller is superuser, false otherwise.
165 * Note that it must NOT set errno.
168 afs_suser(void *credp)
171 struct proc *p = current_proc();
173 #ifdef AFS_DARWIN80_ENV
174 if ((error = proc_suser(p)) == 0) {
179 if ((error = suser(p->p_ucred, &p->p_acflag)) == 0) {
186 #ifdef AFS_DARWIN80_ENV
188 afsio_darwin_partialcopy(uio_t auio, int size)
195 if (proc_is64bit(current_proc())) {
196 res = uio_create(uio_iovcnt(auio), uio_offset(auio),
197 uio_isuserspace(auio) ? UIO_USERSPACE64 : UIO_SYSSPACE32,
200 res = uio_create(uio_iovcnt(auio), uio_offset(auio),
201 uio_isuserspace(auio) ? UIO_USERSPACE32 : UIO_SYSSPACE32,
205 for (i = 0;i < uio_iovcnt(auio) && size > 0;i++) {
206 if (uio_getiov(auio, i, &iovaddr, &iovsize))
210 if (uio_addiov(res, iovaddr, iovsize))
217 vfs_context_t afs_osi_ctxtp;
218 int afs_osi_ctxtp_initialized;
219 static proc_t vfs_context_curproc;
223 get_vfs_context(void)
225 int isglock = ISAFS_GLOCK();
229 if (afs_osi_ctxtp_initialized) {
234 osi_Assert(vfs_context_owner != current_thread());
235 if (afs_osi_ctxtp && current_proc() == vfs_context_curproc) {
237 vfs_context_owner = current_thread();
242 while (afs_osi_ctxtp && vfs_context_ref) {
243 afs_osi_Sleep(&afs_osi_ctxtp);
244 if (afs_osi_ctxtp_initialized) {
250 vfs_context_rele(afs_osi_ctxtp);
252 afs_osi_ctxtp = vfs_context_create(NULL);
253 vfs_context_owner = current_thread();
254 vfs_context_curproc = current_proc();
260 put_vfs_context(void)
262 int isglock = ISAFS_GLOCK();
266 if (afs_osi_ctxtp_initialized) {
271 if (vfs_context_owner == current_thread())
272 vfs_context_owner = (thread_t)0;
274 afs_osi_Wakeup(&afs_osi_ctxtp);
280 afs_cdev_nop_openclose(dev_t dev, int flags, int devtype,struct proc *p)
286 afs_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) {
287 unsigned int retval=0;
288 int code, is64 = proc_is64bit(p);
289 struct afssysargs *a = (struct afssysargs *)data;
290 struct afssysargs64 *a64 = (struct afssysargs64 *)data;
292 if (((unsigned int)cmd != VIOC_SYSCALL) &&
293 ((unsigned int)cmd != VIOC_SYSCALL64))
296 if (((unsigned int)cmd == VIOC_SYSCALL64) && (is64 == 0))
299 if (((unsigned int)cmd == VIOC_SYSCALL) && (is64 != 0))
302 code=afs3_syscall(p, data, &retval);
306 if ((!is64) && retval && a->syscall != AFSCALL_CALL
307 && a->param1 != AFSOP_CACHEINODE)
309 printf("SSCall(%d,%d) is returning non-error value %d\n", a->syscall, a->param1, retval);
311 if ((is64) && retval && a64->syscall != AFSCALL_CALL
312 && a64->param1 != AFSOP_CACHEINODE)
314 printf("SSCall(%d,%llx) is returning non-error value %d\n", a64->syscall, a64->param1, retval);
320 a64->retval = retval;