2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h" /* statistics */
19 /* Try to discard pages, in order to recycle a vcache entry.
21 * We also make some sanity checks: ref count, open count, held locks.
23 * We also do some non-VM-related chores, such as releasing the cred pointer
24 * (for AIX and Solaris) and releasing the gnode (for AIX).
26 * Locking: afs_xvcache lock is held. It must not be dropped.
28 * OSF/1 Locking: VN_LOCK has been called.
31 osi_VM_FlushVCache(struct vcache
*avc
)
33 struct vnode
*vp
= AFSTOV(avc
);
41 if (!(UBCINFOMISSING(vp
) || UBCINFORECLAIMED(vp
))) {
43 kret
=ubc_invalidate(vp
,0,size
);
53 /* Try to store pages to cache, in order to store a file back to the server.
55 * Locking: the vcache entry's lock is held. It will usually be dropped and
59 osi_VM_StoreAllSegments(struct vcache
*avc
)
61 struct vnode
*vp
= AFSTOV(avc
);
62 ReleaseWriteLock(&avc
->lock
);
64 #ifdef AFS_DARWIN80_ENV
65 ubc_msync_range(vp
, 0, ubc_getsize(vp
), UBC_SYNC
|UBC_PUSHDIRTY
);
67 if (UBCINFOEXISTS(vp
)) {
72 ObtainWriteLock(&avc
->lock
, 94);
75 /* Try to invalidate pages, for "fs flush" or "fs flushv"; or
76 * try to free pages, when deleting a file.
78 * Locking: the vcache entry's lock is held. It may be dropped and
81 * Since we drop and re-obtain the lock, we can't guarantee that there won't
82 * be some pages around when we return, newly created by concurrent activity.
85 osi_VM_TryToSmush(struct vcache
*avc
, afs_ucred_t
*acred
, int sync
)
87 struct vnode
*vp
= AFSTOV(avc
);
92 ReleaseWriteLock(&avc
->lock
);
94 #ifdef AFS_DARWIN80_ENV
95 ubc_msync_range(vp
, 0, ubc_getsize(vp
), UBC_INVALIDATE
);
97 if (UBCINFOEXISTS(vp
)) {
98 size
= ubc_getsize(vp
);
99 kret
= ubc_invalidate(vp
, 0, size
);
100 if (kret
!= 1) /* should be KERN_SUCCESS */
101 printf("TryToSmush: invalidate failed (error = %d)\n", kret
);
105 ObtainWriteLock(&avc
->lock
, 59);
108 /* Purge VM for a file when its callback is revoked.
110 * Locking: No lock is held, not even the global lock.
112 /* XXX this seems to not be referenced anywhere. *somebody* ought to be calling
113 this, and also making sure that ubc's idea of the filesize is right more
116 osi_VM_FlushPages(struct vcache
*avc
, afs_ucred_t
*credp
)
118 struct vnode
*vp
= AFSTOV(avc
);
122 #ifdef AFS_DARWIN80_ENV
123 size
= ubc_getsize(vp
);
124 ubc_msync_range(vp
, 0, size
, UBC_INVALIDATE
);
125 /* XXX what about when not CStatd */
126 if (avc
->f
.states
& CStatd
&& size
!= avc
->f
.m
.Length
)
127 ubc_setsize(vp
, avc
->f
.m
.Length
);
129 if (UBCINFOEXISTS(vp
)) {
130 size
= ubc_getsize(vp
);
131 kret
= ubc_invalidate(vp
, 0, size
);
132 if (kret
!= 1) /* Should be KERN_SUCCESS */
133 printf("VMFlushPages: invalidate failed (error = %d)\n", kret
);
134 /* XXX what about when not CStatd */
135 if (avc
->f
.states
& CStatd
&& size
!= avc
->f
.m
.Length
)
137 ubc_setsize(vp
, avc
->f
.m
.Length
);
142 /* Purge pages beyond end-of-file, when truncating a file.
144 * Locking: no lock is held, not even the global lock.
145 * activeV is raised. This is supposed to block pageins, but at present
146 * it only works on Solaris.
149 osi_VM_Truncate(struct vcache
*avc
, int alen
, afs_ucred_t
*acred
)
151 struct vnode
*vp
= AFSTOV(avc
);
152 #ifdef AFS_DARWIN80_ENV
153 ubc_setsize(vp
, alen
);
155 if (UBCINFOEXISTS(vp
) && UBCISVALID(vp
)) {
156 ubc_setsize(vp
, alen
);
162 osi_VM_NukePages(struct vnode
*vp
, off_t offset
, off_t size
)
166 struct vcache
*avc
= VTOAFS(vp
);
168 offset
= trunc_page(offset
);
169 size
= round_page(size
+ 1);
171 ubc_page_op(vp
, (vm_offset_t
) offset
,
172 UPL_POP_SET
| UPL_POP_BUSY
| UPL_POP_DUMP
, 0, 0);
180 osi_VM_Setup(struct vcache
*avc
, int force
)
183 struct vnode
*vp
= AFSTOV(avc
);
185 #ifndef AFS_DARWIN80_ENV
186 if (UBCISVALID(vp
) && ((avc
->f
.states
& CStatd
) || force
)) {
187 if (!UBCINFOEXISTS(vp
)) {
189 avc
->f
.states
|= CUBCinit
;
191 if ((error
= ubc_info_init(vp
))) {
193 avc
->f
.states
&= ~CUBCinit
;
198 avc
->f
.states
&= ~CUBCinit
;
201 if (UBCINFOEXISTS(vp
) && UBCISVALID(vp
)) {
202 ubc_setsize(vp
, avc
->f
.m
.Length
);