From: Felix Frank Date: Tue, 14 Jul 2009 09:01:57 +0000 (+0200) Subject: Move context of afs_CacheStoreProc() call from afs_segments to afs_fetchstore X-Git-Tag: openafs-devel-1_5_62~34 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=5ff34cc364ea80fe1e55262ac97091b42d47e3d8;p=packages%2Fo%2Fopenafs.git Move context of afs_CacheStoreProc() call from afs_segments to afs_fetchstore The innermost loop in afs_StoreAllSegments (looping over chunks) is now inlined in afs_CachStoreProc. This is step one in a series of such inlinings. Reviewed-on: http://gerrit.openafs.org/116 Reviewed-by: Russ Allbery Tested-by: Russ Allbery --- diff --git a/src/afs/afs_fetchstore.c b/src/afs/afs_fetchstore.c index 4e59a6d12..b51841ecc 100644 --- a/src/afs/afs_fetchstore.c +++ b/src/afs/afs_fetchstore.c @@ -227,15 +227,16 @@ rxfs_storeInit(struct vcache *avc, struct storeOps **ops, void **rock) return 0; } - +extern unsigned int storeallmissing; /*! * Called upon store. * * \param acall Ptr to the Rx call structure involved. - * \param fP Ptr to the related file descriptor. - * \param alen Size of the file in bytes. + * \param dclist pointer to the list of dcaches * \param avc Ptr to the vcache entry. - * \param shouldWake is it "safe" to return early from close() ? + * \param bytes per chunk + * \param nchunks number of chunks to store + * \param nomoreP pointer to the "nomore" flag * \param abytesToXferP Set to the number of bytes to xfer. * NOTE: This parameter is only used if AFS_NOSTATS is not defined. * \param abytesXferredP Set to the number of bytes actually xferred. @@ -245,69 +246,145 @@ rxfs_storeInit(struct vcache *avc, struct storeOps **ops, void **rock) */ int afs_CacheStoreProc(register struct rx_call *acall, - register struct osi_file *fP, - register afs_int32 alen, struct vcache *avc, - int *shouldWake, afs_size_t * abytesToXferP, - afs_size_t * abytesXferredP) + struct dcache **dclist, + struct vcache *avc, + afs_size_t bytes, + afs_uint32 nchunks, + int *nomoreP, + afs_size_t * abytesToXferP, + afs_size_t * abytesXferredP) { - afs_int32 code; + afs_int32 code = 0; afs_uint32 tlen; - int offset = 0; struct storeOps *ops; void * rock = NULL; + struct osi_file *fP; + int *shouldwake; + int nomore = *nomoreP; + struct dcache *tdc; + int stored = 0; + unsigned int i; + afs_int32 alen; - afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc, - ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET, - ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen); code = rxfs_storeInit(avc, &ops, &rock); if ( code ) { osi_Panic("afs_CacheStoreProc: rxfs_storeInit failed"); } ((struct rxfs_storeVariables *)rock)->call = acall; - AFS_STATCNT(CacheStoreProc); + for (i = 0; i < nchunks && !code; i++) { + int offset = 0; + tdc = dclist[i]; + alen = tdc->f.chunkBytes; + if (!tdc) { + afs_warn("afs: missing dcache!\n"); + storeallmissing++; + continue; /* panic? */ + } + afs_Trace4(afs_iclSetp, CM_TRACE_STOREALL2, + ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, + tdc->f.chunk, ICL_TYPE_INT32, + tdc->index, ICL_TYPE_INT32, + afs_inode2trace(&tdc->f.inode)); + shouldwake = 0; + if (nomore) { + if (avc->asynchrony == -1) { + if (afs_defaultAsynchrony > + (bytes - stored)) { + shouldwake = &nomore; + } + } else if ((afs_uint32) avc->asynchrony >= + (bytes - stored)) { + shouldwake = &nomore; + } + } + fP = afs_CFileOpen(&tdc->f.inode); + + afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc, + ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET, + ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen); + + AFS_STATCNT(CacheStoreProc); #ifndef AFS_NOSTATS - /* - * In this case, alen is *always* the amount of data we'll be trying - * to ship here. - */ - *(abytesToXferP) = alen; - *(abytesXferredP) = 0; + /* + * In this case, alen is *always* the amount of data we'll be trying + * to ship here. + */ + *(abytesToXferP) = alen; + *(abytesXferredP) = 0; #endif /* AFS_NOSTATS */ - while ( alen > 0 ) { - afs_int32 bytesread, byteswritten; - code = (*ops->prepare)(rock, alen, &tlen); - if ( code ) - break; + while ( alen > 0 ) { + afs_int32 bytesread, byteswritten; + code = (*ops->prepare)(rock, alen, &tlen); + if ( code ) + break; - code = (*ops->read)(rock, fP, offset, tlen, &bytesread); - if (code) - break; + code = (*ops->read)(rock, fP, offset, tlen, &bytesread); + if (code) + break; - tlen = bytesread; - code = (*ops->write)(rock, tlen, &byteswritten); - if (code) - break; + tlen = bytesread; + code = (*ops->write)(rock, tlen, &byteswritten); + if (code) + break; #ifndef AFS_NOSTATS - (*abytesXferredP) += byteswritten; + (*abytesXferredP) += byteswritten; #endif /* AFS_NOSTATS */ - offset += tlen; - alen -= tlen; - /* - * if file has been locked on server, can allow - * store to continue - */ - if (shouldWake && *shouldWake && ((*ops->status)(rock) == 0)) { - *shouldWake = 0; /* only do this once */ - afs_wakeup(avc); + offset += tlen; + alen -= tlen; + /* + * if file has been locked on server, can allow + * store to continue + */ + if (shouldwake && *shouldwake && ((*ops->status)(rock) == 0)) { + *shouldwake = 0; /* only do this once */ + afs_wakeup(avc); + } } + afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc, + ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET, + ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen); + + afs_CFileClose(fP); + if ((tdc->f.chunkBytes < afs_OtherCSize) + && (i < (nchunks - 1)) && code == 0) { + int bsent, tlen, sbytes = + afs_OtherCSize - tdc->f.chunkBytes; + char *tbuffer = + osi_AllocLargeSpace(AFS_LRALLOCSIZ); + + while (sbytes > 0) { + tlen = + (sbytes > + AFS_LRALLOCSIZ ? AFS_LRALLOCSIZ : + sbytes); + memset(tbuffer, 0, tlen); + RX_AFS_GUNLOCK(); + bsent = rx_Write(acall, tbuffer, tlen); + RX_AFS_GLOCK(); + + if (bsent != tlen) { + code = -33; /* XXX */ + break; + } + sbytes -= tlen; + } + osi_FreeLargeSpace(tbuffer); + } + stored += tdc->f.chunkBytes; + + /* ideally, I'd like to unlock the dcache and turn + * off the writing bit here, but that would + * require being able to retry StoreAllSegments in + * the event of a failure. It only really matters + * if user can't read from a 'locked' dcache or + * one which has the writing bit turned on. */ } - afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc, - ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET, - ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen); code = (*ops->destroy)(&rock, code); + + *nomoreP = nomore; return code; } diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 5a53a574e..19e3ad5fb 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -492,10 +492,12 @@ extern int afs_MemWriteUIO(afs_dcache_id_t *ainode, struct uio *uioP); extern int afs_MemCacheTruncate(register struct osi_file *fP, int size); extern int afs_CacheStoreProc(register struct rx_call *acall, - register struct osi_file *fP, - register afs_int32 alen, struct vcache *avc, - int *shouldWake, afs_size_t * abytesToXferP, - afs_size_t * abytesXferredP); + struct dcache **dclist, + struct vcache *avc, + afs_size_t bytes, + afs_uint32 nchunks, int *nomoreP, + afs_size_t * abytesToXferP, + afs_size_t * abytesXferredP); extern int afs_CacheFetchProc(register struct afs_conn *tc, register struct osi_file *fP, afs_size_t abase, struct dcache *adc, diff --git a/src/afs/afs_segments.c b/src/afs/afs_segments.c index 09c013dc6..792e4efdc 100644 --- a/src/afs/afs_segments.c +++ b/src/afs/afs_segments.c @@ -165,7 +165,7 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, register afs_int32 code = 0; register afs_int32 index; register afs_int32 origCBs, foreign = 0; - int hash, stored; + int hash; afs_hyper_t newDV, oldDV; /* DV when we start, and finish, respectively */ struct dcache **dcList, **dclist; unsigned int i, j, minj, moredata, high, off; @@ -308,9 +308,7 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, afs_uint32 nchunks; int nomore; unsigned int first = 0; - int *shouldwake; struct afs_conn *tc; - struct osi_file *tfile; struct rx_call *tcall; XSTATS_DECLS; for (bytes = 0, j = 0; !code && j <= high; j++) { @@ -360,7 +358,6 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, ICL_HANDLE_OFFSET(tlen)); do { - stored = 0; tc = afs_Conn(&avc->f.fid, areq, 0); if (tc) { #ifdef AFS_64BIT_CLIENT @@ -408,31 +405,7 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREDATA); avc->f.truncPos = AFS_NOTRUNC; } - for (i = 0; i < nchunks && !code; i++) { - tdc = dclist[i]; - if (!tdc) { - afs_warn("afs: missing dcache!\n"); - storeallmissing++; - continue; /* panic? */ - } - afs_Trace4(afs_iclSetp, CM_TRACE_STOREALL2, - ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, - tdc->f.chunk, ICL_TYPE_INT32, - tdc->index, ICL_TYPE_INT32, - afs_inode2trace(&tdc->f.inode)); - shouldwake = 0; - if (nomore) { - if (avc->asynchrony == -1) { - if (afs_defaultAsynchrony > - (bytes - stored)) { - shouldwake = &nomore; - } - } else if ((afs_uint32) avc->asynchrony >= - (bytes - stored)) { - shouldwake = &nomore; - } - } - tfile = afs_CFileOpen(&tdc->f.inode); + if ( !code ) { #ifndef AFS_NOSTATS xferP = &(afs_stats_cmfullperf.rpc. @@ -441,9 +414,11 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, osi_GetuTime(&xferStartTime); code = - afs_CacheStoreProc(tcall, tfile, - tdc->f.chunkBytes, avc, - shouldwake, &bytesToXfer, + afs_CacheStoreProc(tcall, dclist, + avc, + bytes, + nchunks, &nomore, + &bytesToXfer, &bytesXferred); osi_GetuTime(&xferStopTime); @@ -512,44 +487,12 @@ afs_StoreAllSegments(register struct vcache *avc, struct vrequest *areq, } #else code = - afs_CacheStoreProc(tcall, tfile, - tdc->f.chunkBytes, avc, - shouldwake, &lp1, &lp2); + afs_CacheStoreProc(tcall, dclist, + avc, + bytes, + nchunks, &nomore, + &lp1, &lp2); #endif /* AFS_NOSTATS */ - afs_CFileClose(tfile); - if ((tdc->f.chunkBytes < afs_OtherCSize) - && (i < (nchunks - 1)) && code == 0) { - int bsent, tlen, sbytes = - afs_OtherCSize - tdc->f.chunkBytes; - char *tbuffer = - osi_AllocLargeSpace(AFS_LRALLOCSIZ); - - while (sbytes > 0) { - tlen = - (sbytes > - AFS_LRALLOCSIZ ? AFS_LRALLOCSIZ : - sbytes); - memset(tbuffer, 0, tlen); - RX_AFS_GUNLOCK(); - bsent = rx_Write(tcall, tbuffer, tlen); - RX_AFS_GLOCK(); - - if (bsent != tlen) { - code = -33; /* XXX */ - break; - } - sbytes -= tlen; - } - osi_FreeLargeSpace(tbuffer); - } - stored += tdc->f.chunkBytes; - - /* ideally, I'd like to unlock the dcache and turn - * off the writing bit here, but that would - * require being able to retry StoreAllSegments in - * the event of a failure. It only really matters - * if user can't read from a 'locked' dcache or - * one which has the writing bit turned on. */ } if (!code) { struct AFSVolSync tsync;