From 0cbe03ec4b3de6560bebbfe65a1e6e6a8846f8c1 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Thu, 27 Sep 2001 03:16:36 +0000 Subject: [PATCH] afs-client-inline-bulkstatus-rpc-support-20010926 this cuts rpc traffic in half for directories on which you have no permissions and is capable of doing more if a useful way can be conceived of caching errors. currently bulkstat works thus: say a directory has 100 files. bulkstat will on the first hit stat the first 30 files, integrating the information if successful, and when you hit file 31, repeat. meaning if you can read that 100 files is 4 bulkstatus rpcs (3*30+10). if you can't, you do bulkstatus, get an abort, then do fetchstatus on the file and find out why you lost. you go on and try bulkstatus again this time for files 2-31 instead of 1-30. same failure, meaning you do 2N rpcs for the N files. inlinebulk doesn't abort but instead fills in stat info for any of the up to 30 files it can, and errors for any it can't. currently the client will pull out any stat info filled in, and then return the error from the first file, meaning if you can't read the directory we do N inlinebulk rpcs instead of N bulkstatus + N fetchstatus rpcs. if the errors for the other 29 could be meaningfully cached (and you have to be careful not to pollute information such that it's not useful for someone in a different auth context) then we could get down to the same 4 rpcs we have for success, but that's an exercise for later give how the cache manager works. ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== create audit event for inlinebulk ==================== rename spare2 --- src/afs/VNOPS/afs_vnop_flock.c | 2 +- src/afs/VNOPS/afs_vnop_lookup.c | 66 +++++++++++++++++++++++---------- src/audit/audit.h | 1 + 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/afs/VNOPS/afs_vnop_flock.c b/src/afs/VNOPS/afs_vnop_flock.c index 2549905d4..250905298 100644 --- a/src/afs/VNOPS/afs_vnop_flock.c +++ b/src/afs/VNOPS/afs_vnop_flock.c @@ -831,7 +831,7 @@ static int GetFlockCount(struct vcache *avc, struct vrequest *areq) if (code) { return(0); /* failed, say it is 'unlocked' */ } else { - return((int)OutStatus.spare2); + return((int)OutStatus.lockCount); } } #endif diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 4ee681d61..26dcd51a0 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -353,7 +353,7 @@ extern int BlobScan(afs_int32 *afile, afs_int32 ablob); * CForeign bit set. */ struct vcache * BStvc = (struct vcache *) 0; -void afs_DoBulkStat(adp, dirCookie, areqp) +int afs_DoBulkStat(adp, dirCookie, areqp) struct vcache *adp; long dirCookie; struct vrequest *areqp; @@ -397,6 +397,7 @@ void afs_DoBulkStat(adp, dirCookie, areqp) struct volume *volp=0; /* volume ptr */ struct VenusFid dotdot; int flagIndex; /* First file with bulk fetch flag set */ + int inlinebulk=0; /* Did we use InlineBulk RPC or not? */ XSTATS_DECLS /* first compute some basic parameters. We dont want to prefetch more @@ -607,8 +608,16 @@ tagain: #ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS */ - code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm, - &volSync); + code = RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm, + &cbParm, &volSync); + if (code == RXGEN_OPCODE) { + code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm, + &volSync); + inlinebulk=0; + } else { + inlinebulk=1; + } + #ifdef RX_ENABLE_LOCKS AFS_GLOCK(); #endif /* RX_ENABLE_LOCKS */ @@ -680,6 +689,8 @@ tagain: * We also have to take into account racing token revocations. */ for(i=0; ierrorCode) + continue; afid.Cell = adp->fid.Cell; afid.Fid.Volume = adp->fid.Fid.Volume; afid.Fid.Vnode = fidsp[i].Vnode; @@ -846,8 +857,16 @@ tagain: if ( volp ) afs_PutVolume(volp, READ_LOCK); + /* If we did the InlineBulk RPC pull out the return code */ + if (inlinebulk && (&statsp[0])->errorCode) { + afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->fid, areqp, + AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK, + (struct cell *)0); + code = (&statsp[0])->errorCode; + } osi_FreeLargeSpace(statMemp); osi_FreeLargeSpace(cbfMemp); + return code; } /* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */ @@ -885,6 +904,7 @@ afs_lookup(adp, aname, avcp, acred) char *tname = (char *)0; register struct vcache *tvc=0; register afs_int32 code; + register afs_int32 bulkcode = 0; int pass = 0, hit = 0; long dirCookie; extern afs_int32 afs_mariner; /*Writing activity to log?*/ @@ -903,7 +923,7 @@ afs_lookup(adp, aname, avcp, acred) *avcp = (struct vcache *) 0; /* Since some callers don't initialize it */ if (code = afs_InitReq(&treq, acred)) { - goto done; + goto done; } /* come back to here if we encounter a non-existent object in a read-only @@ -911,10 +931,12 @@ afs_lookup(adp, aname, avcp, acred) redo: *avcp = (struct vcache *) 0; /* Since some callers don't initialize it */ + bulkcode = 0; if (!(adp->states & CStatd)) { - if (code = afs_VerifyVCache2(adp, &treq)) - goto done; + if (code = afs_VerifyVCache2(adp, &treq)) { + goto done; + } } else code = 0; @@ -980,13 +1002,13 @@ afs_lookup(adp, aname, avcp, acred) ObtainReadLock(&afs_xvcache); osi_vnhold(adp, 0); ReleaseReadLock(&afs_xvcache); - code = 0; - *avcp = tvc = adp; - hit = 1; + code = 0; + *avcp = tvc = adp; + hit = 1; if (adp && !adp->vrefCount) { osi_Panic("TT2"); } - goto done; + goto done; } Check_AtSys(adp, aname, &sysState, &treq); @@ -1122,23 +1144,26 @@ afs_lookup(adp, aname, avcp, acred) ReleaseReadLock(&afs_xvcache); } while (tvc && retry); - if (!tvc || !(tvc->states & CStatd)) { - afs_DoBulkStat(adp, dirCookie, &treq); - } + if (!tvc || !(tvc->states & CStatd)) + bulkcode = afs_DoBulkStat(adp, dirCookie, &treq); + else + bulkcode = 0; /* if the vcache isn't usable, release it */ if (tvc && !(tvc->states & CStatd)) { afs_PutVCache(tvc); tvc = (struct vcache *) 0; } + } else { + tvc = (struct vcache *) 0; + bulkcode = 0; } - else tvc = (struct vcache *) 0; - + /* now get the status info, if we don't already have it */ /* This is kind of weird, but we might wind up accidentally calling * RXAFS_Lookup because we happened upon a file which legitimately * has a 0 uniquifier. That is the result of allowing unique to wrap - * to 0. This was fixed in AFS 3.4. For CForeigh, Unique == 0 means that + * to 0. This was fixed in AFS 3.4. For CForeign, Unique == 0 means that * the file has not yet been looked up. */ if (!tvc) { @@ -1147,10 +1172,10 @@ afs_lookup(adp, aname, avcp, acred) tvc = afs_LookupVCache(&tfid, &treq, &cached, WRITE_LOCK, adp, tname); } - if (!tvc) { /* lookup failed or wasn't called */ - tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0, - WRITE_LOCK); - } + if (!tvc && !bulkcode) { /* lookup failed or wasn't called */ + tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0, + WRITE_LOCK); + } } /* if !tvc */ } /* sub-block just to reduce stack usage */ @@ -1293,6 +1318,7 @@ done: #endif } } + if (bulkcode) code = bulkcode; else code = afs_CheckCode(code, &treq, 19); if (code) { /* If there is an error, make sure *avcp is null. diff --git a/src/audit/audit.h b/src/audit/audit.h index 2e6a1654c..fe6bb2f24 100644 --- a/src/audit/audit.h +++ b/src/audit/audit.h @@ -173,6 +173,7 @@ #define ReleaseLockEvent "AFS_SRX_RelLock" #define SetVolumeStatusEvent "AFS_SRX_SetVolS" #define FlushCPSEvent "AFS_SRX_FlusCPS" +#define InlineBulkFetchStatusEvent "AFS_SRX_BIFchSt" #define PrivilegeEvent "AFS_Priv" #define PrivSetID "AFS_PrivSet" /* Next 5 lines on behalf of MR-AFS */ -- 2.39.5