Windows: rx_Write failures must be processed
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 3 Sep 2009 02:54:17 +0000 (22:54 -0400)
committerJeffrey Altman <jaltman|account-1000011@unknown>
Thu, 3 Sep 2009 13:28:27 +0000 (06:28 -0700)
The error code returned by rx_Write takes precedence under
all circumstances over the error returned by EndRXAFS_StoreData.

cm_ReleaseBIOD must apply the error code to all buffers in the
BIOD list.

cm_ReleaseBIOD accepts an error code, not a boolean indicating
failure.

Fix a related signed/unsigned error.

FIXES 125351

LICENSE MIT

Reviewed-on: http://gerrit.openafs.org/396
Tested-by: Asanka Herath <asanka@secure-endpoints.com>
Reviewed-by: Asanka Herath <asanka@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_dcache.h

index fd82c6c..2b22338 100644 (file)
@@ -268,7 +268,7 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
         }
 #endif
         /* Prefer StoreData error over rx_EndCall error */
-        if (code == 0 && code1 != 0)
+        if (code1 != 0)
             code = code1;
     } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
 
@@ -1282,7 +1282,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp,
 /* release a bulk I/O structure that was setup by cm_SetupFetchBIOD or by
  * cm_SetupStoreBIOD
  */
-void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, int failed, int scp_locked)
+void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked)
 {
     cm_scache_t *scp;          /* do not release; not held in biop */
     cm_buf_t *bufp;
@@ -1325,9 +1325,40 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, int failed, int scp_locked)
                    osi_Log2(afsd_logp, "cm_ReleaseBIOD Waking [scp 0x%p] bp 0x%p", scp, bufp);
                    osi_Wakeup((LONG_PTR) bufp);
                }
-               if (failed)
+               if (code) {
                    bufp->flags &= ~CM_BUF_WRITING;
-               else {
+                    switch (code) {
+                    case CM_ERROR_NOSUCHFILE:
+                    case CM_ERROR_BADFD:
+                    case CM_ERROR_NOACCESS:
+                    case CM_ERROR_QUOTA:
+                    case CM_ERROR_SPACE:
+                    case CM_ERROR_TOOBIG:
+                    case CM_ERROR_READONLY:
+                    case CM_ERROR_NOSUCHPATH:
+                        /*
+                         * Apply the fatal error to this buffer.
+                         */
+                        bufp->flags &= ~CM_BUF_DIRTY;
+                        bufp->flags |= CM_BUF_ERROR;
+                        bufp->dirty_offset = 0;
+                        bufp->dirty_length = 0;
+                        bufp->error = code;
+                        bufp->dataVersion = CM_BUF_VERSION_BAD;
+                        bufp->dirtyCounter++;
+                        break;
+                    case CM_ERROR_TIMEDOUT:
+                    case CM_ERROR_ALLDOWN:
+                    case CM_ERROR_ALLBUSY:
+                    case CM_ERROR_ALLOFFLINE:
+                    case CM_ERROR_CLOCKSKEW:
+                    default:
+                        /* do not mark the buffer in error state but do
+                        * not attempt to complete the rest either.
+                        */
+                        break;
+                    }
+               } else {
                    bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY);
                     bufp->dirty_offset = bufp->dirty_length = 0;
                 }
@@ -1359,9 +1390,9 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *userp
                   cm_req_t *reqp)
 {
     long code, code1;
-    afs_int32 nbytes;                  /* bytes in transfer */
-    afs_int32 nbytes_hi = 0;            /* high-order 32 bits of bytes in transfer */
-    afs_int64 length_found = 0;
+    afs_uint32 nbytes;                 /* bytes in transfer */
+    afs_uint32 nbytes_hi = 0;            /* high-order 32 bits of bytes in transfer */
+    afs_uint64 length_found = 0;
     long rbytes;                       /* bytes in rx_Read call */
     long temp;
     AFSFetchStatus afsStatus;
index 8e27551..2d7e058 100644 (file)
@@ -38,7 +38,7 @@ extern long cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep,
 extern long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp,
        cm_bulkIO_t *biop, cm_user_t *up, cm_req_t *reqp);
 
-extern void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, int failed, int scp_locked);
+extern void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long failed, int scp_locked);
 
 extern long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp,
        long inSize, cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp);