Commit | Line | Data |
---|---|---|
805e021f CE |
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 | ||
14 | #include "afs/sysincludes.h" /* Standard vendor system headers */ | |
15 | #include "afsincludes.h" /* Afs-based standard headers */ | |
16 | #include "afs/afs_stats.h" /* statistics */ | |
17 | ||
18 | /* Try to discard pages, in order to recycle a vcache entry. | |
19 | * | |
20 | * We also make some sanity checks: ref count, open count, held locks. | |
21 | * | |
22 | * We also do some non-VM-related chores, such as releasing the cred pointer | |
23 | * (for AIX and Solaris) and releasing the gnode (for AIX). | |
24 | * | |
25 | * Locking: afs_xvcache lock is held. It must not be dropped. | |
26 | */ | |
27 | int | |
28 | osi_VM_FlushVCache(struct vcache *avc) | |
29 | { | |
30 | if (avc->vrefCount != 0) | |
31 | return EBUSY; | |
32 | ||
33 | if (avc->opens) | |
34 | return EBUSY; | |
35 | ||
36 | /* Just in case someone is still referring to the vnode we | |
37 | * give up trying to get rid of this guy */ | |
38 | if (avc->vrefCount || CheckLock(&avc->lock) || LockWaiters(&avc->lock)) | |
39 | return EBUSY; | |
40 | ||
41 | if (avc->segid) { | |
42 | AFS_GUNLOCK(); | |
43 | vms_delete(avc->segid); | |
44 | AFS_GLOCK(); | |
45 | avc->segid = avc->vmh = NULL; | |
46 | } | |
47 | ||
48 | if (avc->credp) { | |
49 | crfree(avc->credp); | |
50 | avc->credp = NULL; | |
51 | } | |
52 | ||
53 | /* Free the alloced gnode that was accompanying the vcache's vnode */ | |
54 | aix_gnode_rele(AFSTOV(avc)); | |
55 | ||
56 | return 0; | |
57 | } | |
58 | ||
59 | /* Try to store pages to cache, in order to store a file back to the server. | |
60 | * | |
61 | * Locking: the vcache entry's lock is held. It will usually be dropped and | |
62 | * re-obtained. | |
63 | */ | |
64 | void | |
65 | osi_VM_StoreAllSegments(struct vcache *avc) | |
66 | { | |
67 | if (avc->segid) { | |
68 | /* | |
69 | * The execsOrWriters test is done so that we don't thrash on | |
70 | * the vm_writep call below. We only initiate a pageout of the | |
71 | * dirty vm pages on the last store... | |
72 | * this is strictly a pragmatic decision, and _does_ break the | |
73 | * advertised AFS consistency semantics. Without this hack, | |
74 | * AIX systems panic under heavy load. I consider the current | |
75 | * behavior a bug introduced to hack around a worse bug. XXX | |
76 | * | |
77 | * Removed do_writep governing sync'ing behavior. | |
78 | */ | |
79 | ReleaseWriteLock(&avc->lock); /* XXX */ | |
80 | AFS_GUNLOCK(); | |
81 | vm_writep(avc->segid, 0, MAXFSIZE / PAGESIZE - 1); | |
82 | vms_iowait(avc->segid); | |
83 | AFS_GLOCK(); | |
84 | ObtainWriteLock(&avc->lock, 93); /* XXX */ | |
85 | /* | |
86 | * The following is necessary because of the following | |
87 | * asynchronicity: We open a file, write to it and | |
88 | * close the file | |
89 | * if CCore flag is set, we clear it and do the extra | |
90 | * decrement ourselves now. | |
91 | * If we're called by the CCore clearer, the CCore flag | |
92 | * will already be clear, so we don't have to worry about | |
93 | * clearing it twice. | |
94 | * avc was "VN_HELD" and "crheld" when CCore was set in | |
95 | * afs_FakeClose | |
96 | */ | |
97 | if (avc->f.states & CCore) { | |
98 | avc->f.states &= ~CCore; | |
99 | avc->opens--; | |
100 | avc->execsOrWriters--; | |
101 | AFS_RELE(AFSTOV(avc)); | |
102 | crfree((struct ucred *)avc->linkData); | |
103 | avc->linkData = NULL; | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
108 | /* Try to invalidate pages, for "fs flush" or "fs flushv"; or | |
109 | * try to free pages, when deleting a file. | |
110 | * | |
111 | * Locking: the vcache entry's lock is held. It may be dropped and | |
112 | * re-obtained. | |
113 | * | |
114 | * Since we drop and re-obtain the lock, we can't guarantee that there won't | |
115 | * be some pages around when we return, newly created by concurrent activity. | |
116 | */ | |
117 | void | |
118 | osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) | |
119 | { | |
120 | if (avc->segid) { | |
121 | ReleaseWriteLock(&avc->lock); | |
122 | AFS_GUNLOCK(); | |
123 | vm_flushp(avc->segid, 0, MAXFSIZE / PAGESIZE - 1); | |
124 | vms_iowait(avc->segid); /* XXX Wait?? XXX */ | |
125 | AFS_GLOCK(); | |
126 | ObtainWriteLock(&avc->lock, 60); | |
127 | } | |
128 | } | |
129 | ||
130 | /* Purge VM for a file when its callback is revoked. | |
131 | * | |
132 | * Locking: No lock is held, not even the global lock. | |
133 | */ | |
134 | void | |
135 | osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp) | |
136 | { | |
137 | if (avc->segid) { | |
138 | vm_flushp(avc->segid, 0, MAXFSIZE / PAGESIZE - 1); | |
139 | /* | |
140 | * XXX We probably don't need to wait but better be safe XXX | |
141 | */ | |
142 | vms_iowait(avc->segid); | |
143 | } | |
144 | } | |
145 | ||
146 | /* Purge pages beyond end-of-file, when truncating a file. | |
147 | * | |
148 | * Locking: no lock is held, not even the global lock. | |
149 | * activeV is raised. This is supposed to block pageins, but at present | |
150 | * it only works on Solaris. | |
151 | */ | |
152 | void | |
153 | osi_VM_Truncate(struct vcache *avc, int alen, afs_ucred_t *acred) | |
154 | { | |
155 | if (avc->segid) { | |
156 | int firstpage = (alen + PAGESIZE - 1) / PAGESIZE; | |
157 | vm_releasep(avc->segid, firstpage, MAXFSIZE / PAGESIZE - firstpage); | |
158 | vms_iowait(avc->segid); /* Do we need this? */ | |
159 | } | |
160 | } |