Import Upstream version 1.8.5
[hcoop/debian/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 = 0;
36 #else
37 flags = 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 * Replace all of the bogus special-purpose memory allocators...
64 */
65 void *
66 osi_fbsd_alloc(size_t size, int dropglobal)
67 {
68 void *rv;
69 int glocked;
70
71 if (dropglobal) {
72 glocked = ISAFS_GLOCK();
73 if (glocked)
74 AFS_GUNLOCK();
75 rv = malloc(size, M_AFS, M_WAITOK);
76 if (glocked)
77 AFS_GLOCK();
78 } else
79 rv = malloc(size, M_AFS, M_NOWAIT);
80
81 return (rv);
82 }
83
84 void
85 osi_fbsd_free(void *p)
86 {
87 free(p, M_AFS);
88 }
89
90 /**
91 * check if a vcache is in use
92 *
93 * @return status
94 * @retcode 0 success
95 * @retcode EBUSY vcache is in use by someone else
96 * @retcode otherwise other error
97 *
98 * @pre The caller must hold the vnode interlock for the associated vnode
99 * @post The vnode interlock for the associated vnode will still be held
100 * and must be VI_UNLOCK'd by the caller
101 */
102 int
103 osi_fbsd_checkinuse(struct vcache *avc)
104 {
105 struct vnode *vp = AFSTOV(avc);
106
107 ASSERT_VI_LOCKED(vp, "osi_fbsd_checkinuse");
108
109 /* The interlock is needed to check the usecount. */
110 if (vp->v_usecount > 0) {
111 return EBUSY;
112 }
113
114 /* XXX
115 * The value of avc->opens here came to be, at some point,
116 * typically -1. This was caused by incorrectly performing afs_close
117 * processing on vnodes being recycled */
118 if (avc->opens) {
119 return EBUSY;
120 }
121
122 /* if a lock is held, give up */
123 if (CheckLock(&avc->lock)) {
124 return EBUSY;
125 }
126
127 return 0;
128 }