Catch up to FreeBSD non-MPSAFE deorbit
[openafs.git] / src / afs / FBSD / 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 /* 
11  * osi_misc.c
12  *
13  */
14
15 #include <afsconfig.h>
16 #include "afs/param.h"
17
18
19 #include "afs/sysincludes.h"    /* Standard vendor system headers */
20 #include "afsincludes.h"        /* Afs-based standard headers */
21 #include <sys/namei.h>
22
23 int
24 osi_lookupname(char *aname, enum uio_seg seg, int followlink,
25                struct vnode **vpp)
26 {
27     struct nameidata n;
28     int flags, error, glocked;
29
30     glocked = ISAFS_GLOCK();
31     if (glocked)
32         AFS_GUNLOCK();
33
34 #if __FreeBSD_version >= 1000021 /* MPSAFE is gone for good! */
35     flags = LOCKLEAF;
36 #else
37     flags = LOCKLEAF | MPSAFE; /* namei must take Giant if needed */
38 #endif
39     if (followlink)
40         flags |= FOLLOW;
41     else
42         flags |= NOFOLLOW;
43     NDINIT(&n, LOOKUP, flags, seg, aname, curthread);
44     if ((error = namei(&n)) != 0) {
45         if (glocked)
46             AFS_GLOCK();
47         return error;
48     }
49     *vpp = n.ni_vp;
50     /* XXX should we do this?  Usually NOT (matt) */
51 #if defined(AFS_FBSD80_ENV)
52     /*VOP_UNLOCK(n.ni_vp, 0);*/
53 #else
54     VOP_UNLOCK(n.ni_vp, 0, curthread);
55 #endif
56     NDFREE(&n, NDF_ONLY_PNBUF);
57     if (glocked)
58         AFS_GLOCK();
59     return 0;
60 }
61
62 /*
63  * does not implement security features of kern_time.c:settime()
64  */
65 void
66 afs_osi_SetTime(osi_timeval_t * atv)
67 {
68     printf("afs attempted to set clock; use \"afsd -nosettime\"\n");
69 }
70
71 /*
72  * Replace all of the bogus special-purpose memory allocators...
73  */
74 void *
75 osi_fbsd_alloc(size_t size, int dropglobal)
76 {
77         void *rv;
78         int glocked;
79
80         if (dropglobal) {
81             glocked = ISAFS_GLOCK();
82             if (glocked)
83                 AFS_GUNLOCK();
84             rv = malloc(size, M_AFS, M_WAITOK);
85             if (glocked)
86                 AFS_GLOCK();
87         } else
88             rv = malloc(size, M_AFS, M_NOWAIT);
89
90         return (rv);
91 }
92
93 void
94 osi_fbsd_free(void *p)
95 {
96        free(p, M_AFS);
97 }
98
99 /**
100  * check if a vcache is in use
101  *
102  * @return status
103  *  @retcode 0 success
104  *  @retcode EBUSY vcache is in use by someone else
105  *  @retcode otherwise other error
106  *
107  * @pre  The caller must hold the vnode interlock for the associated vnode
108  * @post The vnode interlock for the associated vnode will still be held
109  *       and must be VI_UNLOCK'd by the caller
110  */
111 int
112 osi_fbsd_checkinuse(struct vcache *avc)
113 {
114     struct vnode *vp = AFSTOV(avc);
115
116     ASSERT_VI_LOCKED(vp, "osi_fbsd_checkinuse");
117
118     /* The interlock is needed to check the usecount. */
119     if (vp->v_usecount > 0) {
120         return EBUSY;
121     }
122
123     /* XXX
124      * The value of avc->opens here came to be, at some point,
125      * typically -1.  This was caused by incorrectly performing afs_close
126      * processing on vnodes being recycled */
127     if (avc->opens) {
128         return EBUSY;
129     }
130
131     /* if a lock is held, give up */
132     if (CheckLock(&avc->lock)) {
133         return EBUSY;
134     }
135
136     return 0;
137 }