bypasscache: do errors correctly
authorDerrick Brashear <shadow@dementix.org>
Thu, 6 Oct 2011 08:04:36 +0000 (04:04 -0400)
committerDerrick Brashear <shadow@dementix.org>
Mon, 24 Oct 2011 11:44:31 +0000 (04:44 -0700)
do set errors when we bomb out early
do not unlock and return early when we happen to do a correct zero
length read
do set errors the kernel can deal with if we're feeding a page routine

Change-Id: I1dca1f9e3b0f3d24da3e4f55b473775a737370b4
Reviewed-on: http://gerrit.openafs.org/5554
Reviewed-by: Derrick Brashear <shadow@dementix.org>
Tested-by: Derrick Brashear <shadow@dementix.org>

src/afs/afs_bypasscache.c

index b887289..0dd7106 100644 (file)
@@ -379,7 +379,7 @@ afs_NoCacheFetchProc(struct rx_call *acall,
        code = rx_Read(acall, (char *)&length, sizeof(afs_int32));
        COND_RE_GLOCK(locked);
        if (code != sizeof(afs_int32)) {
-           result = 0;
+           result = EIO;
            afs_warn("Preread error. code: %d instead of %d\n",
                code, (int)sizeof(afs_int32));
            unlock_and_release_pages(auio);
@@ -429,15 +429,17 @@ afs_NoCacheFetchProc(struct rx_call *acall,
                    COND_RE_GLOCK(locked);
                    if (bytes < 0) {
                        afs_warn("afs_NoCacheFetchProc: rx_Read error. Return code was %d\n", bytes);
-                       result = 0;
+                       result = bytes;
                        unlock_and_release_pages(auio);
                        goto done;
                    } else if (bytes == 0) {
-                       result = 0;
+                       /* we failed to read the full length */
+                       result = EIO;
                        afs_warn("afs_NoCacheFetchProc: rx_Read returned zero. Aborting.\n");
                        unlock_and_release_pages(auio);
                        goto done;
                    }
+                   size -= bytes;
                    length -= bytes;
                    iovno = 0;
                }
@@ -445,14 +447,14 @@ afs_NoCacheFetchProc(struct rx_call *acall,
                if (pageoff + (rxiov[iovno].iov_len - iovoff) <= PAGE_CACHE_SIZE) {
                    /* Copy entire (or rest of) current iovec into current page */
                    if (pp)
-                     copy_pages(pp, pageoff, rxiov, iovno, iovoff, auio);
+                       copy_pages(pp, pageoff, rxiov, iovno, iovoff, auio);
                    pageoff += rxiov[iovno].iov_len - iovoff;
                    iovno++;
                    iovoff = 0;
                } else {
                    /* Copy only what's needed to fill current page */
                    if (pp)
-                     copy_page(pp, pageoff, rxiov, iovno, iovoff, auio);
+                       copy_page(pp, pageoff, rxiov, iovno, iovoff, auio);
                    iovoff += PAGE_CACHE_SIZE - pageoff;
                    pageoff = PAGE_CACHE_SIZE;
                }
@@ -654,7 +656,8 @@ done:
      * Copy appropriate fields into vcache
      */
 
-    afs_ProcessFS(avc, &tcallspec->OutStatus, areq);
+    if (!code)
+       afs_ProcessFS(avc, &tcallspec->OutStatus, areq);
 
     osi_Free(areq, sizeof(struct vrequest));
     osi_Free(tcallspec, sizeof(struct tlocal1));