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 */
70 if (tvc
->mvstat
== AFS_MVSTAT_MTPT
)
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
);
96 ObtainReadLock(&afs_xvcache
);
98 /* our tvc ptr is still good until now */
102 ReleaseReadLock(&afs_xvcache
);
110 osi_lookupname_user(user_addr_t aname
, enum uio_seg seg
, int followlink
,
111 struct vnode
**vpp
) {
112 char tname
[PATHBUFLEN
];
116 if (seg
== AFS_UIOUSER
) { /* XXX 64bit */
117 AFS_COPYINSTR(aname
, tname
, sizeof(tname
), &len
, code
);
120 return osi_lookupname(tname
, seg
, followlink
, vpp
);
122 return osi_lookupname(CAST_DOWN(char *, aname
), seg
, followlink
, vpp
);
127 osi_lookupname(char *aname
, enum uio_seg seg
, int followlink
,
128 struct vnode
**vpp
) {
134 flags
|= VNODE_LOOKUP_NOFOLLOW
;
135 ctx
=vfs_context_create(NULL
);
136 code
= vnode_lookup(aname
, flags
, vpp
, ctx
);
137 if (!code
) { /* get a usecount */
141 vfs_context_rele(ctx
);
146 osi_lookupname(char *aname
, enum uio_seg seg
, int followlink
,
157 NDINIT(&n
, LOOKUP
, flags
, seg
, aname
, current_proc());
158 if (error
= namei(&n
))
161 /* should we do this? */
162 VOP_UNLOCK(n
.ni_vp
, 0, current_proc());
168 * afs_suser() returns true if the caller is superuser, false otherwise.
170 * Note that it must NOT set errno.
173 afs_suser(void *credp
)
176 struct proc
*p
= current_proc();
178 #ifdef AFS_DARWIN80_ENV
179 if ((error
= proc_suser(p
)) == 0) {
184 if ((error
= suser(p
->p_ucred
, &p
->p_acflag
)) == 0) {
191 #ifdef AFS_DARWIN80_ENV
193 afsio_partialcopy(struct uio
*auio
, size_t size
)
200 if (proc_is64bit(current_proc())) {
201 res
= uio_create(uio_iovcnt(auio
), uio_offset(auio
),
202 uio_isuserspace(auio
) ? UIO_USERSPACE64
: UIO_SYSSPACE32
,
205 res
= uio_create(uio_iovcnt(auio
), uio_offset(auio
),
206 uio_isuserspace(auio
) ? UIO_USERSPACE32
: UIO_SYSSPACE32
,
210 for (i
= 0;i
< uio_iovcnt(auio
) && size
> 0;i
++) {
211 if (uio_getiov(auio
, i
, &iovaddr
, &iovsize
))
215 if (uio_addiov(res
, iovaddr
, iovsize
))
222 vfs_context_t afs_osi_ctxtp
;
223 int afs_osi_ctxtp_initialized
;
224 static proc_t vfs_context_curproc
;
228 get_vfs_context(void)
230 int isglock
= ISAFS_GLOCK();
234 if (afs_osi_ctxtp_initialized
) {
239 osi_Assert(vfs_context_owner
!= current_thread());
240 if (afs_osi_ctxtp
&& current_proc() == vfs_context_curproc
) {
242 vfs_context_owner
= current_thread();
247 while (afs_osi_ctxtp
&& vfs_context_ref
) {
248 afs_osi_Sleep(&afs_osi_ctxtp
);
249 if (afs_osi_ctxtp_initialized
) {
255 vfs_context_rele(afs_osi_ctxtp
);
257 afs_osi_ctxtp
= vfs_context_create(NULL
);
258 vfs_context_owner
= current_thread();
259 vfs_context_curproc
= current_proc();
265 put_vfs_context(void)
267 int isglock
= ISAFS_GLOCK();
271 if (afs_osi_ctxtp_initialized
) {
276 if (vfs_context_owner
== current_thread())
277 vfs_context_owner
= (thread_t
)0;
279 afs_osi_Wakeup(&afs_osi_ctxtp
);
285 afs_cdev_nop_openclose(dev_t dev
, int flags
, int devtype
,struct proc
*p
)
291 afs_cdev_ioctl(dev_t dev
, u_long cmd
, caddr_t data
, int fflag
, struct proc
*p
) {
292 unsigned int retval
=0;
293 int code
, is64
= proc_is64bit(p
);
294 struct afssysargs
*a
= (struct afssysargs
*)data
;
295 struct afssysargs64
*a64
= (struct afssysargs64
*)data
;
297 if (((unsigned int)cmd
!= VIOC_SYSCALL
) &&
298 ((unsigned int)cmd
!= VIOC_SYSCALL64
))
301 if (((unsigned int)cmd
== VIOC_SYSCALL64
) && (is64
== 0))
304 if (((unsigned int)cmd
== VIOC_SYSCALL
) && (is64
!= 0))
307 code
=afs3_syscall(p
, data
, &retval
);
311 if ((!is64
) && retval
&& a
->syscall
!= AFSCALL_CALL
312 && a
->param1
!= AFSOP_CACHEINODE
)
314 printf("SSCall(%d,%d) is returning non-error value %d\n", a
->syscall
, a
->param1
, retval
);
316 if ((is64
) && retval
&& a64
->syscall
!= AFSCALL_CALL
317 && a64
->param1
!= AFSOP_CACHEINODE
)
319 printf("SSCall(%d,%llx) is returning non-error value %d\n", a64
->syscall
, a64
->param1
, retval
);
325 a64
->retval
= retval
;