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