Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / DARWIN / osi_vcache.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 #include "afs/sysincludes.h" /*Standard vendor system headers */
14 #include "afsincludes.h" /*AFS-based standard headers */
15
16 struct vcache *
17 osi_NewVnode(void) {
18 struct vcache *tvc;
19
20 tvc = afs_osi_Alloc(sizeof(struct vcache));
21 osi_Assert(tvc != NULL);
22 tvc->v = NULL; /* important to clean this, or use memset 0 */
23
24 return tvc;
25 }
26
27
28 #if defined(AFS_DARWIN80_ENV)
29 int
30 osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
31 *slept = 0;
32
33 /* we ignore defersleep, as we *always* need to sleep */
34 if (!VREFCOUNT_GT(avc, 0) && avc->opens == 0 &&
35 (avc->f.states & CUnlinkedDel) == 0) {
36
37 vnode_t tvp = AFSTOV(avc);
38 /* VREFCOUNT_GT only sees usecounts, not iocounts */
39 /* so this may fail to actually recycle the vnode now */
40 /* must call vnode_get to avoid races. */
41 if (vnode_get(tvp) == 0) {
42 *slept=1;
43 /* must release lock, since vnode_put will immediately
44 reclaim if there are no other users */
45 ReleaseWriteLock(&afs_xvcache);
46 AFS_GUNLOCK();
47 vnode_recycle(tvp);
48 vnode_put(tvp);
49 AFS_GLOCK();
50 ObtainWriteLock(&afs_xvcache, 336);
51 }
52 /* we can't use the vnode_recycle return value to figure
53 * this out, since the iocount we have to hold makes it
54 * always "fail" */
55 if (AFSTOV(avc) == tvp) {
56 /* Caller will move this vcache to the head of the VLRU. */
57 return 0;
58 } else
59 return 1;
60 }
61 return 0;
62 }
63 #else
64 int
65 osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
66 if (!VREFCOUNT_GT(avc,0)
67 || ((VREFCOUNT(avc) == 1) && (UBCINFOEXISTS(AFSTOV(avc))))
68 && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0)
69 {
70 /*
71 * vgone() reclaims the vnode, which calls afs_FlushVCache(),
72 * then it puts the vnode on the free list.
73 * If we don't do this we end up with a cleaned vnode that's
74 * not on the free list.
75 */
76 AFS_GUNLOCK();
77 vgone(AFSTOV(avc));
78 AFS_GLOCK();
79 return 1;
80 }
81 return 0;
82 }
83 #endif /* AFS_DARWIN80_ENV */
84
85 void
86 osi_PrePopulateVCache(struct vcache *avc) {
87 memset(avc, 0, sizeof(struct vcache));
88 }
89
90 void
91 osi_AttachVnode(struct vcache *avc, int seq) {
92 ReleaseWriteLock(&afs_xvcache);
93 AFS_GUNLOCK();
94 afs_darwin_getnewvnode(avc); /* includes one refcount */
95 AFS_GLOCK();
96 ObtainWriteLock(&afs_xvcache,338);
97 #ifdef AFS_DARWIN80_ENV
98 LOCKINIT(avc->rwlock);
99 #else
100 lockinit(&avc->rwlock, PINOD, "vcache", 0, 0);
101 #endif
102 }
103
104 void
105 osi_PostPopulateVCache(struct vcache *avc) {
106 #if !defined(AFS_DARWIN80_ENV)
107 avc->v->v_mount = afs_globalVFS;
108 vSetType(avc, VREG);
109 #else
110 vSetType(avc, VNON);
111 #endif
112 }