bypasscache: do errors correctly

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>
This commit is contained in:
Derrick Brashear 2011-10-06 04:04:36 -04:00
parent 6f59c71988
commit 28a159b2bf

View File

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