mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 17:00:15 +00:00
bkg-daemon-dont-break-64bit-pointers-and-handle-requests-in-order-20011102
This patch fixes a problem with 64-bit pointers being munged by the background daemons (by separating sizes and pointers into separate variables -- this bug was apparently introduced by the 64-bit file support patch), and makes the background daemons handle requests in order they came in. The latter will be mostly just useful for some prefetching and fine grained dcache-locking patches
This commit is contained in:
parent
68196d85db
commit
4b156c3800
@ -967,8 +967,8 @@ static int afs_delmap(OSI_VC_ARG(avc), off, prp, addr, len, prot, maxprot,
|
||||
AFS_RWUNLOCK(vp, VRWLOCK_WRITE);
|
||||
/* at least one daemon is idle, so ask it to do the store.
|
||||
* Also, note that we don't lock it any more... */
|
||||
tb = afs_BQueue(BOP_STORE, avc, 0, 1, acred, (long)acred->cr_uid,
|
||||
0L, 0L, 0L);
|
||||
tb = afs_BQueue(BOP_STORE, avc, 0, 1, acred,
|
||||
(afs_size_t) acred->cr_uid, 0L, (void *) 0);
|
||||
/* sleep waiting for the store to start, then retrieve error code */
|
||||
while ((tb->flags & BUVALID) == 0) {
|
||||
tb->flags |= BUWAIT;
|
||||
|
@ -165,8 +165,8 @@ tagain:
|
||||
/* start the daemon (may already be running, however) */
|
||||
tdc->flags |= DFFetchReq;
|
||||
bp = afs_BQueue(BOP_FETCH, avc, B_DONTWAIT, 0, acred,
|
||||
(afs_size_t)filePos, (afs_size_t) tdc,
|
||||
(afs_size_t) 0, (afs_size_t) 0);
|
||||
(afs_size_t)filePos, (afs_size_t) 0,
|
||||
tdc);
|
||||
if (!bp) {
|
||||
tdc->flags &= ~DFFetchReq;
|
||||
trybusy = 0; /* Avoid bkg daemon since they're too busy */
|
||||
@ -318,8 +318,7 @@ void afs_PrefetchChunk(struct vcache *avc, struct dcache *adc,
|
||||
mutex_exit(&tdc->lock);
|
||||
#endif
|
||||
bp = afs_BQueue(BOP_FETCH, avc, B_DONTWAIT, 0, acred,
|
||||
(afs_size_t) offset, (afs_size_t) tdc,
|
||||
(afs_size_t) 1, (afs_size_t) 0);
|
||||
(afs_size_t) offset, (afs_size_t) 1, tdc);
|
||||
if (!bp) {
|
||||
/* Bkg table full; just abort non-important prefetching to avoid deadlocks */
|
||||
tdc->flags &= ~(DFNextStarted | DFFetchReq);
|
||||
@ -614,8 +613,8 @@ tagain:
|
||||
munlocked = 1;
|
||||
#endif
|
||||
bp = afs_BQueue(BOP_FETCH, avc, B_DONTWAIT, 0, acred,
|
||||
(afs_size_t)filePos, (afs_size_t) tdc,
|
||||
(afs_size_t) 0, (afs_size_t) 0);
|
||||
(afs_size_t)filePos, (afs_size_t) 0,
|
||||
tdc);
|
||||
if (!bp) {
|
||||
/* Bkg table full; retry deadlocks */
|
||||
tdc->flags &= ~DFFetchReq;
|
||||
|
@ -844,7 +844,7 @@ afs_close(OSI_VC_ARG(avc), aflags, acred)
|
||||
Also, note that we don't lock it any more... */
|
||||
tb = afs_BQueue(BOP_STORE, avc, 0, 1, acred,
|
||||
(afs_size_t) acred->cr_uid, (afs_size_t) 0,
|
||||
(afs_size_t) 0, (afs_size_t) 0);
|
||||
(void *) 0);
|
||||
/* sleep waiting for the store to start, then retrieve error code */
|
||||
while ((tb->flags & BUVALID) == 0) {
|
||||
tb->flags |= BUWAIT;
|
||||
|
@ -116,11 +116,13 @@ struct sysname_info {
|
||||
struct brequest {
|
||||
struct vcache *vnode; /* vnode to use, with vrefcount bumped */
|
||||
struct AFS_UCRED *cred; /* credentials to use for operation */
|
||||
afs_size_t parm[BPARMS]; /* random parameters */
|
||||
afs_size_t size_parm[BPARMS]; /* random parameters */
|
||||
void *ptr_parm[BPARMS]; /* pointer parameters */
|
||||
afs_int32 code; /* return code */
|
||||
short refCount; /* use counter for this structure */
|
||||
char opcode; /* what to do (store, fetch, etc) */
|
||||
char flags; /* free, etc */
|
||||
afs_int32 ts; /* counter "timestamp" */
|
||||
};
|
||||
|
||||
struct SecretToken {
|
||||
|
@ -28,6 +28,7 @@ short afs_brsWaiters = 0; /* number of users waiting for brs buffers */
|
||||
short afs_brsDaemons = 0; /* number of daemons waiting for brs requests */
|
||||
struct brequest afs_brs[NBRS]; /* request structures */
|
||||
struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
|
||||
static int afs_brs_count = 0; /* request counter, to service reqs in order */
|
||||
|
||||
static int rxepoch_checked=0;
|
||||
#define afs_CheckRXEpoch() {if (rxepoch_checked == 0 && rxkad_EpochWasSet) { \
|
||||
@ -346,7 +347,7 @@ afs_CheckRootVolume () {
|
||||
else return ENOENT;
|
||||
}
|
||||
|
||||
/* parm 0 is the pathname, parm 1 to the fetch is the chunk number */
|
||||
/* ptr_parm 0 is the pathname, size_parm 0 to the fetch is the chunk number */
|
||||
void BPath(ab)
|
||||
register struct brequest *ab; {
|
||||
register struct dcache *tdc;
|
||||
@ -363,14 +364,14 @@ void BPath(ab)
|
||||
if (code = afs_InitReq(&treq, ab->cred)) return;
|
||||
AFS_GUNLOCK();
|
||||
#ifdef AFS_LINUX22_ENV
|
||||
code = gop_lookupname((char *)ab->parm[0], AFS_UIOSYS, 1, (struct vnode **) 0, &dp);
|
||||
code = gop_lookupname((char *)ab->ptr_parm[0], AFS_UIOSYS, 1, (struct vnode **) 0, &dp);
|
||||
if (dp)
|
||||
tvn = (struct vnode*)dp->d_inode;
|
||||
#else
|
||||
code = gop_lookupname((char *)ab->parm[0], AFS_UIOSYS, 1, (struct vnode **) 0, (struct vnode **)&tvn);
|
||||
code = gop_lookupname((char *)ab->ptr_parm[0], AFS_UIOSYS, 1, (struct vnode **) 0, (struct vnode **)&tvn);
|
||||
#endif
|
||||
AFS_GLOCK();
|
||||
osi_FreeLargeSpace((char *)ab->parm[0]); /* free path name buffer here */
|
||||
osi_FreeLargeSpace((char *)ab->ptr_parm[0]); /* free path name buffer here */
|
||||
if (code) return;
|
||||
/* now path may not have been in afs, so check that before calling our cache manager */
|
||||
if (!tvn || !IsAfsVnode((struct vnode *) tvn)) {
|
||||
@ -394,7 +395,7 @@ void BPath(ab)
|
||||
tvc = (struct vcache *) tvn;
|
||||
#endif
|
||||
/* here we know its an afs vnode, so we can get the data for the chunk */
|
||||
tdc = afs_GetDCache(tvc, (afs_size_t) ab->parm[1], &treq, &offset, &len, 1);
|
||||
tdc = afs_GetDCache(tvc, ab->size_parm[0], &treq, &offset, &len, 1);
|
||||
if (tdc) {
|
||||
afs_PutDCache(tdc);
|
||||
}
|
||||
@ -409,8 +410,9 @@ void BPath(ab)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* parm 0 to the fetch is the chunk number; parm 1 is the dcache entry to wakeup,
|
||||
* parm 2 is true iff we should release the dcache entry here.
|
||||
/* size_parm 0 to the fetch is the chunk number,
|
||||
* ptr_parm 0 is the dcache entry to wakeup,
|
||||
* size_parm 1 is true iff we should release the dcache entry here.
|
||||
*/
|
||||
void BPrefetch(ab)
|
||||
register struct brequest *ab; {
|
||||
@ -422,7 +424,7 @@ void BPrefetch(ab)
|
||||
AFS_STATCNT(BPrefetch);
|
||||
if (len = afs_InitReq(&treq, ab->cred)) return;
|
||||
tvc = ab->vnode;
|
||||
tdc = afs_GetDCache(tvc, (afs_size_t)ab->parm[0], &treq, &offset, &len, 1);
|
||||
tdc = afs_GetDCache(tvc, ab->size_parm[0], &treq, &offset, &len, 1);
|
||||
if (tdc) {
|
||||
afs_PutDCache(tdc);
|
||||
}
|
||||
@ -430,10 +432,10 @@ void BPrefetch(ab)
|
||||
* use tdc from GetDCache since afs_GetDCache may fail, but someone may
|
||||
* be waiting for our wakeup anyway.
|
||||
*/
|
||||
tdc = (struct dcache *) (ab->parm[1]);
|
||||
tdc = (struct dcache *) (ab->ptr_parm[0]);
|
||||
tdc->flags &= ~DFFetchReq;
|
||||
afs_osi_Wakeup(&tdc->validPos);
|
||||
if ((afs_size_t)ab->parm[2]) {
|
||||
if (ab->size_parm[1]) {
|
||||
#ifdef AFS_SUN5_ENVX
|
||||
mutex_enter(&tdc->lock);
|
||||
tdc->refCount--;
|
||||
@ -512,13 +514,13 @@ int afs_BBusy() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct brequest *afs_BQueue(aopcode, avc, dontwait, ause, acred, aparm0, aparm1, aparm2, aparm3)
|
||||
struct brequest *afs_BQueue(aopcode, avc, dontwait, ause, acred, asparm0, asparm1, apparm0)
|
||||
register short aopcode;
|
||||
afs_int32 ause, dontwait;
|
||||
register struct vcache *avc;
|
||||
struct AFS_UCRED *acred;
|
||||
/* On 64 bit platforms, "long" does the right thing. */
|
||||
afs_size_t aparm0, aparm1, aparm2, aparm3;
|
||||
afs_size_t asparm0, asparm1;
|
||||
void *apparm0;
|
||||
{
|
||||
register int i;
|
||||
register struct brequest *tb;
|
||||
@ -544,12 +546,12 @@ struct brequest *afs_BQueue(aopcode, avc, dontwait, ause, acred, aparm0, aparm1,
|
||||
#endif
|
||||
}
|
||||
tb->refCount = ause+1;
|
||||
tb->parm[0] = aparm0;
|
||||
tb->parm[1] = aparm1;
|
||||
tb->parm[2] = aparm2;
|
||||
tb->parm[3] = aparm3;
|
||||
tb->size_parm[0] = asparm0;
|
||||
tb->size_parm[1] = asparm1;
|
||||
tb->ptr_parm[0] = apparm0;
|
||||
tb->flags = 0;
|
||||
tb->code = 0;
|
||||
tb->ts = afs_brs_count++;
|
||||
/* if daemons are waiting for work, wake them up */
|
||||
if (afs_brsDaemons > 0) {
|
||||
afs_osi_Wakeup(&afs_brsDaemons);
|
||||
@ -1231,6 +1233,9 @@ void afs_BackgroundDaemon() {
|
||||
|
||||
MObtainWriteLock(&afs_xbrs,302);
|
||||
while (1) {
|
||||
int min_ts;
|
||||
struct brequest *min_tb;
|
||||
|
||||
if (afs_termState == AFSOP_STOP_BKG) {
|
||||
if (--afs_nbrs <= 0)
|
||||
afs_termState = AFSOP_STOP_TRUNCDAEMON;
|
||||
@ -1242,10 +1247,19 @@ void afs_BackgroundDaemon() {
|
||||
/* find a request */
|
||||
tb = afs_brs;
|
||||
foundAny = 0;
|
||||
min_tb = NULL;
|
||||
for(i=0; i<NBRS; i++, tb++) {
|
||||
/* look for request */
|
||||
/* look for request with smallest ts */
|
||||
if ((tb->refCount > 0) && !(tb->flags & BSTARTED)) {
|
||||
/* new request, not yet picked up */
|
||||
if ((min_tb && (min_ts - tb->ts > 0)) || !min_tb) {
|
||||
min_tb = tb;
|
||||
min_ts = tb->ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tb = min_tb) {
|
||||
/* claim and process this request */
|
||||
tb->flags |= BSTARTED;
|
||||
MReleaseWriteLock(&afs_xbrs);
|
||||
foundAny = 1;
|
||||
@ -1273,7 +1287,6 @@ void afs_BackgroundDaemon() {
|
||||
afs_BRelease(tb); /* this grabs and releases afs_xbrs lock */
|
||||
MObtainWriteLock(&afs_xbrs,305);
|
||||
}
|
||||
}
|
||||
if (!foundAny) {
|
||||
/* wait for new request */
|
||||
afs_brsDaemons++;
|
||||
|
@ -2079,7 +2079,8 @@ struct AFS_UCRED *acred;
|
||||
osi_FreeLargeSpace(tp);
|
||||
return EWOULDBLOCK; /* pretty close */
|
||||
}
|
||||
afs_BQueue(BOP_PATH, (struct vcache*)0, 0, 0, acred, (long)tp, 0L, 0L, 0L);
|
||||
afs_BQueue(BOP_PATH, (struct vcache*)0, 0, 0, acred,
|
||||
(afs_size_t) 0, (afs_size_t) 0, tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2682,7 +2682,7 @@ void print_bkg(kmem)
|
||||
if (uentry->refCount == 0) break;
|
||||
printf("[%d] vcache=0x%lx, cred=0x%lx, code=%d, refCount=%d, opcode=%d, flags=%x [%lx, %lx, %lx, %lx]\n",
|
||||
i, uentry->vnode, uentry->cred, uentry->code, uentry->refCount, uentry->opcode, uentry->flags,
|
||||
uentry->parm[0], uentry->parm[1], uentry->parm[2], uentry->parm[3]);
|
||||
uentry->size_parm[0], uentry->size_parm[1], uentry->ptr_parm[0], uentry->ptr_parm[1]);
|
||||
|
||||
}
|
||||
printf("... found %d active 'afs_brs' entries\n", j);
|
||||
|
Loading…
Reference in New Issue
Block a user