64bit-client-mods-build-cleanly-20011113

necessary fixes for aix and solaris, plus fix for linux for when wake_up
doesn't wake the sleeper
This commit is contained in:
Hartmut Reuter 2001-11-13 14:47:11 +00:00 committed by Derrick Brashear
parent b4e3729aae
commit b2821b103c
6 changed files with 201 additions and 109 deletions

View File

@ -129,6 +129,9 @@ typedef struct afs_event {
int seq; /* Sequence number: this is incremented
by wakeup calls; wait will not return until
it changes */
int dontSleep; /* on SMP machines the wakeup call may be
earlier than the sleep call. wakeup sets
dontSleep and sleep resets it at return. */
#if defined(AFS_LINUX24_ENV)
wait_queue_head_t cond;
#else
@ -174,6 +177,7 @@ static afs_event_t *afs_getevent(char *event)
}
newp->event = event;
newp->refcount = 1;
newp->dontSleep = 0;
return newp;
}
@ -185,15 +189,42 @@ void afs_osi_Sleep(char *event)
{
struct afs_event *evp;
int seq;
int count = 0;
int timeout = 1;
evp = afs_getevent(event);
seq = evp->seq;
while (seq == evp->seq) {
AFS_ASSERT_GLOCK();
AFS_GUNLOCK();
interruptible_sleep_on(&evp->cond);
AFS_GLOCK();
if (evp->dontSleep) {
afs_Trace4(afs_iclSetp, CM_TRACE_SLEEP,
ICL_TYPE_POINTER, evp,
ICL_TYPE_INT32, count,
ICL_TYPE_INT32, seq,
ICL_TYPE_INT32, evp->seq);
} else {
seq = evp->seq;
while (seq == evp->seq && !evp->dontSleep) {
AFS_ASSERT_GLOCK();
AFS_GUNLOCK();
#ifdef AFS_SMP
/*
* There seems to be a problem on SMP machines if the wake_up() and
* interruptible_sleep() calls happen at the "same" time.
*/
if (timeout < 1024)
timeout = timeout << 1;
interruptible_sleep_on_timeout(&evp->cond, timeout);
#else
interruptible_sleep_on(&evp->cond);
#endif
AFS_GLOCK();
count++;
afs_Trace4(afs_iclSetp, CM_TRACE_SLEEP,
ICL_TYPE_POINTER, evp,
ICL_TYPE_INT32, count,
ICL_TYPE_INT32, seq,
ICL_TYPE_INT32, evp->seq);
}
}
evp->dontSleep = 0;
relevent(evp);
}
@ -233,8 +264,12 @@ void afs_osi_Wakeup(char *event)
struct afs_event *evp;
evp = afs_getevent(event);
evp->dontSleep = 1;
if (evp->refcount > 1) {
evp->seq++;
afs_Trace2(afs_iclSetp, CM_TRACE_WAKE,
ICL_TYPE_POINTER, evp,
ICL_TYPE_INT32, evp->seq);
wake_up(&evp->cond);
}
relevent(evp);

View File

@ -455,6 +455,11 @@ tagain:
while ((adp->states & CStatd)
&& (dcp->flags & DFFetching)
&& hsame(adp->m.DataVersion, dcp->f.versionNo)) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, dcp,
ICL_TYPE_INT32, dcp->flags);
dcp->flags |= DFWaiting;
ReleaseReadLock(&adp->lock);
afs_osi_Sleep(&dcp->validPos);

View File

@ -186,6 +186,11 @@ tagain:
* data is now streaming in, then wait for some interesting stuff. */
while ((tdc->flags & DFFetching) && tdc->validPos <= filePos) {
/* too early: wait for DFFetching flag to vanish, or data to appear */
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_INT32, tdc->flags);
tdc->flags |= DFWaiting;
ReleaseReadLock(&avc->lock);
afs_osi_Sleep(&tdc->validPos);
@ -634,6 +639,11 @@ tagain:
* data is now streaming in, then wait for some interesting stuff. */
while ((tdc->flags & DFFetching) && tdc->validPos <= filePos) {
/* too early: wait for DFFetching flag to vanish, or data to appear */
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_INT32, tdc->flags);
tdc->flags |= DFWaiting;
ReleaseReadLock(&avc->lock);
afs_osi_Sleep(&tdc->validPos);
@ -664,7 +674,11 @@ tagain:
ObtainReadLock(&avc->lock);
}
}
afs_Trace3(afs_iclSetp, CM_TRACE_VNODEREAD,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(offset),
ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(len));
if (!tdc) {
error = EIO;
break;

View File

@ -518,6 +518,11 @@ tagain:
while ((avc->states & CStatd)
&& (tdc->flags & DFFetching)
&& hsame(avc->m.DataVersion, tdc->f.versionNo)) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_INT32, tdc->flags);
tdc->flags |= DFWaiting;
ReleaseReadLock(&avc->lock);
afs_osi_Sleep(&tdc->validPos);
@ -794,6 +799,11 @@ tagain:
while ((avc->states & CStatd)
&& (tdc->flags & DFFetching)
&& hsame(avc->m.DataVersion, tdc->f.versionNo)) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_INT32, tdc->flags);
tdc->flags |= DFWaiting;
ReleaseReadLock(&avc->lock);
afs_osi_Sleep(&tdc->validPos);

View File

@ -1438,6 +1438,11 @@ static int afs_UFSCacheFetchProc(acall, afile, abase, adc, avc,
length -= tlen;
adc->validPos = abase;
if (adc->flags & DFWaiting) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, adc,
ICL_TYPE_INT32, adc->flags);
adc->flags &= ~DFWaiting;
afs_osi_Wakeup(&adc->validPos);
}
@ -1606,107 +1611,109 @@ struct dcache *afs_GetDCache(avc, abyte, areq, aoffset, alen, aflags)
#endif
}
MReleaseReadLock(&afs_xdcache);
if (!shortcut)
tdc = 0;
}
if (!shortcut)
{
/*
* Hash on the [fid, chunk] and get the corresponding dcache index
* after write-locking the dcache.
*/
if (!tdc) {
/*
* Hash on the [fid, chunk] and get the corresponding dcache index
* after write-locking the dcache.
*/
RetryLookup:
i = DCHash(&avc->fid, chunk);
afs_MaybeWakeupTruncateDaemon(); /* check to make sure our space is fine */
MObtainWriteLock(&afs_xdcache,280);
us = NULLIDX;
for(index = afs_dchashTbl[i]; index != NULLIDX;) {
if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
tdc = afs_GetDSlot(index, (struct dcache *)0);
if (!FidCmp(&tdc->f.fid, &avc->fid) && chunk == tdc->f.chunk) {
/* Move it up in the beginning of the list */
if (afs_dchashTbl[i] != index) {
afs_dcnextTbl[us] = afs_dcnextTbl[index];
afs_dcnextTbl[index] = afs_dchashTbl[i];
afs_dchashTbl[i] = index;
i = DCHash(&avc->fid, chunk);
afs_MaybeWakeupTruncateDaemon(); /* check to make sure our space is fine */
MObtainWriteLock(&afs_xdcache,280);
us = NULLIDX;
for(index = afs_dchashTbl[i]; index != NULLIDX;) {
if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
tdc = afs_GetDSlot(index, (struct dcache *)0);
if (!FidCmp(&tdc->f.fid, &avc->fid) && chunk == tdc->f.chunk) {
/* Move it up in the beginning of the list */
if (afs_dchashTbl[i] != index) {
afs_dcnextTbl[us] = afs_dcnextTbl[index];
afs_dcnextTbl[index] = afs_dchashTbl[i];
afs_dchashTbl[i] = index;
}
MReleaseWriteLock(&afs_xdcache);
break; /* leaving refCount high for caller */
}
tdc->refCount--; /* was incremented by afs_GetDSlot */
tdc = 0;
}
us = index;
index = afs_dcnextTbl[index];
}
/*
* If we didn't find the entry, we'll create one.
*/
if (index == NULLIDX) {
afs_Trace2(afs_iclSetp, CM_TRACE_GETDCACHE1, ICL_TYPE_POINTER, avc,
ICL_TYPE_INT32, chunk);
if (afs_discardDCList == NULLIDX && afs_freeDCList == NULLIDX) {
while (1) {
if (!setLocks) avc->states |= CDCLock;
afs_GetDownD(5, (int*)0); /* just need slots */
if (!setLocks) avc->states &= (~CDCLock);
if (afs_discardDCList != NULLIDX || afs_freeDCList != NULLIDX)
break;
/* If we can't get space for 5 mins we give up and panic */
if (++downDCount > 300)
osi_Panic("getdcache");
MReleaseWriteLock(&afs_xdcache);
afs_osi_Wait(1000, 0, 0);
goto RetryLookup;
}
}
if (afs_discardDCList == NULLIDX ||
((aflags & 2) && afs_freeDCList != NULLIDX)) {
afs_indexFlags[afs_freeDCList] &= ~IFFree;
tdc = afs_GetDSlot(afs_freeDCList, 0);
afs_freeDCList = afs_dvnextTbl[tdc->index];
afs_freeDCCount--;
} else {
afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
tdc = afs_GetDSlot(afs_discardDCList, 0);
afs_discardDCList = afs_dvnextTbl[tdc->index];
afs_discardDCCount--;
size = ((tdc->f.chunkBytes + afs_fsfragsize)^afs_fsfragsize)>>10;
afs_blocksDiscarded -= size;
afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
if (aflags & 2) {
/* Truncate the chunk so zeroes get filled properly */
file = afs_CFileOpen(tdc->f.inode);
afs_CFileTruncate(file, 0);
afs_CFileClose(file);
afs_AdjustSize(tdc, 0);
}
}
/*
* Fill in the newly-allocated dcache record.
*/
afs_indexFlags[tdc->index] &= ~(IFDirtyPages | IFAnyPages);
tdc->f.fid = avc->fid;
afs_indexUnique[tdc->index] = tdc->f.fid.Fid.Unique;
hones(tdc->f.versionNo); /* invalid value */
tdc->f.chunk = chunk;
tdc->validPos = AFS_CHUNKTOBASE(chunk);
/* XXX */
if (tdc->lruq.prev == &tdc->lruq) osi_Panic("lruq 1");
/*
* Now add to the two hash chains - note that i is still set
* from the above DCHash call.
*/
afs_dcnextTbl[tdc->index] = afs_dchashTbl[i];
afs_dchashTbl[i] = tdc->index;
i = DVHash(&avc->fid);
afs_dvnextTbl[tdc->index] = afs_dvhashTbl[i];
afs_dvhashTbl[i] = tdc->index;
tdc->flags = DFEntryMod;
tdc->f.states = 0;
afs_MaybeWakeupTruncateDaemon();
MReleaseWriteLock(&afs_xdcache);
break; /* leaving refCount high for caller */
}
lockedPutDCache(tdc);
}
us = index;
index = afs_dcnextTbl[index];
}
/*
* If we didn't find the entry, we'll create one.
*/
if (index == NULLIDX) {
afs_Trace2(afs_iclSetp, CM_TRACE_GETDCACHE1, ICL_TYPE_POINTER, avc,
ICL_TYPE_INT32, chunk);
if (afs_discardDCList == NULLIDX && afs_freeDCList == NULLIDX) {
while (1) {
if (!setLocks) avc->states |= CDCLock;
afs_GetDownD(5, (int*)0); /* just need slots */
if (!setLocks) avc->states &= (~CDCLock);
if (afs_discardDCList != NULLIDX || afs_freeDCList != NULLIDX)
break;
/* If we can't get space for 5 mins we give up and panic */
if (++downDCount > 300)
osi_Panic("getdcache");
MReleaseWriteLock(&afs_xdcache);
afs_osi_Wait(1000, 0, 0);
goto RetryLookup;
}
}
if (afs_discardDCList == NULLIDX ||
((aflags & 2) && afs_freeDCList != NULLIDX)) {
afs_indexFlags[afs_freeDCList] &= ~IFFree;
tdc = afs_GetDSlot(afs_freeDCList, 0);
afs_freeDCList = afs_dvnextTbl[tdc->index];
afs_freeDCCount--;
} else {
afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
tdc = afs_GetDSlot(afs_discardDCList, 0);
afs_discardDCList = afs_dvnextTbl[tdc->index];
afs_discardDCCount--;
size = ((tdc->f.chunkBytes + afs_fsfragsize)^afs_fsfragsize)>>10;
afs_blocksDiscarded -= size;
afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
if (aflags & 2) {
/* Truncate the chunk so zeroes get filled properly */
file = afs_CFileOpen(tdc->f.inode);
afs_CFileTruncate(file, 0);
afs_CFileClose(file);
afs_AdjustSize(tdc, 0);
}
}
/*
* Fill in the newly-allocated dcache record.
*/
afs_indexFlags[tdc->index] &= ~(IFDirtyPages | IFAnyPages);
tdc->f.fid = avc->fid;
afs_indexUnique[tdc->index] = tdc->f.fid.Fid.Unique;
hones(tdc->f.versionNo); /* invalid value */
tdc->f.chunk = chunk;
/* XXX */
if (tdc->lruq.prev == &tdc->lruq) osi_Panic("lruq 1");
/*
* Now add to the two hash chains - note that i is still set
* from the above DCHash call.
*/
afs_dcnextTbl[tdc->index] = afs_dchashTbl[i];
afs_dchashTbl[i] = tdc->index;
i = DVHash(&avc->fid);
afs_dvnextTbl[tdc->index] = afs_dvhashTbl[i];
afs_dvhashTbl[i] = tdc->index;
tdc->flags = DFEntryMod;
tdc->f.states = 0;
afs_MaybeWakeupTruncateDaemon();
MReleaseWriteLock(&afs_xdcache);
}
} /* else hint failed... */
}
} /* else hint failed... */
afs_Trace4(afs_iclSetp, CM_TRACE_GETDCACHE2, ICL_TYPE_POINTER, avc,
ICL_TYPE_POINTER, tdc,
@ -1727,7 +1734,10 @@ struct dcache *afs_GetDCache(avc, abyte, areq, aoffset, alen, aflags)
* that this chunk's data hasn't been filled by another client.
*/
size = AFS_CHUNKSIZE(abyte);
tlen = *alen;
if (aflags & 4) /* called from write */
tlen = *alen;
else /* called from read */
tlen = tdc->validPos - abyte;
Position = AFS_CHUNKTOBASE(chunk);
afs_Trace4(afs_iclSetp, CM_TRACE_GETDCACHE3,
ICL_TYPE_INT32, tlen,
@ -1803,6 +1813,14 @@ struct dcache *afs_GetDCache(avc, abyte, areq, aoffset, alen, aflags)
hset(afs_indexTimes[tdc->index], afs_indexCounter);
hadd32(afs_indexCounter, 1);
updateV2DC(setLocks,avc,tdc,567);
if (vType(avc) == VDIR)
*aoffset = abyte;
else
*aoffset = AFS_CHUNKOFFSET(abyte);
if (tdc->validPos < abyte)
*alen = (afs_size_t) 0;
else
*alen = tdc->validPos - abyte;
return tdc; /* check if we're done */
}
osi_Assert(setLocks || WriteLocked(&avc->lock));
@ -1920,7 +1938,7 @@ struct dcache *afs_GetDCache(avc, abyte, areq, aoffset, alen, aflags)
afs_RemoveVCB(&avc->fid);
tdc->f.states |= DWriting;
tdc->flags |= DFFetching;
tdc->validPos = Position; /*Last valid position in this chunk*/
tdc->validPos = Position; /* which is AFS_CHUNKBASE(abyte) */
if (tdc->flags & DFFetchReq) {
tdc->flags &= ~DFFetchReq;
afs_osi_Wakeup(&tdc->validPos);
@ -2234,6 +2252,11 @@ struct dcache *afs_GetDCache(avc, abyte, areq, aoffset, alen, aflags)
tdc->flags &= ~DFFetching;
if (tdc->flags & DFWaiting) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
ICL_TYPE_STRING, __FILE__,
ICL_TYPE_INT32, __LINE__,
ICL_TYPE_POINTER, tdc,
ICL_TYPE_INT32, tdc->flags);
tdc->flags &= ~DFWaiting;
afs_osi_Wakeup(&tdc->validPos);
}
@ -2309,7 +2332,7 @@ done:
*aoffset = abyte;
else
*aoffset = AFS_CHUNKOFFSET(abyte);
*alen = (tdc->f.chunkBytes - *aoffset);
*alen = *aoffset + tdc->f.chunkBytes - abyte;
}
return tdc;

View File

@ -1,6 +1,6 @@
# Copyright 2000, International Business Machines Corporation and others.
# All Rights Reserved.
#
#
# This software has been released under the terms of the IBM Public
# License. For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html
@ -26,6 +26,7 @@ error_table 2 ZCM
ec CM_TRACE_STOREALL, "StoreAll vp 0x%lx len (0x%x, 0x%x)"
ec CM_TRACE_INVALL, "InvalAll vp 0x%lx len 0x%x"
ec CM_TRACE_TRUNCALL, "TruncAll vp 0x%lx old len (0x%x, 0x%x) new len (0x%x, 0x%x)"
ec CM_TRACE_GNLINK, "Gn_link vp 0x%lx name %s (returns 0x%x)"
ec CM_TRACE_GMKDIR, "Gn_mkdir vp 0x%lx name %s mode 0x%x (returns 0x%x)"
ec CM_TRACE_GMKNOD, "Gn_mknod vp 0x%lx name %s mode 0x%x (returns 0x%x)"
@ -54,7 +55,7 @@ error_table 2 ZCM
ec CM_TRACE_STUFFVCACHE, "StuffVcache 0x%lx callback host 0x%lx expires %u (in %u secs)"
ec CM_TRACE_GETDCACHE1, "Getdcache vp 0x%lx failed to find chunk 0x%x"
ec CM_TRACE_GETDCACHE2, "GetdCache vp 0x%lx dcache 0x%lx dcache low-version 0x%x, vcache low-version 0x%x"
ec CM_TRACE_GETDCACHE3, "GetdCache tlen 0x%x size 0x%x abyte (0x%x, 0x%x) Position (0x%x, 0x%x)"
ec CM_TRACE_GETDCACHE3, "GetdCache tlen 0x%x flags 0x%x abyte (0x%x, 0x%x) Position (0x%x, 0x%x)"
ec CM_TRACE_STOREMINI, "storemini vp 0x%lx length 0x%x"
ec CM_TRACE_STOREDCACHE, "StoreDCache vp 0x%lx chunk 0x%x length 0x%x at position 0x%x"
ec CM_TRACE_STOREDCACHEDONE, "StoreDCache Done for vp 0x%lx (returns 0x%x)"
@ -152,5 +153,9 @@ error_table 2 ZCM
ec CM_TRACE_STOREPROC2, "StoreProc got 0x%x"
ec CM_TRACE_ADJUSTSIZE, "AdjustSize index %d oldSize %d newSize %d blocksUsed %d"
ec CM_TRACE_SETLENGTH, "%s line %d: m.Length was (0x%x, 0x%x), now (0x%x, 0x%x)"
ec CM_TRACE_DCACHEWAIT, "%s line %d: sleeping or waiting for 0x%x flags 0x%x"
ec CM_TRACE_VNODEREAD, "UFSRead: tdc 0x%x, offset (0x%x, 0x%x) len (0x%x 0x%x)"
ec CM_TRACE_SLEEP, "Sleep: evp 0x%x, count %d seq 0x%x evp->seq 0x%x"
ec CM_TRACE_WAKE, "Wapeup: evp 0x%x, evp->seq 0x%x"
end