return 0;
}
+static void
+FlushAllVCBs(struct rx_connection **rxconns, int nconns, int nservers,
+ struct afs_conn **conns, struct srvAddr **addrs)
+{
+ afs_int32 *results;
+ afs_int32 i;
+
+ results = afs_osi_Alloc(nservers * sizeof (afs_int32));
+ osi_Assert(results != NULL);
+
+ AFS_GUNLOCK();
+ multi_Rx(rxconns,nconns)
+ {
+ multi_RXAFS_GiveUpAllCallBacks();
+ results[multi_i] = multi_error;
+ } multi_End;
+ AFS_GLOCK();
+
+ /*
+ * Freeing the CBR will unlink it from the server's CBR list
+ * do it here, not in the loop, because a dynamic CBR will call
+ * into the memory management routines.
+ */
+ for ( i = 0 ; i < nconns ; i++ ) {
+ if (results[i] == 0) {
+ /* Unchain all of them */
+ while (addrs[i]->server->cbrs)
+ afs_FreeCBR(addrs[i]->server->cbrs);
+ }
+ }
+ afs_osi_Free(results, nservers * sizeof(afs_int32));
+}
+
/*!
* Flush all queued callbacks to all servers.
*
struct afs_conn *tc;
int safety1, safety2, safety3;
XSTATS_DECLS;
+
+ if (AFS_IS_DISCONNECTED)
+ return ENETDOWN;
+
if ((code = afs_InitReq(&treq, afs_osi_credp)))
return code;
treq.flags |= O_NONBLOCK;
if (lockit)
ObtainWriteLock(&afs_xvcb, 273);
+ /*
+ * Shutting down.
+ * First, attempt a multi across everything, all addresses
+ * for all servers we know of.
+ */
+
+ if (lockit == 2)
+ afs_LoopServers(2, NULL, 0, FlushAllVCBs, NULL);
+
ObtainReadLock(&afs_xserver);
for (i = 0; i < NSERVERS; i++) {
for (safety1 = 0, tsp = afs_servers[i];
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",
afs_FlushReclaimedVcaches();
#if defined(AFS_LINUX22_ENV)
- if(!afsd_dynamic_vcaches) {
+ if(!afsd_dynamic_vcaches && afs_vcount >= afs_maxvcount) {
afs_ShakeLooseVCaches(anumber);
if (afs_vcount >= afs_maxvcount) {
afs_warn("afs_NewVCache - none freed\n");
tc = afs_Conn(afid, areq, SHARED_LOCK);
if (tc) {
if (serverp)
- *serverp = tc->srvr->server;
+ *serverp = tc->parent->srvr->server;
start = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_XLOOKUP);
RX_AFS_GUNLOCK();
iheldthelock = VOP_ISLOCKED(vp, curthread);
if (!iheldthelock)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+ AFS_GUNLOCK();
vinvalbuf(vp, V_SAVE, curthread, PINOD, 0);
+ AFS_GLOCK();
if (!iheldthelock)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#elif defined(AFS_FBSD_ENV)
tc = afs_Conn(afid, areq, SHARED_LOCK);
avc->dchint = NULL; /* invalidate hints */
if (tc) {
- avc->callback = tc->srvr->server;
+ avc->callback = tc->parent->srvr->server;
start = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
RX_AFS_GUNLOCK();
tvc = found_tvc;
/* should I have a read lock on the vnode here? */
if (tvc) {
+#ifndef AFS_DARWIN80_ENV
#if defined(AFS_SGI_ENV) && !defined(AFS_SGI53_ENV)
afs_int32 retry = 0;
osi_vnhold(tvc, &retry);
#else
osi_vnhold(tvc, (int *)0); /* already held, above */
#endif
+#endif
/*
* We obtained the xvcache lock above.
*/
ReleaseWriteLock(&afs_xvcache);
- afs_FlushVCBs(1);
+ afs_FlushVCBs(2);
}
/*!