From 1cfa2259eca210ca480f16a725ca70f5cfc2c8d4 Mon Sep 17 00:00:00 2001 From: Felix Frank Date: Tue, 14 Jul 2009 10:51:03 +0200 Subject: [PATCH] Move context of CacheFetchProc from afs_dcache.c to afs_fetchstore.c GetDCache() is quite bloated. This inlinining makes code more readable. For protocols to come besides rxfs (such as rxosd), some initializations may need to be performed differently. Thus, much has to be moved to the specific rxfs_fetchInit() function rather than afs_CacheFetchProc() proper. Reviewed-on: http://gerrit.openafs.org/112 Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear --- src/afs/afs.h | 8 +++ src/afs/afs_dcache.c | 140 +++-------------------------------------- src/afs/afs_fetchstore.c | 158 ++++++++++++++++++++++++++++++++++++++++++----- src/afs/afs_prototypes.h | 5 +- 4 files changed, 163 insertions(+), 148 deletions(-) diff --git a/src/afs/afs.h b/src/afs/afs.h index b60c53e..b217f7e 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1139,6 +1139,12 @@ struct memCacheEntry { char *data; /* bytes */ }; +struct afs_FetchOutput { + struct AFSVolSync tsync; + struct AFSFetchStatus OutStatus; + struct AFSCallBack CallBack; +}; + /* macro to mark a dcache entry as bad */ #define ZapDCE(x) \ do { \ @@ -1362,6 +1368,8 @@ struct fetchOps { int (*read)(void *rock, afs_uint32 tlen, afs_uint32 *bytesread); int (*write)(void *rock, struct osi_file *fp, afs_uint32 offset, afs_uint32 tlen, afs_uint32 *byteswritten); + int (*close)(void *rock, struct vcache *avc, struct dcache *adc, + struct afs_FetchOutput *Outputs); int (*destroy)(void **rock, afs_int32 error); }; diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 457da99..cd23c01 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -1580,12 +1580,6 @@ struct dcache *afs_AllocDCache(struct vcache *avc, * The vcache entry pointed to by avc is unlocked upon entry. */ -struct tlocal1 { - struct AFSVolSync tsync; - struct AFSFetchStatus OutStatus; - struct AFSCallBack CallBack; -}; - /* * Update the vnode-to-dcache hint if we can get the vnode lock * right away. Assumes dcache entry is at least read-locked. @@ -1607,7 +1601,7 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, register struct vrequest *areq, afs_size_t * aoffset, afs_size_t * alen, int aflags) { - register afs_int32 i, code, code1 = 0, shortcut; + register afs_int32 i, code, shortcut; #if defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) register afs_int32 adjustsize = 0; #endif @@ -1616,14 +1610,9 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, afs_int32 us; afs_int32 chunk; afs_size_t maxGoodLength; /* amount of good data at server */ - struct rx_call *tcall; afs_size_t Position = 0; -#ifdef AFS_64BIT_CLIENT - afs_size_t tsize; - afs_size_t lengthFound; /* as returned from server */ -#endif /* AFS_64BIT_CLIENT */ afs_int32 size, tlen; /* size of segment to transfer */ - struct tlocal1 *tsmall = 0; + struct afs_FetchOutput *tsmall = 0; register struct dcache *tdc; register struct osi_file *file; register struct afs_conn *tc; @@ -2124,7 +2113,7 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, tdc->dflags); } tsmall = - (struct tlocal1 *)osi_AllocLargeSpace(sizeof(struct tlocal1)); + (struct afs_FetchOutput *)osi_AllocLargeSpace(sizeof(struct afs_FetchOutput)); setVcacheStatus = 0; #ifndef AFS_NOSTATS /* @@ -2208,10 +2197,6 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK); if (tc) { -#ifdef AFS_64BIT_CLIENT - afs_int32 length_hi; -#endif - afs_int32 length, bytes; #ifndef AFS_NOSTATS numFetchLoops++; if (fromReplica) @@ -2225,98 +2210,8 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, setNewCallback = 1; } i = osi_Time(); - RX_AFS_GUNLOCK(); - tcall = rx_NewCall(tc->id); - RX_AFS_GLOCK(); - XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHDATA); -#ifdef AFS_64BIT_CLIENT - length_hi = code = 0; - if (!afs_serverHasNo64Bit(tc)) { - tsize = size; - RX_AFS_GUNLOCK(); - code = - StartRXAFS_FetchData64(tcall, - (struct AFSFid *)&avc->f.fid. - Fid, Position, tsize); - if (code != 0) { - RX_AFS_GLOCK(); - afs_Trace2(afs_iclSetp, CM_TRACE_FETCH64CODE, - ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, - code); - } else { - bytes = - rx_Read(tcall, (char *)&length_hi, - sizeof(afs_int32)); - RX_AFS_GLOCK(); - if (bytes == sizeof(afs_int32)) { - length_hi = ntohl(length_hi); - } else { - length_hi = 0; - code = rx_Error(tcall); - RX_AFS_GUNLOCK(); - code1 = rx_EndCall(tcall, code); - RX_AFS_GLOCK(); - tcall = (struct rx_call *)0; - } - } - } - if (code == RXGEN_OPCODE || afs_serverHasNo64Bit(tc)) { - if (Position > 0x7FFFFFFF) { - code = EFBIG; - } else { - afs_int32 pos; - pos = Position; - RX_AFS_GUNLOCK(); - if (!tcall) - tcall = rx_NewCall(tc->id); - code = - StartRXAFS_FetchData(tcall, (struct AFSFid *) - &avc->f.fid.Fid, pos, - size); - RX_AFS_GLOCK(); - } - afs_serverSetNo64Bit(tc); - } - if (code == 0) { - RX_AFS_GUNLOCK(); - bytes = - rx_Read(tcall, (char *)&length, - sizeof(afs_int32)); - RX_AFS_GLOCK(); - if (bytes == sizeof(afs_int32)) { - length = ntohl(length); - } else { - code = rx_Error(tcall); - } - } - FillInt64(lengthFound, length_hi, length); - afs_Trace3(afs_iclSetp, CM_TRACE_FETCH64LENG, - ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code, - ICL_TYPE_OFFSET, - ICL_HANDLE_OFFSET(lengthFound)); -#else /* AFS_64BIT_CLIENT */ - RX_AFS_GUNLOCK(); - code = - StartRXAFS_FetchData(tcall, - (struct AFSFid *)&avc->f.fid.Fid, - Position, size); - RX_AFS_GLOCK(); - if (code == 0) { - RX_AFS_GUNLOCK(); - bytes = - rx_Read(tcall, (char *)&length, - sizeof(afs_int32)); - RX_AFS_GLOCK(); - if (bytes == sizeof(afs_int32)) { - length = ntohl(length); - } else { - code = rx_Error(tcall); - } - } -#endif /* AFS_64BIT_CLIENT */ - if (code == 0) { - + { #ifndef AFS_NOSTATS xferP = &(afs_stats_cmfullperf.rpc. @@ -2324,10 +2219,10 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, osi_GetuTime(&xferStartTime); code = - afs_CacheFetchProc(tcall, file, + afs_CacheFetchProc(tc, file, (afs_size_t) Position, tdc, avc, &bytesToXfer, - &bytesXferred, length); + &bytesXferred, size, tsmall); osi_GetuTime(&xferStopTime); (xferP->numXfers)++; @@ -2394,28 +2289,13 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, } #else code = - afs_CacheFetchProc(tcall, file, Position, tdc, - avc, 0, 0, length); + afs_CacheFetchProc(tc, file, Position, tdc, + avc, 0, 0, size, tsmall); #endif /* AFS_NOSTATS */ } - if (code == 0) { - RX_AFS_GUNLOCK(); - code = - EndRXAFS_FetchData(tcall, &tsmall->OutStatus, - &tsmall->CallBack, - &tsmall->tsync); - RX_AFS_GLOCK(); - } XSTATS_END_TIME; - RX_AFS_GUNLOCK(); - if (tcall) - code1 = rx_EndCall(tcall, code); - RX_AFS_GLOCK(); - } else { - code = -1; - } - if (!code && code1) - code = code1; + } else + code = -1; if (code == 0) { /* callback could have been broken (or expired) in a race here, diff --git a/src/afs/afs_fetchstore.c b/src/afs/afs_fetchstore.c index 9cb6376..08a231b 100644 --- a/src/afs/afs_fetchstore.c +++ b/src/afs/afs_fetchstore.c @@ -391,6 +391,35 @@ rxfs_fetchUfsWrite(void *r, struct osi_file *fP, return 0; } + +afs_int32 +rxfs_fetchClose(void *r, struct vcache *avc, struct dcache * adc, + struct afs_FetchOutput *tsmall) +{ + afs_int32 code, code1 = 0; + struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r; + + if (!v->call) + return -1; + + RX_AFS_GUNLOCK(); + code = EndRXAFS_FetchData(v->call, &tsmall->OutStatus, + &tsmall->CallBack, + &tsmall->tsync); + RX_AFS_GLOCK(); + + RX_AFS_GUNLOCK(); + if (v->call) + code1 = rx_EndCall(v->call, code); + RX_AFS_GLOCK(); + if (!code && code1) + code = code1; + + v->call = NULL; + + return code; +} + afs_int32 rxfs_fetchDestroy(void **r, afs_int32 error) { @@ -429,6 +458,7 @@ struct fetchOps rxfs_fetchUfsOps = { rxfs_fetchMore, rxfs_fetchUfsRead, rxfs_fetchUfsWrite, + rxfs_fetchClose, rxfs_fetchDestroy }; @@ -437,22 +467,117 @@ struct fetchOps rxfs_fetchMemOps = { rxfs_fetchMore, rxfs_fetchMemRead, rxfs_fetchMemWrite, + rxfs_fetchClose, rxfs_fetchDestroy }; afs_int32 -rxfs_fetchInit(register struct rx_call *acall, struct vcache *avc, - afs_offs_t abase, afs_uint32 *length, struct dcache *adc, +rxfs_fetchInit(register struct afs_conn *tc, struct vcache *avc,afs_offs_t Position, + afs_uint32 size, afs_uint32 *out_length, struct dcache *adc, struct osi_file *fP, struct fetchOps **ops, void **rock) { struct rxfs_fetchVariables *v; + int code, code1; + afs_int32 length_hi, length, bytes; +#ifdef AFS_64BIT_CLIENT + afs_size_t tsize; + afs_size_t lengthFound; /* as returned from server */ +#endif /* AFS_64BIT_CLIENT */ v = (struct rxfs_fetchVariables *) osi_AllocSmallSpace(sizeof(struct rxfs_fetchVariables)); if (!v) osi_Panic("rxfs_fetchInit: osi_AllocSmallSpace returned NULL\n"); memset(v, 0, sizeof(struct rxfs_fetchVariables)); - v->call = acall; + RX_AFS_GUNLOCK(); + v->call = rx_NewCall(tc->id); + RX_AFS_GLOCK(); + +#ifdef AFS_64BIT_CLIENT + length_hi = code = 0; + if (!afs_serverHasNo64Bit(tc)) { + tsize = size; + RX_AFS_GUNLOCK(); + code = + StartRXAFS_FetchData64(v->call, (struct AFSFid *)&avc->f.fid.Fid, + Position, tsize); + if (code != 0) { + RX_AFS_GLOCK(); + afs_Trace2(afs_iclSetp, CM_TRACE_FETCH64CODE, + ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code); + } else { + bytes = rx_Read(v->call, (char *)&length_hi, sizeof(afs_int32)); + RX_AFS_GLOCK(); + if (bytes == sizeof(afs_int32)) { + length_hi = ntohl(length_hi); + } else { + length_hi = 0; + code = rx_Error(v->call); + RX_AFS_GUNLOCK(); + code1 = rx_EndCall(v->call, code); + RX_AFS_GLOCK(); + v->call = NULL; + } + } + } + if (code == RXGEN_OPCODE || afs_serverHasNo64Bit(tc)) { + if (Position > 0x7FFFFFFF) { + code = EFBIG; + } else { + afs_int32 pos; + pos = Position; + RX_AFS_GUNLOCK(); + if (!v->call) + v->call = rx_NewCall(tc->id); + code = + StartRXAFS_FetchData(v->call, (struct AFSFid *) + &avc->f.fid.Fid, pos, + size); + RX_AFS_GLOCK(); + } + afs_serverSetNo64Bit(tc); + } + if (code == 0) { + RX_AFS_GUNLOCK(); + bytes = + rx_Read(v->call, (char *)&length, + sizeof(afs_int32)); + RX_AFS_GLOCK(); + if (bytes == sizeof(afs_int32)) { + length = ntohl(length); + } else { + code = rx_Error(v->call); + } + } + FillInt64(lengthFound, length_hi, length); + afs_Trace3(afs_iclSetp, CM_TRACE_FETCH64LENG, + ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code, + ICL_TYPE_OFFSET, + ICL_HANDLE_OFFSET(lengthFound)); +#else /* AFS_64BIT_CLIENT */ + RX_AFS_GUNLOCK(); + code = + StartRXAFS_FetchData(v->call, + (struct AFSFid *)&avc->f.fid.Fid, + Position, size); + RX_AFS_GLOCK(); + if (code == 0) { + RX_AFS_GUNLOCK(); + bytes = + rx_Read(v->call, (char *)&length, + sizeof(afs_int32)); + RX_AFS_GLOCK(); + if (bytes == sizeof(afs_int32)) { + length = ntohl(length); + } else { + code = rx_Error(v->call); + } + } +#endif /* AFS_64BIT_CLIENT */ + if (code) { + osi_FreeSmallSpace(v); + return code; + } if ( cacheDiskType == AFS_FCACHE_TYPE_UFS ) { v->tbuffer = osi_AllocLargeSpace(AFS_LRALLOCSIZ); @@ -465,7 +590,7 @@ rxfs_fetchInit(register struct rx_call *acall, struct vcache *avc, else { afs_Trace4(afs_iclSetp, CM_TRACE_MEMFETCH, ICL_TYPE_POINTER, avc, ICL_TYPE_POINTER, fP, ICL_TYPE_OFFSET, - ICL_HANDLE_OFFSET(abase), ICL_TYPE_INT32, *length); + ICL_HANDLE_OFFSET(Position), ICL_TYPE_INT32, length); /* * We need to alloc the iovecs on the heap so that they are "pinned" * rather than declare them on the stack - defect 11272 @@ -478,6 +603,7 @@ rxfs_fetchInit(register struct rx_call *acall, struct vcache *avc, *ops = (struct fetchOps *) &rxfs_fetchMemOps; } *rock = (void *)v; + *out_length = length; return 0; } @@ -486,7 +612,7 @@ rxfs_fetchInit(register struct rx_call *acall, struct vcache *avc, * Routine called on fetch; also tells people waiting for data * that more has arrived. * - * \param acall Ptr to the Rx call structure. + * \param tc Ptr to the Rx connection structure. * \param fP File descriptor for the cache file. * \param abase Base offset to fetch. * \param adc Ptr to the dcache entry for the file, write-locked. @@ -495,15 +621,18 @@ rxfs_fetchInit(register struct rx_call *acall, struct vcache *avc, * NOTE: This parameter is only used if AFS_NOSTATS is not defined. * \param abytesXferredP Set to the number of bytes actually xferred. * NOTE: This parameter is only used if AFS_NOSTATS is not defined. + * \param size Amount of data that should be fetched. + * \param tsmall Ptr to the afs_FetchOutput structure. * * \note Environment: Nothing interesting. */ int -afs_CacheFetchProc(register struct rx_call *acall, - register struct osi_file *fP, afs_size_t abase, - struct dcache *adc, struct vcache *avc, - afs_size_t * abytesToXferP, afs_size_t * abytesXferredP, - afs_int32 lengthFound) +afs_CacheFetchProc(register struct afs_conn *tc, + register struct osi_file *fP, afs_size_t abase, + struct dcache *adc, struct vcache *avc, + afs_size_t * abytesToXferP, afs_size_t * abytesXferredP, + afs_int32 size, + struct afs_FetchOutput *tsmall) { register afs_int32 code; afs_uint32 length; @@ -515,10 +644,6 @@ afs_CacheFetchProc(register struct rx_call *acall, AFS_STATCNT(CacheFetchProc); - length = lengthFound; - - if ( cacheDiskType != AFS_FCACHE_TYPE_UFS ) { - } #ifndef AFS_NOSTATS (*abytesToXferP) = 0; (*abytesXferredP) = 0; @@ -526,8 +651,7 @@ afs_CacheFetchProc(register struct rx_call *acall, adc->validPos = abase; - code = rxfs_fetchInit(acall, avc, abase, &length, adc, fP, - (struct fetchOps **)&ops, (char**)&rock); + code = rxfs_fetchInit(tc, avc, abase, size, &length, adc, fP, &ops, &rock); if ( !code ) do { if (moredata) { code = (*ops->more)(rock, &length, &moredata); @@ -587,6 +711,8 @@ afs_CacheFetchProc(register struct rx_call *acall, } code = 0; } while (moredata); + if (!code) + code = (*ops->close)(rock, avc, adc, tsmall); (*ops->destroy)(&rock, code); return code; } diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index b3e1a81..d212596 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -496,13 +496,14 @@ extern int afs_CacheStoreProc(register struct rx_call *acall, register afs_int32 alen, struct vcache *avc, int *shouldWake, afs_size_t * abytesToXferP, afs_size_t * abytesXferredP); -extern int afs_CacheFetchProc(register struct rx_call *acall, +extern int afs_CacheFetchProc(register struct afs_conn *tc, register struct osi_file *fP, afs_size_t abase, struct dcache *adc, struct vcache *avc, afs_size_t * abytesToXferP, afs_size_t * abytesXferredP, - afs_int32 lengthFound); + afs_int32 size, + struct afs_FetchOutput *tsmall); extern void shutdown_memcache(void); -- 1.9.4