extern struct vnodeops *afs_ops;
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
if (!VREFCOUNT_GT(avc,0)
&& avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
#if defined(AFS_DARWIN80_ENV)
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
*slept = 0;
+ /* we ignore defersleep, as we *always* need to sleep */
if (!VREFCOUNT_GT(avc, 0) && avc->opens == 0 &&
(avc->f.states & CUnlinkedDel) == 0) {
}
#else
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
if (!VREFCOUNT_GT(avc,0)
|| ((VREFCOUNT(avc) == 1) && (UBCINFOEXISTS(AFSTOV(avc))))
&& avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0)
#endif
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
/*
* essentially all we want to do here is check that the
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
+ /* we can't control whether we sleep */
if (!VREFCOUNT_GT(avc,0)
&& avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
code = afs_FlushVCache(avc, slept);
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
+ /* we can't control whether we sleep */
if (!VREFCOUNT_GT(avc,0)
&& avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) {
code = afs_FlushVCache(avc, slept);
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
struct dentry *dentry;
struct list_head *cur, *head;
/* First, see if we can evict the inode from the dcache */
- if (avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+ if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
*slept = 1;
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
#endif
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
struct dentry *dentry;
struct list_head *cur, *head;
/* First, see if we can evict the inode from the dcache */
- if (avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+ if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
+ *slept = 1;
+ ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
afs_linux_lock_dcache();
head = &(AFSTOV(avc))->i_dentry;
afs_linux_unlock_dcache();
inuse:
AFS_GLOCK();
+ ObtainWriteLock(&afs_xvcache, 733);
}
/* See if we can evict it from the VLRUQ */
if (VREFCOUNT_GT(avc,0) && !VREFCOUNT_GT(avc,1) && avc->opens == 0
&& (avc->f.states & CUnlinkedDel) == 0) {
+ int didsleep = *slept;
code = afs_FlushVCache(avc, slept);
+ /* flushvcache wipes slept; restore slept if we did before */
+ if (didsleep)
+ *slept = didsleep;
+
if (code == 0)
return 1;
}
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
*slept = 0;
if (!VREFCOUNT_GT(avc,0)
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
*slept = 0;
if (!VREFCOUNT_GT(avc,0)
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
if (!VREFCOUNT_GT(avc,0)
#include "afsincludes.h" /*AFS-based standard headers */
int
-osi_TryEvictVCache(struct vcache *avc, int *slept) {
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
if (!VREFCOUNT_GT(avc,0)
#endif
struct vcache;
-extern int osi_TryEvictVCache(struct vcache *, int *);
+extern int osi_TryEvictVCache(struct vcache *, int *, int);
extern struct vcache *osi_NewVnode(void);
extern void osi_PrePopulateVCache(struct vcache *);
extern void osi_PostPopulateVCache(struct vcache *);
afs_int32 i, loop;
struct vcache *tvc;
struct afs_q *tq, *uq;
- int fv_slept;
+ int fv_slept, defersleep = 0;
afs_int32 target = anumber;
i = 0;
}
fv_slept = 0;
- if (osi_TryEvictVCache(tvc, &fv_slept))
+ if (osi_TryEvictVCache(tvc, &fv_slept, defersleep))
anumber--;
if (fv_slept) {
i = 0;
continue; /* start over - may have raced. */
}
- if (tq == uq)
+ if (tq == uq) {
+ if (anumber && !defersleep) {
+ defersleep = 1;
+ tq = VLRU.prev;
+ continue;
+ }
break;
+ }
}
if (!afsd_dynamic_vcaches && anumber == target) {
afs_warn("afs_ShakeLooseVCaches: warning none freed, using %d of %d\n",