Don't throw data away in afs_StoreMini
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Fri, 22 Jan 2010 20:11:21 +0000 (20:11 +0000)
committerDerrick Brashear <shadow|account-1000005@unknown>
Fri, 22 Jan 2010 22:48:48 +0000 (14:48 -0800)
afs_StoreMini had some interesting error handling. Instead of returning
the error code from StoreData, it would return the error from EndCall,
potentially masking the StoreData error. When it encountered an error
it would discard all of the cached data.

StoreMini's only caller is afs_StoreAllSegments. If StoreAllSegments is
called from DoPartialWrite, then it squashes the error code. This
combination could lead to the user's data being disposed of, without an
error being reported.

Fix all of this by not invalidating segments in StoreMini. Make
StoreMini static to make it clear its only used by StoreAllSegments, and
fix the error handling in StoreMini so that StoreData errors always take
priority.

Change-Id: I41f0c753655fac343485d2a473ad70b6ae96bb78
Reviewed-on: http://gerrit.openafs.org/1147
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

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

index e97cd7b..9c84983 100644 (file)
@@ -795,7 +795,6 @@ extern int HandleIoctl(register struct vcache *avc, register afs_int32 acom,
 
 
 /* afs_segments.c */
-extern int afs_StoreMini(register struct vcache *avc, struct vrequest *areq);
 extern int afs_StoreAllSegments(register struct vcache *avc,
                                struct vrequest *areq, int sync);
 extern int afs_InvalidateAllSegments(struct vcache *avc);
index 04f5c9c..a821d73 100644 (file)
@@ -35,14 +35,14 @@ afs_uint32 afs_stampValue = 0;
  *     We're write-locked upon entry.
  */
 
-int
+static int
 afs_StoreMini(register struct vcache *avc, struct vrequest *areq)
 {
     register struct afs_conn *tc;
     struct AFSStoreStatus InStatus;
     struct AFSFetchStatus OutStatus;
     struct AFSVolSync tsync;
-    register afs_int32 code;
+    register afs_int32 code, code2;
     register struct rx_call *tcall;
     afs_size_t tlen, xlen = 0;
     XSTATS_DECLS;
@@ -109,7 +109,9 @@ afs_StoreMini(register struct vcache *avc, struct vrequest *areq)
            if (code == 0) {
                code = EndRXAFS_StoreData(tcall, &OutStatus, &tsync);
            }
-           code = rx_EndCall(tcall, code);
+           code2 = rx_EndCall(tcall, code);
+           if (code2 && !code)
+               code = code2;
            RX_AFS_GLOCK();
            XSTATS_END_TIME;
 #ifdef AFS_64BIT_CLIENT
@@ -124,14 +126,10 @@ afs_StoreMini(register struct vcache *avc, struct vrequest *areq)
             (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_STOREDATA,
              SHARED_LOCK, NULL));
 
-    if (code == 0) {
+    if (code == 0)
        afs_ProcessFS(avc, &OutStatus, areq);
-    } else {
-       /* blew it away */
-       afs_InvalidateAllSegments(avc);
-    }
-    return code;
 
+    return code;
 }                              /*afs_StoreMini */
 
 /*