afs: Treat vc_error as a CheckCode-translated code
authorAndrew Deason <adeason@sinenomine.net>
Thu, 26 Dec 2013 21:42:46 +0000 (16:42 -0500)
committerDerrick Brashear <shadow@your-file-system.com>
Wed, 29 Jan 2014 15:34:47 +0000 (07:34 -0800)
The vcache field vc_error is generally treated as an error code that
has been translated through afs_CheckCode, but this is inconsistent in
a few places. Fix this in a few ways:

 - Adjust afs_nfsrdwr so we do not call afs_CheckCode on vc_error,
   translating the error code twice.

 - Change afs_close to store vc_error in code_checkcode, and have the
   logging code check for specific values in code_checkcode as well.
   Log unknown values of code and code_checkcode, so we can
   distinguish between e.g. a 'code' value of VBUSY, and a
   'code_checkcode' value of ETIMEDOUT.

Change-Id: Iab4928efd183fb6c5b0b0f30375b9952ba13b45a
Reviewed-on: http://gerrit.openafs.org/10634
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Tested-by: Derrick Brashear <shadow@your-file-system.com>

src/afs/SOLARIS/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_write.c

index 55415ff..93d717a 100644 (file)
@@ -610,6 +610,7 @@ afs_nfsrdwr(struct vcache *avc, struct uio *auio, enum uio_rw arw,
 {
     afs_int32 code;
     afs_int32 code2;
+    afs_int32 code_checkcode = 0;
     int counter;
     afs_int32 mode, sflags;
     char *data;
@@ -908,7 +909,7 @@ afs_nfsrdwr(struct vcache *avc, struct uio *auio, enum uio_rw arw,
     }
 
     if (!code && avc->vc_error) {
-       code = avc->vc_error;
+       code = code_checkcode = avc->vc_error;
     }
     ReleaseWriteLock(&avc->lock);
     if (!code) {
@@ -922,7 +923,11 @@ afs_nfsrdwr(struct vcache *avc, struct uio *auio, enum uio_rw arw,
      */
     if (code == 0 && extraResid > 0)
        auio->uio_resid += extraResid;
-    return afs_CheckCode(code, &treq, 46);
+    if (code_checkcode) {
+       return code_checkcode;
+    } else {
+       return afs_CheckCode(code, &treq, 46);
+    }
 }
 
 int
index 2bc85eb..fee9326 100644 (file)
@@ -576,9 +576,13 @@ afs_close(OSI_VC_DECL(avc), afs_int32 aflags, afs_ucred_t *acred)
 #ifdef AFS_AIX32_ENV
            osi_ReleaseVM(avc, acred);
 #endif
-           /* printf("avc->vc_error=%d\n", avc->vc_error); */
-           code = avc->vc_error;
-           code_checkcode = 0;
+           /* We don't know what the original raw error code was, so set
+            * 'code' to 0. But we have the afs_CheckCode-translated error
+            * code, so put that in code_checkcode. We cannot just set code
+            * to avc->vc_error, since vc_error is a checkcode-translated
+            * error code, and 'code' is supposed to be a raw error code. */
+           code = 0;
+           code_checkcode = avc->vc_error;
            avc->vc_error = 0;
        }
        ReleaseWriteLock(&avc->lock);
@@ -588,19 +592,19 @@ afs_close(OSI_VC_DECL(avc), afs_int32 aflags, afs_ucred_t *acred)
            afs_warnuser("afs: failed to store file (network problems)\n");
        }
 #ifdef AFS_SUN5_ENV
-       else if (code == ENOSPC) {
+       else if (code == ENOSPC || code_checkcode == ENOSPC) {
            afs_warnuser
                ("afs: failed to store file (over quota or partition full)\n");
        }
 #else
-       else if (code == ENOSPC) {
+       else if (code == ENOSPC || code_checkcode == ENOSPC) {
            afs_warnuser("afs: failed to store file (partition full)\n");
-       } else if (code == EDQUOT) {
+       } else if (code == EDQUOT || code_checkcode == EDQUOT) {
            afs_warnuser("afs: failed to store file (over quota)\n");
        }
 #endif
-       else if (code != 0)
-           afs_warnuser("afs: failed to store file (%d)\n", code);
+       else if (code || code_checkcode)
+           afs_warnuser("afs: failed to store file (%d/%d)\n", code, code_checkcode);
 
        /* finally, we flush any text pages lying around here */
        hzero(avc->flushDV);
@@ -616,7 +620,8 @@ afs_close(OSI_VC_DECL(avc), afs_int32 aflags, afs_ucred_t *acred)
 #ifdef AFS_AIX32_ENV
            osi_ReleaseVM(avc, acred);
 #endif
-           code = avc->vc_error;
+           code = 0;
+           code_checkcode = avc->vc_error;
            avc->vc_error = 0;
        }
 #if defined(AFS_FBSD80_ENV)