Move context of afs_CacheStoreProc() call from afs_segments to afs_fetchstore
authorFelix Frank <Felix.Frank@Desy.de>
Tue, 14 Jul 2009 09:01:57 +0000 (11:01 +0200)
committerRuss Allbery <rra@stanford.edu>
Thu, 20 Aug 2009 02:47:19 +0000 (19:47 -0700)
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 <rra@stanford.edu>
Tested-by: Russ Allbery <rra@stanford.edu>

src/afs/afs_fetchstore.c
src/afs/afs_prototypes.h
src/afs/afs_segments.c

index 4e59a6d..b51841e 100644 (file)
@@ -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;
 }
 
index 5a53a57..19e3ad5 100644 (file)
@@ -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,
index 09c013d..792e4ef 100644 (file)
@@ -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;